public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationAction(AnalyzeCompilation);
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxTreeAction(SyntaxTreeAction);
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.RegisterSyntaxNodeAction(
         (nodeContext) =>
         {
             Diagnostic diagnostic;
             if (TryGetDiagnostic(nodeContext, out diagnostic))
             {
                 nodeContext.ReportDiagnostic(diagnostic);
             }
         },
         new SyntaxKind[] {
             SyntaxKind.MethodDeclaration,
                       SyntaxKind.FieldDeclaration,
                       SyntaxKind.PropertyDeclaration,
                       SyntaxKind.IndexerDeclaration,
                       SyntaxKind.EventDeclaration,
                       SyntaxKind.ConstructorDeclaration,
                       SyntaxKind.OperatorDeclaration,
                       SyntaxKind.ClassDeclaration,
                       SyntaxKind.InterfaceDeclaration,
                       SyntaxKind.StructDeclaration,
                       SyntaxKind.EnumDeclaration,
                       SyntaxKind.DelegateDeclaration
         }
     );
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var exportAttributes = new List<INamedTypeSymbol>();

                foreach (var mefNamespace in s_mefNamespaces)
                {
                    var exportAttribute = compilationContext.Compilation.GetTypeByMetadataName(mefNamespace + ".ExportAttribute");

                    if (exportAttribute == null)
                    {
                        // We don't need to check assemblies unless they're referencing both versions of MEF, so we're done
                        return;
                    }

                    exportAttributes.Add(exportAttribute);
                }

                compilationContext.RegisterSymbolAction(c => AnalyzeSymbol(c, exportAttributes), SymbolKind.NamedType);
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var exportAttribute = compilationContext.Compilation.GetTypeByMetadataName("System.Composition.ExportAttribute");

                if (exportAttribute == null)
                {
                    // We don't need to check assemblies unless they're referencing both MEFv2, so we're done
                    return;
                }

                compilationContext.RegisterSymbolAction(symbolContext =>
                {
                    var namedType = (INamedTypeSymbol)symbolContext.Symbol;
                    var namedTypeAttributes = namedType.GetApplicableAttributes();

                    var exportAttributeApplication = namedTypeAttributes.FirstOrDefault(ad => ad.AttributeClass.DerivesFrom(exportAttribute));

                    if (exportAttributeApplication != null)
                    {
                        if (!namedTypeAttributes.Any(ad => ad.AttributeClass.Name == "SharedAttribute" &&
                                                           ad.AttributeClass.ContainingNamespace.Equals(exportAttribute.ContainingNamespace)))
                        {
                            // '{0}' is exported with MEFv2 and hence must be marked as Shared
                            symbolContext.ReportDiagnostic(Diagnostic.Create(Rule, exportAttributeApplication.ApplicationSyntaxReference.GetSyntax().GetLocation(), namedType.Name));
                        }
                    }
                }, SymbolKind.NamedType);
            });
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(DoStatementAction, SyntaxKind.DoStatement);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(OnCompilationStart);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterSymbolAction(
                symbolAnalysisContext =>
                {
                    ISymbol symbol = symbolAnalysisContext.Symbol;
                    if (!symbol.ContainingType.IsGenericType ||
                        symbol.DeclaredAccessibility != Accessibility.Public ||
                        !symbol.IsStatic)
                    {
                        return;
                    }

                    var methodSymbol = symbol as IMethodSymbol;
                    if (methodSymbol != null &&
                        (methodSymbol.IsAccessorMethod() ||
                         (methodSymbol.MethodKind == MethodKind.UserDefinedOperator &&
                          (methodSymbol.Name == WellKnownMemberNames.EqualityOperatorName ||
                           methodSymbol.Name == WellKnownMemberNames.InequalityOperatorName))))
                    {
                        return;
                    }

                    symbolAnalysisContext.ReportDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name));
                }, SymbolKind.Method, SymbolKind.Property);
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(DocumentationTriviaAction, SyntaxKind.SingleLineDocumentationCommentTrivia);
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(RegionDirectiveTriviaAction, SyntaxKind.RegionDirectiveTrivia);
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSymbolAction(Analyzer.HandleFieldDeclaration, SymbolKind.Field);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterSyntaxNodeAction(
                nodeContext =>
                {
                    GetDiagnostics(nodeContext, ((InvocationExpressionSyntax)nodeContext.Node).ArgumentList?.Arguments);
                },
                new SyntaxKind[] { SyntaxKind.InvocationExpression }
            );
            context.RegisterSyntaxNodeAction(
                nodeContext =>
                {
                    GetDiagnostics(nodeContext, ((ElementAccessExpressionSyntax)nodeContext.Node).ArgumentList?.Arguments);
                },
                new SyntaxKind[] { SyntaxKind.ElementAccessExpression }
            );
            context.RegisterSyntaxNodeAction(
                nodeContext =>
                {
                    GetDiagnostics(nodeContext, ((ObjectCreationExpressionSyntax)nodeContext.Node).ArgumentList?.Arguments);
                },
                new SyntaxKind[] { SyntaxKind.ObjectCreationExpression }
            );

            context.RegisterSyntaxNodeAction(
                nodeContext =>
                {
                    GetDiagnostics(nodeContext, ((AttributeSyntax)nodeContext.Node).ArgumentList?.Arguments);
                },
                new SyntaxKind[] { SyntaxKind.Attribute }
            );
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterSyntaxNodeAction<SyntaxKind>(AnalyzeNode, SyntaxKind.ThrowStatement);
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(AnonymousMethodExpressionAction, SyntaxKind.AnonymousMethodExpression);
        }
        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);
                });
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            analysisContext.EnableConcurrentExecution();

            analysisContext.RegisterSymbolAction(AnalyzeMethodSymbol, SymbolKind.Method);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            // this is stateless analyzer, can run concurrently
            analysisContext.EnableConcurrentExecution();

            // this has no meaning on running on generated code which user can't control
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(c =>
            {
                INamedTypeSymbol @string = WellKnownTypes.String(c.Compilation);
                INamedTypeSymbol uri = WellKnownTypes.Uri(c.Compilation);
                if (@string == null || uri == null)
                {
                    // we don't have required types
                    return;
                }

                var analyzer = new Analyzer(c.Compilation, @string, uri, GetInvocationExpression);

                // REVIEW: I need to do this thing because OperationAnalysisContext doesn't give me OwningSymbol
                c.RegisterOperationBlockStartAction(sc =>
                {
                    sc.RegisterOperationAction(oc => analyzer.Analyze(oc, sc.OwningSymbol), OperationKind.InvocationExpression);
                });
            });
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.RegisterSyntaxNodeAction(
         nodeContext =>
         {
             Diagnostic diagnostic;
             if (TryGetDiagnostic(nodeContext, out diagnostic))
             {
                 nodeContext.ReportDiagnostic(diagnostic);
             }
         },
         new SyntaxKind[] {
             SyntaxKind.EqualsExpression,
             SyntaxKind.NotEqualsExpression,
             SyntaxKind.LessThanExpression,
             SyntaxKind.LessThanOrEqualExpression,
             SyntaxKind.GreaterThanExpression,
             SyntaxKind.GreaterThanOrEqualExpression
         }
     );
     context.RegisterSyntaxNodeAction(
         nodeContext =>
         {
             Diagnostic diagnostic;
             if (TryGetDiagnostic2(nodeContext, out diagnostic))
             {
                 nodeContext.ReportDiagnostic(diagnostic);
             }
         },
         new SyntaxKind[] { SyntaxKind.LogicalNotExpression }
     );
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationStartContext =>
            {
                var immutableArrayType = compilationStartContext.Compilation.GetTypeByMetadataName(ImmutableArrayMetadataName);
                if (immutableArrayType == null)
                {
                    return;
                }

                compilationStartContext.RegisterOperationAction(operationContext =>
                {
                    var invocation = (IInvocationExpression)operationContext.Operation;
                    if (invocation.IsInvalid ||
                        invocation.TargetMethod?.Name != "ToImmutableArray")
                    {
                        return;
                    }

                    var receiverType = invocation.GetReceiverType(operationContext.Compilation, beforeConversion: true, cancellationToken: operationContext.CancellationToken);
                    if (receiverType != null &&
                        receiverType.DerivesFromOrImplementsAnyConstructionOf(immutableArrayType))
                    {
                        operationContext.ReportDiagnostic(Diagnostic.Create(Rule, invocation.Syntax.GetLocation()));
                    }
                }, OperationKind.InvocationExpression);
            });
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(BinaryExpressionAction, HandledBinaryExpressionKinds);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterSymbolAction(
                (symbol) =>
                {
                    Diagnostic diagnostic;
                    if (TryGetDiagnostic(symbol, out diagnostic))
                    {
                        symbol.ReportDiagnostic(diagnostic);
                    }
                },
                new SymbolKind[] {
                    SymbolKind.Method
                }
            );

            context.RegisterSyntaxNodeAction(
               (nodeContext) =>
               {
                   Diagnostic diagnostic;
                   if (TryGetDiagnostic(nodeContext, out diagnostic))
                   {
                       nodeContext.ReportDiagnostic(diagnostic);
                   }
               },
               new SyntaxKind[] {
                   SyntaxKind.AnonymousMethodExpression,
                    SyntaxKind.ParenthesizedLambdaExpression,
                    SyntaxKind.SimpleLambdaExpression
               }
           );
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(EnumMemberDeclarationAction, SyntaxKind.EnumMemberDeclaration);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol conditionalAttributeSymbol = WellKnownTypes.ConditionalAttribute(compilationContext.Compilation);

                compilationContext.RegisterOperationBlockAction(context =>
                {
                    var method = context.OwningSymbol as IMethodSymbol;
                    if (method == null)
                    {
                        return;
                    }

                    if (!method.IsFinalizer())
                    {
                        return;
                    }

                    if (IsEmptyFinalizer(context.OperationBlocks, conditionalAttributeSymbol))
                    {
                        context.ReportDiagnostic(context.OwningSymbol.CreateDiagnostic(Rule));
                    }
                });
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterSyntaxNodeAction(AnalyzeXmlAttribute, SyntaxKind.XmlTextAttribute);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterSymbolAction(symbolContext =>
            {
                var method = (IMethodSymbol)symbolContext.Symbol;
                if (!IsEventLikeNameCandidate(method.Name))
                {
                    Debug.Assert(!HasEventLikeName(method), "fast check failed but eventual check succeeds?");
                    return;
                }

                // Bail out for implicitly declared methods, overridden methods, interface implementations, constructors and finalizers (FxCop compat).
                if (method.IsImplicitlyDeclared ||
                    method.IsOverride ||
                    method.IsImplementationOfAnyInterfaceMember() ||
                    method.IsConstructor() ||
                    method.IsFinalizer())
                {
                    return;
                }

                if (HasEventLikeName(method))
                {
                    // Consider making '{0}' an event.
                    var diagnostic = method.CreateDiagnostic(Rule, method.Name);
                    symbolContext.ReportDiagnostic(diagnostic);
                }
            }, SymbolKind.Method);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
                compilationContext =>
                {
                    Compilation compilation = compilationContext.Compilation;
                    ITypeSymbol argumentExceptionType = compilation.GetTypeByMetadataName("System.ArgumentException");

                    if (argumentExceptionType == null)
                    {
                        return;
                    }

                    compilationContext.RegisterOperationBlockStartAction(
                        operationBlockStartContext =>
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationContext => AnalyzeObjectCreation(
                                    operationContext,
                                    operationBlockStartContext.OwningSymbol,
                                    argumentExceptionType),
                                OperationKind.ObjectCreationExpression);
                        });
                });
        }
        /// <inheritdoc/>
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();

            context.RegisterSyntaxNodeAction(TypeParameterConstraintClauseAction, SyntaxKind.TypeParameterConstraintClause);
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
               (context) =>
               {
                   INamedTypeSymbol iCollectionType = WellKnownTypes.ICollection(context.Compilation);
                   INamedTypeSymbol genericICollectionType = WellKnownTypes.GenericICollection(context.Compilation);
                   INamedTypeSymbol iEnumerableType = WellKnownTypes.IEnumerable(context.Compilation);
                   INamedTypeSymbol genericIEnumerableType = WellKnownTypes.GenericIEnumerable(context.Compilation);
                   INamedTypeSymbol iListType = WellKnownTypes.IList(context.Compilation);
                   INamedTypeSymbol genericIListType = WellKnownTypes.GenericIList(context.Compilation);

                   if (iCollectionType == null && genericICollectionType == null &&
                       iEnumerableType == null && genericIEnumerableType == null &&
                       iListType == null && genericIListType == null)
                   {
                       return;
                   }

                   context.RegisterSymbolAction(c => AnalyzeSymbol(c,
                                                iCollectionType, genericICollectionType,
                                                iEnumerableType, genericIEnumerableType,
                                                iListType, genericIListType),
                                                SymbolKind.NamedType);
               });
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
                (context) =>
                {
                    INamedTypeSymbol dllImportType = context.Compilation.GetTypeByMetadataName("System.Runtime.InteropServices.DllImportAttribute");
                    if (dllImportType == null)
                    {
                        return;
                    }

                    INamedTypeSymbol marshalAsType = context.Compilation.GetTypeByMetadataName("System.Runtime.InteropServices.MarshalAsAttribute");
                    if (marshalAsType == null)
                    {
                        return;
                    }

                    INamedTypeSymbol stringBuilderType = context.Compilation.GetTypeByMetadataName("System.Text.StringBuilder");
                    if (stringBuilderType == null)
                    {
                        return;
                    }

                    INamedTypeSymbol unmanagedType = context.Compilation.GetTypeByMetadataName("System.Runtime.InteropServices.UnmanagedType");
                    if (unmanagedType == null)
                    {
                        return;
                    }

                    context.RegisterSymbolAction(new SymbolAnalyzer(dllImportType, marshalAsType, stringBuilderType, unmanagedType).AnalyzeSymbol, SymbolKind.Method);
                });
        }
Ejemplo n.º 31
0
        /// <inheritdoc />
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);

            context.RegisterCompilationStartAction(compilationStartContext =>
            {
                var mainThreadAssertingMethods = CommonInterest.ReadMethods(compilationStartContext.Options, CommonInterest.FileNamePatternForMethodsThatAssertMainThread, compilationStartContext.CancellationToken).ToImmutableArray();
                var mainThreadSwitchingMethods = CommonInterest.ReadMethods(compilationStartContext.Options, CommonInterest.FileNamePatternForMethodsThatSwitchToMainThread, compilationStartContext.CancellationToken).ToImmutableArray();
                var membersRequiringMainThread = CommonInterest.ReadTypesAndMembers(compilationStartContext.Options, CommonInterest.FileNamePatternForMembersRequiringMainThread, compilationStartContext.CancellationToken).ToImmutableArray();
                var diagnosticProperties       = ImmutableDictionary <string, string> .Empty
                                                 .Add(CommonInterest.FileNamePatternForMethodsThatAssertMainThread.ToString(), string.Join("\n", mainThreadAssertingMethods))
                                                 .Add(CommonInterest.FileNamePatternForMethodsThatSwitchToMainThread.ToString(), string.Join("\n", mainThreadSwitchingMethods));

                var methodsDeclaringUIThreadRequirement = new HashSet <IMethodSymbol>();
                var methodsAssertingUIThreadRequirement = new HashSet <IMethodSymbol>();
                var callerToCalleeMap = new Dictionary <IMethodSymbol, List <CallInfo> >();

                compilationStartContext.RegisterCodeBlockStartAction <SyntaxKind>(codeBlockStartContext =>
                {
                    var methodAnalyzer = new MethodAnalyzer
                    {
                        MainThreadAssertingMethods          = mainThreadAssertingMethods,
                        MainThreadSwitchingMethods          = mainThreadSwitchingMethods,
                        MembersRequiringMainThread          = membersRequiringMainThread,
                        MethodsDeclaringUIThreadRequirement = methodsDeclaringUIThreadRequirement,
                        MethodsAssertingUIThreadRequirement = methodsAssertingUIThreadRequirement,
                        DiagnosticProperties = diagnosticProperties,
                    };
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeInvocation), SyntaxKind.InvocationExpression);
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeMemberAccess), SyntaxKind.SimpleMemberAccessExpression);
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeCast), SyntaxKind.CastExpression);
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeAs), SyntaxKind.AsExpression);
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeAs), SyntaxKind.IsExpression);
                    codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeIsPattern), SyntaxKind.IsPatternExpression);
                });

                compilationStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(c => AddToCallerCalleeMap(c, callerToCalleeMap)), SyntaxKind.InvocationExpression);
                compilationStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(c => AddToCallerCalleeMap(c, callerToCalleeMap)), SyntaxKind.SimpleMemberAccessExpression);
                compilationStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(c => AddToCallerCalleeMap(c, callerToCalleeMap)), SyntaxKind.IdentifierName);

                compilationStartContext.RegisterCompilationEndAction(compilationEndContext =>
                {
                    var calleeToCallerMap = CreateCalleeToCallerMap(callerToCalleeMap);
                    var transitiveClosureOfMainThreadRequiringMethods = GetTransitiveClosureOfMainThreadRequiringMethods(methodsAssertingUIThreadRequirement, calleeToCallerMap);
                    foreach (var implicitUserMethod in transitiveClosureOfMainThreadRequiringMethods.Except(methodsDeclaringUIThreadRequirement))
                    {
                        var reportSites = from info in callerToCalleeMap[implicitUserMethod]
                                          where transitiveClosureOfMainThreadRequiringMethods.Contains(info.MethodSymbol)
                                          group info by info.MethodSymbol into bySymbol
                                          select new { Location = bySymbol.First().InvocationSyntax.GetLocation(), CalleeMethod = bySymbol.Key };
                        foreach (var site in reportSites)
                        {
                            bool isAsync          = Utils.IsAsyncReady(implicitUserMethod);
                            var descriptor        = isAsync ? DescriptorAsync : DescriptorSync;
                            string calleeName     = Utils.GetFullName(site.CalleeMethod);
                            var formattingArgs    = isAsync ? new object[] { calleeName } : new object[] { calleeName, mainThreadAssertingMethods.FirstOrDefault() };
                            Diagnostic diagnostic = Diagnostic.Create(
                                descriptor,
                                site.Location,
                                diagnosticProperties,
                                formattingArgs);
                            compilationEndContext.ReportDiagnostic(diagnostic);
                        }
                    }
                });
            });
        }
Ejemplo n.º 32
0
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
 }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationAction(compilationContext =>
            {
                if (compilationContext.Compilation.SyntaxTrees.FirstOrDefault() is not SyntaxTree tree)
                {
                    return;
                }

                // Try read the additional file containing the code metrics configuration.
                if (!TryGetRuleIdToThresholdMap(
                        compilationContext.Options.AdditionalFiles,
                        compilationContext.CancellationToken,
                        out AdditionalText? additionalTextOpt,
                        out ImmutableDictionary <string, IReadOnlyList <(SymbolKind?, uint)> >?ruleIdToThresholdMap,
                        out List <Diagnostic>?invalidFileDiagnostics) &&
                    invalidFileDiagnostics != null)
                {
                    // Report any invalid additional file diagnostics.
                    foreach (var diagnostic in invalidFileDiagnostics)
                    {
                        compilationContext.ReportDiagnostic(diagnostic);
                    }

                    return;
                }

                var metricsAnalysisContext = new CodeMetricsAnalysisContext(compilationContext.Compilation, compilationContext.CancellationToken,
                                                                            namedType => IsConfiguredToSkipFromInheritanceCount(namedType, compilationContext, tree));
                var computeTask = CodeAnalysisMetricData.ComputeAsync(metricsAnalysisContext);
                computeTask.Wait(compilationContext.CancellationToken);

                // Analyze code metrics tree and report diagnostics.
                analyzeMetricsData(computeTask.Result);

                void analyzeMetricsData(CodeAnalysisMetricData codeAnalysisMetricData)
                {
                    var symbol = codeAnalysisMetricData.Symbol;

                    // CA1501: Avoid excessive inheritance
                    if (symbol.Kind == SymbolKind.NamedType && codeAnalysisMetricData.DepthOfInheritance.HasValue)
                    {
                        uint?inheritanceThreshold = getThreshold(CA1501RuleId, symbol.Kind);
                        if (inheritanceThreshold.HasValue && codeAnalysisMetricData.DepthOfInheritance.Value > inheritanceThreshold.Value)
                        {
                            // '{0}' has an object hierarchy '{1}' levels deep within the defining module. If possible, eliminate base classes within the hierarchy to decrease its hierarchy level below '{2}': '{3}'
                            var arg1       = symbol.Name;
                            var arg2       = codeAnalysisMetricData.DepthOfInheritance;
                            var arg3       = inheritanceThreshold + 1;
                            var arg4       = string.Join(", ", ((INamedTypeSymbol)symbol).GetBaseTypes(t => !IsConfiguredToSkipFromInheritanceCount(t, compilationContext, tree)).Select(t => t.Name));
                            var diagnostic = symbol.CreateDiagnostic(CA1501Rule, arg1, arg2, arg3, arg4);
                            compilationContext.ReportDiagnostic(diagnostic);
                        }
                    }

                    // CA1502: Avoid excessive complexity
                    uint?complexityThreshold = getThreshold(CA1502RuleId, symbol.Kind);
                    if (complexityThreshold.HasValue && codeAnalysisMetricData.CyclomaticComplexity > complexityThreshold.Value)
                    {
                        // '{0}' has a cyclomatic complexity of '{1}'. Rewrite or refactor the code to decrease its complexity below '{2}'.
                        var arg1       = symbol.Name;
                        var arg2       = codeAnalysisMetricData.CyclomaticComplexity;
                        var arg3       = complexityThreshold.Value + 1;
                        var diagnostic = symbol.CreateDiagnostic(CA1502Rule, arg1, arg2, arg3);
                        compilationContext.ReportDiagnostic(diagnostic);
                    }

                    // CA1505: Avoid unmaintainable code
                    uint?maintainabilityIndexThreshold = getThreshold(CA1505RuleId, symbol.Kind);
                    if (maintainabilityIndexThreshold.HasValue && maintainabilityIndexThreshold.Value > codeAnalysisMetricData.MaintainabilityIndex)
                    {
                        // '{0}' has a maintainability index of '{1}'. Rewrite or refactor the code to increase its maintainability index (MI) above '{2}'.
                        var arg1       = symbol.Name;
                        var arg2       = codeAnalysisMetricData.MaintainabilityIndex;
                        var arg3       = maintainabilityIndexThreshold.Value - 1;
                        var diagnostic = symbol.CreateDiagnostic(CA1505Rule, arg1, arg2, arg3);
                        compilationContext.ReportDiagnostic(diagnostic);
                    }

                    // CA1506: Avoid excessive class coupling
                    uint?classCouplingThreshold = getThreshold(CA1506RuleId, symbol.Kind);
                    if (classCouplingThreshold.HasValue && codeAnalysisMetricData.CoupledNamedTypes.Count > classCouplingThreshold.Value)
                    {
                        // '{0}' is coupled with '{1}' different types from '{2}' different namespaces. Rewrite or refactor the code to decrease its class coupling below '{3}'.
                        var arg1       = symbol.Name;
                        var arg2       = codeAnalysisMetricData.CoupledNamedTypes.Count;
                        var arg3       = GetDistinctContainingNamespacesCount(codeAnalysisMetricData.CoupledNamedTypes);
                        var arg4       = classCouplingThreshold.Value + 1;
                        var diagnostic = symbol.CreateDiagnostic(CA1506Rule, arg1, arg2, arg3, arg4);
                        compilationContext.ReportDiagnostic(diagnostic);
                    }

                    foreach (var child in codeAnalysisMetricData.Children)
                    {
                        analyzeMetricsData(child);
                    }
                }

                uint?getThreshold(string ruleId, SymbolKind symbolKind)
                {
                    // Check if we have custom threshold value for the given ruleId and symbolKind.
                    if (ruleIdToThresholdMap != null &&
                        ruleIdToThresholdMap.TryGetValue(ruleId, out IReadOnlyList <(SymbolKind?symbolKindOpt, uint threshold)> values))
                    {
                        foreach ((SymbolKind? symbolKindOpt, uint threshold) in values)
                        {
                            if (symbolKindOpt.HasValue && symbolKindOpt.Value == symbolKind)
                            {
                                return(threshold);
                            }
                        }

                        if (values.Count == 1 &&
                            values[0].symbolKindOpt == null &&
                            isApplicableByDefault(ruleId, symbolKind))
                        {
                            return(values[0].threshold);
                        }
                    }

                    return(getDefaultThreshold(ruleId, symbolKind));
                }

                static bool isApplicableByDefault(string ruleId, SymbolKind symbolKind)
                {
                    switch (ruleId)
                    {
                    case CA1501RuleId:
                        return(symbolKind == SymbolKind.NamedType);

                    case CA1502RuleId:
                        return(symbolKind == SymbolKind.Method);

                    case CA1505RuleId:
                        switch (symbolKind)
                        {
                        case SymbolKind.NamedType:
                        case SymbolKind.Method:
                        case SymbolKind.Field:
                        case SymbolKind.Property:
                        case SymbolKind.Event:
                            return(true);

                        default:
                            return(false);
                        }

                    case CA1506RuleId:
                        switch (symbolKind)
                        {
                        case SymbolKind.NamedType:
                        case SymbolKind.Method:
                        case SymbolKind.Field:
                        case SymbolKind.Property:
                        case SymbolKind.Event:
                            return(true);

                        default:
                            return(false);
                        }

                    default:
                        throw new NotImplementedException();
                    }
                }
 /// <inheritdoc/>
 public override void Initialize(AnalysisContext context)
 {
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.EnableConcurrentExecution();
     context.RegisterSyntaxNodeAction(HandleObjectCreation, SyntaxKind.ObjectCreationExpression);
 }
Ejemplo n.º 35
0
 /// <summary>
 ///     This is used to initialize the analyzer.
 /// </summary>
 /// <param name="context">
 ///     The context the analysis should take place in.
 /// </param>
 public override void Initialize(AnalysisContext context)
 {
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
     context.EnableConcurrentExecution();
     context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);
 }
Ejemplo n.º 36
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol expectedExceptionType = WellKnownTypes.ExpectedException(compilationContext.Compilation);
                INamedTypeSymbol nunitAssertType       = WellKnownTypes.NunitAssert(compilationContext.Compilation);
                INamedTypeSymbol xunitAssertType       = WellKnownTypes.XunitAssert(compilationContext.Compilation);

                compilationContext.RegisterOperationBlockStartAction(osContext =>
                {
                    if (!(osContext.OwningSymbol is IMethodSymbol method))
                    {
                        return;
                    }

                    osContext.RegisterOperationAction(opContext =>
                    {
                        IOperation expression     = ((IExpressionStatementOperation)opContext.Operation).Operation;
                        DiagnosticDescriptor rule = null;
                        string targetMethodName   = null;
                        switch (expression.Kind)
                        {
                        case OperationKind.ObjectCreation:
                            IMethodSymbol ctor = ((IObjectCreationOperation)expression).Constructor;
                            if (ctor != null)
                            {
                                rule             = ObjectCreationRule;
                                targetMethodName = ctor.ContainingType.Name;
                            }
                            break;

                        case OperationKind.Invocation:
                            IInvocationOperation invocationExpression = ((IInvocationOperation)expression);
                            IMethodSymbol targetMethod = invocationExpression.TargetMethod;
                            if (targetMethod == null)
                            {
                                break;
                            }

                            if (IsStringCreatingMethod(targetMethod))
                            {
                                rule = StringCreationRule;
                            }
                            else if (IsTryParseMethod(targetMethod))
                            {
                                rule = TryParseRule;
                            }
                            else if (IsHResultOrErrorCodeReturningMethod(targetMethod))
                            {
                                rule = HResultOrErrorCodeRule;
                            }
                            else if (IsPureMethod(targetMethod, opContext.Compilation))
                            {
                                rule = PureMethodRule;
                            }

                            targetMethodName = targetMethod.Name;
                            break;
                        }

                        if (rule != null)
                        {
                            if (ShouldSkipAnalyzing(opContext, expectedExceptionType, xunitAssertType, nunitAssertType))
                            {
                                return;
                            }

                            Diagnostic diagnostic = Diagnostic.Create(rule, expression.Syntax.GetLocation(), method.Name, targetMethodName);
                            opContext.ReportDiagnostic(diagnostic);
                        }
                    }, OperationKind.ExpressionStatement);
                });
            });
        }
Ejemplo n.º 37
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterSymbolAction(symbolAnalysisContext =>
            {
                var symbol = symbolAnalysisContext.Symbol;

                // FxCop compat: only analyze externally visible symbols
                if (!symbol.IsExternallyVisible())
                {
                    return;
                }

                switch (symbol.Kind)
                {
                case SymbolKind.Namespace:
                    {
                        if (ContainsUnderScore(symbol.Name))
                        {
                            symbolAnalysisContext.ReportDiagnostic(symbol.CreateDiagnostic(NamespaceRule, symbol.ToDisplayString()));
                        }

                        return;
                    }

                case SymbolKind.NamedType:
                    {
                        var namedType = symbol as INamedTypeSymbol;
                        AnalyzeTypeParameters(symbolAnalysisContext, namedType.TypeParameters);

                        if (namedType.TypeKind == TypeKind.Delegate &&
                            namedType.DelegateInvokeMethod != null)
                        {
                            AnalyzeParameters(symbolAnalysisContext, namedType.DelegateInvokeMethod.Parameters);
                        }

                        if (!ContainsUnderScore(symbol.Name))
                        {
                            return;
                        }

                        symbolAnalysisContext.ReportDiagnostic(symbol.CreateDiagnostic(TypeRule, symbol.ToDisplayString()));
                        return;
                    }

                case SymbolKind.Field:
                    {
                        var fieldSymbol = symbol as IFieldSymbol;
                        if (ContainsUnderScore(symbol.Name) && (fieldSymbol.IsConst || (fieldSymbol.IsStatic && fieldSymbol.IsReadOnly)))
                        {
                            symbolAnalysisContext.ReportDiagnostic(symbol.CreateDiagnostic(MemberRule, symbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)));
                            return;
                        }

                        return;
                    }

                default:
                    {
                        if (symbol is IMethodSymbol methodSymbol)
                        {
                            if (methodSymbol.IsOperator())
                            {
                                // Do not flag for operators.
                                return;
                            }

                            if (methodSymbol.MethodKind == MethodKind.Conversion)
                            {
                                // Do not flag for conversion methods generated for operators.
                                return;
                            }

                            AnalyzeParameters(symbolAnalysisContext, methodSymbol.Parameters);
                            AnalyzeTypeParameters(symbolAnalysisContext, methodSymbol.TypeParameters);
                        }

                        if (symbol is IPropertySymbol propertySymbol)
                        {
                            AnalyzeParameters(symbolAnalysisContext, propertySymbol.Parameters);
                        }

                        if (!ContainsUnderScore(symbol.Name) || IsInvalidSymbol(symbol))
                        {
                            return;
                        }

                        symbolAnalysisContext.ReportDiagnostic(symbol.CreateDiagnostic(MemberRule, symbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)));
                        return;
                    }
                }
            },
                                                 SymbolKind.Namespace,                                                      // Namespace
                                                 SymbolKind.NamedType,                                                      //Type
                                                 SymbolKind.Method, SymbolKind.Property, SymbolKind.Field, SymbolKind.Event // Members
                                                 );

            analysisContext.RegisterCompilationAction(compilationAnalysisContext =>
            {
                var compilation = compilationAnalysisContext.Compilation;
                if (ContainsUnderScore(compilation.AssemblyName))
                {
                    compilationAnalysisContext.ReportDiagnostic(compilation.Assembly.CreateDiagnostic(AssemblyRule, compilation.AssemblyName));
                }
            });
        }
Ejemplo n.º 38
0
 /// <inheritdoc/>
 private protected override void Register(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.RegisterSyntaxTreeAction(AnalyzeSyntaxTree);
 }
Ejemplo n.º 39
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationContext.Compilation);
                INamedTypeSymbol cancellationTokenType = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingCancellationToken);
                INamedTypeSymbol iprogressType         = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIProgress1);
                if (cancellationTokenType == null)
                {
                    return;
                }

                compilationContext.RegisterSymbolAction(symbolContext =>
                {
                    var methodSymbol = (IMethodSymbol)symbolContext.Symbol;
                    if (methodSymbol.IsOverride ||
                        methodSymbol.IsImplementationOfAnyInterfaceMember())
                    {
                        return;
                    }

                    int last = methodSymbol.Parameters.Length - 1;
                    if (last >= 0 && methodSymbol.Parameters[last].IsParams)
                    {
                        last--;
                    }

                    // Skip optional parameters, UNLESS one of them is a CancellationToken
                    // AND it's not the last one.
                    if (last >= 0 && methodSymbol.Parameters[last].IsOptional &&
                        !methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;

                        while (last >= 0 && methodSymbol.Parameters[last].IsOptional)
                        {
                            if (methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                            {
                                symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                                   Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                            }

                            last--;
                        }
                    }

                    // Ignore multiple cancellation token parameters at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;
                    }

                    // Ignore parameters passed by reference when they appear at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].RefKind != RefKind.None)
                    {
                        last--;
                    }

                    // Ignore IProgress<T> when last
                    if (last >= 0 &&
                        iprogressType != null &&
                        methodSymbol.Parameters[last].Type.OriginalDefinition.Equals(iprogressType))
                    {
                        last--;
                    }

                    for (int i = last - 1; i >= 0; i--)
                    {
                        ITypeSymbol parameterType = methodSymbol.Parameters[i].Type;
                        if (!parameterType.Equals(cancellationTokenType))
                        {
                            continue;
                        }

                        // Bail if the CancellationToken is the first parameter of an extension method.
                        if (i == 0 && methodSymbol.IsExtensionMethod)
                        {
                            continue;
                        }

                        symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                           Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                        break;
                    }
                },
                                                        SymbolKind.Method);
            });
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
     context.RegisterCompilationStartAction(RegisterScopeBuilderAnalyzer);
 }
Ejemplo n.º 41
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
                compilationStartAnalysisContext =>
            {
                Compilation compilation = compilationStartAnalysisContext.Compilation;

                ImmutableHashSet <INamedTypeSymbol> nativeResourceTypes = ImmutableHashSet.Create(
                    compilation.GetSpecialType(SpecialType.System_IntPtr),
                    compilation.GetSpecialType(SpecialType.System_UIntPtr),
                    compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeInteropServicesHandleRef)
                    );
                var disposableType = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable);

                compilationStartAnalysisContext.RegisterOperationAction(
                    operationAnalysisContext =>
                {
                    var assignment = (IAssignmentOperation)operationAnalysisContext.Operation;

                    IOperation target = assignment.Target;
                    if (target == null)
                    {
                        // This can happen if the left-hand side is an undefined symbol.
                        return;
                    }

                    if (target.Kind != OperationKind.FieldReference)
                    {
                        return;
                    }

                    var fieldReference = (IFieldReferenceOperation)target;
                    if (!(fieldReference.Member is IFieldSymbol field) || field.Kind != SymbolKind.Field || field.IsStatic)
                    {
                        return;
                    }

                    if (!nativeResourceTypes.Contains(field.Type))
                    {
                        return;
                    }

                    INamedTypeSymbol containingType = field.ContainingType;
                    if (containingType == null || containingType.IsValueType)
                    {
                        return;
                    }

                    if (!containingType.AllInterfaces.Contains(disposableType))
                    {
                        return;
                    }

                    if (containingType.HasFinalizer())
                    {
                        return;
                    }

                    if (assignment.Value == null || assignment.Value.Kind != OperationKind.Invocation)
                    {
                        return;
                    }

                    var invocation = (IInvocationOperation)assignment.Value;
                    if (invocation == null)
                    {
                        return;
                    }

                    IMethodSymbol method = invocation.TargetMethod;

                    // TODO: What about COM?
                    if (method.GetDllImportData() == null)
                    {
                        return;
                    }

                    operationAnalysisContext.ReportDiagnostic(containingType.CreateDiagnostic(Rule));
                },
                    OperationKind.SimpleAssignment);
            });
        }
Ejemplo n.º 42
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            context.RegisterCompilationStartAction(context =>
            {
                if (!ComponentSymbols.TryCreate(context.Compilation, out var symbols))
                {
                    // Types we need are not defined.
                    return;
                }

                context.RegisterOperationBlockStartAction(startBlockContext =>
                {
                    startBlockContext.RegisterOperationAction(context =>
                    {
                        IOperation leftHandSide;

                        if (context.Operation is IAssignmentOperation assignmentOperation)
                        {
                            leftHandSide = assignmentOperation.Target;
                        }
                        else
                        {
                            var incrementOrDecrementOperation = (IIncrementOrDecrementOperation)context.Operation;
                            leftHandSide = incrementOrDecrementOperation.Target;
                        }

                        if (leftHandSide == null)
                        {
                            // Malformed assignment, no left hand side.
                            return;
                        }

                        if (leftHandSide.Kind != OperationKind.PropertyReference)
                        {
                            // We don't want to capture situations where a user does
                            // MyOtherProperty = aComponent.SomeParameter
                            return;
                        }

                        var propertyReference = (IPropertyReferenceOperation)leftHandSide;
                        var componentProperty = (IPropertySymbol)propertyReference.Member;

                        if (!ComponentFacts.IsParameter(symbols, componentProperty))
                        {
                            // This is not a property reference that we care about, it is not decorated with [Parameter].
                            return;
                        }

                        var propertyContainingType = componentProperty.ContainingType;
                        if (!ComponentFacts.IsComponent(symbols, context.Compilation, propertyContainingType))
                        {
                            // Someone referenced a property as [Parameter] inside something that is not a component.
                            return;
                        }

                        var assignmentContainingType = startBlockContext.OwningSymbol?.ContainingType;
                        if (assignmentContainingType == null)
                        {
                            // Assignment location has no containing type. Most likely we're operating on malformed code, don't try and validate.
                            return;
                        }

                        var conversion = context.Compilation.ClassifyConversion(propertyContainingType, assignmentContainingType);
                        if (conversion.Exists && conversion.IsIdentity)
                        {
                            // The assignment is taking place inside of the declaring component.
                            return;
                        }

                        if (conversion.Exists && conversion.IsExplicit)
                        {
                            // The assignment is taking place within the components type hierarchy. This means the user is setting this in a supported
                            // scenario.
                            return;
                        }

                        // At this point the user is referencing a component parameter outside of its declaring class.

                        context.ReportDiagnostic(Diagnostic.Create(
                                                     DiagnosticDescriptors.ComponentParametersShouldNotBeSetOutsideOfTheirDeclaredComponent,
                                                     propertyReference.Syntax.GetLocation(),
                                                     propertyReference.Member.Name));
                    }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment, OperationKind.CoalesceAssignment, OperationKind.Increment, OperationKind.Decrement);
                });
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                context.EnableConcurrentExecution();
            }
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics);
            context.RegisterCompilationStartAction(context => {
                if (!context.Options.IsMSBuildPropertyValueTrue(MSBuildPropertyOptionNames.EnableTrimAnalyzer, context.Compilation))
                {
                    return;
                }

                context.RegisterOperationBlockAction(context => {
                    if (context.OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope())
                    {
                        return;
                    }

                    // See https://github.com/dotnet/linker/issues/2587
                    // Need to punt on handling compiler generated methods until the linker is fixed
                    // async is handled here and the rest are handled just below
                    // iterators could be handled here once https://github.com/dotnet/roslyn/issues/20179 is fixed
                    if (context.OwningSymbol is IMethodSymbol methodSymbol && methodSymbol.IsAsync)
                    {
                        return;
                    }

                    // Sub optimal way to handle analyzer not to generate warnings until the linker is fixed
                    // Iterators, local functions and lambdas are handled
                    foreach (IOperation blockOperation in context.OperationBlocks)
                    {
                        if (blockOperation is IBlockOperation blocks)
                        {
                            foreach (IOperation operation in blocks.Operations)
                            {
                                if (operation.Kind == OperationKind.AnonymousFunction ||
                                    operation.Kind == OperationKind.LocalFunction ||
                                    operation.Kind == OperationKind.YieldBreak ||
                                    operation.Kind == OperationKind.YieldReturn)
                                {
                                    return;
                                }
                            }
                        }
                    }

                    foreach (var operationBlock in context.OperationBlocks)
                    {
                        ControlFlowGraph cfg = context.GetControlFlowGraph(operationBlock);
                        TrimDataFlowAnalysis trimDataFlowAnalysis = new (context, cfg);

                        foreach (var diagnostic in trimDataFlowAnalysis.ComputeTrimAnalysisPatterns().CollectDiagnostics())
                        {
                            context.ReportDiagnostic(diagnostic);
                        }
                    }
                });
                context.RegisterSyntaxNodeAction(context => {
                    ProcessGenericParameters(context);
                }, SyntaxKind.GenericName);
                context.RegisterSymbolAction(context => {
                    VerifyMemberOnlyApplyToTypesOrStrings(context, context.Symbol);
                    VerifyDamOnPropertyAndAccessorMatch(context, (IMethodSymbol)context.Symbol);
                    VerifyDamOnDerivedAndBaseMethodsMatch(context, (IMethodSymbol)context.Symbol);
                }, SymbolKind.Method);
                context.RegisterSymbolAction(context => {
                    VerifyDamOnInterfaceAndImplementationMethodsMatch(context, (INamedTypeSymbol)context.Symbol);
                }, SymbolKind.NamedType);
                context.RegisterSymbolAction(context => {
                    VerifyMemberOnlyApplyToTypesOrStrings(context, context.Symbol);
                }, SymbolKind.Property);
                context.RegisterSymbolAction(context => {
                    VerifyMemberOnlyApplyToTypesOrStrings(context, context.Symbol);
                }, SymbolKind.Field);
            });
        }
Ejemplo n.º 44
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(compilationStartContext =>
            {
                var objectType = compilationStartContext.Compilation.GetSpecialType(SpecialType.System_Object);

                if (objectType == null)
                {
                    return;
                }

                var objectObjectParameters = new[]
                {
                    ParameterInfo.GetParameterInfo(objectType),
                    ParameterInfo.GetParameterInfo(objectType)
                };

                var referenceEqualsMethodGroup = objectType.GetMembers("ReferenceEquals").OfType <IMethodSymbol>();
                var referenceEqualsMethod      = referenceEqualsMethodGroup.GetFirstOrDefaultMemberWithParameterInfos(
                    objectObjectParameters);

                if (referenceEqualsMethod == null)
                {
                    return;
                }

                var typeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartContext.Compilation);
                var referenceEqualityComparer =
                    typeProvider.GetOrCreateTypeByMetadataName("System.Collections.Generic.ReferenceEqualityComparer");

                IMethodSymbol?comparerEqualsMethod = null;

                if (referenceEqualityComparer != null)
                {
                    var equalsMethodGroup = referenceEqualityComparer.GetMembers("Equals").OfType <IMethodSymbol>();
                    comparerEqualsMethod  = equalsMethodGroup.GetFirstOrDefaultMemberWithParameterInfos(
                        objectObjectParameters);
                }

                compilationStartContext.RegisterOperationAction(operationContext =>
                {
                    var invocationExpression = (IInvocationOperation)operationContext.Operation;
                    var targetMethod         = invocationExpression.TargetMethod;
                    DiagnosticDescriptor rule;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    if (referenceEqualsMethod.Equals(targetMethod))
                    {
                        rule = MethodRule;
                    }
                    else if (comparerEqualsMethod != null && comparerEqualsMethod.Equals(targetMethod))
                    {
                        rule = ComparerRule;
                    }
                    else
                    {
                        return;
                    }

                    foreach (var argument in invocationExpression.Arguments)
                    {
                        var val = argument.Value;

                        // Only check through one level of conversion,
                        // which will be either the boxing conversion to object,
                        // or a reference type implicit conversion to object.
                        if (val is IConversionOperation conversion)
                        {
                            val = conversion.Operand;
                        }

                        if (val.Type?.IsValueType == true)
                        {
                            operationContext.ReportDiagnostic(
                                val.CreateDiagnostic(
                                    rule,
                                    val.Type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)));
                        }
                    }
                },
                                                                OperationKind.Invocation);
            });
        }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(csaContext =>
            {
                #region "Get All the WellKnown Types and Members"
                var iformatProviderType = csaContext.Compilation.GetTypeByMetadataName("System.IFormatProvider");
                var cultureInfoType     = csaContext.Compilation.GetTypeByMetadataName("System.Globalization.CultureInfo");
                if (iformatProviderType == null || cultureInfoType == null)
                {
                    return;
                }

                var objectType          = csaContext.Compilation.GetSpecialType(SpecialType.System_Object);
                var stringType          = csaContext.Compilation.GetSpecialType(SpecialType.System_String);
                var stringFormatMembers = stringType?.GetMembers("Format").OfType <IMethodSymbol>();

                var stringFormatMemberWithStringAndObjectParameter = stringFormatMembers.GetSingleOrDefaultMemberWithParameterInfos(
                    GetParameterInfo(stringType),
                    GetParameterInfo(objectType));
                var stringFormatMemberWithStringObjectAndObjectParameter = stringFormatMembers.GetSingleOrDefaultMemberWithParameterInfos(
                    GetParameterInfo(stringType),
                    GetParameterInfo(objectType),
                    GetParameterInfo(objectType));
                var stringFormatMemberWithStringObjectObjectAndObjectParameter = stringFormatMembers.GetSingleOrDefaultMemberWithParameterInfos(
                    GetParameterInfo(stringType),
                    GetParameterInfo(objectType),
                    GetParameterInfo(objectType),
                    GetParameterInfo(objectType));
                var stringFormatMemberWithStringAndParamsObjectParameter = stringFormatMembers.GetSingleOrDefaultMemberWithParameterInfos(
                    GetParameterInfo(stringType),
                    GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true));
                var stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter = stringFormatMembers.GetSingleOrDefaultMemberWithParameterInfos(
                    GetParameterInfo(iformatProviderType),
                    GetParameterInfo(stringType),
                    GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true));

                var currentCultureProperty     = cultureInfoType?.GetMembers("CurrentCulture").OfType <IPropertySymbol>().SingleOrDefault();
                var invariantCultureProperty   = cultureInfoType?.GetMembers("InvariantCulture").OfType <IPropertySymbol>().SingleOrDefault();
                var currentUICultureProperty   = cultureInfoType?.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().SingleOrDefault();
                var installedUICultureProperty = cultureInfoType?.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().SingleOrDefault();

                var threadType = csaContext.Compilation.GetTypeByMetadataName("System.Threading.Thread");
                var currentThreadCurrentUICultureProperty = threadType?.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().SingleOrDefault();

                var activatorType       = csaContext.Compilation.GetTypeByMetadataName("System.Activator");
                var resourceManagerType = csaContext.Compilation.GetTypeByMetadataName("System.Resources.ResourceManager");

                var computerInfoType = csaContext.Compilation.GetTypeByMetadataName("Microsoft.VisualBasic.Devices.ComputerInfo");
                var installedUICulturePropertyOfComputerInfoType = computerInfoType?.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().SingleOrDefault();

                var obsoleteAttributeType = WellKnownTypes.ObsoleteAttribute(csaContext.Compilation);
                #endregion

                csaContext.RegisterOperationAction(oaContext =>
                {
                    var invocationExpression = (IInvocationOperation)oaContext.Operation;
                    var targetMethod         = invocationExpression.TargetMethod;

                    #region "Exceptions"
                    if (targetMethod.IsGenericMethod || targetMethod.ContainingType == null || targetMethod.ContainingType.IsErrorType() ||
                        (targetMethod.ContainingType != null &&
                         (activatorType != null && activatorType.Equals(targetMethod.ContainingType)) ||
                         (resourceManagerType != null && resourceManagerType.Equals(targetMethod.ContainingType))))
                    {
                        return;
                    }
                    #endregion

                    #region "IFormatProviderAlternateStringRule Only"
                    if (stringType != null && cultureInfoType != null &&
                        (targetMethod.Equals(stringFormatMemberWithStringAndObjectParameter) ||
                         targetMethod.Equals(stringFormatMemberWithStringObjectAndObjectParameter) ||
                         targetMethod.Equals(stringFormatMemberWithStringObjectObjectAndObjectParameter) ||
                         targetMethod.Equals(stringFormatMemberWithStringAndParamsObjectParameter)))
                    {
                        // Sample message for IFormatProviderAlternateStringRule: Because the behavior of string.Format(string, object) could vary based on the current user's locale settings,
                        // replace this call in IFormatProviderStringTest.M() with a call to string.Format(IFormatProvider, string, params object[]).
                        oaContext.ReportDiagnostic(
                            invocationExpression.Syntax.CreateDiagnostic(
                                IFormatProviderAlternateStringRule,
                                targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));

                        return;
                    }
                    #endregion

                    #region "IFormatProviderAlternateStringRule & IFormatProviderAlternateRule"

                    IEnumerable <IMethodSymbol> methodsWithSameNameAsTargetMethod = targetMethod.ContainingType.GetMembers(targetMethod.Name).OfType <IMethodSymbol>().WhereMethodDoesNotContainAttribute(obsoleteAttributeType).ToList();
                    if (methodsWithSameNameAsTargetMethod.Count() > 1)
                    {
                        var correctOverloads = methodsWithSameNameAsTargetMethod.GetMethodOverloadsWithDesiredParameterAtLeadingOrTrailing(targetMethod, iformatProviderType).ToList();

                        // If there are two matching overloads, one with CultureInfo as the first parameter and one with CultureInfo as the last parameter,
                        // report the diagnostic on the overload with CultureInfo as the last parameter, to match the behavior of FxCop.
                        var correctOverload = correctOverloads.FirstOrDefault(overload => overload.Parameters.Last().Type.Equals(iformatProviderType)) ?? correctOverloads.FirstOrDefault();

                        // Sample message for IFormatProviderAlternateRule: Because the behavior of Convert.ToInt64(string) could vary based on the current user's locale settings,
                        // replace this call in IFormatProviderStringTest.TestMethod() with a call to Convert.ToInt64(string, IFormatProvider).
                        if (correctOverload != null)
                        {
                            oaContext.ReportDiagnostic(
                                invocationExpression.Syntax.CreateDiagnostic(
                                    targetMethod.ReturnType.Equals(stringType) ?
                                    IFormatProviderAlternateStringRule :
                                    IFormatProviderAlternateRule,
                                    targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                    oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                    correctOverload.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));
                        }
                    }
                    #endregion

                    #region "UICultureStringRule & UICultureRule"
                    IEnumerable <int> IformatProviderParameterIndices = GetIndexesOfParameterType(targetMethod, iformatProviderType);
                    foreach (var index in IformatProviderParameterIndices)
                    {
                        var argument = invocationExpression.Arguments[index];

                        if (argument != null && currentUICultureProperty != null &&
                            installedUICultureProperty != null && currentThreadCurrentUICultureProperty != null)
                        {
                            var semanticModel = oaContext.Compilation.GetSemanticModel(argument.Syntax.SyntaxTree);

                            var symbol = semanticModel.GetSymbolInfo(argument.Value.Syntax).Symbol;

                            if (symbol != null &&
                                (symbol.Equals(currentUICultureProperty) ||
                                 symbol.Equals(installedUICultureProperty) ||
                                 symbol.Equals(currentThreadCurrentUICultureProperty) ||
                                 (installedUICulturePropertyOfComputerInfoType != null && symbol.Equals(installedUICulturePropertyOfComputerInfoType))))
                            {
                                // Sample message
                                // 1. UICultureStringRule - 'TestClass.TestMethod()' passes 'Thread.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.CalleeMethod(string, IFormatProvider)'.
                                // This property returns a culture that is inappropriate for formatting methods.
                                // 2. UICultureRule -'TestClass.TestMethod()' passes 'CultureInfo.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.Callee(IFormatProvider, string)'.
                                // This property returns a culture that is inappropriate for formatting methods.

                                oaContext.ReportDiagnostic(
                                    invocationExpression.Syntax.CreateDiagnostic(
                                        targetMethod.ReturnType.Equals(stringType) ?
                                        UICultureStringRule :
                                        UICultureRule,
                                        oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                        symbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                        targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));
                            }
                        }
                    }
                    #endregion
                }, OperationKind.Invocation);
            });
        }
Ejemplo n.º 46
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterCompilationStartAction(compilationContext =>
            {
                if (!DisposeAnalysisHelper.TryGetOrCreate(compilationContext.Compilation, out var disposeAnalysisHelper))
                {
                    return;
                }

                var reportedLocations = new ConcurrentDictionary <Location, bool>();
                compilationContext.RegisterOperationBlockAction(operationBlockContext =>
                {
                    if (operationBlockContext.OwningSymbol is not IMethodSymbol containingMethod ||
                        !disposeAnalysisHelper.HasAnyDisposableCreationDescendant(operationBlockContext.OperationBlocks, containingMethod) ||
                        operationBlockContext.Options.IsConfiguredToSkipAnalysis(NotDisposedRule, containingMethod, operationBlockContext.Compilation))
                    {
                        return;
                    }

                    var disposeAnalysisKind = operationBlockContext.Options.GetDisposeAnalysisKindOption(NotDisposedOnExceptionPathsRule, containingMethod,
                                                                                                         operationBlockContext.Compilation, DisposeAnalysisKind.NonExceptionPaths);
                    var trackExceptionPaths = disposeAnalysisKind.AreExceptionPathsEnabled();

                    // For non-exception paths analysis, we can skip interprocedural analysis for certain invocations.
                    var interproceduralAnalysisPredicate = !trackExceptionPaths ?
                                                           new InterproceduralAnalysisPredicate(
                        skipAnalysisForInvokedMethodPredicate: SkipInterproceduralAnalysis,
                        skipAnalysisForInvokedLambdaOrLocalFunctionPredicate: null,
                        skipAnalysisForInvokedContextPredicate: null) :
                                                           null;

                    if (disposeAnalysisHelper.TryGetOrComputeResult(operationBlockContext.OperationBlocks, containingMethod,
                                                                    operationBlockContext.Options, NotDisposedRule, PointsToAnalysisKind.PartialWithoutTrackingFieldsAndProperties, trackInstanceFields: false, trackExceptionPaths: trackExceptionPaths,
                                                                    disposeAnalysisResult: out var disposeAnalysisResult, pointsToAnalysisResult: out var pointsToAnalysisResult, interproceduralAnalysisPredicate: interproceduralAnalysisPredicate))
                    {
                        using var notDisposedDiagnostics      = ArrayBuilder <Diagnostic> .GetInstance();
                        using var mayBeNotDisposedDiagnostics = ArrayBuilder <Diagnostic> .GetInstance();

                        // Compute diagnostics for undisposed objects at exit block for non-exceptional exit paths.
                        var exitBlock         = disposeAnalysisResult.ControlFlowGraph.GetExit();
                        var disposeDataAtExit = disposeAnalysisResult.ExitBlockOutput.Data;
                        ComputeDiagnostics(disposeDataAtExit,
                                           notDisposedDiagnostics, mayBeNotDisposedDiagnostics, disposeAnalysisResult, pointsToAnalysisResult,
                                           disposeAnalysisKind, isDisposeDataForExceptionPaths: false);

                        if (trackExceptionPaths)
                        {
                            // Compute diagnostics for undisposed objects at handled exception exit paths.
                            var disposeDataAtHandledExceptionPaths = disposeAnalysisResult.ExceptionPathsExitBlockOutput !.Data;
                            ComputeDiagnostics(disposeDataAtHandledExceptionPaths,
                                               notDisposedDiagnostics, mayBeNotDisposedDiagnostics, disposeAnalysisResult, pointsToAnalysisResult,
                                               disposeAnalysisKind, isDisposeDataForExceptionPaths: true);

                            // Compute diagnostics for undisposed objects at unhandled exception exit paths, if any.
                            var disposeDataAtUnhandledExceptionPaths = disposeAnalysisResult.MergedStateForUnhandledThrowOperations?.Data;
                            if (disposeDataAtUnhandledExceptionPaths != null)
                            {
                                ComputeDiagnostics(disposeDataAtUnhandledExceptionPaths,
                                                   notDisposedDiagnostics, mayBeNotDisposedDiagnostics, disposeAnalysisResult, pointsToAnalysisResult,
                                                   disposeAnalysisKind, isDisposeDataForExceptionPaths: true);
                            }
                        }

                        if (!notDisposedDiagnostics.Any() && !mayBeNotDisposedDiagnostics.Any())
                        {
                            return;
                        }

                        // Report diagnostics preferring *not* disposed diagnostics over may be not disposed diagnostics
                        // and avoiding duplicates.
                        foreach (var diagnostic in notDisposedDiagnostics.Concat(mayBeNotDisposedDiagnostics))
                        {
                            if (reportedLocations.TryAdd(diagnostic.Location, true))
                            {
                                operationBlockContext.ReportDiagnostic(diagnostic);
                            }
                        }
                    }
                });

                return;

                // Local functions.

                bool SkipInterproceduralAnalysis(IMethodSymbol invokedMethod)
                {
                    // Skip interprocedural analysis if we are invoking a method and not passing any disposable object as an argument
                    // and not receiving a disposable object as a return value.
                    // We also check that we are not passing any object type argument which might hold disposable object
                    // and also check that we are not passing delegate type argument which can
                    // be a lambda or local function that has access to disposable object in current method's scope.

                    if (CanBeDisposable(invokedMethod.ReturnType))
                    {
                        return(false);
                    }

                    foreach (var p in invokedMethod.Parameters)
                    {
                        if (CanBeDisposable(p.Type))
                        {
                            return(false);
                        }
                    }

                    return(true);

                    bool CanBeDisposable(ITypeSymbol type)
                    => type.SpecialType == SpecialType.System_Object ||
                    type.DerivesFrom(disposeAnalysisHelper !.IDisposable) ||
                    type.TypeKind == TypeKind.Delegate;
                }
            });
        }
Ejemplo n.º 47
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterOperationBlockStartActionInternal(osContext =>
            {
                var method = osContext.OwningSymbol as IMethodSymbol;
                if (method == null)
                {
                    return;
                }

                osContext.RegisterOperationActionInternal(opContext =>
                {
                    IOperation expression     = ((IExpressionStatement)opContext.Operation).Expression;
                    DiagnosticDescriptor rule = null;
                    string targetMethodName   = null;
                    switch (expression.Kind)
                    {
                    case OperationKind.ObjectCreationExpression:
                        IMethodSymbol ctor = ((IObjectCreationExpression)expression).Constructor;
                        if (ctor != null)
                        {
                            rule             = ObjectCreationRule;
                            targetMethodName = ctor.ContainingType.Name;
                        }
                        break;

                    case OperationKind.InvocationExpression:
                        IInvocationExpression invocationExpression = ((IInvocationExpression)expression);
                        IMethodSymbol targetMethod = invocationExpression.TargetMethod;
                        if (targetMethod == null)
                        {
                            break;
                        }

                        if (IsStringCreatingMethod(targetMethod))
                        {
                            rule = StringCreationRule;
                        }
                        else if (IsTryParseMethod(targetMethod))
                        {
                            rule = TryParseRule;
                        }
                        else if (IsHResultOrErrorCodeReturningMethod(targetMethod))
                        {
                            rule = HResultOrErrorCodeRule;
                        }
                        else if (IsPureMethod(targetMethod, opContext.Compilation))
                        {
                            rule = PureMethodRule;
                        }

                        targetMethodName = targetMethod.Name;
                        break;
                    }

                    if (rule != null)
                    {
                        Diagnostic diagnostic = Diagnostic.Create(rule, expression.Syntax.GetLocation(), method.Name, targetMethodName);
                        opContext.ReportDiagnostic(diagnostic);
                    }
                }, OperationKind.ExpressionStatement);
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var attributeTokenType = compilationContext.Compilation.GetTypeByMetadataName("SkipNamedAttribute");

                var objectType                = compilationContext.Compilation.GetSpecialType(SpecialType.System_Object);
                var taskTokenType             = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
                var taskGenericTokenType      = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
                var valueTaskTokenType        = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.Tasks.ValueTask");
                var valueTaskGenericTokenType = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.Tasks.ValueTask`1");
                var taskCompletionSourceType  = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.Tasks.TaskCompletionSource`1");
                var methodBaseTokenType       = compilationContext.Compilation.GetTypeByMetadataName("System.Reflection.MethodBase");
                var fieldInfoTokenType        = compilationContext.Compilation.GetTypeByMetadataName("System.Reflection.FieldInfo");
                var propertyInfoTokenType     = compilationContext.Compilation.GetTypeByMetadataName("System.Reflection.PropertyInfo");
                var msTestAssertTokenType     = compilationContext.Compilation.GetTypeByMetadataName("Microsoft.VisualStudio.TestTools.UnitTesting.Assert");
                var nunitAssertTokenType      = compilationContext.Compilation.GetTypeByMetadataName("NUnit.Framework.Assert");
                var xunitAssertTokenType      = compilationContext.Compilation.GetTypeByMetadataName("Xunit.Assert");
                var keyValuePairTokenType     = compilationContext.Compilation.GetTypeByMetadataName("System.Collection.Generic.KeyValuePair`2");
                var propertyBuilderType       = compilationContext.Compilation.GetTypeByMetadataName("Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder`1");
                var syntaxNodeType            = compilationContext.Compilation.GetTypeByMetadataName("Microsoft.CodeAnalysis.SyntaxNode");

                compilationContext.RegisterSyntaxNodeAction(syntaxContext =>
                {
                    var argument = (ArgumentSyntax)syntaxContext.Node;
                    if (argument.NameColon != null)
                    {
                        return;
                    }

                    if (argument.Expression == null)
                    {
                        return;
                    }

                    var kind = argument.Expression.Kind();
                    if (kind == SyntaxKind.TrueLiteralExpression ||
                        kind == SyntaxKind.FalseLiteralExpression ||
                        kind == SyntaxKind.NullLiteralExpression)
                    {
                        // Exclude in some methods such as ConfigureAwait(false)
                        var invocationExpression = argument.FirstAncestorOrSelf <InvocationExpressionSyntax>();
                        if (invocationExpression != null)
                        {
                            var methodSymbol = (IMethodSymbol?)syntaxContext.SemanticModel.GetSymbolInfo(invocationExpression).Symbol;
                            if (methodSymbol != null)
                            {
                                var argumentIndex = ArgumentIndex(argument);

                                if (methodSymbol.Parameters.Length == 1 && methodSymbol.Name.StartsWith("Is", StringComparison.Ordinal))
                                {
                                    return;
                                }

                                if (methodSymbol.Parameters.Length == 1 && methodSymbol.Name == nameof(Task.ConfigureAwait))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, objectType, nameof(object.Equals)))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, objectType, nameof(object.ReferenceEquals)))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, taskTokenType, nameof(Task.FromResult)))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, taskCompletionSourceType, nameof(TaskCompletionSource <object> .SetResult)))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, taskCompletionSourceType, nameof(TaskCompletionSource <object> .TrySetResult)))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, methodBaseTokenType, nameof(MethodBase.Invoke)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, fieldInfoTokenType, nameof(FieldInfo.SetValue)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, fieldInfoTokenType, nameof(FieldInfo.GetValue)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, propertyInfoTokenType, nameof(PropertyInfo.SetValue)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, propertyInfoTokenType, nameof(PropertyInfo.GetValue)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, msTestAssertTokenType, "*"))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, nunitAssertTokenType, "*"))
                                {
                                    return;
                                }

                                if (IsMethod(methodSymbol, xunitAssertTokenType, "*"))
                                {
                                    return;
                                }

                                if ((string.Equals(methodSymbol.Name, "Parse", StringComparison.Ordinal) || string.Equals(methodSymbol.Name, "TryParse", StringComparison.Ordinal)) && argumentIndex == 0)
                                {
                                    return;
                                }

                                // e.g. SyntaxNode.WithElse
                                if (methodSymbol.Name.StartsWith("With", StringComparison.Ordinal) && methodSymbol.ContainingType.IsOrInheritFrom(syntaxNodeType))
                                {
                                    return;
                                }

                                var operation = syntaxContext.SemanticModel.GetOperation(argument, syntaxContext.CancellationToken);
                                if (operation != null && operation.IsInExpressionArgument())
                                {
                                    return;
                                }
                            }
                        }

                        syntaxContext.ReportDiagnostic(s_rule, syntaxContext.Node);
                    }
                }, SyntaxKind.Argument);
            });
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.RegisterSyntaxNodeAction(AnalyzeNode, ImmutableArray.Create(SyntaxKind.LocalDeclarationStatement));
 }
 public override void Initialize(AnalysisContext context)
 {
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
     context.EnableConcurrentExecution();
     context.RegisterSyntaxNodeAction(AnalyzeIdentifierGuid, SyntaxKind.IdentifierName);
 }
Ejemplo n.º 51
0
 public override void Initialize(AnalysisContext analysisContext)
 {
     analysisContext.EnableConcurrentExecution();
     analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     analysisContext.RegisterSymbolAction(AnalyzeNamedType, SymbolKind.NamedType);
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var formatInfo = new StringFormatInfo(compilationContext.Compilation);

                compilationContext.RegisterOperationAction(operationContext =>
                {
                    var invocation = (IInvocationOperation)operationContext.Operation;

                    StringFormatInfo.Info?info = formatInfo.TryGet(invocation.TargetMethod, operationContext);
                    if (info == null || invocation.Arguments.Length <= info.FormatStringIndex)
                    {
                        // not a target method
                        return;
                    }

                    IArgumentOperation formatStringArgument = invocation.Arguments[info.FormatStringIndex];
                    if (!object.Equals(formatStringArgument?.Value?.Type, formatInfo.String) ||
                        !(formatStringArgument?.Value?.ConstantValue.Value is string))
                    {
                        // wrong argument
                        return;
                    }

                    var stringFormat = (string)formatStringArgument.Value.ConstantValue.Value;
                    int expectedStringFormatArgumentCount = GetFormattingArguments(stringFormat);

                    // explicit parameter case
                    if (info.ExpectedStringFormatArgumentCount >= 0)
                    {
                        // __arglist is not supported here
                        if (invocation.TargetMethod.IsVararg)
                        {
                            // can't deal with this for now.
                            return;
                        }

                        if (info.ExpectedStringFormatArgumentCount != expectedStringFormatArgumentCount)
                        {
                            operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(Rule));
                        }

                        return;
                    }

                    // ensure argument is an array
                    IArgumentOperation paramsArgument = invocation.Arguments[info.FormatStringIndex + 1];
                    if (paramsArgument.ArgumentKind is not ArgumentKind.ParamArray and not ArgumentKind.Explicit)
                    {
                        // wrong format
                        return;
                    }

                    if (paramsArgument.Value is not IArrayCreationOperation arrayCreation ||
                        arrayCreation.GetElementType() is not ITypeSymbol elementType ||
                        !object.Equals(elementType, formatInfo.Object) ||
                        arrayCreation.DimensionSizes.Length != 1)
                    {
                        // wrong format
                        return;
                    }

                    // compiler generating object array for params case
                    IArrayInitializerOperation intializer = arrayCreation.Initializer;
                    if (intializer == null)
                    {
                        // unsupported format
                        return;
                    }

                    // REVIEW: "ElementValues" is a bit confusing where I need to double dot those to get number of elements
                    int actualArgumentCount = intializer.ElementValues.Length;
                    if (actualArgumentCount != expectedStringFormatArgumentCount)
                    {
                        operationContext.ReportDiagnostic(operationContext.Operation.Syntax.CreateDiagnostic(Rule));
                    }
                }, OperationKind.Invocation);
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            Debug.Assert(TypeMetadataName != null);
            Debug.Assert(MethodMetadataName != null);
            Debug.Assert(Rule != null);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(compilationStartAnalysisContext =>
            {
                var compilation           = compilationStartAnalysisContext.Compilation;
                var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation);

                if (!wellKnownTypeProvider.TryGetTypeByMetadataName(
                        TypeMetadataName,
                        out INamedTypeSymbol xmlSchemaTypeSymbol))
                {
                    return;
                }

                wellKnownTypeProvider.TryGetTypeByMetadataName(
                    WellKnownTypeNames.SystemXmlXmlReader,
                    out INamedTypeSymbol xmlReaderTypeSymbol);

                compilationStartAnalysisContext.RegisterOperationAction(operationAnalysisContext =>
                {
                    var operation = operationAnalysisContext.Operation;
                    IMethodSymbol methodSymbol = null;
                    string methodName          = null;

                    switch (operation.Kind)
                    {
                    case OperationKind.Invocation:
                        methodSymbol = (operation as IInvocationOperation).TargetMethod;
                        methodName   = methodSymbol.Name;
                        break;

                    case OperationKind.ObjectCreation:
                        methodSymbol = (operation as IObjectCreationOperation).Constructor;
                        methodName   = methodSymbol.ContainingType.Name;
                        break;

                    default:
                        return;
                    }

                    if (methodName.StartsWith(MethodMetadataName, StringComparison.Ordinal) &&
                        methodSymbol.IsOverrideOrVirtualMethodOf(xmlSchemaTypeSymbol))
                    {
                        if (xmlReaderTypeSymbol != null &&
                            methodSymbol.Parameters.Length > 0 &&
                            methodSymbol.Parameters[0].Type.Equals(xmlReaderTypeSymbol))
                        {
                            return;
                        }

                        operationAnalysisContext.ReportDiagnostic(
                            operation.CreateDiagnostic(
                                Rule,
                                methodSymbol.ContainingType.Name,
                                methodName));
                    }
                }, OperationKind.Invocation, OperationKind.ObjectCreation);
            });
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.RegisterCompilationStartAction(AnalyzeCompilationStart);
 }
 /// <inheritdoc/>
 public override void Initialize(AnalysisContext context)
 {
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.EnableConcurrentExecution();
     context.RegisterSyntaxNodeAction(x => Handle(x), SyntaxKind.Argument);
 }
Ejemplo n.º 56
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            // Analyze type names.
            analysisContext.RegisterCompilationStartAction(
                compilationStartAnalysisContext =>
            {
                var suffixToBaseTypeDictionaryBuilder = ImmutableDictionary.CreateBuilder <string, ImmutableArray <INamedTypeSymbol> >();

                foreach (string suffix in s_suffixToBaseTypeNamesDictionary.Keys)
                {
                    ImmutableArray <string> typeNames = s_suffixToBaseTypeNamesDictionary[suffix];

                    ImmutableArray <INamedTypeSymbol> namedTypeSymbolArray = ImmutableArray.CreateRange(
                        typeNames.Select(typeName => compilationStartAnalysisContext.Compilation.GetOrCreateTypeByMetadataName(typeName)?.OriginalDefinition).WhereNotNull());

                    suffixToBaseTypeDictionaryBuilder.Add(suffix, namedTypeSymbolArray);
                }

                var suffixToBaseTypeDictionary = suffixToBaseTypeDictionaryBuilder.ToImmutableDictionary();

                compilationStartAnalysisContext.RegisterSymbolAction(
                    (SymbolAnalysisContext symbolAnalysisContext) =>
                {
                    var namedTypeSymbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol;

                    // Note all the descriptors/rules for this analyzer have the same ID and category and hence
                    // will always have identical configured visibility.
                    if (!symbolAnalysisContext.Options.MatchesConfiguredVisibility(TypeNoAlternateRule, namedTypeSymbol, symbolAnalysisContext.Compilation, symbolAnalysisContext.CancellationToken))
                    {
                        return;
                    }

                    var allowedSuffixes = symbolAnalysisContext.Options.GetStringOptionValue(EditorConfigOptionNames.AllowedSuffixes, TypeNoAlternateRule,
                                                                                             namedTypeSymbol.Locations[0].SourceTree, symbolAnalysisContext.Compilation, symbolAnalysisContext.CancellationToken)
                                          .Split('|')
                                          .ToImmutableHashSet();

                    string name             = namedTypeSymbol.Name;
                    Compilation compilation = symbolAnalysisContext.Compilation;

                    foreach (string suffix in s_suffixToBaseTypeNamesDictionary.Keys)
                    {
                        if (IsNotChildOfAnyButHasSuffix(namedTypeSymbol, suffixToBaseTypeDictionary[suffix], suffix, allowedSuffixes))
                        {
                            symbolAnalysisContext.ReportDiagnostic(
                                namedTypeSymbol.CreateDiagnostic(TypeNoAlternateRule, name, suffix));
                            return;
                        }
                    }

                    foreach (string suffix in s_suffixToAllowedTypesDictionary.Keys)
                    {
                        if (IsInvalidSuffix(name, suffix, allowedSuffixes) &&
                            !s_suffixToAllowedTypesDictionary[suffix].Contains(name))
                        {
                            symbolAnalysisContext.ReportDiagnostic(
                                namedTypeSymbol.CreateDiagnostic(TypeNoAlternateRule, name, suffix));
                            return;
                        }
                    }

                    if (IsInvalidSuffix(name, ImplSuffix, allowedSuffixes))
                    {
                        symbolAnalysisContext.ReportDiagnostic(
                            namedTypeSymbol.CreateDiagnostic(MemberWithAlternateRule, ImplSuffix, name, CoreSuffix));
                        return;
                    }

                    // FxCop performed the length check for "Ex", but not for any of the other
                    // suffixes, because alone among the suffixes, "Ex" is the only one that
                    // isn't itself a known type or a language keyword.
                    if (IsInvalidSuffix(name, ExSuffix, allowedSuffixes) && name.Length > ExSuffix.Length)
                    {
                        symbolAnalysisContext.ReportDiagnostic(
                            namedTypeSymbol.CreateDiagnostic(TypeNewerVersionRule, ExSuffix, name));
                        return;
                    }

                    if (IsInvalidSuffix(name, NewSuffix, allowedSuffixes))
                    {
                        symbolAnalysisContext.ReportDiagnostic(
                            namedTypeSymbol.CreateDiagnostic(TypeNewerVersionRule, NewSuffix, name));
                        return;
                    }

                    if (namedTypeSymbol.TypeKind == TypeKind.Enum)
                    {
                        if (IsInvalidSuffix(name, FlagSuffix, allowedSuffixes))
                        {
                            symbolAnalysisContext.ReportDiagnostic(
                                namedTypeSymbol.CreateDiagnostic(TypeNoAlternateRule, name, FlagSuffix));
                            return;
                        }

                        if (IsInvalidSuffix(name, FlagsSuffix, allowedSuffixes))
                        {
                            symbolAnalysisContext.ReportDiagnostic(
                                namedTypeSymbol.CreateDiagnostic(TypeNoAlternateRule, name, FlagsSuffix));
                            return;
                        }
                    }
                }, SymbolKind.NamedType);
            });

            // Analyze method names.
            analysisContext.RegisterSymbolAction(
                (SymbolAnalysisContext context) =>
            {
                var memberSymbol = context.Symbol;

                // Note all the descriptors/rules for this analyzer have the same ID and category and hence
                // will always have identical configured visibility.
                if (!context.Options.MatchesConfiguredVisibility(TypeNoAlternateRule, memberSymbol, context.Compilation, context.CancellationToken))
                {
                    return;
                }

                if (memberSymbol.IsOverride || memberSymbol.IsImplementationOfAnyInterfaceMember())
                {
                    return;
                }

                // If this is a method, and it's actually the getter or setter of a property,
                // then don't complain. We'll complain about the property itself.
                if (memberSymbol is IMethodSymbol methodSymbol && methodSymbol.IsPropertyAccessor())
                {
                    return;
                }

                string name = memberSymbol.Name;

                var allowedSuffixes = context.Options.GetStringOptionValue(EditorConfigOptionNames.AllowedSuffixes, TypeNoAlternateRule,
                                                                           memberSymbol.Locations[0].SourceTree, context.Compilation, context.CancellationToken)
                                      .Split('|')
                                      .ToImmutableHashSet();

                if (IsInvalidSuffix(name, ExSuffix, allowedSuffixes))
                {
                    context.ReportDiagnostic(
                        memberSymbol.CreateDiagnostic(MemberNewerVersionRule, ExSuffix, name));
                    return;
                }

                // We only fire on member suffix "New" if the type already defines
                // another member minus the suffix, e.g., we only fire on "MemberNew" if
                // "Member" already exists. For some reason FxCop did not apply the
                // same logic to the "Ex" suffix, and we follow FxCop's implementation.
                if (IsInvalidSuffix(name, NewSuffix, allowedSuffixes))
                {
                    string nameWithoutSuffix        = name.WithoutSuffix(NewSuffix);
                    INamedTypeSymbol containingType = memberSymbol.ContainingType;

                    if (MemberNameExistsInHierarchy(nameWithoutSuffix, containingType, memberSymbol.Kind))
                    {
                        context.ReportDiagnostic(
                            memberSymbol.CreateDiagnostic(MemberNewerVersionRule, NewSuffix, name));
                        return;
                    }
                }

                if (IsInvalidSuffix(name, ImplSuffix, allowedSuffixes))
                {
                    context.ReportDiagnostic(
                        memberSymbol.CreateDiagnostic(MemberWithAlternateRule, ImplSuffix, name, CoreSuffix));
                }
            }, SymbolKind.Event, SymbolKind.Field, SymbolKind.Method, SymbolKind.Property);
        }
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
     context.RegisterSyntaxNodeAction(AnalyzeMethodDeclaration, SyntaxKind.MethodDeclaration);
 }
Ejemplo n.º 58
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol?iDbCommandType     = compilationContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDataIDbCommand);
                INamedTypeSymbol?iDataAdapterType   = compilationContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDataIDataAdapter);
                IPropertySymbol?commandTextProperty = iDbCommandType?.GetMembers("CommandText").OfType <IPropertySymbol>().FirstOrDefault();

                if (iDbCommandType == null ||
                    iDataAdapterType == null ||
                    commandTextProperty == null)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    ISymbol symbol = operationBlockStartContext.OwningSymbol;
                    var isInDbCommandConstructor   = false;
                    var isInDataAdapterConstructor = false;

                    if (symbol.Kind != SymbolKind.Method)
                    {
                        return;
                    }

                    var methodSymbol = (IMethodSymbol)symbol;

                    if (methodSymbol.MethodKind == MethodKind.Constructor)
                    {
                        CheckForDbCommandAndDataAdapterImplementation(symbol.ContainingType, iDbCommandType, iDataAdapterType, out isInDbCommandConstructor, out isInDataAdapterConstructor);
                    }

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var creation = (IObjectCreationOperation)operationContext.Operation;
                        AnalyzeMethodCall(operationContext, creation.Constructor, symbol, creation.Arguments, creation.Syntax, isInDbCommandConstructor, isInDataAdapterConstructor, iDbCommandType, iDataAdapterType);
                    }, OperationKind.ObjectCreation);

                    // If an object calls a constructor in a base class or the same class, this will get called.
                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var invocation = (IInvocationOperation)operationContext.Operation;

                        // We only analyze constructor invocations
                        if (invocation.TargetMethod.MethodKind != MethodKind.Constructor)
                        {
                            return;
                        }

                        // If we're calling another constructor in the same class from this constructor, assume that all parameters are safe and skip analysis. Parameter usage
                        // will be analyzed there
                        if (Equals(invocation.TargetMethod.ContainingType, symbol.ContainingType))
                        {
                            return;
                        }

                        AnalyzeMethodCall(operationContext, invocation.TargetMethod, symbol, invocation.Arguments, invocation.Syntax, isInDbCommandConstructor, isInDataAdapterConstructor, iDbCommandType, iDataAdapterType);
                    }, OperationKind.Invocation);

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var propertyReference = (IPropertyReferenceOperation)operationContext.Operation;

                        // We're only interested in implementations of IDbCommand.CommandText
                        if (!propertyReference.Property.IsOverrideOrImplementationOfInterfaceMember(commandTextProperty))
                        {
                            return;
                        }

                        // Make sure we're in assignment statement
                        if (!(propertyReference.Parent is IAssignmentOperation assignment))
                        {
                            return;
                        }

                        // Only if the property reference is actually the target of the assignment
                        if (assignment.Target != propertyReference)
                        {
                            return;
                        }

                        ReportDiagnosticIfNecessary(operationContext, assignment.Value, assignment.Syntax, propertyReference.Property, symbol);
                    }, OperationKind.PropertyReference);
                });
            });
        }
Ejemplo n.º 59
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();

            context.RegisterOperationAction(AnalyzeInvocationOp, OperationKind.Invocation);
        }
Ejemplo n.º 60
0
 /// <inheritdoc/>
 public override void Initialize(AnalysisContext context)
 {
     context.EnableConcurrentExecution();
     context.RegisterSyntaxNodeAction(Handle, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration);
 }