Esempio n. 1
0
        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);
            });
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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&lt;T&gt;, 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&lt;T&gt;, where T is a valid EventArgs
                            symbolContext.ReportDiagnostic(eventSymbol.CreateDiagnostic(RuleForEvents, eventSymbol.Name, eventType.ToDisplayString()));
                        }
                    }
                }, SymbolKind.Event);
            });
        }