Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter trees to only those containing global-usings or attributes prior to analyzing them. #62444

Merged
merged 10 commits into from
Jul 7, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.SourceGeneration;
using Microsoft.CodeAnalysis.PooledObjects;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.SourceGeneration;
using Roslyn.Utilities;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.CodeAnalysis.CSharp
{
Expand Down Expand Up @@ -60,8 +60,8 @@ public override SeparatedSyntaxList<SyntaxNode> GetAttributesOfAttributeList(Syn
public override bool IsLambdaExpression(SyntaxNode node)
=> node is LambdaExpressionSyntax;

public override SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode node)
=> ((NameSyntax)node).GetUnqualifiedName().Identifier;
public override string GetUnqualifiedIdentifierOfName(SyntaxNode node)
=> ((NameSyntax)node).GetUnqualifiedName().Identifier.ValueText;

public override void AddAliases(GreenNode node, ArrayBuilder<(string aliasName, string symbolName)> aliases, bool global)
{
Expand Down Expand Up @@ -109,8 +109,27 @@ private static Syntax.InternalSyntax.SimpleNameSyntax GetUnqualifiedName(Syntax.

public override void AddAliases(CompilationOptions compilation, ArrayBuilder<(string aliasName, string symbolName)> aliases)
{
// C# doesn't have global aliases at the compilation level.
// C# doesn't have global aliases at the compilation-options, only the compilation-unit level.
return;
}

public override bool ContainsGlobalAliases(SyntaxNode root)
{
// Walk down the green tree to avoid unnecessary allocations of red nodes.
//
// Global usings can only exist at the compilation-unit level, so no need to dive any deeper than that.
var compilationUnit = (Syntax.InternalSyntax.CompilationUnitSyntax)root.Green;

foreach (var directive in compilationUnit.Usings)
{
if (directive.GlobalKeyword != null &&
directive.Alias != null)
{
return true;
}
}

return false;
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1023,8 +1023,8 @@ class C { }
Assert.Collection(runResult.TrackedSteps["result_ForAttribute"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));

Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.False(runResult.TrackedSteps.ContainsKey("individualFileGlobalAliases_ForAttribute"));
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Expand Down Expand Up @@ -1063,8 +1063,8 @@ class C { }
Assert.Collection(runResult.TrackedSteps["result_ForAttribute"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));

Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.False(runResult.TrackedSteps.ContainsKey("individualFileGlobalAliases_ForAttribute"));
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Expand Down Expand Up @@ -1106,14 +1106,13 @@ class C { }

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Removed, s.Outputs.Single().Reason));
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));

// the per-file global aliases get changed (because the last file is removed).
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

// however, the collected global aliases stays the same.
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
Expand Down Expand Up @@ -1161,16 +1160,15 @@ class C { }

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Unchanged, s.Outputs.Single().Reason));
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason);
}

Expand Down Expand Up @@ -1211,17 +1209,16 @@ class C { }

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Unchanged, s.Outputs.Single().Reason));
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["result_ForAttribute"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Expand Down Expand Up @@ -1266,7 +1263,6 @@ class Dummy {}

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Unchanged, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Expand Down Expand Up @@ -1312,19 +1308,13 @@ class C { }
compilation.SyntaxTrees.First()));
runResult = driver.GetRunResult().Results[0];

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Removed, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.False(runResult.TrackedSteps.ContainsKey("individualFileGlobalAliases_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("collectedGlobalAliases_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("allUpGlobalAliases_ForAttribute"));

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason),
o => Assert.Equal(IncrementalStepRunReason.Removed, o.Reason));
Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason);
Assert.False(runResult.TrackedSteps.ContainsKey("compilationUnit_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("compilationUnitAndGlobalAliases_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttribute"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chsienki i need help here. for some reason the incremental generator is not tracking any steps here when the list filters down to the empty set. Can you help me debug through this to find out why that is?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at this, and I see whats going on. I think I have a fix for it, but its a little involved. I think we should open an issue here, and take the fix as a separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked with #62468

}

[Fact]
Expand Down Expand Up @@ -1358,7 +1348,6 @@ class C { }
runResult = driver.GetRunResult().Results[0];

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.New, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Expand Down Expand Up @@ -1403,7 +1392,6 @@ class C { }
runResult = driver.GetRunResult().Results[0];

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.New, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Expand Down Expand Up @@ -1454,11 +1442,9 @@ class D { }"))));

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.New, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
Expand Down Expand Up @@ -1506,11 +1492,9 @@ class D { }"))));

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.New, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs,
o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason),
Expand Down Expand Up @@ -1567,8 +1551,7 @@ class D { }"))));

Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Unchanged, s.Outputs.Single().Reason));
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;

namespace Microsoft.CodeAnalysis.SourceGeneration
Expand All @@ -29,13 +30,15 @@ internal interface ISyntaxHelper

bool IsLambdaExpression(SyntaxNode node);

SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode node);
string GetUnqualifiedIdentifierOfName(SyntaxNode node);

/// <summary>
/// <paramref name="node"/> must be a compilation unit or namespace block.
/// </summary>
void AddAliases(GreenNode node, ArrayBuilder<(string aliasName, string symbolName)> aliases, bool global);
void AddAliases(CompilationOptions options, ArrayBuilder<(string aliasName, string symbolName)> aliases);

bool ContainsGlobalAliases(SyntaxNode root);
}

internal abstract class AbstractSyntaxHelper : ISyntaxHelper
Expand All @@ -45,7 +48,7 @@ internal abstract class AbstractSyntaxHelper : ISyntaxHelper

public abstract bool IsValidIdentifier(string name);

public abstract SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode name);
public abstract string GetUnqualifiedIdentifierOfName(SyntaxNode name);

public abstract bool IsAnyNamespaceBlock(SyntaxNode node);

Expand All @@ -60,5 +63,7 @@ internal abstract class AbstractSyntaxHelper : ISyntaxHelper

public abstract void AddAliases(GreenNode node, ArrayBuilder<(string aliasName, string symbolName)> aliases, bool global);
public abstract void AddAliases(CompilationOptions options, ArrayBuilder<(string aliasName, string symbolName)> aliases);

public abstract bool ContainsGlobalAliases(SyntaxNode root);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,10 @@ public NodeStateTable<T> ToImmutableAndFree()
}

#if DEBUG
// If the caller requested a specific capacity, then we should have added exactly that amount of items.
Debug.Assert(_requestedTableCapacity == null || _requestedTableCapacity == _states.Count);
// If the caller requested a specific capacity, then we should have added either that amount, or some
// amount less than that. It's possible to have added less as a Where clause will mean some amount of
// states are filtered out.
Debug.Assert(_requestedTableCapacity == null || _states.Count <= _requestedTableCapacity);
#endif
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved

// if we added the exact same entries as before, then we can directly embed previous' entry array,
Expand Down
Loading