From 99dd5e0b428e4478b690d1176e30c61ad148aecb Mon Sep 17 00:00:00 2001 From: "Mingzhe Huang (from Dev Box)" Date: Wed, 25 Oct 2023 17:21:23 +0800 Subject: [PATCH] extract analyzer descriptors --- .../ModelName/AZC0030Tests.cs | 10 +++--- .../ModelName/AZC0031Tests.cs | 4 ++- .../ModelName/AZC0032Tests.cs | 4 ++- .../ModelName/AZC0033Tests.cs | 6 ++-- .../ModelName/SuffixAnalyzerBaseTests.cs | 8 +++-- .../Azure.ClientSdk.Analyzers/Descriptors.cs | 36 +++++++++++++++++++ .../ModelName/DataSuffixAnalyzer.cs | 10 ++---- .../ModelName/DefinitionSuffixAnalyzer.cs | 10 ++---- .../ModelName/GeneralSuffixAnalyzer.cs | 12 ++----- .../ModelName/OperationSuffixAnalyzer.cs | 12 ++----- 10 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0030Tests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0030Tests.cs index d58964a283c..4a3e8b1b8ad 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0030Tests.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0030Tests.cs @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName { public class AZC0030Tests { + private const string diagnosticId = "AZC0030"; + [Fact] public async Task GoodSuffix() { @@ -35,7 +37,7 @@ public static ResponseParameters DeserializeResponseParameters(JsonElement eleme } } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(4, 18, 4, 36).WithArguments("ResponseParameters", "Parameters", "'ResponseContent' or 'ResponsePatch'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 18, 4, 36).WithArguments("ResponseParameters", "Parameters", "'ResponseContent' or 'ResponsePatch'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } @@ -53,7 +55,7 @@ public static DiskOption DeserializeDiskOption(JsonElement element) } } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(4, 18, 4, 28).WithArguments("DiskOption", "Option", "'DiskConfig'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 18, 4, 28).WithArguments("DiskOption", "Option", "'DiskConfig'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } @@ -70,7 +72,7 @@ public class DiskOption } } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(6, 22, 6, 32).WithArguments("DiskOption", "Option", "'DiskConfig'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(6, 22, 6, 32).WithArguments("DiskOption", "Option", "'DiskConfig'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } @@ -91,7 +93,7 @@ public static CreationResponses DeserializeCreationResponses(JsonElement element } } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(6, 22, 6, 39).WithArguments("CreationResponses", "Responses", "'CreationResults'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(6, 22, 6, 39).WithArguments("CreationResponses", "Responses", "'CreationResults'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0031Tests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0031Tests.cs index 1c55ae0982f..1e3391672a8 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0031Tests.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0031Tests.cs @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName { public class AZC0031Tests { + private const string diagnosticId = "AZC0031"; + [Fact] public async Task ModelWithDefinitionSuffix() { @@ -19,7 +21,7 @@ public partial class AadAuthenticationDefinition { } }"; - var expected = VerifyCS.Diagnostic(DefinitionSuffixAnalyzer.DiagnosticId).WithSpan(4, 26, 4, 53).WithArguments("AadAuthenticationDefinition", "Definition"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 26, 4, 53).WithArguments("AadAuthenticationDefinition", "Definition"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0032Tests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0032Tests.cs index 299e9acce32..1731ab1975f 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0032Tests.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0032Tests.cs @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName { public class AZC0032Tests { + private const string diagnosticId = "AZC0032"; + [Fact] public async Task ModelClassWithDataSuffix() { @@ -23,7 +25,7 @@ public static AadAuthenticationData DeserializeAadAuthenticationData(JsonElement } } }"; - var expected = VerifyCS.Diagnostic(DataSuffixAnalyzer.DiagnosticId).WithSpan(4, 26, 4, 47).WithArguments("AadAuthenticationData", "Data"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 26, 4, 47).WithArguments("AadAuthenticationData", "Data"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0033Tests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0033Tests.cs index d177712e462..ed6aadc96cf 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0033Tests.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/AZC0033Tests.cs @@ -10,6 +10,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName { public class AZC0033Tests { + private const string diagnosticId = "AZC0033"; + [Fact] public async Task OperationClassIsNotChecked() { @@ -75,8 +77,8 @@ public static DnsArmOperation DeserializeDnsArmOperation(JsonElement element) } }"; DiagnosticResult[] expected = { - VerifyCS.Diagnostic(OperationSuffixAnalyzer.DiagnosticId).WithSpan(4, 18, 4, 30).WithArguments("DnsOperation", "Operation", "DnsData", "DnsInfo"), - VerifyCS.Diagnostic(OperationSuffixAnalyzer.DiagnosticId).WithSpan(11, 18, 11, 33).WithArguments("DnsArmOperation", "Operation", "DnsArmData", "DnsArmInfo") + VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 18, 4, 30).WithArguments("DnsOperation", "Operation", "DnsData", "DnsInfo"), + VerifyCS.Diagnostic(diagnosticId).WithSpan(11, 18, 11, 33).WithArguments("DnsArmOperation", "Operation", "DnsArmData", "DnsArmInfo") }; await VerifyCS.VerifyAnalyzerAsync(test, expected); } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/SuffixAnalyzerBaseTests.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/SuffixAnalyzerBaseTests.cs index eeb46226264..32be2243ac3 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/SuffixAnalyzerBaseTests.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers.Tests/ModelName/SuffixAnalyzerBaseTests.cs @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName { public class SuffixAnalyzerBaseTests { + private const string diagnosticId = "AZC0030"; + [Fact] public async Task NonPublicClassIsNotChecked() { @@ -38,7 +40,7 @@ public class MonitorParameter }")] public async Task ClassWithoutSerliaizationMethodsButInModelsNamespaceIsChecked(string test) { - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(3, 14, 3, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(3, 14, 3, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } @@ -55,7 +57,7 @@ public static MonitorParameter DeserializeMonitorParameter(JsonElement element) return null; } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(4, 14, 4, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(4, 14, 4, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } @@ -77,7 +79,7 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) return; } }"; - var expected = VerifyCS.Diagnostic(GeneralSuffixAnalyzer.DiagnosticId).WithSpan(9, 14, 9, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); + var expected = VerifyCS.Diagnostic(diagnosticId).WithSpan(9, 14, 9, 30).WithArguments("MonitorParameter", "Parameter", "'MonitorContent' or 'MonitorPatch'"); await VerifyCS.VerifyAnalyzerAsync(test, expected); } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs index 3871e5fee57..25016015a76 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/Descriptors.cs @@ -136,6 +136,42 @@ internal class Descriptors "The Azure.Core internal shared source types {0} should not be used outside of the Azure.Core library.", DiagnosticCategory.Usage, DiagnosticSeverity.Warning, true); + + public static readonly DiagnosticDescriptor AZC0030 = new DiagnosticDescriptor( + nameof(AZC0030), + "Improper model name suffix", + "Model name '{0}' ends with '{1}'. Suggest to rename it to {2} or any other appropriate name.", + DiagnosticCategory.Naming, + DiagnosticSeverity.Warning, + true, + "Suffix is not recommended. Consider to remove or modify it."); + + public static readonly DiagnosticDescriptor AZC0031 = new DiagnosticDescriptor( + nameof(AZC0031), + "Improper model name suffix", + "Model name '{0}' ends with '{1}'. Suggest to rename it to an appropriate name.", + DiagnosticCategory.Naming, + DiagnosticSeverity.Warning, + true, + "Suffix is not recommended. Consider to remove or modify it."); + + public static readonly DiagnosticDescriptor AZC0032 = new DiagnosticDescriptor( + nameof(AZC0032), + "Improper model name suffix", + "Model name '{0}' ends with '{1}'. Suggest to rename it to an appropriate name.", + DiagnosticCategory.Naming, + DiagnosticSeverity.Warning, + true, + "Suffix is not recommended. Consider to remove or modify it."); + + public static readonly DiagnosticDescriptor AZC0033 = new DiagnosticDescriptor( + nameof(AZC0033), + "Improper model name suffix", + "Model name '{0}' ends with '{1}'. Suggest to rename it to '{2}' or '{3}', if an appropriate name could not be found.", + DiagnosticCategory.Naming, + DiagnosticSeverity.Warning, + true, + "Suffix is not recommended. Consider to remove or modify it."); #endregion #region General diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DataSuffixAnalyzer.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DataSuffixAnalyzer.cs index 86755a9c0b4..339fb0d9f91 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DataSuffixAnalyzer.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DataSuffixAnalyzer.cs @@ -16,15 +16,9 @@ namespace Azure.ClientSdk.Analyzers.ModelName [DiagnosticAnalyzer(LanguageNames.CSharp)] public class DataSuffixAnalyzer : SuffixAnalyzerBase { - public const string DiagnosticId = nameof(AZC0032); - - private static readonly DiagnosticDescriptor AZC0032 = new DiagnosticDescriptor(DiagnosticId, Title, - GeneralRenamingMessageFormat, DiagnosticCategory.Naming, DiagnosticSeverity.Warning, isEnabledByDefault: true, - description: Description); - private static readonly string[] dataSuffix = new string[] { "Data" }; - public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(AZC0032); } } + public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Descriptors.AZC0032); } } // unless the model derives from ResourceData/TrackedResourceData protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContext context) => IsTypeOf(symbol, "Azure.ResourceManager.Models", "ResourceData") || @@ -35,7 +29,7 @@ protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContex protected override Diagnostic GetDiagnostic(INamedTypeSymbol typeSymbol, string suffix, SymbolAnalysisContext context) { var name = typeSymbol.Name; - return Diagnostic.Create(AZC0032, context.Symbol.Locations[0], + return Diagnostic.Create(Descriptors.AZC0032, context.Symbol.Locations[0], new Dictionary { { "SuggestedName", name.Substring(0, name.Length - suffix.Length) } }.ToImmutableDictionary(), name, suffix); } } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DefinitionSuffixAnalyzer.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DefinitionSuffixAnalyzer.cs index f93a5cc2b22..45062ab471f 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DefinitionSuffixAnalyzer.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/DefinitionSuffixAnalyzer.cs @@ -17,15 +17,9 @@ namespace Azure.ClientSdk.Analyzers.ModelName [DiagnosticAnalyzer(LanguageNames.CSharp)] public class DefinitionSuffixAnalyzer : SuffixAnalyzerBase { - public const string DiagnosticId = nameof(AZC0031); - - private static readonly DiagnosticDescriptor AZC0031 = new DiagnosticDescriptor(DiagnosticId, Title, - GeneralRenamingMessageFormat, DiagnosticCategory.Naming, DiagnosticSeverity.Warning, isEnabledByDefault: true, - description: Description); - private static readonly string[] definitionSuffix = new string[] { "Definition" }; - public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(AZC0031); } } + public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Descriptors.AZC0031); } } // unless the type is a Resource or after removing the suffix it's another type protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContext context) @@ -47,7 +41,7 @@ protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContex protected override Diagnostic GetDiagnostic(INamedTypeSymbol typeSymbol, string suffix, SymbolAnalysisContext context) { var name = typeSymbol.Name; - return Diagnostic.Create(AZC0031, context.Symbol.Locations[0], + return Diagnostic.Create(Descriptors.AZC0031, context.Symbol.Locations[0], new Dictionary { { "SuggestedName", name.Substring(0, name.Length - suffix.Length) } }.ToImmutableDictionary(), name, suffix); } } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/GeneralSuffixAnalyzer.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/GeneralSuffixAnalyzer.cs index bda36c4c7f9..ade8cc58d01 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/GeneralSuffixAnalyzer.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/GeneralSuffixAnalyzer.cs @@ -15,20 +15,12 @@ namespace Azure.ClientSdk.Analyzers.ModelName [DiagnosticAnalyzer(LanguageNames.CSharp)] public class GeneralSuffixAnalyzer : SuffixAnalyzerBase { - public const string DiagnosticId = nameof(AZC0030); - - private static readonly string messageFormat = "Model name '{0}' ends with '{1}'. Suggest to rename it to {2} or any other appropriate name."; - private static readonly ImmutableHashSet reservedNames = ImmutableHashSet.Create("ErrorResponse"); - private static readonly DiagnosticDescriptor AZC0030 = new DiagnosticDescriptor(DiagnosticId, Title, - messageFormat, DiagnosticCategory.Naming, DiagnosticSeverity.Warning, isEnabledByDefault: true, - description: Description); - // Avoid to use suffixes "Request(s)", "Parameter(s)", "Option(s)", "Response(s)", "Collection" private static readonly string[] generalSuffixes = new string[] { "Request", "Requests", "Response", "Responses", "Parameter", "Parameters", "Option", "Options", "Collection"}; - public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(AZC0030); } } + public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Descriptors.AZC0030); } } protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContext context) => reservedNames.Contains(symbol.Name); @@ -37,7 +29,7 @@ protected override Diagnostic GetDiagnostic(INamedTypeSymbol typeSymbol, string { var name = typeSymbol.Name; var suggestedName = GetSuggestedName(name, suffix); - return Diagnostic.Create(AZC0030, context.Symbol.Locations[0], + return Diagnostic.Create(Descriptors.AZC0030, context.Symbol.Locations[0], new Dictionary { { "SuggestedName", suggestedName } }.ToImmutableDictionary(), name, suffix, suggestedName); } diff --git a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/OperationSuffixAnalyzer.cs b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/OperationSuffixAnalyzer.cs index b230d969d4d..fecdd64be68 100644 --- a/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/OperationSuffixAnalyzer.cs +++ b/src/dotnet/Azure.ClientSdk.Analyzers/Azure.ClientSdk.Analyzers/ModelName/OperationSuffixAnalyzer.cs @@ -14,17 +14,9 @@ namespace Azure.ClientSdk.Analyzers.ModelName [DiagnosticAnalyzer(LanguageNames.CSharp)] public class OperationSuffixAnalyzer : SuffixAnalyzerBase { - public const string DiagnosticId = nameof(AZC0033); - - private static readonly string messageFormat = "Model name '{0}' ends with '{1}'. Suggest to rename it to '{2}' or '{3}', if an appropriate name could not be found."; - - private static readonly DiagnosticDescriptor AZC0033 = new DiagnosticDescriptor(DiagnosticId, Title, - messageFormat, DiagnosticCategory.Naming, DiagnosticSeverity.Warning, isEnabledByDefault: true, - description: Description); - private static readonly string[] operationSuffix = new string[] { "Operation" }; - public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(AZC0033); } } + public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Descriptors.AZC0033); } } // Unless the model derivew from Operation protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContext context) => IsTypeOf(symbol, "Azure", "Operation"); @@ -34,7 +26,7 @@ protected override Diagnostic GetDiagnostic(INamedTypeSymbol typeSymbol, string { var name = typeSymbol.Name; var nameWithoutSuffix = name.Substring(0, name.Length - suffix.Length); - return Diagnostic.Create(AZC0033, context.Symbol.Locations[0], + return Diagnostic.Create(Descriptors.AZC0033, context.Symbol.Locations[0], name, suffix, $"{nameWithoutSuffix}Data", $"{nameWithoutSuffix}Info"); } }