Skip to content

Commit

Permalink
Bring IsContructor Method from roslyn source
Browse files Browse the repository at this point in the history
Delete the diagnostic target class and just warn if the class has the attribute on the class
Add support for event raise usage in the analyzer
Rebase to 6.0.2xx
  • Loading branch information
tlakollo committed Oct 27, 2021
1 parent 93430fa commit a102cb8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,11 @@ public static bool IsSubclassOf (this ISymbol symbol, string ns, string type)

return false;
}

public static bool IsConstructor ([NotNullWhen (returnValue: true)] this ISymbol? symbol)
=> (symbol as IMethodSymbol)?.MethodKind == MethodKind.Constructor;

public static bool IsStaticConstructor ([NotNullWhen (returnValue: true)] this ISymbol? symbol)
=> (symbol as IMethodSymbol)?.MethodKind == MethodKind.StaticConstructor;
}
}
17 changes: 8 additions & 9 deletions src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,13 @@ public override void Initialize (AnalysisContext context)
var objectCreation = (IObjectCreationOperation) operationContext.Operation;
var ctor = objectCreation.Constructor;
if (ctor is not null) {
CheckCalledMember (operationContext, ctor, incompatibleMembers, IsConstructor: true);
CheckCalledMember (operationContext, ctor, incompatibleMembers);
}
}, OperationKind.ObjectCreation);
context.RegisterOperationAction (operationContext => {
var fieldReference = (IFieldReferenceOperation) operationContext.Operation;
if (AnalyzerDiagnosticTargets.HasFlag (DiagnosticTargets.Class) &&
fieldReference.Field.IsStatic &&
if (fieldReference.Field.IsStatic &&
fieldReference.Syntax.IsKind (SyntaxKind.SimpleMemberAccessExpression) &&
fieldReference.Field.ContainingType is INamedTypeSymbol fieldDeclaringType &&
fieldDeclaringType.TryGetAttribute (RequiresAttributeName, out var requiresAttribute)) {
Expand Down Expand Up @@ -129,6 +128,9 @@ fieldReference.Field.ContainingType is INamedTypeSymbol fieldDeclaringType &&
if (eventSymbol.RemoveMethod is IMethodSymbol eventRemoveMethod)
CheckCalledMember (operationContext, eventRemoveMethod, incompatibleMembers);
if (eventSymbol.RaiseMethod is IMethodSymbol eventRaiseMethod)
CheckCalledMember (operationContext, eventRaiseMethod, incompatibleMembers);
}, OperationKind.EventReference);
context.RegisterOperationAction (operationContext => {
Expand Down Expand Up @@ -169,23 +171,20 @@ void CheckAttributeInstantiation (
void CheckCalledMember (
OperationAnalysisContext operationContext,
ISymbol member,
ImmutableArray<ISymbol> incompatibleMembers,
bool IsConstructor = false)
ImmutableArray<ISymbol> incompatibleMembers)
{
ISymbol containingSymbol = FindContainingSymbol (operationContext, AnalyzerDiagnosticTargets);
INamedTypeSymbol memberDeclaringType = member.ContainingType;
INamedTypeSymbol containingSymbolDeclaringType = containingSymbol.ContainingType;
if (AnalyzerDiagnosticTargets.HasFlag (DiagnosticTargets.Class) &&
(!IsConstructor && member.IsStatic || IsConstructor) &&
if ((!member.IsConstructor () && member.IsStatic || member.IsConstructor ()) &&
memberDeclaringType.TryGetAttribute (RequiresAttributeName, out var typeRequires) &&
!containingSymbolDeclaringType.HasAttribute (RequiresAttributeName))
ReportRequiresDiagnostic (operationContext, member, typeRequires);
// Do not emit any diagnostic if caller is annotated with the attribute too.
if (containingSymbol.HasAttribute (RequiresAttributeName) ||
(AnalyzerDiagnosticTargets.HasFlag (DiagnosticTargets.Class)
&& containingSymbolDeclaringType.HasAttribute (RequiresAttributeName)))
containingSymbolDeclaringType.HasAttribute (RequiresAttributeName))
return;
// Check also for RequiresAttribute in the associated symbol
Expand Down

0 comments on commit a102cb8

Please sign in to comment.