Skip to content

Commit

Permalink
extract analyzer descriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingzhe Huang (from Dev Box) committed Oct 25, 2023
1 parent 9c6636c commit 99dd5e0
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName
{
public class AZC0030Tests
{
private const string diagnosticId = "AZC0030";

[Fact]
public async Task GoodSuffix()
{
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName
{
public class AZC0031Tests
{
private const string diagnosticId = "AZC0031";

[Fact]
public async Task ModelWithDefinitionSuffix()
{
Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName
{
public class AZC0032Tests
{
private const string diagnosticId = "AZC0032";

[Fact]
public async Task ModelClassWithDataSuffix()
{
Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName
{
public class AZC0033Tests
{
private const string diagnosticId = "AZC0033";

[Fact]
public async Task OperationClassIsNotChecked()
{
Expand Down Expand Up @@ -75,8 +77,8 @@ public static DnsArmOperation<T> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Azure.ClientSdk.Analyzers.Tests.ModelName
{
public class SuffixAnalyzerBaseTests
{
private const string diagnosticId = "AZC0030";

[Fact]
public async Task NonPublicClassIsNotChecked()
{
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(AZC0032); } }
public override ImmutableArray<DiagnosticDescriptor> 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") ||
Expand All @@ -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<string, string> { { "SuggestedName", name.Substring(0, name.Length - suffix.Length) } }.ToImmutableDictionary(), name, suffix);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(AZC0031); } }
public override ImmutableArray<DiagnosticDescriptor> 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)
Expand All @@ -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<string, string> { { "SuggestedName", name.Substring(0, name.Length - suffix.Length) } }.ToImmutableDictionary(), name, suffix);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> 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<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(AZC0030); } }
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Descriptors.AZC0030); } }

protected override bool ShouldSkip(INamedTypeSymbol symbol, SymbolAnalysisContext context) => reservedNames.Contains(symbol.Name);

Expand All @@ -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<string, string> { { "SuggestedName", suggestedName } }.ToImmutableDictionary(), name, suffix, suggestedName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(AZC0033); } }
public override ImmutableArray<DiagnosticDescriptor> 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");
Expand All @@ -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");
}
}
Expand Down

0 comments on commit 99dd5e0

Please sign in to comment.