Skip to content

Commit

Permalink
Fix finding attribute data for syntax for assembly/module symbols (#7…
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored Jul 20, 2022
1 parent dc2db86 commit ddded2f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ public void AnalyzeAttribute(SyntaxNodeAnalysisContext context)
AttributeSyntax syntax = (AttributeSyntax)context.Node;
ISymbol attributedSymbol = context.ContainingSymbol!;

AttributeData attr = GetAttributeData(syntax, attributedSymbol);
if (attr.AttributeClass?.ToDisplayString() == TypeNames.CustomMarshallerAttribute
AttributeData? attr = syntax.FindAttributeData(attributedSymbol);
if (attr?.AttributeClass?.ToDisplayString() == TypeNames.CustomMarshallerAttribute
&& attr.AttributeConstructor is not null)
{
DiagnosticReporter managedTypeReporter = DiagnosticReporter.CreateForLocation(syntax.FindArgumentWithNameOrArity("managedType", 0).FindTypeExpressionOrNullLocation(), context.ReportDiagnostic);
Expand Down Expand Up @@ -313,20 +313,6 @@ private void AnalyzeMarshallerType(DiagnosticReporter diagnosticFactory, INamedT
{
// TODO: Implement for the V2 shapes
}

private static AttributeData GetAttributeData(AttributeSyntax syntax, ISymbol symbol)
{
if (syntax.FirstAncestorOrSelf<AttributeListSyntax>().Target?.Identifier.IsKind(SyntaxKind.ReturnKeyword) == true)
{
return ((IMethodSymbol)symbol).GetReturnTypeAttributes().First(attributeSyntaxLocationMatches);
}
return symbol.GetAttributes().First(attributeSyntaxLocationMatches);

bool attributeSyntaxLocationMatches(AttributeData attrData)
{
return attrData.ApplicationSyntaxReference!.SyntaxTree == syntax.SyntaxTree && attrData.ApplicationSyntaxReference.Span == syntax.Span;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public void AnalyzeAttribute(SyntaxNodeAnalysisContext context)
AttributeSyntax syntax = (AttributeSyntax)context.Node;
ISymbol attributedSymbol = context.ContainingSymbol!;

AttributeData attr = GetAttributeData(syntax, attributedSymbol);
if (attr.AttributeClass?.ToDisplayString() == TypeNames.NativeMarshallingAttribute
AttributeData? attr = syntax.FindAttributeData(attributedSymbol);
if (attr?.AttributeClass?.ToDisplayString() == TypeNames.NativeMarshallingAttribute
&& attr.AttributeConstructor is not null)
{
INamedTypeSymbol? entryType = (INamedTypeSymbol?)attr.ConstructorArguments[0].Value;
Expand Down Expand Up @@ -163,20 +163,6 @@ private void AnalyzeManagedTypeMarshallingInfo(
}
}

private static AttributeData GetAttributeData(AttributeSyntax syntax, ISymbol symbol)
{
if (syntax.FirstAncestorOrSelf<AttributeListSyntax>().Target?.Identifier.IsKind(SyntaxKind.ReturnKeyword) == true)
{
return ((IMethodSymbol)symbol).GetReturnTypeAttributes().First(attributeSyntaxLocationMatches);
}
return symbol.GetAttributes().First(attributeSyntaxLocationMatches);

bool attributeSyntaxLocationMatches(AttributeData attrData)
{
return attrData.ApplicationSyntaxReference!.SyntaxTree == syntax.SyntaxTree && attrData.ApplicationSyntaxReference.Span == syntax.Span;
}
}

private static ITypeSymbol GetSymbolType(ISymbol symbol)
{
return symbol switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,31 @@ public static Location FindTypeExpressionOrNullLocation(this AttributeArgumentSy
return walker.TypeExpressionLocation;
}

public static AttributeData? FindAttributeData(this AttributeSyntax syntax, ISymbol targetSymbol)
{
AttributeTargetSpecifierSyntax attributeTarget = syntax.FirstAncestorOrSelf<AttributeListSyntax>().Target;
if (attributeTarget is not null)
{
switch (attributeTarget.Identifier.Kind())
{
case SyntaxKind.ReturnKeyword:
return ((IMethodSymbol)targetSymbol).GetReturnTypeAttributes().First(attributeSyntaxLocationMatches);
case SyntaxKind.AssemblyKeyword:
return targetSymbol.ContainingAssembly.GetAttributes().First(attributeSyntaxLocationMatches);
case SyntaxKind.ModuleKeyword:
return targetSymbol.ContainingModule.GetAttributes().First(attributeSyntaxLocationMatches);
default:
return null;
}
}
return targetSymbol.GetAttributes().First(attributeSyntaxLocationMatches);

bool attributeSyntaxLocationMatches(AttributeData attrData)
{
return attrData.ApplicationSyntaxReference!.SyntaxTree == syntax.SyntaxTree && attrData.ApplicationSyntaxReference.Span == syntax.Span;
}
}

private sealed class FindTypeLocationWalker : CSharpSyntaxWalker
{
public Location? TypeExpressionLocation { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,19 @@ static unsafe class MarshallerType<U, V, W> where W : unmanaged
await VerifyCS.VerifyAnalyzerAsync(source,
VerifyCS.Diagnostic(GenericEntryPointMarshallerTypeMustBeClosedOrMatchArityRule).WithLocation(0).WithArguments("MarshallerType<U, V, W>", "ManagedType<T>"));
}

[Fact]
public async Task UnrelatedAssemblyOrModuleTargetDiagnostic_DoesNotCauseException()
{
string source = """
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly:AssemblyMetadata("MyKey", "MyValue")]
[module:SkipLocalsInit]
""";

await VerifyCS.VerifyAnalyzerAsync(source);
}
}
}

0 comments on commit ddded2f

Please sign in to comment.