Skip to content

Commit 3bc89cd

Browse files
committed
Use GetEntrypoint API and transformations for better caching
1 parent 707bd27 commit 3bc89cd

File tree

2 files changed

+19
-32
lines changed

2 files changed

+19
-32
lines changed

src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,35 @@ namespace Microsoft.AspNetCore.SourceGenerators;
1010
[Generator]
1111
public class PublicProgramSourceGenerator : IIncrementalGenerator
1212
{
13+
private const string PublicPartialProgramClassSource = """
14+
// <auto-generated />
15+
public partial class Program { }
16+
""";
17+
1318
public void Initialize(IncrementalGeneratorInitializationContext context)
1419
{
15-
var internalGeneratedProgramClass = context.CompilationProvider.Select((compilation, cancellationToken) =>
16-
{
17-
var program = compilation.GetTypeByMetadataName("Program");
20+
var internalGeneratedProgramClass = context.CompilationProvider
21+
// Get the entry point associated with the compilation, this maps to the Main method definition
22+
.Select((compilation, cancellationToken) => compilation.GetEntryPoint(cancellationToken))
23+
// Get the containing symbol of the entry point, this maps to the Program class
24+
.Select((symbol, _) => symbol?.ContainingSymbol)
1825
// If the program class is already public, we don't need to generate anything.
19-
if (program is null || program.DeclaredAccessibility == Accessibility.Public)
20-
{
21-
return null;
22-
}
23-
// If the discovered `Program` type is an interface, struct or generic type then its not
26+
.Select((symbol, _) => symbol?.DeclaredAccessibility == Accessibility.Public ? null : symbol)
27+
// If the discovered `Program` type is not a class then its not
2428
// generated and has been defined in source, so we can skip it
25-
if (program.TypeKind == TypeKind.Struct || program.TypeKind == TypeKind.Interface || program.IsGenericType)
26-
{
27-
return null;
28-
}
29+
.Select((symbol, _) => symbol is INamedTypeSymbol { TypeKind: TypeKind.Class } ? symbol : null)
2930
// If there are multiple partial declarations, then do nothing since we don't want
3031
// to trample on visibility explicitly set by the user
31-
if (program.DeclaringSyntaxReferences.Length > 1)
32-
{
33-
return null;
34-
}
32+
.Select((symbol, _) => symbol is { DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences } ? declaringSyntaxReferences.Single() : null)
3533
// If the `Program` class is already declared in user code, we don't need to generate anything.
36-
if (program.DeclaringSyntaxReferences.SingleOrDefault()?.GetSyntax(cancellationToken) is ClassDeclarationSyntax)
37-
{
38-
return null;
39-
}
40-
return program;
41-
});
34+
.Select((declaringSyntaxReference, cancellationToken) => declaringSyntaxReference?.GetSyntax(cancellationToken) is ClassDeclarationSyntax ? null : declaringSyntaxReference);
4235

43-
context.RegisterSourceOutput(internalGeneratedProgramClass, (context, symbol) =>
36+
context.RegisterSourceOutput(internalGeneratedProgramClass, (context, result) =>
4437
{
45-
if (symbol is null)
38+
if (result is not null)
4639
{
47-
return;
40+
context.AddSource("PublicTopLevelProgram.Generated.g.cs", PublicPartialProgramClassSource);
4841
}
49-
50-
var output = """
51-
// <auto-generated />
52-
public partial class Program { }
53-
""";
54-
context.AddSource("PublicTopLevelProgram.Generated.cs", output);
5542
});
5643
}
5744
}

src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public async Task GeneratesSource_ProgramWithTopLevelStatements()
2525
public partial class Program { }
2626
""";
2727

28-
await VerifyCS.VerifyAsync(source, "PublicTopLevelProgram.Generated.cs", expected);
28+
await VerifyCS.VerifyAsync(source, "PublicTopLevelProgram.Generated.g.cs", expected);
2929
}
3030

3131
[Fact]

0 commit comments

Comments
 (0)