Skip to content

Commit

Permalink
Merge pull request #5124 from Youssef1313/refactor-ca1824
Browse files Browse the repository at this point in the history
Tiny Refactoring CA1824
  • Loading branch information
mavasani authored Jun 28, 2021
2 parents 89812e6 + a35b306 commit 3ab8d26
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ namespace Microsoft.NetCore.CSharp.Analyzers.Resources
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class CSharpMarkAssembliesWithNeutralResourcesLanguageAnalyzer : MarkAssembliesWithNeutralResourcesLanguageAnalyzer
{
protected override void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Action onResourceFound)
protected override void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Action onResourceFound, INamedTypeSymbol generatedCode)
{
context.RegisterSyntaxNodeAction(nc =>
context.RegisterSyntaxNodeAction(context =>
{
if (!CheckAttribute(nc.Node))
var attributeSyntax = (AttributeSyntax)context.Node;
if (!CheckAttribute(attributeSyntax))
{
return;
}
if (!CheckResxGeneratedFile(nc.SemanticModel, nc.Node, ((AttributeSyntax)nc.Node).ArgumentList.Arguments[0].Expression, nc.CancellationToken))
if (!CheckResxGeneratedFile(context.SemanticModel, attributeSyntax, attributeSyntax.ArgumentList.Arguments[0].Expression, generatedCode, context.CancellationToken))
{
return;
}
Expand All @@ -33,9 +34,8 @@ protected override void RegisterAttributeAnalyzer(CompilationStartAnalysisContex
}, SyntaxKind.Attribute);
}

private static bool CheckAttribute(SyntaxNode node)
private static bool CheckAttribute(AttributeSyntax attribute)
{
var attribute = node as AttributeSyntax;
return attribute?.Name?.GetLastToken().Text?.Equals(GeneratedCodeAttribute, StringComparison.Ordinal) == true &&
attribute.ArgumentList.Arguments.Count > 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public abstract class MarkAssembliesWithNeutralResourcesLanguageAnalyzer : Diagn
isDataflowRule: false,
isReportedAtCompilationEnd: true);

protected abstract void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Action onResourceFound);
protected abstract void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Action onResourceFound, INamedTypeSymbol generatedCode);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

Expand All @@ -51,35 +51,45 @@ public override void Initialize(AnalysisContext context)
// any diagnostics from it.
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);

context.RegisterCompilationStartAction(cc =>
context.RegisterCompilationStartAction(context =>
{
var hasResource = false;
if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCodeDomCompilerGeneratedCodeAttribute, out var generatedCode))
{
return;
}
RegisterAttributeAnalyzer(cc, () => hasResource = true);
INamedTypeSymbol? attribute = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemResourcesNeutralResourcesLanguageAttribute);
if (attribute is null)
{
return;
}
cc.RegisterCompilationEndAction(ce =>
if (TryCheckNeutralResourcesLanguageAttribute(context.Compilation, attribute, out var data))
{
// attribute already exist
return;
}
var hasResource = false;
RegisterAttributeAnalyzer(context, () => hasResource = true, generatedCode);
context.RegisterCompilationEndAction(context =>
{
// there is nothing to do.
if (!hasResource)
{
return;
}
if (TryCheckNeutralResourcesLanguageAttribute(ce, out AttributeData data))
{
// attribute already exist
return;
}
if (data != null)
{
// we have the attribute but its doing it wrong.
ce.ReportDiagnostic(data.ApplicationSyntaxReference.GetSyntax(ce.CancellationToken).CreateDiagnostic(Rule));
context.ReportDiagnostic(data.ApplicationSyntaxReference.GetSyntax(context.CancellationToken).CreateDiagnostic(Rule));
return;
}
// attribute just don't exist
ce.ReportNoLocationDiagnostic(Rule);
context.ReportNoLocationDiagnostic(Rule);
});
});
}
Expand All @@ -89,14 +99,13 @@ protected static bool CheckDesignerFile(SyntaxTree tree)
return tree.FilePath?.IndexOf(Designer, StringComparison.OrdinalIgnoreCase) > 0;
}

protected static bool CheckResxGeneratedFile(SemanticModel model, SyntaxNode attribute, SyntaxNode argument, CancellationToken cancellationToken)
protected static bool CheckResxGeneratedFile(SemanticModel model, SyntaxNode attribute, SyntaxNode argument, INamedTypeSymbol generatedCode, CancellationToken cancellationToken)
{
if (!CheckDesignerFile(model.SyntaxTree))
{
return false;
}

INamedTypeSymbol? generatedCode = model.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCodeDomCompilerGeneratedCodeAttribute);
if (model.GetSymbolInfo(attribute, cancellationToken).Symbol?.ContainingType?.Equals(generatedCode) != true)
{
return false;
Expand All @@ -121,15 +130,12 @@ protected static bool CheckResxGeneratedFile(SemanticModel model, SyntaxNode att
return true;
}

private static bool TryCheckNeutralResourcesLanguageAttribute(CompilationAnalysisContext context, out AttributeData attributeData)
private static bool TryCheckNeutralResourcesLanguageAttribute(Compilation compilation, INamedTypeSymbol attribute, out AttributeData? attributeData)
{
INamedTypeSymbol? attribute = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemResourcesNeutralResourcesLanguageAttribute);
INamedTypeSymbol? @string = context.Compilation.GetSpecialType(SpecialType.System_String);

IEnumerable<AttributeData> attributes = context.Compilation.Assembly.GetAttributes().Where(d => d.AttributeClass?.Equals(attribute) == true);
IEnumerable<AttributeData> attributes = compilation.Assembly.GetAttributes().Where(d => SymbolEqualityComparer.Default.Equals(attribute, d.AttributeClass));
foreach (AttributeData data in attributes)
{
if (data.ConstructorArguments.Any(c => c.Type?.Equals(@string) == true && !string.IsNullOrWhiteSpace((string)c.Value)))
if (data.ConstructorArguments.Any(c => c.Value is string constantValue && !string.IsNullOrWhiteSpace(constantValue)))
{
// found one that already does right thing.
attributeData = data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ Namespace Microsoft.NetCore.VisualBasic.Analyzers.Resources
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Public NotInheritable Class BasicMarkAssembliesWithNeutralResourcesLanguageAnalyzer
Inherits MarkAssembliesWithNeutralResourcesLanguageAnalyzer
Protected Overrides Sub RegisterAttributeAnalyzer(context As CompilationStartAnalysisContext, onResourceFound As Action)
Protected Overrides Sub RegisterAttributeAnalyzer(context As CompilationStartAnalysisContext, onResourceFound As Action, generatedCode As INamedTypeSymbol)
context.RegisterSyntaxNodeAction(
Sub(nc)
If Not CheckBasicAttribute(nc.Node) Then
Dim attributeSyntax = DirectCast(nc.Node, AttributeSyntax)
If Not CheckBasicAttribute(attributeSyntax) Then
Return
End If

If Not CheckResxGeneratedFile(nc.SemanticModel, nc.Node, DirectCast(nc.Node, AttributeSyntax).ArgumentList.Arguments(0).GetExpression(), nc.CancellationToken) Then
If Not CheckResxGeneratedFile(nc.SemanticModel, attributeSyntax, attributeSyntax.ArgumentList.Arguments(0).GetExpression(), generatedCode, nc.CancellationToken) Then
Return
End If

onResourceFound()
End Sub, SyntaxKind.Attribute)
End Sub

Private Shared Function CheckBasicAttribute(node As SyntaxNode) As Boolean
Dim attribute = TryCast(node, AttributeSyntax)
Private Shared Function CheckBasicAttribute(attribute As AttributeSyntax) As Boolean
Return (attribute?.Name?.GetLastToken().Text.Equals(GeneratedCodeAttribute, StringComparison.Ordinal) = True AndAlso
attribute.ArgumentList.Arguments.Count > 0).GetValueOrDefault()
End Function
Expand Down

0 comments on commit 3ab8d26

Please sign in to comment.