Пример #1
0
        public void Track(SonarAnalysisContext context, params Condition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSymbolAction(TrackMethodDeclaration, SymbolKind.Method);
                }
            });

            void TrackMethodDeclaration(SymbolAnalysisContext c)
            {
                if (IsTrackedMethod((IMethodSymbol)c.Symbol, c.Compilation))
                {
                    foreach (var declaration in c.Symbol.DeclaringSyntaxReferences)
                    {
                        var methodIdentifier = GetMethodIdentifier(declaration.GetSyntax());
                        if (methodIdentifier.HasValue)
                        {
                            c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, methodIdentifier.Value.GetLocation()));
                        }
                    }
                }
            }

            bool IsTrackedMethod(IMethodSymbol methodSymbol, Compilation compilation)
            {
                var conditionContext = new MethodDeclarationContext(methodSymbol, compilation);

                return(conditions.All(c => c(conditionContext)));
            }
        }
Пример #2
0
        public void Track(SonarAnalysisContext context, params ElementAccessCondition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackElementAccess,
                        TrackedSyntaxKinds);
                }
            });

            void TrackElementAccess(SyntaxNodeAnalysisContext c)
            {
                if (IsTrackedElementAccess(c.Node, c.SemanticModel))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, c.Node.GetLocation()));
                }
            }

            bool IsTrackedElementAccess(SyntaxNode expression, SemanticModel semanticModel)
            {
                var conditionContext = new ElementAccessContext(expression, semanticModel);

                return(conditions.All(c => c(conditionContext)));
            }
        }
Пример #3
0
        public void Track(SonarAnalysisContext context, object[] diagnosticMessageArgs, params ObjectCreationCondition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackObjectCreation,
                        TrackedSyntaxKinds);
                }
            });

            void TrackObjectCreation(SyntaxNodeAnalysisContext c)
            {
                if (IsTrackedObjectCreation(c.Node, c.SemanticModel))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, c.Node.GetLocation(), diagnosticMessageArgs));
                }
            }

            bool IsTrackedObjectCreation(SyntaxNode objectCreationExpression, SemanticModel semanticModel)
            {
                var objectCreationContext = new ObjectCreationContext(objectCreationExpression, semanticModel);

                return(conditions.All(c => c(objectCreationContext)));
            }
        }
Пример #4
0
        public void Track(SonarAnalysisContext context, object[] diagnosticMessageArgs, params Condition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackAndReportIfNecessary,
                        TrackedSyntaxKinds);
                }
            });

            void TrackAndReportIfNecessary(SyntaxNodeAnalysisContext c)
            {
                if (CreateContext(c) is { } trackingContext &&
                    conditions.All(c => c(trackingContext)) &&
                    trackingContext.PrimaryLocation != null &&
                    trackingContext.PrimaryLocation != Location.None)
                {
                    c.ReportDiagnosticWhenActive(
                        Diagnostic.Create(Rule,
                                          trackingContext.PrimaryLocation,
                                          trackingContext.SecondaryLocations.ToAdditionalLocations(),
                                          trackingContext.SecondaryLocations.ToProperties(),
                                          diagnosticMessageArgs));
                }
            }
        }
Пример #5
0
 public static void RegisterSyntaxTreeActionInNonGenerated(this SonarAnalysisContext context, GeneratedCodeRecognizer generatedCodeRecognizer, Action <SyntaxTreeAnalysisContext> action) =>
 context.RegisterCompilationStartAction(csac =>
                                        csac.RegisterSyntaxTreeAction(c =>
 {
     if (ShouldAnalyze(context, generatedCodeRecognizer, c.GetSyntaxTree(), csac.Compilation, c.Options))
     {
         action(c);
     }
 }));
Пример #6
0
        public void Track(SonarAnalysisContext context, params BaseClassCondition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackInheritance,
                        TrackedSyntaxKinds);
                }
            });

            void TrackInheritance(SyntaxNodeAnalysisContext c)
            {
                Location issueLocation;

                if (IsTrackedRelationship(c.Node, c.SemanticModel, out issueLocation))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, issueLocation));
                }
            }

            bool IsTrackedRelationship(SyntaxNode contextNode, SemanticModel semanticModel, out Location issueLocation)
            {
                var baseTypeList = GetBaseTypeNodes(contextNode);

                if (baseTypeList == null || !baseTypeList.Any())
                {
                    issueLocation = Location.None;
                    return(false);
                }

                var baseClassContext = new BaseTypeContext(contextNode, baseTypeList, semanticModel);

                // We can't pass the issueLocation to the lambda directly so we need a temporary variable
                Location locationToReport = null;

                if (conditions.All(c => c(baseClassContext, out locationToReport)))
                {
                    issueLocation = locationToReport;
                    return(true);
                }
                issueLocation = Location.None;
                return(false);
            }
        }
Пример #7
0
 public static void RegisterSyntaxTreeActionInNonGenerated(
     this SonarAnalysisContext context,
     GeneratedCodeRecognizer generatedCodeRecognizer,
     Action <SyntaxTreeAnalysisContext> action)
 {
     context.RegisterCompilationStartAction(
         csac =>
     {
         csac.RegisterSyntaxTreeAction(
             c =>
         {
             if (!c.Tree.IsGenerated(generatedCodeRecognizer, csac.Compilation))
             {
                 action(c);
             }
         });
     });
 }
Пример #8
0
        public void Track(SonarAnalysisContext context, params PropertyAccessCondition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackMemberAccess,
                        TrackedSyntaxKinds);
                }
            });

            void TrackMemberAccess(SyntaxNodeAnalysisContext c)
            {
                if (IsTrackedProperty(c.Node, c.SemanticModel))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, c.Node.GetLocation()));
                }
            }

            bool IsTrackedProperty(SyntaxNode expression, SemanticModel semanticModel)
            {
                // We register for both MemberAccess and IdentifierName and we want to
                // avoid raising two times for the same identifier.
                if (IsIdentifierWithinMemberAccess(expression))
                {
                    return(false);
                }

                var propertyName = GetPropertyName(expression);

                if (propertyName == null)
                {
                    return(false);
                }

                var conditionContext = new PropertyAccessContext(expression, propertyName, semanticModel);

                return(conditions.All(c => c(conditionContext)));
            }
        }
Пример #9
0
        public void Track(SonarAnalysisContext context, params InvocationCondition[] conditions)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                if (IsEnabled(c.Options))
                {
                    c.RegisterSyntaxNodeActionInNonGenerated(
                        GeneratedCodeRecognizer,
                        TrackInvocationExpression,
                        TrackedSyntaxKinds);
                }
            });

            void TrackInvocationExpression(SyntaxNodeAnalysisContext c)
            {
                if (IsTrackedMethod(c.Node, c.SemanticModel))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, c.Node.GetLocation()));
                }
            }

            bool IsTrackedMethod(SyntaxNode invocation, SemanticModel semanticModel)
            {
                var methodName = GetMethodName(invocation);

                if (methodName == null)
                {
                    return(false);
                }

                var conditionContext = new InvocationContext(invocation, methodName, semanticModel);

                return(conditions.All(c => c(conditionContext)));
            }
        }