From 08fd759a4c0a58b0cd2f6a9b6b5db3c92e71447a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 22 Dec 2024 12:57:11 +0100 Subject: [PATCH 1/9] Simplify PublicTopLevelProgramGenerator --- .../PublicTopLevelProgramGenerator.cs | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 5dc4ec276607..421f1a95b528 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -18,24 +18,28 @@ public partial class Program { } public void Initialize(IncrementalGeneratorInitializationContext context) { var internalGeneratedProgramClass = context.CompilationProvider - // Get the entry point associated with the compilation, this maps to the Main method definition - .Select(static (compilation, cancellationToken) => compilation.GetEntryPoint(cancellationToken)) - // Get the containing symbol of the entry point, this maps to the Program class - .Select(static (symbol, _) => symbol?.ContainingSymbol) - // If the program class is already public, we don't need to generate anything. - .Select(static (symbol, _) => symbol?.DeclaredAccessibility == Accessibility.Public ? null : symbol) - // If the discovered `Program` type is not a class then its not - // generated and has been defined in source, so we can skip it - .Select(static (symbol, _) => symbol is INamedTypeSymbol { TypeKind: TypeKind.Class } ? symbol : null) - // If there are multiple partial declarations, then do nothing since we don't want - // to trample on visibility explicitly set by the user - .Select(static (symbol, _) => symbol is { DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences } ? declaringSyntaxReferences.Single() : null) - // If the `Program` class is already declared in user code, we don't need to generate anything. - .Select(static (declaringSyntaxReference, cancellationToken) => declaringSyntaxReference?.GetSyntax(cancellationToken) is ClassDeclarationSyntax ? null : declaringSyntaxReference); + .Select(static (compilation, cancellationToken) => + { + var entryPoint = compilation.GetEntryPoint(cancellationToken); + return entryPoint is + { + // Get the entry point associated with the compilation, this maps to the Main method definition + // Get the containing symbol of the entry point, this maps to the Program class + // If the discovered `Program` type is not a class then its not + // generated and has been defined in source, so we can skip it + // If the program class is already public, we don't need to generate anything. + ContainingSymbol: { DeclaredAccessibility: Accessibility.Public, TypeKind: TypeKind.Class }, + // If there are multiple partial declarations, then do nothing since we don't want + // to trample on visibility explicitly set by the user + DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences + } && + // If the `Program` class is already declared in user code, we don't need to generate anything. + declaringSyntaxReferences.Single() is not ClassDeclarationSyntax; + }); context.RegisterSourceOutput(internalGeneratedProgramClass, (context, result) => { - if (result is not null) + if (result) { context.AddSource("PublicTopLevelProgram.Generated.g.cs", PublicPartialProgramClassSource); } From 2d16767325ef979cc53d3af83ff64dfe4f4fb236 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 22 Dec 2024 12:59:12 +0100 Subject: [PATCH 2/9] Fix --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 421f1a95b528..f524a1720717 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -20,11 +20,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var internalGeneratedProgramClass = context.CompilationProvider .Select(static (compilation, cancellationToken) => { - var entryPoint = compilation.GetEntryPoint(cancellationToken); - return entryPoint is + // Get the entry point associated with the compilation, this maps to the Main method definition + // Get the containing symbol of the entry point, this maps to the Program class + return compilation.GetEntryPoint(cancellationToken)?.ContainingSymbol is { - // Get the entry point associated with the compilation, this maps to the Main method definition - // Get the containing symbol of the entry point, this maps to the Program class // If the discovered `Program` type is not a class then its not // generated and has been defined in source, so we can skip it // If the program class is already public, we don't need to generate anything. From 1251fcb95245092dd0700dc769682f4fa175d3b5 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 22 Dec 2024 13:00:47 +0100 Subject: [PATCH 3/9] Use expression body --- .../PublicTopLevelProgramGenerator.cs | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index f524a1720717..d1e833da9cf9 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -17,24 +17,22 @@ public partial class Program { } public void Initialize(IncrementalGeneratorInitializationContext context) { - var internalGeneratedProgramClass = context.CompilationProvider - .Select(static (compilation, cancellationToken) => - { - // Get the entry point associated with the compilation, this maps to the Main method definition - // Get the containing symbol of the entry point, this maps to the Program class - return compilation.GetEntryPoint(cancellationToken)?.ContainingSymbol is - { - // If the discovered `Program` type is not a class then its not - // generated and has been defined in source, so we can skip it - // If the program class is already public, we don't need to generate anything. - ContainingSymbol: { DeclaredAccessibility: Accessibility.Public, TypeKind: TypeKind.Class }, - // If there are multiple partial declarations, then do nothing since we don't want - // to trample on visibility explicitly set by the user - DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences - } && - // If the `Program` class is already declared in user code, we don't need to generate anything. - declaringSyntaxReferences.Single() is not ClassDeclarationSyntax; - }); + var internalGeneratedProgramClass = context.CompilationProvider.Select(static (compilation, cancellationToken) => + // Get the entry point associated with the compilation, this maps to the Main method definition + // Get the containing symbol of the entry point, this maps to the Program class + compilation.GetEntryPoint(cancellationToken)?.ContainingSymbol is + { + // If the discovered `Program` type is not a class then its not + // generated and has been defined in source, so we can skip it + // If the program class is already public, we don't need to generate anything. + ContainingSymbol: { DeclaredAccessibility: Accessibility.Public, TypeKind: TypeKind.Class }, + // If there are multiple partial declarations, then do nothing since we don't want + // to trample on visibility explicitly set by the user + DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences + } && + // If the `Program` class is already declared in user code, we don't need to generate anything. + declaringSyntaxReferences.Single() is not ClassDeclarationSyntax + ); context.RegisterSourceOutput(internalGeneratedProgramClass, (context, result) => { From 3e10c8728089b90f069cc6cafbb26f8444d3fae8 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 31 Dec 2024 01:10:14 +0100 Subject: [PATCH 4/9] Fix build --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index d1e833da9cf9..05584950e73b 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -20,12 +20,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var internalGeneratedProgramClass = context.CompilationProvider.Select(static (compilation, cancellationToken) => // Get the entry point associated with the compilation, this maps to the Main method definition // Get the containing symbol of the entry point, this maps to the Program class - compilation.GetEntryPoint(cancellationToken)?.ContainingSymbol is + compilation.GetEntryPoint(cancellationToken)?.ContainingSymbol is INamedTypeSymbol { // If the discovered `Program` type is not a class then its not // generated and has been defined in source, so we can skip it // If the program class is already public, we don't need to generate anything. - ContainingSymbol: { DeclaredAccessibility: Accessibility.Public, TypeKind: TypeKind.Class }, + DeclaredAccessibility: Accessibility.Public, + TypeKind: TypeKind.Class, // If there are multiple partial declarations, then do nothing since we don't want // to trample on visibility explicitly set by the user DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences From 675e6aca9ffafa04f929ed2e586c1c4eb572d3a5 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 31 Dec 2024 02:23:20 +0100 Subject: [PATCH 5/9] Fix build error --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 05584950e73b..2144f36cb75a 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -32,7 +32,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences } && // If the `Program` class is already declared in user code, we don't need to generate anything. - declaringSyntaxReferences.Single() is not ClassDeclarationSyntax + declaringSyntaxReferences.Single().GetSyntax(cancellationToken) is not ClassDeclarationSyntax ); context.RegisterSourceOutput(internalGeneratedProgramClass, (context, result) => From 1bea5a6a639dd297b619df7923c66afb97af2c76 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 13 Jan 2025 21:34:53 +0100 Subject: [PATCH 6/9] Fix accessibility check --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 2144f36cb75a..e7048722e8a6 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -25,7 +25,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // If the discovered `Program` type is not a class then its not // generated and has been defined in source, so we can skip it // If the program class is already public, we don't need to generate anything. - DeclaredAccessibility: Accessibility.Public, + DeclaredAccessibility: not Accessibility.Public, TypeKind: TypeKind.Class, // If there are multiple partial declarations, then do nothing since we don't want // to trample on visibility explicitly set by the user From fbfa14b5881fb429c375dbba213a3eb43e97194c Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 15 Jan 2025 14:06:20 +0100 Subject: [PATCH 7/9] Pattern matching --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index e7048722e8a6..236f0991a47b 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -29,10 +29,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context) TypeKind: TypeKind.Class, // If there are multiple partial declarations, then do nothing since we don't want // to trample on visibility explicitly set by the user - DeclaringSyntaxReferences: { Length: 1 } declaringSyntaxReferences + DeclaratingSyntaxReferences: [var singleSyntaxReference] } && // If the `Program` class is already declared in user code, we don't need to generate anything. - declaringSyntaxReferences.Single().GetSyntax(cancellationToken) is not ClassDeclarationSyntax + singleSyntaxReference.GetSyntax(cancellationToken) is not ClassDeclarationSyntax ); context.RegisterSourceOutput(internalGeneratedProgramClass, (context, result) => From cfe96a4607fa2486b9217d38326b6380a510e93b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 15 Jan 2025 14:06:56 +0100 Subject: [PATCH 8/9] Fix typo --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 236f0991a47b..eab540766ccc 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -29,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) TypeKind: TypeKind.Class, // If there are multiple partial declarations, then do nothing since we don't want // to trample on visibility explicitly set by the user - DeclaratingSyntaxReferences: [var singleSyntaxReference] + DeclaraingSyntaxReferences: [var singleSyntaxReference] } && // If the `Program` class is already declared in user code, we don't need to generate anything. singleSyntaxReference.GetSyntax(cancellationToken) is not ClassDeclarationSyntax From 5aa54549d1f5c2cef5d91d8bb1e589857a64da4f Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 15 Jan 2025 14:07:51 +0100 Subject: [PATCH 9/9] Fix typo --- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index eab540766ccc..16ca6b6dad84 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -29,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) TypeKind: TypeKind.Class, // If there are multiple partial declarations, then do nothing since we don't want // to trample on visibility explicitly set by the user - DeclaraingSyntaxReferences: [var singleSyntaxReference] + DeclaringSyntaxReferences: [var singleSyntaxReference] } && // If the `Program` class is already declared in user code, we don't need to generate anything. singleSyntaxReference.GetSyntax(cancellationToken) is not ClassDeclarationSyntax