From 20567067655b1b6710b3bbdfcd6f89815c110649 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Wed, 5 Jun 2024 18:09:03 +0200 Subject: [PATCH] Move analyzer to separate project. (#355) --- Carter.sln | 15 ++++ src/Carter.Analyzers/Carter.Analyzers.csproj | 19 +++++ ...ModuleShouldNotHaveDependenciesAnalyzer.cs | 22 ++--- .../DiagnosticDescriptors.cs | 0 src/Carter/Carter.csproj | 11 +-- .../DependencyContextAssemblyCatalog.cs | 2 - src/Carter/ICarterModule.cs | 2 + src/Carter/ModelBinding/BindExtensions.cs | 2 - .../Analyzers/CSharpPreviewAnalyzerTest.cs | 25 ++++++ ...terModuleShouldNotHaveDependenciesTests.cs | 82 +++++++++++++------ test/Carter.Tests/Carter.Tests.csproj | 1 + 11 files changed, 133 insertions(+), 48 deletions(-) create mode 100644 src/Carter.Analyzers/Carter.Analyzers.csproj rename src/{Carter/Analyzers => Carter.Analyzers}/CarterModuleShouldNotHaveDependenciesAnalyzer.cs (73%) rename src/{Carter/Analyzers => Carter.Analyzers}/DiagnosticDescriptors.cs (100%) create mode 100644 test/Carter.Tests/Analyzers/CSharpPreviewAnalyzerTest.cs diff --git a/Carter.sln b/Carter.sln index 0a23153..08932f7 100644 --- a/Carter.sln +++ b/Carter.sln @@ -32,6 +32,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Carter.ResponseNegotiators. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Carter.ResponseNegotiators.Newtonsoft.Tests", "test\Carter.ResponseNegotiators.Newtonsoft.Tests\Carter.ResponseNegotiators.Newtonsoft.Tests.csproj", "{47DD3AA8-F072-41E3-AF7F-119DBBD8D14A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Carter.Analyzers", "src\Carter.Analyzers\Carter.Analyzers.csproj", "{C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -150,6 +152,18 @@ Global {47DD3AA8-F072-41E3-AF7F-119DBBD8D14A}.Release|x64.Build.0 = Release|Any CPU {47DD3AA8-F072-41E3-AF7F-119DBBD8D14A}.Release|x86.ActiveCfg = Release|Any CPU {47DD3AA8-F072-41E3-AF7F-119DBBD8D14A}.Release|x86.Build.0 = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|x64.ActiveCfg = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|x64.Build.0 = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|x86.ActiveCfg = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Debug|x86.Build.0 = Debug|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|Any CPU.Build.0 = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|x64.ActiveCfg = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|x64.Build.0 = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|x86.ActiveCfg = Release|Any CPU + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -164,6 +178,7 @@ Global {E5D99119-96EB-4C01-9EC2-A06FC3EEC182} = {35DE35A0-758D-4FDD-BDA3-67F04F65677D} {D30E87B0-39AE-41FE-8BA3-E5F9FBFFDD64} = {5D056A8A-821C-4C3C-A281-4FA7F8CE251B} {47DD3AA8-F072-41E3-AF7F-119DBBD8D14A} = {DCB5B9A0-F06D-4BDF-917D-A459C790C718} + {C15C71C0-73CE-41DA-8EEE-C66318BF3A6C} = {5D056A8A-821C-4C3C-A281-4FA7F8CE251B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9096DE78-6327-48BA-AE0E-336F769681A7} diff --git a/src/Carter.Analyzers/Carter.Analyzers.csproj b/src/Carter.Analyzers/Carter.Analyzers.csproj new file mode 100644 index 0000000..6216913 --- /dev/null +++ b/src/Carter.Analyzers/Carter.Analyzers.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.0 + enable + enable + 12 + true + RS2008 + + + + + + + + + + diff --git a/src/Carter/Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs b/src/Carter.Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs similarity index 73% rename from src/Carter/Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs rename to src/Carter.Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs index 70ac8ad..3219595 100644 --- a/src/Carter/Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs +++ b/src/Carter.Analyzers/CarterModuleShouldNotHaveDependenciesAnalyzer.cs @@ -44,28 +44,28 @@ private static void OnTypeAnalysis(SymbolAnalysisContext context, INamedTypeSymb foreach (var syntaxReference in constructor.DeclaringSyntaxReferences) { var node = syntaxReference.GetSyntax(); - SyntaxToken identifier; - if (node is ConstructorDeclarationSyntax constructorDeclaration) + SyntaxToken? identifier = node switch { - identifier = constructorDeclaration.Identifier; - } else if (node is RecordDeclarationSyntax recordDeclaration) - { - identifier = recordDeclaration.Identifier; - } - else + ConstructorDeclarationSyntax constructorDeclaration => constructorDeclaration.Identifier, + RecordDeclarationSyntax recordDeclaration => recordDeclaration.Identifier, + ClassDeclarationSyntax classDeclaration => classDeclaration.Identifier, + StructDeclarationSyntax structDeclaration => structDeclaration.Identifier, + _ => null + }; + if (!identifier.HasValue) { continue; } var diagnostic = Diagnostic.Create( DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies, - identifier.GetLocation(), - identifier.Text + identifier.Value.GetLocation(), + identifier.Value.Text ); context.ReportDiagnostic(diagnostic); } } } - public override ImmutableArray SupportedDiagnostics { get; } = [DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies]; + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies); } diff --git a/src/Carter/Analyzers/DiagnosticDescriptors.cs b/src/Carter.Analyzers/DiagnosticDescriptors.cs similarity index 100% rename from src/Carter/Analyzers/DiagnosticDescriptors.cs rename to src/Carter.Analyzers/DiagnosticDescriptors.cs diff --git a/src/Carter/Carter.csproj b/src/Carter/Carter.csproj index 2aa310f..91aad0b 100644 --- a/src/Carter/Carter.csproj +++ b/src/Carter/Carter.csproj @@ -13,27 +13,24 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true README.md - true - RS2008 - + + + + - all - - - diff --git a/src/Carter/DependencyContextAssemblyCatalog.cs b/src/Carter/DependencyContextAssemblyCatalog.cs index 610f2d8..300ae56 100644 --- a/src/Carter/DependencyContextAssemblyCatalog.cs +++ b/src/Carter/DependencyContextAssemblyCatalog.cs @@ -89,9 +89,7 @@ private static Assembly SafeLoadAssembly(AssemblyName assemblyName) { try { -#pragma warning disable RS1035 return Assembly.Load(assemblyName); -#pragma warning restore RS1035 } catch (Exception) { diff --git a/src/Carter/ICarterModule.cs b/src/Carter/ICarterModule.cs index d6b131b..7227af0 100644 --- a/src/Carter/ICarterModule.cs +++ b/src/Carter/ICarterModule.cs @@ -54,7 +54,9 @@ protected CarterModule() : this(string.Empty) /// Initializes a new instance of /// /// A base path to group routes in your +#pragma warning disable CARTER1 protected CarterModule(string basePath) +#pragma warning restore CARTER1 { this.basePath = basePath; } diff --git a/src/Carter/ModelBinding/BindExtensions.cs b/src/Carter/ModelBinding/BindExtensions.cs index 7e4fa52..54b6590 100644 --- a/src/Carter/ModelBinding/BindExtensions.cs +++ b/src/Carter/ModelBinding/BindExtensions.cs @@ -88,7 +88,6 @@ public static async Task BindAndSaveFile(this HttpRequest request, string saveLo private static async Task SaveFileInternal(IFormFile file, string saveLocation, string fileName = "") { -#pragma warning disable RS1035 if (!Directory.Exists(saveLocation)) Directory.CreateDirectory(saveLocation); @@ -96,6 +95,5 @@ private static async Task SaveFileInternal(IFormFile file, string saveLocation, using (var fileToSave = File.Create(Path.Combine(saveLocation, fileName))) await file.CopyToAsync(fileToSave); -#pragma warning restore RS1035 } } \ No newline at end of file diff --git a/test/Carter.Tests/Analyzers/CSharpPreviewAnalyzerTest.cs b/test/Carter.Tests/Analyzers/CSharpPreviewAnalyzerTest.cs new file mode 100644 index 0000000..8bafe68 --- /dev/null +++ b/test/Carter.Tests/Analyzers/CSharpPreviewAnalyzerTest.cs @@ -0,0 +1,25 @@ +namespace Carter.Tests.Analyzers; + +using System.IO; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Testing; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; + +public sealed class CSharpPreviewAnalyzerTest : CSharpAnalyzerTest + where TAnalyzer : DiagnosticAnalyzer, new() +{ + public CSharpPreviewAnalyzerTest(string code) + { + var carterPackage = new PackageIdentity("Carter", "8.1.0"); + var aspNetPackage = new PackageIdentity("Microsoft.AspNetCore.App.Ref", "8.0.0"); + var bclPackage = new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"); + ReferenceAssemblies = new ReferenceAssemblies("net8.0", bclPackage, Path.Combine("ref", "net8.0")).AddPackages([carterPackage, aspNetPackage]); + TestCode = code; + + } + protected override ParseOptions CreateParseOptions() + => new CSharpParseOptions(LanguageVersion.Preview, DocumentationMode.Diagnose); +} diff --git a/test/Carter.Tests/Analyzers/CarterModuleShouldNotHaveDependenciesTests.cs b/test/Carter.Tests/Analyzers/CarterModuleShouldNotHaveDependenciesTests.cs index 2d58df5..5bbc561 100644 --- a/test/Carter.Tests/Analyzers/CarterModuleShouldNotHaveDependenciesTests.cs +++ b/test/Carter.Tests/Analyzers/CarterModuleShouldNotHaveDependenciesTests.cs @@ -1,9 +1,7 @@ namespace Carter.Tests.Analyzers; -using System.IO; using System.Threading.Tasks; using Carter.Analyzers; -using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Testing.Verifiers; using Xunit; @@ -33,7 +31,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -55,7 +53,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -81,7 +79,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -103,7 +101,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -129,7 +127,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -151,7 +149,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} .WithLocation(0) .WithArguments("MyCarterModule"); - return this.VerifyAsync(code, diagnosticResult); + return VerifyAsync(code, diagnosticResult); } [Theory] @@ -173,7 +171,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -195,7 +193,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -217,7 +215,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -243,7 +241,7 @@ public void AddRoutes(IEndpointRouteBuilder app) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -262,7 +260,7 @@ internal MyCarterModule(string s, int i) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -278,7 +276,7 @@ public Task RecordNonCarterModuleWithConstructorDependencies_NoDiagnostic(string } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } [Theory] @@ -301,22 +299,54 @@ public MySubCarterModule(string s) {} } """; - return this.VerifyAsync(code); + return VerifyAsync(code); } - private Task VerifyAsync(string code, DiagnosticResult? diagnosticResult = null) + [Theory] + [InlineData("class")] + [InlineData("struct")] + public Task EmptyPrimaryConstructor_NoDiagnostic(string type) { - var carterPackage = new PackageIdentity("Carter", "8.1.0"); - var aspNetPackage = new PackageIdentity("Microsoft.AspNetCore.App.Ref", "8.0.0"); - var bclPackage = new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"); - var referenceAssemblies = new ReferenceAssemblies("net8.0", bclPackage, Path.Combine("ref", "net8.0")) - .AddPackages([carterPackage, aspNetPackage]); - AnalyzerTest test = new CSharpAnalyzerTest - { - TestCode = code, - ReferenceAssemblies = referenceAssemblies - }; + var code = $$""" + using Carter; + using Microsoft.AspNetCore.Routing; + + {{type}} MyCarterModule() : ICarterModule + { + public void AddRoutes(IEndpointRouteBuilder app) {} + } + """; + + return VerifyAsync(code); + } + + [Theory] + [InlineData("class", "string s")] + [InlineData("struct", "string s")] + [InlineData("class", "string s, int i")] + [InlineData("struct", "string s, int i")] + public Task PrimaryConstructor_Diagnostic(string type, string parameters) + { + var code = $$""" + using Carter; + using Microsoft.AspNetCore.Routing; + + {{type}} {|#0:MyCarterModule|}({{parameters}}) : ICarterModule + { + public void AddRoutes(IEndpointRouteBuilder app) {} + } + """; + + var diagnosticResult = new DiagnosticResult(DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies) + .WithLocation(0) + .WithArguments("MyCarterModule"); + + return VerifyAsync(code, diagnosticResult); + } + private static Task VerifyAsync(string code, DiagnosticResult? diagnosticResult = null) + { + AnalyzerTest test = new CSharpPreviewAnalyzerTest(code); if (diagnosticResult.HasValue) { test.ExpectedDiagnostics.Add(diagnosticResult.Value); diff --git a/test/Carter.Tests/Carter.Tests.csproj b/test/Carter.Tests/Carter.Tests.csproj index 98b491d..16966d6 100644 --- a/test/Carter.Tests/Carter.Tests.csproj +++ b/test/Carter.Tests/Carter.Tests.csproj @@ -4,6 +4,7 @@ +