Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public override void Initialize (AnalysisContext context)
// Examine generic instantiations in base types and interface list
context.RegisterSymbolAction (context => {
var type = (INamedTypeSymbol) context.Symbol;
if (type.Locations.Length == 0)
return;
// RUC on type doesn't silence DAM warnings about generic base/interface types.
// This knowledge lives in IsInRequiresUnreferencedCodeAttributeScope,
// which we still call for consistency here, but it is expected to return false.
Expand All @@ -111,17 +113,23 @@ public override void Initialize (AnalysisContext context)
return;

var returnType = method.ReturnType;
foreach (var diagnostic in ProcessGenericParameters (returnType, method.Locations[0]))
context.ReportDiagnostic (diagnostic);
if (method.Locations.Length > 0) {
foreach (var diagnostic in ProcessGenericParameters (returnType, method.Locations[0]))
context.ReportDiagnostic (diagnostic);
}

foreach (var parameter in method.Parameters) {
foreach (var diagnostic in ProcessGenericParameters (parameter.Type, parameter.Locations[0]))
context.ReportDiagnostic (diagnostic);
if (parameter.Locations.Length > 0) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is the only one necessary to fix the reported issue.

foreach (var diagnostic in ProcessGenericParameters (parameter.Type, parameter.Locations[0]))
context.ReportDiagnostic (diagnostic);
}
}
}, SymbolKind.Method);
// Examine generic instantiations in field type.
context.RegisterSymbolAction (context => {
var field = (IFieldSymbol) context.Symbol;
if (field.Locations.Length == 0)
return;
if (field.IsInRequiresUnreferencedCodeAttributeScope (out _))
return;

Expand Down Expand Up @@ -244,12 +252,14 @@ static List<Diagnostic> GetDynamicallyAccessedMembersDiagnostics (SingleValue so

static void VerifyMemberOnlyApplyToTypesOrStrings (SymbolAnalysisContext context, ISymbol member)
{
if (member.Locations.Length == 0)
return;
if (member is IFieldSymbol field && field.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None && !field.Type.IsTypeInterestingForDataflow ())
context.ReportDiagnostic (Diagnostic.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersOnFieldCanOnlyApplyToTypesOrStrings), member.Locations[0], member.GetDisplayName ()));
else if (member is IMethodSymbol method) {
if (method.GetDynamicallyAccessedMemberTypesOnReturnType () != DynamicallyAccessedMemberTypes.None && !method.ReturnType.IsTypeInterestingForDataflow ())
context.ReportDiagnostic (Diagnostic.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersOnMethodReturnValueCanOnlyApplyToTypesOrStrings), member.Locations[0], member.GetDisplayName ()));
if (method.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None && !method.ContainingType.IsTypeInterestingForDataflow ())
if (method.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None && !method.ContainingType.IsTypeInterestingForDataflow () && member.Locations.Length > 0)
context.ReportDiagnostic (Diagnostic.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnMethods), member.Locations[0]));
foreach (var parameter in method.Parameters) {
if (parameter.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None && !parameter.Type.IsTypeInterestingForDataflow ())
Expand Down Expand Up @@ -277,17 +287,19 @@ static void VerifyDamOnMethodsMatch (SymbolAnalysisContext context, IMethodSymbo
(IMethodSymbol attributableMethod, DynamicallyAccessedMemberTypes missingAttribute) = GetTargetAndRequirements (overrideMethod,
baseMethod, overrideMethodReturnAnnotation, baseMethodReturnAnnotation);

Location attributableSymbolLocation = attributableMethod.Locations[0];
if (attributableMethod.Locations.Length > 0) {
Location attributableSymbolLocation = attributableMethod.Locations[0];

// code fix does not support merging multiple attributes. If an attribute is present or the method is not in source, do not provide args for code fix.
(Location[]? sourceLocation, Dictionary<string, string?>? DAMArgs) = (!attributableSymbolLocation.IsInSource
|| (overrideMethod.TryGetReturnAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _)
&& baseMethod.TryGetReturnAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _))
) ? (null, null) : CreateArguments (attributableSymbolLocation, missingAttribute);
// code fix does not support merging multiple attributes. If an attribute is present or the method is not in source, do not provide args for code fix.
(Location[]? sourceLocation, Dictionary<string, string?>? DAMArgs) = (!attributableSymbolLocation.IsInSource
|| (overrideMethod.TryGetReturnAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _)
&& baseMethod.TryGetReturnAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _))
) ? (null, null) : CreateArguments (attributableSymbolLocation, missingAttribute);

context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides),
overrideMethod.Locations[0], sourceLocation, DAMArgs?.ToImmutableDictionary (), overrideMethod.GetDisplayName (), baseMethod.GetDisplayName ()));
context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides),
overrideMethod.Locations[0], sourceLocation, DAMArgs?.ToImmutableDictionary (), overrideMethod.GetDisplayName (), baseMethod.GetDisplayName ()));
}
}

foreach (var overrideParam in overrideMethod.GetMetadataParameters ()) {
Expand Down Expand Up @@ -320,23 +332,26 @@ static void VerifyDamOnMethodsMatch (SymbolAnalysisContext context, IMethodSymbo

(IMethodSymbol attributableMethod, DynamicallyAccessedMemberTypes missingAttribute) = GetTargetAndRequirements (overrideMethod, baseMethod, methodTypeParameterAnnotation, overriddenMethodTypeParameterAnnotation);

Location attributableSymbolLocation = attributableMethod.TypeParameters[i].Locations[0];

// code fix does not support merging multiple attributes. If an attribute is present or the method is not in source, do not provide args for code fix.
(Location[]? sourceLocation, Dictionary<string, string?>? DAMArgs) = (!attributableSymbolLocation.IsInSource
|| (overrideMethod.TypeParameters[i].TryGetAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _)
&& baseMethod.TypeParameters[i].TryGetAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _))
) ? (null, null) : CreateArguments (attributableSymbolLocation, missingAttribute);

context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides),
overrideMethod.TypeParameters[i].Locations[0], sourceLocation, DAMArgs?.ToImmutableDictionary (),
overrideMethod.TypeParameters[i].GetDisplayName (), overrideMethod.GetDisplayName (),
baseMethod.TypeParameters[i].GetDisplayName (), baseMethod.GetDisplayName ()));
var attributableSymbol = attributableMethod.TypeParameters[i];
if (attributableSymbol.Locations.Length > 0) {
Location attributableSymbolLocation = attributableSymbol.Locations[0];

// code fix does not support merging multiple attributes. If an attribute is present or the method is not in source, do not provide args for code fix.
(Location[]? sourceLocation, Dictionary<string, string?>? DAMArgs) = (!attributableSymbolLocation.IsInSource
|| (overrideMethod.TypeParameters[i].TryGetAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _)
&& baseMethod.TypeParameters[i].TryGetAttribute (DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var _))
) ? (null, null) : CreateArguments (attributableSymbolLocation, missingAttribute);

context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides),
overrideMethod.TypeParameters[i].Locations[0], sourceLocation, DAMArgs?.ToImmutableDictionary (),
overrideMethod.TypeParameters[i].GetDisplayName (), overrideMethod.GetDisplayName (),
baseMethod.TypeParameters[i].GetDisplayName (), baseMethod.GetDisplayName ()));
}
}
}

if (!overrideMethod.IsStatic && overrideMethod.GetDynamicallyAccessedMemberTypes () != baseMethod.GetDynamicallyAccessedMemberTypes ())
if (!overrideMethod.IsStatic && overrideMethod.GetDynamicallyAccessedMemberTypes () != baseMethod.GetDynamicallyAccessedMemberTypes () && overrideMethod.Locations.Length > 0)
context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides),
overrideMethod.Locations[0],
Expand Down Expand Up @@ -364,12 +379,15 @@ static void VerifyDamOnPropertyAndAccessorMatch (SymbolAnalysisContext context,
// None on parameter of 'set' matches unannotated
|| methodSymbol.MethodKind == MethodKind.PropertySet
&& methodSymbol.Parameters[methodSymbol.Parameters.Length - 1].GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None) {
context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor),
methodSymbol.AssociatedSymbol!.Locations[0],
methodSymbol.AssociatedSymbol!.GetDisplayName (),
methodSymbol.GetDisplayName ()
));
var associatedSymbol = methodSymbol.AssociatedSymbol!;
if (associatedSymbol.Locations.Length > 0) {
context.ReportDiagnostic (Diagnostic.Create (
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor),
associatedSymbol.Locations[0],
associatedSymbol.GetDisplayName (),
methodSymbol.GetDisplayName ()
));
}
return;
}
}
Expand Down
Loading