-
Notifications
You must be signed in to change notification settings - Fork 204
Analyzer to detect missing ASP.NET Core integration registration #1917
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
Merged
Merged
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
6301376
Analyzer
surgupta-msft c50dfe9
Add analyzer
surgupta-msft 2d5b70b
Fix test
surgupta-msft 4819a5d
Adding docs for Analyzer
surgupta-msft 047edbb
Added tests for aspnet analyzer
surgupta-msft d9c1665
Add more tests and code cleanup
surgupta-msft cb41c98
Addressing PR feedback
surgupta-msft 2bb5684
Adding check for Main method
surgupta-msft 5309d78
Merge branch 'main' into surgupta/aspnet-analyzer
surgupta-msft bfd7b3a
Updated analyzer check
surgupta-msft fb93b38
Making Analyzer as part of AspNet package
surgupta-msft ba7f0b0
Add analyzer as part of AspNet project
surgupta-msft 18edbcf
Update sdk analyzer diagnostics
surgupta-msft b097472
Updating version
surgupta-msft 23f0aac
Minor updates
surgupta-msft 7d460f3
Minor csproj cleanup
surgupta-msft 1b35d92
Adding a new project for AspNet analyzers
surgupta-msft 6d2b485
Fix formatting in csproj file
surgupta-msft a2ba972
Removing unecessary check
surgupta-msft eff85a8
Merge branch 'main' into surgupta/aspnet-analyzer
surgupta-msft a03e4a2
Test fix
surgupta-msft 90827fa
Revert "Test fix"
surgupta-msft 7868a53
Test fix
surgupta-msft aa2adfc
Moving aspnet projects in a folder
surgupta-msft 1cbf4f7
Revert "Moving aspnet projects in a folder"
surgupta-msft b9f2351
Fix typo
surgupta-msft 0fcd2fd
Set diagnostic warning
surgupta-msft ba6aa87
Adding new tests project for aspnet core
surgupta-msft 55c1d3e
Added release notes
surgupta-msft c7377e4
Updated analyzer rule doc
surgupta-msft 1f847ca
Removing tools files
surgupta-msft 6b81e33
Rebase with main
surgupta-msft a0cf107
PR cleanup
surgupta-msft 028bfce
PR cleanup
surgupta-msft 226e3b4
Format csproj
surgupta-msft 7e00672
Revert "Format csproj"
surgupta-msft b3b2a09
build fix
surgupta-msft 1e40912
Rebase with main
surgupta-msft 2da778f
Update sln with project
surgupta-msft 54ae68d
Update sln
surgupta-msft 7b0e909
Update sln
surgupta-msft 4b0c3ce
Updating name to ASP.Net Core Integration
surgupta-msft 6b84c1d
Merge branch 'main' into surgupta/aspnet-analyzer
surgupta-msft 4d66267
Updated condition to generate diagnostic
surgupta-msft 529c4c8
Minor cleanup
surgupta-msft 03f59bc
Docs update, minor test update
surgupta-msft 20abb2f
Narrowing symbol location
surgupta-msft 24bcd68
address PR comments
surgupta-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # AZFW0011: Missing Registration for ASP.NET Core Integration | ||
|
|
||
| | | Value | | ||
| |-|-| | ||
| | **Rule ID** |AZFW00014| | ||
| | **Category** |[Usage]| | ||
| | **Severity** |Error| | ||
|
|
||
| ## Cause | ||
|
|
||
| This rule is triggered when worker using the ASP.NET Core Integration uses `ConfigureFunctionsWorkerDefaults()`. | ||
|
|
||
| ## Rule description | ||
|
|
||
| When using the ASP.NET Core Integration, the worker must configure the worker using the `ConfigureFunctionsWebApplication()` method. This rule will be violated when the worker uses `ConfigureFunctionsWorkerDefaults()`. | ||
|
|
||
|
|
||
| ## How to fix violations | ||
|
|
||
| Replace usage of `ConfigureFunctionsWorkerDefaults` with `ConfigureFunctionsWebApplication` method in the Function App. Refer to [public documentation](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide#aspnet-core-integration) for guidance on ASP.NET Core Integration. | ||
|
|
||
|
|
||
| ## When to suppress | ||
|
|
||
| It is okay to suppress this if `ConfigureFunctionsWebApplication` is called indirectly through a different API. | ||
22 changes: 22 additions & 0 deletions
22
extensions/Worker.Extensions.Http.AspNetCore.Analyzers/DiagnosticDescriptors.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // Copyright (c) .NET Foundation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
|
|
||
| namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore | ||
| { | ||
| internal class DiagnosticDescriptors | ||
| { | ||
| public const string Usage = "Usage"; | ||
|
|
||
| private static DiagnosticDescriptor Create(string id, string title, string messageFormat, string category, DiagnosticSeverity severity) | ||
| { | ||
| var helpLink = $"https://aka.ms/azfw-rules?ruleid={id}"; | ||
| return new DiagnosticDescriptor(id, title, messageFormat, category, severity, isEnabledByDefault: true, helpLinkUri: helpLink); | ||
| } | ||
|
|
||
| public static DiagnosticDescriptor CorrectRegistrationExpectedInAspNetIntegration { get; } | ||
| = Create(id: "AZFW0014", title: "Missing expected registration of ASP.NET Core Integration services", messageFormat: "The registration for method '{0}' is expected for ASP.NET Core Integration.", | ||
| category: Usage, severity: DiagnosticSeverity.Error); | ||
| } | ||
| } |
100 changes: 100 additions & 0 deletions
100
...ns/Worker.Extensions.Http.AspNetCore.Analyzers/RegistrationExpectedInASPNetIntegration.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| // Copyright (c) .NET Foundation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
|
||
| using System.Collections.Generic; | ||
| using System.Collections.Immutable; | ||
| using System.Linq; | ||
| using Microsoft.CodeAnalysis; | ||
| using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
| using Microsoft.CodeAnalysis.Diagnostics; | ||
|
|
||
| namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore | ||
| { | ||
| /// <summary> | ||
| /// Analyzer to verify whether expected registration is present for ASP.NET Core Integration. | ||
| /// </summary> | ||
| [DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
| public sealed class RegistrationExpectedInASPNetIntegration : DiagnosticAnalyzer | ||
| { | ||
| /// Diagnostics supported by the analyzer | ||
| public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.CorrectRegistrationExpectedInAspNetIntegration); | ||
|
|
||
| private const string ExpectedRegistrationMethod = "ConfigureFunctionsWebApplication"; | ||
| private const string IncorrectRegistrationMethod = "ConfigureFunctionsWorkerDefaults"; | ||
|
|
||
| /// Initialization method | ||
| public override void Initialize(AnalysisContext context) | ||
| { | ||
| context.EnableConcurrentExecution(); | ||
| context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze); | ||
| context.RegisterSymbolAction(AnalyzeMethod, SymbolKind.Method); | ||
| } | ||
|
|
||
| private static void AnalyzeMethod(SymbolAnalysisContext context) | ||
| { | ||
| var symbol = (IMethodSymbol)context.Symbol; | ||
|
|
||
| if (!IsMainMethod(symbol)) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| var syntaxReference = symbol.DeclaringSyntaxReferences.FirstOrDefault(); | ||
| var root = syntaxReference.SyntaxTree.GetRoot(); | ||
| var methodCallExpressions = root.DescendantNodes().OfType<InvocationExpressionSyntax>(); | ||
|
|
||
| if (methodCallExpressions is null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| var incorrectMethodCallExpressions = methodCallExpressions.Where(invocation => (invocation.Expression as MemberAccessExpressionSyntax)?.Name.Identifier.ValueText == IncorrectRegistrationMethod); | ||
| var incorrectMethodInvocationPresent = incorrectMethodCallExpressions.Any(); | ||
|
|
||
| if (!incorrectMethodInvocationPresent) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| //Finding exact location of method call | ||
| Location location = GetSymbolLocation(root, incorrectMethodCallExpressions); | ||
|
|
||
| var expectedMethodInvocationPresent = methodCallExpressions.Any(invocation => (invocation.Expression as MemberAccessExpressionSyntax)?.Name.Identifier.ValueText == ExpectedRegistrationMethod); | ||
|
|
||
| if (!expectedMethodInvocationPresent) | ||
| { | ||
| var diagnostic = Diagnostic.Create(DiagnosticDescriptors.CorrectRegistrationExpectedInAspNetIntegration, location, ExpectedRegistrationMethod); | ||
| context.ReportDiagnostic(diagnostic); | ||
| } | ||
| } | ||
|
|
||
| // Checks if a method symbol is a Main method. This also checks for implicit main in top-level statements | ||
| private static bool IsMainMethod(IMethodSymbol symbol) | ||
| { | ||
| return symbol?.IsStatic == true && symbol.Name switch | ||
| { | ||
| "Main" => true, | ||
| "$Main" => true, | ||
| "<Main>$" => true, | ||
| _ => false | ||
| }; | ||
| } | ||
|
|
||
| private static Location GetSymbolLocation(SyntaxNode root, IEnumerable<InvocationExpressionSyntax> methodCallExpressions) | ||
| { | ||
| Location location = Location.None; | ||
|
|
||
| if (methodCallExpressions != null) | ||
| { | ||
| var lineSpan = methodCallExpressions.FirstOrDefault().GetLocation().SourceSpan; | ||
| var node = root.DescendantNodes(lineSpan) | ||
| .First(n => lineSpan.Contains(n.FullSpan)).DescendantNodes() | ||
| .OfType<IdentifierNameSyntax>().FirstOrDefault(c => c.Identifier.Text == IncorrectRegistrationMethod); | ||
|
|
||
| location = node.GetLocation(); | ||
| } | ||
|
|
||
| return location; | ||
| } | ||
| } | ||
| } |
34 changes: 34 additions & 0 deletions
34
...r.Extensions.Http.AspNetCore.Analyzers/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <VersionPrefix>1.0.0</VersionPrefix> | ||
| <OutputType>Library</OutputType> | ||
| <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking> | ||
| <IncludeBuildOutput>false</IncludeBuildOutput> | ||
| <TargetFramework>netstandard2.0</TargetFramework> | ||
| <PackageId>Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers</PackageId> | ||
|
surgupta-msft marked this conversation as resolved.
surgupta-msft marked this conversation as resolved.
|
||
| <Description>This package provides development time code analysis for ASP.NET Core extensions for .NET isolated functions.</Description> | ||
| <AssemblyName>Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers</AssemblyName> | ||
| <RootNamespace>Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers</RootNamespace> | ||
| <Nullable>disable</Nullable> | ||
| <TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput</TargetsForTfmSpecificContentInPackage> | ||
| </PropertyGroup> | ||
|
|
||
| <Import Project="..\..\build\Common.props" /> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3"> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| </PackageReference> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" /> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="1.1.1" /> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.1.1" /> | ||
| </ItemGroup> | ||
|
|
||
| <Target Name="_AddAnalyzersToOutput"> | ||
| <ItemGroup> | ||
| <TfmSpecificPackageFile Include="$(OutputPath)\Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers.dll" PackagePath="analyzers/dotnet/cs" /> | ||
| </ItemGroup> | ||
| </Target> | ||
| </Project> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.