public UnusedParametersAnalyzer(IMethodSymbol method, UnusedParameterDictionary finalUnusedParameters) { // Initialization: Assume all parameters are unused. _unusedParameters = new HashSet <IParameterSymbol>(method.Parameters); _finalUnusedParameters = finalUnusedParameters; _method = method; }
public UnusedParametersAnalyzer(IMethodSymbol method, UnusedParameterDictionary finalUnusedParameters) { // Initialization: Assume all parameters are unused, except the ones with special discard name. _unusedParameters = new HashSet <IParameterSymbol>(method.Parameters.Where(p => !p.IsSymbolWithSpecialDiscardName())); _finalUnusedParameters = finalUnusedParameters; _method = method; }
public UnusedParametersAnalyzer(IMethodSymbol method, UnusedParameterDictionary finalUnusedParameters, ImmutableHashSet <INamedTypeSymbol> exceptionsToSkip) { // Initialization: Assume all parameters are unused. _unusedParameters = new HashSet <IParameterSymbol>(method.Parameters); _exceptionsToSkip = exceptionsToSkip; _finalUnusedParameters = finalUnusedParameters; _method = method; }
private static void AnalyzeMethod( IMethodSymbol method, OperationBlockStartAnalysisContext startOperationBlockContext, UnusedParameterDictionary unusedMethodParameters, INamedTypeSymbol eventsArgSymbol, ISet <IMethodSymbol> methodsUsedAsDelegates, ImmutableHashSet <INamedTypeSymbol> attributeSetForMethodsToIgnore) { // We only care about methods with parameters. if (method.Parameters.IsEmpty) { return; } // Ignore implicitly declared methods, extern methods, abstract methods, virtual methods, interface implementations and finalizers (FxCop compat). if (method.IsImplicitlyDeclared || method.IsExtern || method.IsAbstract || method.IsVirtual || method.IsOverride || method.IsImplementationOfAnyInterfaceMember() || method.IsFinalizer()) { return; } // Ignore property accessors. if (method.IsPropertyAccessor()) { return; } // Ignore event handler methods "Handler(object, MyEventArgs)" if (eventsArgSymbol != null && method.Parameters.Length == 2 && method.Parameters[0].Type.SpecialType == SpecialType.System_Object && method.Parameters[1].Type.Inherits(eventsArgSymbol)) { return; } // Ignore methods with any attributes in 'attributeSetForMethodsToIgnore'. if (method.GetAttributes().Any(a => a.AttributeClass != null && attributeSetForMethodsToIgnore.Contains(a.AttributeClass))) { return; } // Ignore methods that were used as delegates if (methodsUsedAsDelegates.Contains(method)) { return; } // Initialize local mutable state in the start action. var analyzer = new UnusedParametersAnalyzer(method, unusedMethodParameters); // Register an intermediate non-end action that accesses and modifies the state. startOperationBlockContext.RegisterOperationAction(analyzer.AnalyzeParameterReference, OperationKind.ParameterReference); // Register an end action to add unused parameters to the unusedMethodParameters dictionary startOperationBlockContext.RegisterOperationBlockEndAction(analyzer.OperationBlockEndAction); }
private static void AnalyzeMethod( IMethodSymbol method, OperationBlockStartAnalysisContext startOperationBlockContext, UnusedParameterDictionary unusedMethodParameters, INamedTypeSymbol?eventsArgSymbol, ISet <IMethodSymbol> methodsUsedAsDelegates, ImmutableHashSet <INamedTypeSymbol?> attributeSetForMethodsToIgnore) { // We only care about methods with parameters. if (method.Parameters.IsEmpty) { return; } // Ignore implicitly declared methods, extern methods, abstract methods, virtual methods, interface implementations and finalizers (FxCop compat). if (method.IsImplicitlyDeclared || method.IsExtern || method.IsAbstract || method.IsVirtual || method.IsOverride || method.IsImplementationOfAnyInterfaceMember() || method.IsFinalizer()) { return; } // Ignore property accessors. if (method.IsPropertyAccessor()) { return; } // Ignore event handler methods "Handler(object, MyEventArgs)" if (method.Parameters.Length == 2 && method.Parameters[0].Type.SpecialType == SpecialType.System_Object && // UWP has specific EventArgs not inheriting from System.EventArgs. It was decided to go for a suffix match rather than a whitelist. (method.Parameters[1].Type.Inherits(eventsArgSymbol) || method.Parameters[1].Type.Name.EndsWith("EventArgs", StringComparison.Ordinal))) { return; } // Ignore methods with any attributes in 'attributeSetForMethodsToIgnore'. if (method.GetAttributes().Any(a => a.AttributeClass != null && attributeSetForMethodsToIgnore.Contains(a.AttributeClass))) { return; } // Ignore methods that were used as delegates if (methodsUsedAsDelegates.Contains(method)) { return; } // Bail out if user has configured to skip analysis for the method. if (!method.MatchesConfiguredVisibility( startOperationBlockContext.Options, Rule, startOperationBlockContext.CancellationToken, defaultRequiredVisibility: SymbolVisibilityGroup.All)) { return; } // Initialize local mutable state in the start action. var analyzer = new UnusedParametersAnalyzer(method, unusedMethodParameters); // Register an intermediate non-end action that accesses and modifies the state. startOperationBlockContext.RegisterOperationAction(analyzer.AnalyzeParameterReference, OperationKind.ParameterReference); // Register an end action to add unused parameters to the unusedMethodParameters dictionary startOperationBlockContext.RegisterOperationBlockEndAction(analyzer.OperationBlockEndAction); }