public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( (context) => { INamedTypeSymbol eventHandler = WellKnownTypes.EventHandler(context.Compilation); if (eventHandler == null) { return; } INamedTypeSymbol genericEventHandler = WellKnownTypes.GenericEventHandler(context.Compilation); if (genericEventHandler == null) { return; } INamedTypeSymbol eventArgs = WellKnownTypes.EventArgs(context.Compilation); if (eventArgs == null) { return; } INamedTypeSymbol comSourceInterfacesAttribute = WellKnownTypes.ComSourceInterfaceAttribute(context.Compilation); if (comSourceInterfacesAttribute == null) { return; } context.RegisterSymbolAction(GetAnalyzer(context.Compilation, eventHandler, genericEventHandler, eventArgs, comSourceInterfacesAttribute).AnalyzeSymbol, SymbolKind.Event); }); }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.RegisterCompilationStartAction( (context) => { var eventHandler = WellKnownTypes.EventHandler(context.Compilation); if (eventHandler == null) { return; } var genericEventHandler = WellKnownTypes.GenericEventHandler(context.Compilation); if (genericEventHandler == null) { return; } var eventArgs = WellKnownTypes.EventArgs(context.Compilation); if (eventArgs == null) { return; } var comSourceInterfacesAttribute = WellKnownTypes.ComSourceInterfaceAttribute(context.Compilation); if (comSourceInterfacesAttribute == null) { return; } context.RegisterSymbolAction(GetAnalyzer(context.Compilation, eventHandler, genericEventHandler, eventArgs, comSourceInterfacesAttribute).AnalyzeSymbol, SymbolKind.Event); }); }
public ICompilationEndedAnalyzer OnCompilationStarted(Compilation compilation, Action <Diagnostic> addDiagnostic, CancellationToken cancellationToken) { var eventHandler = WellKnownTypes.EventHandler(compilation); if (eventHandler == null) { return(null); } var genericEventHandler = WellKnownTypes.GenericEventHandler(compilation); if (genericEventHandler == null) { return(null); } var eventArgs = WellKnownTypes.EventArgs(compilation); if (eventArgs == null) { return(null); } var comSourceInterfacesAttribute = WellKnownTypes.ComSourceInterfaceAttribute(compilation); if (comSourceInterfacesAttribute == null) { return(null); } return(GetAnalyzer(compilation, eventHandler, genericEventHandler, eventArgs, comSourceInterfacesAttribute)); }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( (context) => { INamedTypeSymbol eventArgs = WellKnownTypes.EventArgs(context.Compilation); if (eventArgs == null) { return; } // Only analyze compilations that have a generic event handler defined. if (WellKnownTypes.GenericEventHandler(context.Compilation) == null) { return; }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( (context) => { INamedTypeSymbol eventArgs = WellKnownTypes.EventArgs(context.Compilation); if (eventArgs == null) { return; } // Only analyze compilations that have a generic event handler defined. if (WellKnownTypes.GenericEventHandler(context.Compilation) == null) { return; } bool IsDelegateTypeWithInvokeMethod(INamedTypeSymbol namedType) => namedType.TypeKind == TypeKind.Delegate && namedType.DelegateInvokeMethod != null; bool IsEventArgsParameter(IParameterSymbol parameter) { var type = parameter.Type; if (IsAssignableTo(context.Compilation, type, eventArgs)) { return(true); } // FxCop compat: Struct with name ending with "EventArgs" are allowed. if (type.IsValueType) { return(type.Name.EndsWith("EventArgs", StringComparison.Ordinal)); } return(false); } bool IsValidNonGenericEventHandler(IMethodSymbol delegateInvokeMethod) { Debug.Assert(delegateInvokeMethod != null); return(delegateInvokeMethod.ReturnsVoid && delegateInvokeMethod.Parameters.Length == 2 && delegateInvokeMethod.Parameters[0].Type.SpecialType == SpecialType.System_Object && IsEventArgsParameter(delegateInvokeMethod.Parameters[1])); } context.RegisterSymbolAction(symbolContext => { // Note all the descriptors/rules for this analyzer have the same ID and category and hence // will always have identical configured visibility. var namedType = (INamedTypeSymbol)symbolContext.Symbol; if (namedType.MatchesConfiguredVisibility(symbolContext.Options, RuleForDelegates, symbolContext.CancellationToken) && IsDelegateTypeWithInvokeMethod(namedType) && IsValidNonGenericEventHandler(namedType.DelegateInvokeMethod)) { // CA1003: Remove '{0}' and replace its usage with a generic EventHandler, for e.g. EventHandler<T>, where T is a valid EventArgs symbolContext.ReportDiagnostic(namedType.CreateDiagnostic(RuleForDelegates, namedType.Name)); } }, SymbolKind.NamedType); INamedTypeSymbol comSourceInterfacesAttribute = WellKnownTypes.ComSourceInterfaceAttribute(context.Compilation); bool ContainingTypeHasComSourceInterfacesAttribute(IEventSymbol eventSymbol) => comSourceInterfacesAttribute != null && eventSymbol.ContainingType.GetAttributes().Any(a => Equals(a.AttributeClass, comSourceInterfacesAttribute)); context.RegisterSymbolAction(symbolContext => { // NOTE: Legacy FxCop reports CA1009 for delegate type that handles a public or protected event and does not have the correct signature, return type, or parameter names. // which recommends fixing the signature to use a valid non-generic event handler. // We do not report CA1009, but instead report CA1003 and recommend using a generic event handler. // Note all the descriptors/rules for this analyzer have the same ID and category and hence // will always have identical configured visibility. var eventSymbol = (IEventSymbol)symbolContext.Symbol; if (eventSymbol.MatchesConfiguredVisibility(symbolContext.Options, RuleForEvents, symbolContext.CancellationToken) && !eventSymbol.IsOverride && !eventSymbol.IsImplementationOfAnyInterfaceMember() && !ContainingTypeHasComSourceInterfacesAttribute(eventSymbol) && eventSymbol.Type is INamedTypeSymbol eventType && IsDelegateTypeWithInvokeMethod(eventType)) { if (eventType.IsImplicitlyDeclared) { // CA1003: Change the event '{0}' to use a generic EventHandler by defining the event type explicitly, for e.g. Event MyEvent As EventHandler(Of MyEventArgs). symbolContext.ReportDiagnostic(eventSymbol.CreateDiagnostic(RuleForEvents2, eventSymbol.Name)); } else if (!IsValidNonGenericEventHandler(eventType.DelegateInvokeMethod)) { // CA1003: Change the event '{0}' to replace the type '{1}' with a generic EventHandler, for e.g. EventHandler<T>, where T is a valid EventArgs symbolContext.ReportDiagnostic(eventSymbol.CreateDiagnostic(RuleForEvents, eventSymbol.Name, eventType.ToDisplayString())); } } }, SymbolKind.Event); }); }