private void AnalyzeMethod(SymbolAnalysisContext context) { context.TryGetSemanticModel(out var semanticModel); var method = (IMethodSymbol)context.Symbol; if (IsOverridenMethod(method) || method.IsAsyncOrTaskBased(context.Compilation) || method.IsIteratorBlock()) { // If the method overrides a base method or implements an interface, // then we can't enforce 'in'-modifier return; } var largeStructThreshold = Settings.GetLargeStructThresholdOrDefault(context.TryGetAnalyzerConfigOptions()); // Should analyze only subset of methods, not all of them. if (method.MethodKind == MethodKind.Ordinary || method.MethodKind == MethodKind.AnonymousFunction || method.MethodKind == MethodKind.LambdaMethod || method.MethodKind == MethodKind.LocalFunction || method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.UserDefinedOperator) { foreach (var p in method.Parameters) { if (!ParameterIsCapturedByAnonymousMethod(p, method, semanticModel)) { WarnIfParameterIsReadOnly(context.Compilation, largeStructThreshold, p, diagnostic => context.ReportDiagnostic(diagnostic)); } } } }
private void AnalyzeNamedType(SymbolAnalysisContext context) { var symbol = (INamedTypeSymbol)context.Symbol; if (symbol.TypeKind != TypeKind.Delegate) { // We're interested only in 'delegate void FooBar(MyStruct s);' cases. return; } if (symbol.DelegateInvokeMethod is null || symbol.DelegateInvokeMethod.Parameters.IsEmpty) { // No need to do any work if there are no parameters return; } var largeStructThreshold = Settings.GetLargeStructThresholdOrDefault(context.TryGetAnalyzerConfigOptions()); foreach (var parameterSymbol in symbol.DelegateInvokeMethod.Parameters) { WarnIfParameterIsReadOnly(context.Compilation, largeStructThreshold, parameterSymbol, diagnostic => context.ReportDiagnostic(diagnostic)); } }