Skip to content

Commit

Permalink
Improve MA0016 report location and cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
meziantou committed Dec 29, 2023
1 parent 2636f8d commit dd96912
Show file tree
Hide file tree
Showing 15 changed files with 676 additions and 339 deletions.
103 changes: 98 additions & 5 deletions src/Meziantou.Analyzer/Internals/ContextExtensions.cs
Expand Up @@ -43,26 +43,119 @@ public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticD
}
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, IFieldSymbol symbol, DiagnosticFieldReportOptions reportOptions, string?[]? messageArgs = null) => ReportDiagnostic(context, descriptor, ImmutableDictionary<string, string?>.Empty, symbol, reportOptions, messageArgs);
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IFieldSymbol symbol, DiagnosticFieldReportOptions reportOptions, string?[]? messageArgs = null)
{
foreach (var location in symbol.Locations)
{
if (reportOptions.HasFlag(DiagnosticFieldReportOptions.ReportOnReturnType))
{
var node = location.SourceTree?.GetRoot(context.CancellationToken).FindNode(location.SourceSpan);
if (node is VariableDeclaratorSyntax { Parent: VariableDeclarationSyntax { Type: not null and var type } })
{
ReportDiagnostic(context, descriptor, properties, type.GetLocation(), messageArgs);
return;
}
}

ReportDiagnostic(context, descriptor, properties, location, messageArgs);
}
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, IMethodSymbol symbol, DiagnosticMethodReportOptions reportOptions, string?[]? messageArgs = null) => ReportDiagnostic(context, descriptor, ImmutableDictionary<string, string?>.Empty, symbol, reportOptions, messageArgs);
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IMethodSymbol symbol, DiagnosticMethodReportOptions reportOptions, string?[]? messageArgs = null)
{
foreach (var location in symbol.Locations)
{
if (reportOptions.HasFlag(DiagnosticMethodReportOptions.ReportOnReturnType))
{
var node = location.SourceTree?.GetRoot(context.CancellationToken).FindNode(location.SourceSpan);
if (node is MethodDeclarationSyntax methodDeclarationSyntax)
{
ReportDiagnostic(context, descriptor, properties, methodDeclarationSyntax.ReturnType.GetLocation(), messageArgs);
return;
}

if (node is DelegateDeclarationSyntax delegateDeclarationSyntax)
{
ReportDiagnostic(context, descriptor, properties, delegateDeclarationSyntax.ReturnType.GetLocation(), messageArgs);
return;
}
}

ReportDiagnostic(context, descriptor, properties, location, messageArgs);
}
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, IParameterSymbol symbol, DiagnosticParameterReportOptions reportOptions, string?[]? messageArgs = null) => ReportDiagnostic(context, descriptor, ImmutableDictionary<string, string?>.Empty, symbol, reportOptions, messageArgs);
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IParameterSymbol symbol, DiagnosticParameterReportOptions reportOptions, string?[]? messageArgs = null)
{
foreach (var location in symbol.Locations)
{
if (reportOptions.HasFlag(DiagnosticParameterReportOptions.ReportOnType))
{
var node = location.SourceTree?.GetRoot(context.CancellationToken).FindNode(location.SourceSpan);
if (node is ParameterSyntax { Type: not null and var parameterType })
{
ReportDiagnostic(context, descriptor, properties, parameterType.GetLocation(), messageArgs);
return;
}
}

ReportDiagnostic(context, descriptor, properties, location, messageArgs);
}
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, IPropertySymbol symbol, DiagnosticPropertyReportOptions reportOptions, string?[]? messageArgs = null) => ReportDiagnostic(context, descriptor, ImmutableDictionary<string, string?>.Empty, symbol, reportOptions, messageArgs);
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IPropertySymbol symbol, DiagnosticPropertyReportOptions reportOptions, string?[]? messageArgs = null)
{
foreach (var location in symbol.Locations)
{
if (reportOptions.HasFlag(DiagnosticPropertyReportOptions.ReportOnReturnType))
{
var node = location.SourceTree?.GetRoot(context.CancellationToken).FindNode(location.SourceSpan);
if (node is PropertyDeclarationSyntax { Type: not null and var returnType })
{
ReportDiagnostic(context, descriptor, properties, returnType.GetLocation(), messageArgs);
return;
}

if (node is IndexerDeclarationSyntax { Type: not null and var returnType2 })
{
ReportDiagnostic(context, descriptor, properties, returnType2.GetLocation(), messageArgs);
return;
}
}

ReportDiagnostic(context, descriptor, properties, location, messageArgs);
}
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, IOperation operation, string?[]? messageArgs = null)
=> ReportDiagnostic(context, descriptor, ImmutableDictionary<string, string?>.Empty, operation, messageArgs);
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IOperation operation, string?[]? messageArgs = null)
=> context.ReportDiagnostic(CreateDiagnostic(descriptor, operation.Syntax.GetLocation(), properties, messageArgs));

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, ILocalFunctionOperation operation, DiagnosticReportOptions options, string?[]? messageArgs = null)
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, ILocalFunctionOperation operation, DiagnosticMethodReportOptions options, string?[]? messageArgs = null)
{
if (options.HasFlag(DiagnosticReportOptions.ReportOnMethodName) &&
operation.Syntax is LocalFunctionStatementSyntax memberAccessExpression)
if (options.HasFlag(DiagnosticMethodReportOptions.ReportOnMethodName) && operation.Syntax is LocalFunctionStatementSyntax memberAccessExpression)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, memberAccessExpression.Identifier.GetLocation(), properties, messageArgs));
return;
}

if (options.HasFlag(DiagnosticMethodReportOptions.ReportOnReturnType) && operation.Syntax is LocalFunctionStatementSyntax memberAccessExpression2)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, memberAccessExpression2.ReturnType.GetLocation(), properties, messageArgs));
return;
}

context.ReportDiagnostic(descriptor, properties, operation, messageArgs);
}

public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IInvocationOperation operation, DiagnosticReportOptions options, params string?[]? messageArgs)
public static void ReportDiagnostic(this DiagnosticReporter context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IInvocationOperation operation, DiagnosticInvocationReportOptions options, params string?[]? messageArgs)
{
if (options.HasFlag(DiagnosticReportOptions.ReportOnMethodName) &&
if (options.HasFlag(DiagnosticInvocationReportOptions.ReportOnMember) &&
operation.Syntax.ChildNodes().FirstOrDefault() is MemberAccessExpressionSyntax memberAccessExpression)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, memberAccessExpression.Name.GetLocation(), properties, messageArgs));
Expand Down

0 comments on commit dd96912

Please sign in to comment.