|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities.TestGenerators;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.SourceGeneration;
internal static class IncrementalGeneratorInitializationContextExtensions
{
public static IncrementalValuesProvider<T> ForAttributeWithSimpleName<T>(
this IncrementalGeneratorInitializationContext context, string simpleName)
where T : SyntaxNode
{
return context.SyntaxProvider.ForAttributeWithSimpleName(
simpleName,
(node, _) => node is T).SelectMany((t, _) => t.matches.Cast<T>()).WithTrackingName("result_ForAttribute");
}
public static IncrementalValuesProvider<T> ForAttributeWithMetadataName<T>(
this IncrementalGeneratorInitializationContext context, string fullyQualifiedMetadataName)
where T : SyntaxNode
{
return context.SyntaxProvider.ForAttributeWithMetadataName(
fullyQualifiedMetadataName,
(node, _) => node is T,
(context, cancellationToken) => (T)context.TargetNode);
}
}
public class GeneratorDriverTests_Attributes_FullyQualifiedName : CSharpTestBase
{
#region Non-Incremental tests
// These tests just validate basic correctness of results in different scenarios, without actually validating
// that the incremental nature of this provider works properly.
[Fact]
public void FindCorrectAttributeOnTopLevelClass_WhenSearchingForClassDeclaration1()
{
var source = @"
[N1.X]
class C1 { }
[N2.X]
class C2 { }
namespace N1
{
class XAttribute : System.Attribute { }
}
namespace N2
{
class XAttribute : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("N1.XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C1" }));
}
[Theory]
[InlineData("XAttribute")]
[InlineData("X")]
[InlineData("N1.xAttribute")]
[InlineData("N1.x")]
public void DoNotFindAttributeOnTopLevelClass_WhenSearchingSimpleName1(string name)
{
var source = @"
[N1.X]
class C1 { }
[N2.X]
class C2 { }
namespace N1
{
class XAttribute : System.Attribute { }
}
namespace N2
{
class XAttribute : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>(name);
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
}
[Fact]
public void FindCorrectAttributeOnTopLevelClass_WhenSearchingForClassDeclaration2()
{
var source = @"
[N1.X]
class C1 { }
[N2.X]
class C2 { }
namespace N1
{
class XAttribute : System.Attribute { }
}
namespace N2
{
class XAttribute : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("N2.XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C2" }));
}
[Theory]
[InlineData("CLSCompliant(true)")]
[InlineData("CLSCompliantAttribute(true)")]
[InlineData("System.CLSCompliant(true)")]
[InlineData("System.CLSCompliantAttribute(true)")]
public void FindAssemblyAttribute1(string attribute)
{
var source = @$"
using System;
[assembly: {attribute}]
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<CompilationUnitSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.Single()));
}
[Theory]
[InlineData("CLSCompliant(true)")]
[InlineData("CLSCompliantAttribute(true)")]
[InlineData("System.CLSCompliant(true)")]
[InlineData("System.CLSCompliantAttribute(true)")]
public void FindModuleAttribute1(string attribute)
{
var source = @$"
using System;
[module: {attribute}]
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<CompilationUnitSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.Single()));
}
[Theory]
[InlineData("")]
[InlineData("class WithoutAttributes { }")]
public void FindAssemblyAttribute2(string source2)
{
var source1 = @"
using System;
[assembly: CLSCompliant(true)]
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<CompilationUnitSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.First()));
}
[Theory]
[InlineData("")]
[InlineData("class WithoutAttributes { }")]
public void FindAssemblyAttribute3(string source1)
{
var source2 = @"
using System;
[assembly: CLSCompliant(true)]
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<CompilationUnitSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.Last()));
}
[Fact]
public void FindAssemblyAttribute4()
{
var source1 = @"
using System;
[assembly: CLSCompliant(true)]
";
var source2 = @"
using System;
[assembly: CLSCompliant(false)]
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<CompilationUnitSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.First()),
step => Assert.True(step.Outputs.Single().Value is CompilationUnitSyntax c && c.SyntaxTree == compilation.SyntaxTrees.Last()));
}
[Fact]
public void FindTopLocalFunctionAttribute1()
{
var source = @"
using System;
[CLSCompliant(true)]
void LocalFunc()
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<LocalFunctionStatementSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is LocalFunctionStatementSyntax { Identifier.ValueText: "LocalFunc" }));
}
[Fact]
public void FindNestedLocalFunctionAttribute1()
{
var source = @"
using System;
class C
{
void M()
{
[CLSCompliant(true)]
void LocalFunc()
{
}
}
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<LocalFunctionStatementSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is LocalFunctionStatementSyntax { Identifier.ValueText: "LocalFunc" }));
}
[Fact]
public void FindNestedLocalFunctionAttribute2()
{
var source = @"
using System;
class C
{
void M()
{
var v = () =>
{
[CLSCompliant(true)]
void LocalFunc()
{
}
};
}
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<LocalFunctionStatementSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is LocalFunctionStatementSyntax { Identifier.ValueText: "LocalFunc" }));
}
[Fact]
public void FindTypeParameterFunctionAttribute1()
{
var source = @"
using System;
class C<[CLSCompliant(true)] T>
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<TypeParameterSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is TypeParameterSyntax { Identifier.ValueText: "T" }));
}
[Fact]
public void FindMethodAttribute1()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
void M()
{
}
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<MethodDeclarationSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is MethodDeclarationSyntax { Identifier.ValueText: "M" }));
}
[Fact]
public void FindMethodReturnAttribute1()
{
var source = @"
using System;
class C
{
[return: CLSCompliant(true)]
void M()
{
}
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<MethodDeclarationSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is MethodDeclarationSyntax { Identifier.ValueText: "M" }));
}
[Fact]
public void FindPartialMethodAttribute1()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
internal partial void M();
internal partial void M() { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<MethodDeclarationSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is MethodDeclarationSyntax { Identifier.ValueText: "M", Body: null, ExpressionBody: null }));
}
[Fact]
public void FindPartialMethodAttribute2()
{
var source = @"
using System;
class C
{
internal partial void M();
[CLSCompliant(true)]
internal partial void M() { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<MethodDeclarationSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is MethodDeclarationSyntax { Identifier.ValueText: "M", Body: not null }));
}
[Fact]
public void FindFieldAttribute1()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
int m;
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<VariableDeclaratorSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is VariableDeclaratorSyntax { Identifier.ValueText: "m" }));
}
[Fact]
public void FindFieldAttribute2()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
int m, n;
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<VariableDeclaratorSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.Collection(step.Outputs,
v => Assert.True(v.Value is VariableDeclaratorSyntax { Identifier.ValueText: "m" }),
v => Assert.True(v.Value is VariableDeclaratorSyntax { Identifier.ValueText: "n" })));
}
[Fact]
public void FindEventFieldAttribute1()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
event Action m;
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<VariableDeclaratorSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is VariableDeclaratorSyntax { Identifier.ValueText: "m" }));
}
[Fact]
public void FindEventFieldAttribute2()
{
var source = @"
using System;
class C
{
[CLSCompliant(true)]
event Action m, n;
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<VariableDeclaratorSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.Collection(step.Outputs,
v => Assert.True(v.Value is VariableDeclaratorSyntax { Identifier.ValueText: "m" }),
v => Assert.True(v.Value is VariableDeclaratorSyntax { Identifier.ValueText: "n" })));
}
[Fact]
public void FindParenthesizedLambdaAttribute1()
{
var source = @"
using System;
Func<int, int> v = [CLSCompliant(true)] (int i) => i;
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<LambdaExpressionSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is LambdaExpressionSyntax));
}
[Fact]
public void FindAccessorAttribute1()
{
var source = @"
using System;
class C
{
int Prop
{
[CLSCompliant(true)]
get => 0;
}
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<AccessorDeclarationSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is AccessorDeclarationSyntax { RawKind: (int)SyntaxKind.GetAccessorDeclaration }));
}
[Fact]
public void FindTypeParameterAttribute1()
{
var source = @"
using System;
class C<[CLSCompliant(true)]T>
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<TypeParameterSyntax>("System.CLSCompliantAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is TypeParameterSyntax { Identifier.ValueText: "T" }));
}
[Fact]
public void FindNestedAttribute1()
{
var source = @"
[Outer1.Inner]
class C1 { }
[Outer2.Inner]
class C2 { }
class Outer1
{
public class InnerAttribute : System.Attribute { }
}
class Outer2
{
public class InnerAttribute : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer1+InnerAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C1" }));
}
[Fact]
public void FindNestedAttribute2()
{
var source = @"
[Outer1.Inner]
class C1 { }
[Outer2.Inner]
class C2 { }
class Outer1
{
public class InnerAttribute : System.Attribute { }
}
class Outer2
{
public class InnerAttribute : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer2+InnerAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C2" }));
}
[Fact]
public void FindNestedGenericAttribute1()
{
var source = @"
[Outer1.Inner<int>]
class C1 { }
[Outer2.Inner<int, string>]
class C2 { }
class Outer1
{
public class InnerAttribute<T1> : System.Attribute{ }
}
class Outer2
{
public class InnerAttribute<T1, T2> : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer1+InnerAttribute`1");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C1" }));
}
[Fact]
public void FindNestedGenericAttribute2()
{
var source = @"
[Outer1.Inner<int>]
class C1 { }
[Outer2.Inner<int, string>]
class C2 { }
class Outer1
{
public class InnerAttribute<T1> : System.Attribute{ }
}
class Outer2
{
public class InnerAttribute<T1, T2> : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer2+InnerAttribute`2");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C2" }));
}
[Fact]
public void DoNotFindNestedGenericAttribute1()
{
var source = @"
[Outer1.Inner<int>]
class C1 { }
[Outer2.Inner<int, string>]
class C2 { }
class Outer1
{
public class InnerAttribute<T1> : System.Attribute{ }
}
class Outer2
{
public class InnerAttribute<T1, T2> : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer1+InnerAttribute`2");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
}
[Fact]
public void DoNotFindNestedGenericAttribute2()
{
var source = @"
[Outer1.Inner<int>]
class C1 { }
[Outer2.Inner<int, string>]
class C2 { }
class Outer1
{
public class InnerAttribute<T1> : System.Attribute{ }
}
class Outer2
{
public class InnerAttribute<T1, T2> : System.Attribute { }
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("Outer2+InnerAttribute`1");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists1()
{
var source = @"
[X][X]
class C { }
class XAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 2);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists1B()
{
var source = @"
[X, X]
class C { }
class XAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 2);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists2()
{
var source = @"
[X][Y]
class C { }
class XAttribute : System.Attribute { }
class YAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 1);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists2B()
{
var source = @"
[X, Y]
class C { }
class XAttribute : System.Attribute { }
class YAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 1);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists3()
{
var source = @"
[Y][X]
class C { }
class XAttribute : System.Attribute { }
class YAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 1);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
[Fact]
public void FindAttributeOnTopLevelClass_WhenSearchingForClassDeclaration_MultipleAttributeLists3B()
{
var source = @"
[Y, X]
class C { }
class XAttribute : System.Attribute { }
class YAttribute : System.Attribute { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var counter = 0;
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.SyntaxProvider.ForAttributeWithMetadataName<ClassDeclarationSyntax>(
"XAttribute",
(_, _) => true,
(ctx, _) =>
{
Assert.True(ctx.Attributes.Length == 1);
return (ClassDeclarationSyntax)ctx.TargetNode;
});
ctx.RegisterSourceOutput(input, (spc, node) => { counter++; });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
Assert.Equal(1, counter);
}
#endregion
#region Incremental tests
// These tests validate minimal recomputation performed after changes are made to the compilation.
[Fact]
public void RerunOnSameCompilationCachesResultFully()
{
var source = @"
[X]
class C { }
class XAttribute : System.Attribute
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
// re-run without changes
driver = driver.RunGenerators(compilation);
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_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);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
[Fact]
public void RerunWithReferencesChange()
{
var source = @"
[X]
class C { }
class XAttribute : System.Attribute
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
// re-run without changes
driver = driver.RunGenerators(compilation.RemoveAllReferences());
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_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);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
[Fact]
public void RerunWithAddedFile1()
{
var source = @"
[X]
class C { }
class XAttribute : System.Attribute
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
driver = driver.RunGenerators(compilation.AddSyntaxTrees(compilation.SyntaxTrees.First().WithChangedText(SourceText.From(""))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_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));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
[Fact]
public void RerunWithAddedFile2()
{
var source = @"
[X]
class C { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
driver = driver.RunGenerators(compilation.AddSyntaxTrees(compilation.SyntaxTrees.First().WithChangedText(SourceText.From(@"
class XAttribute : System.Attribute
{
}"))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_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));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
[Fact]
public void RerunWithAddedFile_MultipleResults_SameFile1()
{
var source = @"
[X]
class C1 { }
[X]
class C2 { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
driver = driver.RunGenerators(compilation.AddSyntaxTrees(compilation.SyntaxTrees.First().WithChangedText(SourceText.From(@"
class XAttribute : System.Attribute
{
}"))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.Collection(step.Outputs,
t => Assert.True(t.Value is ClassDeclarationSyntax { Identifier.ValueText: "C1" }),
t => Assert.True(t.Value is ClassDeclarationSyntax { Identifier.ValueText: "C2" })));
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["compilationGlobalAliases_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));
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Collection(runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs,
t => Assert.Equal(IncrementalStepRunReason.Cached, t.Reason));
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs,
t => Assert.Equal(IncrementalStepRunReason.Modified, t.Reason),
t => Assert.Equal(IncrementalStepRunReason.Modified, t.Reason));
}
[Fact]
public void RerunWithAddedFile_MultipleResults_MultipleFile1()
{
var source1 = @"
[X]
class C1 { }
";
var source2 = @"
[X]
class C2 { }
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
driver = driver.RunGenerators(compilation.AddSyntaxTrees(compilation.SyntaxTrees.First().WithChangedText(SourceText.From(@"
class XAttribute : System.Attribute
{
}"))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.Collection(step.Outputs, t => Assert.True(t.Value is ClassDeclarationSyntax { Identifier.ValueText: "C1" })),
step => Assert.Collection(step.Outputs, t => Assert.True(t.Value is ClassDeclarationSyntax { Identifier.ValueText: "C2" })));
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["compilationGlobalAliases_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));
Assert.Collection(runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Collection(runResult.TrackedSteps["result_ForAttributeInternal"],
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason));
Assert.Collection(runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"],
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason));
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason),
s => Assert.Equal(IncrementalStepRunReason.Modified, s.Outputs.Single().Reason));
}
[Fact]
public void RerunWithChangedFileThatNowReferencesAttribute1()
{
var source = @"
class C { }
class XAttribute : System.Attribute
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
Assert.Single(compilation.SyntaxTrees);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
driver = driver.RunGenerators(compilation.ReplaceSyntaxTree(
compilation.SyntaxTrees.First(),
compilation.SyntaxTrees.First().WithChangedText(SourceText.From(@"
[X]
class C { }
class XAttribute : System.Attribute
{
}
"))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
[Fact]
public void RerunWithChangedFileThatNowReferencesAttribute2()
{
var source1 = @"
class C { }
";
var source2 = @"
class XAttribute : System.Attribute
{
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugDllThrowing, parseOptions: parseOptions);
var generator = new IncrementalGeneratorWrapper(new PipelineCallbackGenerator(ctx =>
{
var input = ctx.ForAttributeWithMetadataName<ClassDeclarationSyntax>("XAttribute");
ctx.RegisterSourceOutput(input, (spc, node) => { });
}));
GeneratorDriver driver = CSharpGeneratorDriver.Create(new ISourceGenerator[] { generator }, parseOptions: parseOptions, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
var runResult = driver.GetRunResult().Results[0];
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttributeWithMetadataName"));
driver = driver.RunGenerators(compilation.ReplaceSyntaxTree(
compilation.SyntaxTrees.First(),
compilation.SyntaxTrees.First().WithChangedText(SourceText.From(@"
[X]
class C { }
"))));
runResult = driver.GetRunResult().Results[0];
Assert.Collection(runResult.TrackedSteps["result_ForAttributeWithMetadataName"],
step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" }));
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["compilationGlobalAliases_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.Modified, o.Reason));
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason);
}
#endregion
}
|