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);
{
// 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;
- }
- }
}
}
}
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;
}
}
- 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
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; }
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);
+ }
}
}