コード例 #1
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(c =>
            {
                if (!ReportsOnTestSource && c.Compilation.IsTest())
                {
                    return;
                }

                var shouldRaise = true;

                c.RegisterSemanticModelAction(cc =>
                {
                    var requiredAttributeFound = cc.SemanticModel.SyntaxTree.GetRoot()
                                                 .DescendantNodes()
                                                 .OfType <AttributeListSyntax>()
                                                 .SelectMany(list => list.Attributes)
                                                 .Any(a => IsRequiredAttribute(a, cc.SemanticModel));

                    if (requiredAttributeFound)
                    {
                        shouldRaise = false;
                    }
                });

                c.RegisterCompilationEndAction(cc =>
                {
                    if (shouldRaise)
                    {
                        cc.ReportDiagnostic(Diagnostic.Create(Rule, null));
                    }
                });
            });
        }
コード例 #2
0
        protected override void Initialize(SonarAnalysisContext context) =>
        context.RegisterCompilationStartAction(analysisContext =>
        {
            analysisContext.RegisterSyntaxNodeAction(c =>
            {
                var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node);
                if (declarationSymbol == null)
                {
                    return;
                }

                CheckGenericTypeParameters(declarationSymbol, c);
            },
                                                     SyntaxKind.MethodDeclaration,
                                                     SyntaxKindEx.LocalFunctionStatement);

            analysisContext.RegisterSyntaxNodeAction(c =>
            {
                if (c.ContainingSymbol.Kind != SymbolKind.NamedType)
                {
                    return;
                }

                CheckGenericTypeParameters(c.ContainingSymbol, c);
            },
                                                     SyntaxKind.ClassDeclaration,
                                                     SyntaxKindEx.RecordDeclaration);
        });
コード例 #3
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                ccc =>
            {
                if (!IsEnabled(ccc.Options))
                {
                    return;
                }

                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var objectCreation = (ObjectCreationExpressionSyntax)c.Node;
                    if (objectInitializationTracker.ShouldBeReported(objectCreation, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], objectCreation.GetLocation()));
                    }
                },
                    SyntaxKind.ObjectCreationExpression);

                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var assignment = (AssignmentExpressionSyntax)c.Node;

                    if (objectInitializationTracker.ShouldBeReported(assignment, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], assignment.GetLocation()));
                    }
                },
                    SyntaxKind.SimpleAssignmentExpression);
            });
        }
コード例 #4
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                cc =>
            {
                if (!TryReadConfiguration(cc.Options))
                {
                    return;
                }

                protobufFileIndex = 0;

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <BaseMethodDeclarationSyntax>(c, x => x.Body),
                    SyntaxKind.ConstructorDeclaration,
                    SyntaxKind.OperatorDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <MethodDeclarationSyntax>(c, x => (CSharpSyntaxNode)x.Body ?? x.ExpressionBody?.Expression),
                    SyntaxKind.MethodDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <AccessorDeclarationSyntax>(c, node => node.Body),
                    SyntaxKind.GetAccessorDeclaration,
                    SyntaxKind.SetAccessorDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <PropertyDeclarationSyntax>(c, node => node.ExpressionBody?.Expression),
                    SyntaxKind.PropertyDeclaration);
            });
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                var hasResx = false;

                c.RegisterSyntaxNodeAction(
                    cc =>
                {
                    if (IsResxGeneratedFile(cc.SemanticModel, (ClassDeclarationSyntax)cc.Node))
                    {
                        hasResx = true;
                    }
                }, SyntaxKind.ClassDeclaration);

                c.RegisterCompilationEndAction(
                    cc =>
                {
                    if (!hasResx || HasNeutralResourcesLanguageAttribute(cc.Compilation.Assembly))
                    {
                        return;
                    }

                    cc.ReportDiagnosticWhenActive(Diagnostic.Create(rule, null));
                });
            });
        }
コード例 #6
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            base.Initialize(context);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                if (IsEnabled(compilationContext.Options))
                {
                    context.RegisterSyntaxNodeActionInNonGenerated(VisitAttribute, SyntaxKind.Attribute);
                }
            });
        }
コード例 #7
0
        protected override void Initialize(SonarAnalysisContext context) =>
        context.RegisterCompilationStartAction(c =>
        {
            if (!IsEnabled(c.Options))
            {
                return;
            }

            c.RegisterSyntaxNodeActionInNonGenerated(Language.GeneratedCodeRecognizer, VisitInvocations, Language.SyntaxKind.InvocationExpression);

            c.RegisterSyntaxNodeActionInNonGenerated(Language.GeneratedCodeRecognizer, VisitAssignments, Language.SyntaxKind.IdentifierName);
        });
コード例 #8
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                compilationStartContext =>
            {
                var allNamedTypeSymbols   = compilationStartContext.Compilation.GlobalNamespace.GetAllNamedTypes();
                var typeInterfaceMappings = allNamedTypeSymbols.Select(type =>
                                                                       new
                {
                    Type       = type.OriginalDefinition,
                    Interfaces = type.OriginalDefinition.AllInterfaces.Select(i => i.OriginalDefinition)
                });

                var interfaceImplementerMappings = new Dictionary <INamedTypeSymbol, HashSet <INamedTypeSymbol> >();
                foreach (var typeInterfaceMapping in typeInterfaceMappings)
                {
                    if (typeInterfaceMapping.Type.IsInterface())
                    {
                        if (!interfaceImplementerMappings.ContainsKey(typeInterfaceMapping.Type))
                        {
                            interfaceImplementerMappings.Add(typeInterfaceMapping.Type, new HashSet <INamedTypeSymbol>());
                        }

                        interfaceImplementerMappings[typeInterfaceMapping.Type].Add(typeInterfaceMapping.Type);
                    }

                    foreach (var @interface in typeInterfaceMapping.Interfaces)
                    {
                        if (!interfaceImplementerMappings.ContainsKey(@interface))
                        {
                            interfaceImplementerMappings.Add(@interface, new HashSet <INamedTypeSymbol>());
                        }

                        interfaceImplementerMappings[@interface].Add(typeInterfaceMapping.Type);
                    }
                }

                compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var cast           = (CastExpressionSyntax)c.Node;
                    var interfaceType  = c.SemanticModel.GetTypeInfo(cast.Type).Type as INamedTypeSymbol;
                    var expressionType = c.SemanticModel.GetTypeInfo(cast.Expression).Type as INamedTypeSymbol;

                    CheckTypesForInvalidCast(interfaceType, expressionType, interfaceImplementerMappings,
                                             cast.Type.GetLocation(), c);
                },
                    SyntaxKind.CastExpression);
            });

            context.RegisterExplodedGraphBasedAnalysis((e, c) => CheckEmptyNullableCast(e, c));
        }
コード例 #9
0
        protected override void Initialize(SonarAnalysisContext context) =>
        context.RegisterCompilationStartAction(
            compilationStartContext =>
        {
            var symbolsWhereTypeIsCreated = new ConcurrentBag <SyntaxNodeWithSymbol <SyntaxNode, ISymbol> >();
            var symbolsWhereLocaleIsSet   = new ConcurrentBag <ISymbol>();

            compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(ProcessObjectCreations(symbolsWhereTypeIsCreated),
                                                                           SyntaxKind.ObjectCreationExpression,
                                                                           SyntaxKindEx.ImplicitObjectCreationExpression);
            compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(ProcessSimpleAssignments(symbolsWhereLocaleIsSet), SyntaxKind.SimpleAssignmentExpression);
            compilationStartContext.RegisterCompilationEndAction(ProcessCollectedSymbols(symbolsWhereTypeIsCreated, symbolsWhereLocaleIsSet));
        });
コード例 #10
0
        protected override void Initialize(SonarAnalysisContext context) =>
        context.RegisterCompilationStartAction(
            ccc =>
        {
            if (!IsEnabled(ccc.Options))
            {
                return;
            }

            context.RegisterSyntaxNodeActionInNonGenerated(CheckIgnoreAntiforgeryTokenAttribute,
                                                           SyntaxKind.Attribute,
                                                           SyntaxKind.ObjectCreationExpression,
                                                           ImplicitObjectCreationExpression);
        });
コード例 #11
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            var analysisContext = new ParameterLoadingAnalysisContext(context);
            Initialize(analysisContext);

            context.RegisterCompilationStartAction(
                cac =>
                {
                    ParameterLoader.SetParameterValues(this, cac.Options);
                    foreach (var compilationStartActions in analysisContext.CompilationStartActions)
                    {
                        compilationStartActions(cac);
                    }
                });
        }
コード例 #12
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                ccc =>
            {
                if (!IsEnabled(ccc.Options))
                {
                    return;
                }

                context.RegisterSyntaxNodeActionInNonGenerated(
                    GetAnalysisAction(rule),
                    SyntaxKind.StringLiteralExpression);
            });
        }
コード例 #13
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            var analysisContext = new ParameterLoadingAnalysisContext(context);

            Initialize(analysisContext);

            context.RegisterCompilationStartAction(
                cac =>
            {
                ParameterLoader.SetParameterValues(this, cac.Options);
                foreach (var compilationStartActions in analysisContext.CompilationStartActions)
                {
                    compilationStartActions(cac);
                }
            });
        }
コード例 #14
0
 protected sealed override void Initialize(SonarAnalysisContext context)
 {
     context.RegisterCompilationStartAction(
         c =>
     {
         c.RegisterCompilationEndAction(
             cc =>
         {
             var requiredAttributeFound = cc.Compilation.Assembly.GetAttributes(AttributeToFind).Any();
             if (!requiredAttributeFound)
             {
                 cc.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], null));
             }
         });
     });
 }
コード例 #15
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                {
                    var methodDeclaration = c.Node as MethodDeclarationSyntax;
                    var classDeclaration  = c.Node as ClassDeclarationSyntax;

                    if (methodDeclaration != null &&
                        !IsMethodCandidate(methodDeclaration, c.SemanticModel))
                    {
                        return;
                    }

                    var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node);
                    if (declarationSymbol == null)
                    {
                        return;
                    }

                    var helper = GetTypeParameterHelper(methodDeclaration, classDeclaration);
                    if (helper.TypeParameterList == null || helper.TypeParameterList.Parameters.Count == 0)
                    {
                        return;
                    }

                    var declarations = declarationSymbol.DeclaringSyntaxReferences
                                       .Select(reference => reference.GetSyntax());

                    var usedTypeParameters = GetUsedTypeParameters(declarations, c, analysisContext.Compilation);

                    foreach (var typeParameter in helper.TypeParameterList.Parameters
                             .Select(typeParameter => typeParameter.Identifier.Text)
                             .Where(typeParameter => !usedTypeParameters.Contains(typeParameter)))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(rule,
                                                                       helper.TypeParameterList.Parameters.First(tp => tp.Identifier.Text == typeParameter)
                                                                       .GetLocation(),
                                                                       typeParameter, helper.ContainerSyntaxTypeName));
                    }
                },
                    SyntaxKind.MethodDeclaration,
                    SyntaxKind.ClassDeclaration);
            });
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                csac =>
            {
                var nodesWithSecuritySafeCritical = new Dictionary <SyntaxNode, AttributeSyntax>();
                var nodesWithSecurityCritical     = new Dictionary <SyntaxNode, AttributeSyntax>();

                csac.RegisterSyntaxNodeActionInNonGenerated(
                    snac => CollectSecurityAttributes(snac, nodesWithSecuritySafeCritical, nodesWithSecurityCritical),
                    SyntaxKind.Attribute);

                csac.RegisterCompilationEndAction(
                    cac => ReportOnConflictingTransparencyAttributes(cac, nodesWithSecuritySafeCritical,
                                                                     nodesWithSecurityCritical));
            });
        }
コード例 #17
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(c =>
            {
                if (c.Compilation.IsTest())
                {
                    return;
                }

                c.RegisterCompilationEndAction(cc =>
                {
                    var requiredAttributeFound = cc.Compilation.Assembly.GetAttributes().Any(a => a.AttributeClass.Is(AttributeToFind));
                    if (!requiredAttributeFound)
                    {
                        cc.ReportDiagnostic(Diagnostic.Create(Rule, null));
                    }
                });
            });
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                ccc =>
            {
                if (!IsEnabled(ccc.Options))
                {
                    return;
                }

                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var objectCreation = (ObjectCreationExpressionSyntax)c.Node;

                    if (IsTrackedType(objectCreation, c.SemanticModel) &&
                        !ObjectCreatedWithAllowedValue(objectCreation, c.SemanticModel) &&
                        !IsLaterAssignedWithAllowedValue(objectCreation, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], objectCreation.GetLocation()));
                    }
                },
                    SyntaxKind.ObjectCreationExpression);

                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var assignment = (AssignmentExpressionSyntax)c.Node;

                    // Ignore assignments within object initializers, they are
                    // reported in the ObjectCreationExpression handler
                    if (assignment.FirstAncestorOrSelf <InitializerExpressionSyntax>() == null &&
                        IsTrackedPropertyName(assignment.Left) &&
                        IsPropertyOnTrackedType(assignment.Left, c.SemanticModel) &&
                        !IsAllowedValue(assignment.Right, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], assignment.GetLocation()));
                    }
                },
                    SyntaxKind.SimpleAssignmentExpression);
            });
        }
コード例 #19
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                compilationStartContext =>
            {
                var allNamedTypeSymbols = compilationStartContext.Compilation.GlobalNamespace.GetAllNamedTypes();
                var allInterfacesWithImplementationsOverriddenEquals =
                    allNamedTypeSymbols
                    .Where(t => t.AllInterfaces.Any() && HasEqualsOverride(t))
                    .SelectMany(t => t.AllInterfaces)
                    .ToImmutableHashSet();

                compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var binary = (BinaryExpressionSyntax)c.Node;
                    if (!IsBinaryCandidateForReporting(binary, c.SemanticModel))
                    {
                        return;
                    }

                    var typeLeft  = c.SemanticModel.GetTypeInfo(binary.Left).Type;
                    var typeRight = c.SemanticModel.GetTypeInfo(binary.Right).Type;
                    if (typeLeft == null ||
                        typeRight == null ||
                        IsAllowedType(typeLeft) ||
                        IsAllowedType(typeRight))
                    {
                        return;
                    }

                    if (MightOverrideEquals(typeLeft, allInterfacesWithImplementationsOverriddenEquals) ||
                        MightOverrideEquals(typeRight, allInterfacesWithImplementationsOverriddenEquals))
                    {
                        c.ReportDiagnostic(Diagnostic.Create(rule, binary.OperatorToken.GetLocation()));
                    }
                },
                    SyntaxKind.EqualsExpression,
                    SyntaxKind.NotEqualsExpression);
            });
        }
コード例 #20
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            base.Initialize(context);

            context.RegisterCompilationStartAction(
                c =>
            {
                if (!IsEnabled(c.Options))
                {
                    return;
                }

                c.RegisterSyntaxNodeActionInNonGenerated(
                    new VariableDeclarationBannedWordsFinder(this).GetAnalysisAction(rule),
                    SyntaxKind.VariableDeclarator);

                c.RegisterSyntaxNodeActionInNonGenerated(
                    new AssignmentExpressionBannedWordsFinder(this).GetAnalysisAction(rule),
                    SyntaxKind.SimpleAssignmentStatement);
            });
        }
コード例 #21
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSyntaxNodeActionInNonGenerated(c =>
            {
                var statement = (OptionStatementSyntax)c.Node;
                if (statement.NameKeyword.IsKind(SyntaxKind.StrictKeyword) && !statement.ValueKeyword.IsKind(SyntaxKind.OnKeyword))
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, statement.GetLocation(), StatementMessage));
                }
            },
                                                           SyntaxKind.OptionStatement);

            context.RegisterCompilationStartAction(cStart =>
                                                   cStart.RegisterCompilationEndAction(c =>
            {
                if (c.Compilation.VB().Options.OptionStrict != OptionStrict.On)
                {
                    c.ReportDiagnosticWhenActive(Diagnostic.Create(Rule, null, string.Format(AssemblyMessageFormat, c.Compilation.AssemblyName)));
                }
            }));
        }
コード例 #22
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                {
                    var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node);
                    if (declarationSymbol == null)
                    {
                        return;
                    }

                    var helper = CreateParametersInfo(c.Node, c.SemanticModel);
                    if (helper.Parameters == null || helper.Parameters.Parameters.Count == 0)
                    {
                        return;
                    }

                    var declarations = declarationSymbol.DeclaringSyntaxReferences
                                       .Select(reference => reference.GetSyntax());

                    var typeParameterNames = helper.Parameters.Parameters.Select(typeParameter => typeParameter.Identifier.Text).ToArray();

                    var usedTypeParameters = GetUsedTypeParameters(declarations, typeParameterNames, c, analysisContext.Compilation);

                    foreach (var typeParameter in typeParameterNames
                             .Where(typeParameter => !usedTypeParameters.Contains(typeParameter)))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(rule,
                                                                       helper.Parameters.Parameters.First(tp => tp.Identifier.Text == typeParameter)
                                                                       .GetLocation(),
                                                                       typeParameter, helper.ContainerName));
                    }
                },
                    SyntaxKind.MethodDeclaration,
                    SyntaxKind.ClassDeclaration,
                    SyntaxKindEx.LocalFunctionStatement);
            });
        }
コード例 #23
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                cc =>
            {
                configuration.Read(cc.Options);

                if (string.IsNullOrEmpty(configuration.ProjectOutputPath) ||
                    !configuration.EnabledRules.Any(SecurityRules.Contains))
                {
                    return;
                }

                InitProtobufDirectory();

                protobufFileIndex = 0;

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <ConstructorDeclarationSyntax>(c, x => x.Body),
                    SyntaxKind.ConstructorDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <MethodDeclarationSyntax>(c, x => (CSharpSyntaxNode)x.Body ?? x.ExpressionBody?.Expression),
                    SyntaxKind.MethodDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <OperatorDeclarationSyntax>(c, x => (CSharpSyntaxNode)x.Body ?? x.ExpressionBody?.Expression),
                    SyntaxKind.OperatorDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <AccessorDeclarationSyntax>(c, node => node.Body),
                    SyntaxKind.GetAccessorDeclaration,
                    SyntaxKind.SetAccessorDeclaration);

                cc.RegisterSyntaxNodeActionInNonGenerated(
                    c => WriteUCFG <PropertyDeclarationSyntax>(c, node => node.ExpressionBody?.Expression),
                    SyntaxKind.PropertyDeclaration);
            });
        }
コード例 #24
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                ccc =>
            {
                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var objectCreation = (ObjectCreationExpressionSyntax)c.Node;

                    var trackers = TrackerFactory.Create(c.Compilation, VersionProvider);
                    if (trackers.xmlDocumentTracker.ShouldBeReported(objectCreation, c.SemanticModel) ||
                        trackers.xmlTextReaderTracker.ShouldBeReported(objectCreation, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, objectCreation.GetLocation()));
                    }

                    VerifyXPathDocumentConstructor(c);
                },
                    SyntaxKind.ObjectCreationExpression);

                ccc.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var assignment = (AssignmentExpressionSyntax)c.Node;

                    var trackers = TrackerFactory.Create(c.Compilation, VersionProvider);
                    if (trackers.xmlDocumentTracker.ShouldBeReported(assignment, c.SemanticModel) ||
                        trackers.xmlTextReaderTracker.ShouldBeReported(assignment, c.SemanticModel))
                    {
                        c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, assignment.GetLocation()));
                    }
                },
                    SyntaxKind.SimpleAssignmentExpression);

                ccc.RegisterSyntaxNodeActionInNonGenerated(VerifyXmlReaderInvocations, SyntaxKind.InvocationExpression);
            });
        }
コード例 #25
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                var fieldsByNamedType = MultiValueDictionary<INamedTypeSymbol, IFieldSymbol>.Create<HashSet<IFieldSymbol>>();
                var fieldsAssigned = ImmutableHashSet<IFieldSymbol>.Empty;

                analysisContext.RegisterSymbolAction(c =>
                {
                    var namedTypeSymbol = (INamedTypeSymbol)c.Symbol;
                    if (!namedTypeSymbol.IsClass() ||
                        namedTypeSymbol.Implements(KnownType.System_IDisposable))
                    {
                        return;
                    }

                    var disposableFields = namedTypeSymbol.GetMembers()
                        .OfType<IFieldSymbol>()
                        .Where(IsNonStaticNonPublicDisposableField)
                        .ToImmutableHashSet();

                    fieldsByNamedType.AddRangeWithKey(namedTypeSymbol, disposableFields);
                }, SymbolKind.NamedType);


                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var assignment = (AssignmentExpressionSyntax)c.Node;
                    var expression = assignment.Right;
                    var fieldSymbol = c.SemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol;

                    fieldsAssigned = AddFieldIfNeeded(fieldSymbol, expression, fieldsAssigned);
                }, SyntaxKind.SimpleAssignmentExpression);

                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var field = (FieldDeclarationSyntax)c.Node;

                    foreach (var variableDeclaratorSyntax in field.Declaration.Variables
                        .Where(declaratorSyntax => declaratorSyntax.Initializer != null))
                    {
                        var fieldSymbol = c.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax) as IFieldSymbol;

                        fieldsAssigned = AddFieldIfNeeded(fieldSymbol, variableDeclaratorSyntax.Initializer.Value,
                            fieldsAssigned);
                    }

                }, SyntaxKind.FieldDeclaration);

                analysisContext.RegisterCompilationEndAction(c =>
                {
                    foreach (var kv in fieldsByNamedType)
                    {
                        foreach (var classSyntax in kv.Key.DeclaringSyntaxReferences
                            .Select(declaringSyntaxReference => declaringSyntaxReference.GetSyntax())
                            .OfType<ClassDeclarationSyntax>())
                        {
                            var assignedFields = kv.Value.Intersect(fieldsAssigned).ToList();

                            if (!assignedFields.Any())
                            {
                                continue;
                            }
                            var variableNames = string.Join(", ",
                                assignedFields.Select(symbol => $"\"{symbol.Name}\"").OrderBy(s => s));

                            c.ReportDiagnosticIfNonGenerated(
                                Diagnostic.Create(Rule, classSyntax.Identifier.GetLocation(), variableNames),
                                c.Compilation);
                        }
                    }
                });
            });
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                if (analysisContext.Compilation.IsTest())
                {
                    return;
                }

                var fieldsByNamedType = MultiValueDictionary <INamedTypeSymbol, IFieldSymbol> .Create <HashSet <IFieldSymbol> >();
                var fieldsAssigned    = ImmutableHashSet <IFieldSymbol> .Empty;

                analysisContext.RegisterSymbolAction(c =>
                {
                    var namedTypeSymbol = (INamedTypeSymbol)c.Symbol;
                    if (!namedTypeSymbol.IsClass() ||
                        namedTypeSymbol.Implements(KnownType.System_IDisposable))
                    {
                        return;
                    }

                    var disposableFields = namedTypeSymbol.GetMembers()
                                           .OfType <IFieldSymbol>()
                                           .Where(IsNonStaticNonPublicDisposableField)
                                           .ToImmutableHashSet();

                    fieldsByNamedType.AddRangeWithKey(namedTypeSymbol, disposableFields);
                }, SymbolKind.NamedType);


                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var assignment  = (AssignmentExpressionSyntax)c.Node;
                    var expression  = assignment.Right;
                    var fieldSymbol = c.SemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol;

                    fieldsAssigned = AddFieldIfNeeded(fieldSymbol, expression, fieldsAssigned);
                }, SyntaxKind.SimpleAssignmentExpression);

                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var field = (FieldDeclarationSyntax)c.Node;

                    foreach (var variableDeclaratorSyntax in field.Declaration.Variables
                             .Where(declaratorSyntax => declaratorSyntax.Initializer != null))
                    {
                        var fieldSymbol = c.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax) as IFieldSymbol;

                        fieldsAssigned = AddFieldIfNeeded(fieldSymbol, variableDeclaratorSyntax.Initializer.Value,
                                                          fieldsAssigned);
                    }
                }, SyntaxKind.FieldDeclaration);

                analysisContext.RegisterCompilationEndAction(c =>
                {
                    foreach (var kv in fieldsByNamedType)
                    {
                        foreach (var classSyntax in kv.Key.DeclaringSyntaxReferences
                                 .Select(declaringSyntaxReference => declaringSyntaxReference.GetSyntax())
                                 .OfType <ClassDeclarationSyntax>())
                        {
                            var assignedFields = kv.Value.Intersect(fieldsAssigned).ToList();

                            if (!assignedFields.Any())
                            {
                                continue;
                            }
                            var variableNames = string.Join(", ",
                                                            assignedFields.Select(symbol => $"\"{symbol.Name}\"").OrderBy(s => s));

                            c.ReportDiagnosticIfNonGenerated(
                                Diagnostic.Create(Rule, classSyntax.Identifier.GetLocation(), variableNames),
                                c.Compilation);
                        }
                    }
                });
            });
        }
コード例 #27
0
        protected sealed override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                var shouldRaise = true;
                possibleUnusedInternalMembers = new ConcurrentBag <Diagnostic>();

                c.RegisterSemanticModelAction(
                    cc =>
                {
                    var isInternalsVisibleToAttributeFound = cc.SemanticModel.SyntaxTree.GetRoot()
                                                             .DescendantNodes()
                                                             .OfType <AttributeListSyntax>()
                                                             .SelectMany(list => list.Attributes)
                                                             .Any(a => IsInternalVisibleToAttribute(a, cc.SemanticModel));
                    if (isInternalsVisibleToAttributeFound)
                    {
                        shouldRaise = false;
                    }
                });

                c.RegisterSymbolAction(
                    cc =>
                {
                    var namedType = (INamedTypeSymbol)cc.Symbol;
                    if (!namedType.IsClassOrStruct() ||
                        namedType.ContainingType != null)
                    {
                        return;
                    }

                    var declarationCollector = new RemovableDeclarationCollector(namedType, cc.Compilation);

                    var declaredPrivateSymbols = new HashSet <ISymbol>();
                    var fieldLikeSymbols       = new BidirectionalDictionary <ISymbol, SyntaxNode>();

                    CollectRemovableNamedTypes(declarationCollector, declaredPrivateSymbols);
                    CollectRemovableFieldLikeDeclarations(declarationCollector, declaredPrivateSymbols, fieldLikeSymbols);
                    CollectRemovableEventsAndProperties(declarationCollector, declaredPrivateSymbols);
                    CollectRemovableMethods(declarationCollector, declaredPrivateSymbols);

                    if (!declaredPrivateSymbols.Any())
                    {
                        return;
                    }

                    var usedSymbols       = new HashSet <ISymbol>();
                    var emptyConstructors = new HashSet <ISymbol>();

                    var propertyAccessorAccess = new Dictionary <IPropertySymbol, AccessorAccess>();

                    CollectUsedSymbols(declarationCollector, usedSymbols, declaredPrivateSymbols, propertyAccessorAccess);
                    CollectUsedSymbolsFromCtorInitializerAndCollectEmptyCtors(declarationCollector,
                                                                              usedSymbols, emptyConstructors);

                    ReportIssues(cc, usedSymbols, declaredPrivateSymbols, emptyConstructors, fieldLikeSymbols);
                    ReportUnusedPropertyAccessors(cc, usedSymbols, declaredPrivateSymbols, propertyAccessorAccess);
                },
                    SymbolKind.NamedType);

                c.RegisterCompilationEndAction(
                    cc =>
                {
                    if (!shouldRaise)
                    {
                        return;
                    }

                    foreach (var diagnostic in possibleUnusedInternalMembers)
                    {
                        cc.ReportDiagnosticIfNonGenerated(diagnostic, cc.Compilation);
                    }
                });
            });
        }
コード例 #28
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                    {
                        var methodDeclaration = c.Node as MethodDeclarationSyntax;
                        var classDeclaration = c.Node as ClassDeclarationSyntax;

                        if (methodDeclaration != null &&
                            !IsMethodCandidate(methodDeclaration, c.SemanticModel))
                        {
                            return;
                        }

                        var declarationSymbol = c.SemanticModel.GetDeclaredSymbol(c.Node);
                        if (declarationSymbol == null)
                        {
                            return;
                        }

                        var helper = GetTypeParameterHelper(methodDeclaration, classDeclaration);
                        if (helper.TypeParameterList == null || helper.TypeParameterList.Parameters.Count == 0)
                        {
                            return;
                        }

                        var declarations = declarationSymbol.DeclaringSyntaxReferences
                            .Select(reference => reference.GetSyntax());

                        var usedTypeParameters = GetUsedTypeParameters(declarations, c, analysisContext.Compilation);

                        foreach (var typeParameter in helper.TypeParameterList.Parameters
                            .Select(typeParameter => typeParameter.Identifier.Text)
                            .Where(typeParameter => !usedTypeParameters.Contains(typeParameter)))
                        {
                            c.ReportDiagnostic(Diagnostic.Create(Rule,
                                helper.TypeParameterList.Parameters.First(tp => tp.Identifier.Text == typeParameter)
                                    .GetLocation(),
                                typeParameter, helper.ContainerSyntaxTypeName));
                        }
                    },
                    SyntaxKind.MethodDeclaration,
                    SyntaxKind.ClassDeclaration);
            });
        }
コード例 #29
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(analysisContext =>
            {
                var candidateFields = ImmutableHashSet<IFieldSymbol>.Empty;
                var assignedAsReadonly = ImmutableHashSet<IFieldSymbol>.Empty;
                var nonCandidateFields = ImmutableHashSet<IFieldSymbol>.Empty;

                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var fieldDeclaration = (FieldDeclarationSyntax) c.Node;

                    foreach (var field in fieldDeclaration.Declaration.Variables
                        .Select(variableDeclaratorSyntax => new
                        {
                            Syntax = variableDeclaratorSyntax,
                            Symbol = c.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax) as IFieldSymbol
                        })
                        .Where(f => f.Symbol != null)
                        .Where(f => FieldIsRelevant(f.Symbol)))
                    {
                        candidateFields = candidateFields.Add(field.Symbol);

                        if (field.Syntax.Initializer != null)
                        {
                            assignedAsReadonly = assignedAsReadonly.Add(field.Symbol);
                        }
                    }
                }, SyntaxKind.FieldDeclaration);

                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                    {
                        var assignment = (AssignmentExpressionSyntax) c.Node;
                        var expression = assignment.Left;

                        ProcessExpressionChange(expression, c.SemanticModel, ref nonCandidateFields, ref assignedAsReadonly);
                    },
                    SyntaxKind.SimpleAssignmentExpression,
                    SyntaxKind.AddAssignmentExpression,
                    SyntaxKind.SubtractAssignmentExpression,
                    SyntaxKind.MultiplyAssignmentExpression,
                    SyntaxKind.DivideAssignmentExpression,
                    SyntaxKind.ModuloAssignmentExpression,
                    SyntaxKind.AndAssignmentExpression,
                    SyntaxKind.ExclusiveOrAssignmentExpression,
                    SyntaxKind.OrAssignmentExpression,
                    SyntaxKind.LeftShiftAssignmentExpression,
                    SyntaxKind.RightShiftAssignmentExpression);

                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                    {
                        var unary = (PrefixUnaryExpressionSyntax)c.Node;
                        var expression = unary.Operand;

                        ProcessExpressionChange(expression, c.SemanticModel, ref nonCandidateFields, ref assignedAsReadonly);
                    },
                    SyntaxKind.PreDecrementExpression,
                    SyntaxKind.PreIncrementExpression);

                analysisContext.RegisterSyntaxNodeAction(
                    c =>
                    {
                        var unary = (PostfixUnaryExpressionSyntax)c.Node;
                        var expression = unary.Operand;

                        ProcessExpressionChange(expression, c.SemanticModel, ref nonCandidateFields, ref assignedAsReadonly);
                    },
                    SyntaxKind.PostDecrementExpression,
                    SyntaxKind.PostIncrementExpression);

                analysisContext.RegisterSyntaxNodeAction(c =>
                {
                    var argument = (ArgumentSyntax) c.Node;
                    if (argument.RefOrOutKeyword.IsKind(SyntaxKind.None))
                    {
                        return;
                    }

                    var fieldSymbol = c.SemanticModel.GetSymbolInfo(argument.Expression).Symbol as IFieldSymbol;
                    if (FieldIsRelevant(fieldSymbol))
                    {
                        nonCandidateFields = nonCandidateFields.Add(fieldSymbol);
                    }
                }, SyntaxKind.Argument);

                analysisContext.RegisterCompilationEndAction(c =>
                {
                    var fields = candidateFields.Except(nonCandidateFields);
                    fields = fields.Intersect(assignedAsReadonly);
                    foreach (var field in fields)
                    {
                        var declarationReference = field.DeclaringSyntaxReferences.FirstOrDefault();
                        var fieldSyntax = declarationReference?.GetSyntax() as VariableDeclaratorSyntax;
                        if (fieldSyntax == null)
                        {
                            continue;
                        }

                        c.ReportDiagnosticIfNonGenerated(
                            Diagnostic.Create(Rule, fieldSyntax.Identifier.GetLocation(), fieldSyntax.Identifier.ValueText),
                            c.Compilation);
                    }
                });
            });
        }
コード例 #30
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                analysisContext =>
                {
                    var disposeMethod = GetDisposeMethod(analysisContext.Compilation);
                    if (disposeMethod == null)
                    {
                        return;
                    }

                    var disposeMethodsCalledFromDispose = MultiValueDictionary<INamedTypeSymbol, IMethodSymbol>.Create<HashSet<IMethodSymbol>>();
                    var implementingDisposeMethods = ImmutableHashSet<IMethodSymbol>.Empty;
                    var allDisposeMethods = ImmutableHashSet<IMethodSymbol>.Empty;

                    analysisContext.RegisterSymbolAction(c =>
                        CollectDisposeMethods(c, disposeMethod, ref allDisposeMethods, ref implementingDisposeMethods),
                        SymbolKind.Method);

                    analysisContext.RegisterCodeBlockStartAction<SyntaxKind>(
                        cbc =>
                        {
                            var methodDeclaration = cbc.CodeBlock as MethodDeclarationSyntax;
                            if (methodDeclaration == null ||
                                methodDeclaration.Identifier.ValueText != DisposeMethodName)
                            {
                                return;
                            }

                            var declaredMethodSymbol = cbc.SemanticModel.GetDeclaredSymbol(methodDeclaration);
                            if (declaredMethodSymbol == null ||
                                !MethodIsDisposeImplementation(declaredMethodSymbol, disposeMethod))
                            {
                                return;
                            }

                            var disposableType = declaredMethodSymbol.ContainingType;
                            cbc.RegisterSyntaxNodeAction(
                                c => CollectDisposeMethodsCalledFromDispose((InvocationExpressionSyntax) c.Node,
                                    c.SemanticModel, disposableType, disposeMethodsCalledFromDispose),
                                SyntaxKind.InvocationExpression);
                        });

                    analysisContext.RegisterCompilationEndAction(
                        c =>
                            ReportDisposeMethods(allDisposeMethods, implementingDisposeMethods,
                                disposeMethodsCalledFromDispose, c));
                });
        }
コード例 #31
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                c =>
            {
                // Collect potentially removable internal types from the project to evaluate when
                // the compilation is over, depending on whether InternalsVisibleTo attribute is present
                // or not.
                var removableInternalTypes = new ConcurrentBag <ISymbol>();
                // Collect here all named types from the project to look for internal member usages.
                var allNamedTypes = new ConcurrentBag <INamedTypeSymbol>();

                c.RegisterSymbolAction(
                    cc =>
                {
                    var namedType = (INamedTypeSymbol)cc.Symbol;
                    if (!namedType.IsClassOrStruct() ||
                        namedType.ContainingType != null ||
                        namedType.DerivesFromAny(IgnoredTypes))
                    {
                        return;
                    }

                    // Collect all symbols to try to look for used internal members when the compilation ends
                    allNamedTypes.Add(namedType);

                    // Collect symbols of private members that could potentially be removed
                    var removableSymbolsCollector = new RemovableSymbolCollector(c.Compilation.GetSemanticModel);

                    VisitDeclaringReferences(namedType, removableSymbolsCollector);

                    // Keep the removable internal types for when the compilation ends
                    foreach (var internalSymbol in removableSymbolsCollector.InternalSymbols.OfType <INamedTypeSymbol>())
                    {
                        removableInternalTypes.Add(internalSymbol);
                    }

                    var usageCollector = new SymbolUsageCollector(
                        c.Compilation.GetSemanticModel,
                        removableSymbolsCollector.PrivateSymbols.Select(s => s.Name).ToHashSet());

                    VisitDeclaringReferences(namedType, usageCollector);

                    var diagnostics = GetDiagnostics(usageCollector, removableSymbolsCollector.PrivateSymbols, "private",
                                                     removableSymbolsCollector.FieldLikeSymbols);
                    foreach (var diagnostic in diagnostics)
                    {
                        cc.ReportDiagnosticIfNonGenerated(diagnostic, cc.Compilation);
                    }
                },
                    SymbolKind.NamedType);

                c.RegisterCompilationEndAction(
                    cc =>
                {
                    var foundInternalsVisibleTo = cc.Compilation.Assembly
                                                  .GetAttributes(KnownType.System_Runtime_CompilerServices_InternalsVisibleToAttribute)
                                                  .Any();

                    if (foundInternalsVisibleTo ||
                        removableInternalTypes.Count == 0)
                    {
                        return;
                    }

                    var usageCollector = new SymbolUsageCollector(
                        c.Compilation.GetSemanticModel,
                        removableInternalTypes.Select(s => s.Name).ToHashSet());

                    foreach (var symbol in allNamedTypes)
                    {
                        VisitDeclaringReferences(symbol, usageCollector);
                    }

                    var diagnostics = GetDiagnostics(usageCollector, removableInternalTypes.ToHashSet(), "internal",
                                                     new BidirectionalDictionary <ISymbol, SyntaxNode>());
                    foreach (var diagnostic in diagnostics)
                    {
                        cc.ReportDiagnosticIfNonGenerated(diagnostic, cc.Compilation);
                    }
                });
            });
        }
コード例 #32
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                compilationStartContext =>
                {
                    var allNamedTypeSymbols = compilationStartContext.Compilation.GlobalNamespace.GetAllNamedTypes();
                    var typeInterfaceMappings = allNamedTypeSymbols.Select(type =>
                        new
                        {
                            Type = type.OriginalDefinition,
                            Interfaces = type.OriginalDefinition.AllInterfaces.Select(i => i.OriginalDefinition)
                        });

                    var interfaceImplementerMappings = new Dictionary<INamedTypeSymbol, HashSet<INamedTypeSymbol>>();
                    foreach (var typeInterfaceMapping in typeInterfaceMappings)
                    {
                        if (typeInterfaceMapping.Type.IsInterface())
                        {
                            if (!interfaceImplementerMappings.ContainsKey(typeInterfaceMapping.Type))
                            {
                                interfaceImplementerMappings.Add(typeInterfaceMapping.Type, new HashSet<INamedTypeSymbol>());
                            }

                            interfaceImplementerMappings[typeInterfaceMapping.Type].Add(typeInterfaceMapping.Type);
                        }

                        foreach (var @interface in typeInterfaceMapping.Interfaces)
                        {
                            if (!interfaceImplementerMappings.ContainsKey(@interface))
                            {
                                interfaceImplementerMappings.Add(@interface, new HashSet<INamedTypeSymbol>());
                            }

                            interfaceImplementerMappings[@interface].Add(typeInterfaceMapping.Type);
                        }
                    }

                    compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                        c =>
                        {
                            var cast = (CastExpressionSyntax)c.Node;
                            var interfaceType = c.SemanticModel.GetTypeInfo(cast.Type).Type as INamedTypeSymbol;
                            var expressionType = c.SemanticModel.GetTypeInfo(cast.Expression).Type as INamedTypeSymbol;

                            CheckTypesForInvalidCast(interfaceType, expressionType, interfaceImplementerMappings,
                                cast.Type.GetLocation(), c);
                        },
                        SyntaxKind.CastExpression);

                    compilationStartContext.RegisterSyntaxNodeAction(
                        c =>
                        {
                            var cast = (BinaryExpressionSyntax)c.Node;
                            var interfaceType = c.SemanticModel.GetTypeInfo(cast.Right).Type as INamedTypeSymbol;
                            var expressionType = c.SemanticModel.GetTypeInfo(cast.Left).Type as INamedTypeSymbol;

                            CheckTypesForInvalidCast(interfaceType, expressionType, interfaceImplementerMappings,
                                cast.Right.GetLocation(), c);
                        },
                        SyntaxKind.AsExpression,
                        SyntaxKind.IsExpression);
                });

            context.RegisterExplodedGraphBasedAnalysis((e, c) => CheckEmptyNullableCast(e, c));
        }
コード例 #33
0
        protected override void Initialize(SonarAnalysisContext context) =>
        context.RegisterCompilationStartAction(
            c =>
        {
            // Collect potentially removable internal types from the project to evaluate when
            // the compilation is over, depending on whether InternalsVisibleTo attribute is present
            // or not.
            var removableInternalTypes = new ConcurrentBag <ISymbol>();

            c.RegisterSymbolAction(
                cc =>
            {
                var namedType = (INamedTypeSymbol)cc.Symbol;

                if (namedType.TypeKind != TypeKind.Struct &&
                    namedType.TypeKind != TypeKind.Class &&
                    namedType.TypeKind != TypeKind.Delegate &&
                    namedType.TypeKind != TypeKind.Enum &&
                    namedType.TypeKind != TypeKind.Interface)
                {
                    return;
                }

                if (namedType.ContainingType != null || namedType.DerivesFromAny(IgnoredTypes))
                {
                    return;
                }

                // Collect symbols of private members that could potentially be removed
                var removableSymbolsCollector = new CSharpRemovableSymbolWalker(c.Compilation.GetSemanticModel);
                if (!VisitDeclaringReferences(namedType, removableSymbolsCollector, c.Compilation, includeGeneratedFile: false))
                {
                    return;
                }

                // Keep the removable internal types for when the compilation ends
                foreach (var internalSymbol in removableSymbolsCollector.InternalSymbols.OfType <INamedTypeSymbol>())
                {
                    removableInternalTypes.Add(internalSymbol);
                }

                var usageCollector = new CSharpSymbolUsageCollector(c.Compilation, removableSymbolsCollector.PrivateSymbols);
                if (!VisitDeclaringReferences(namedType, usageCollector, c.Compilation, includeGeneratedFile: true))
                {
                    return;
                }

                var diagnostics = GetDiagnosticsForUnusedPrivateMembers(usageCollector, removableSymbolsCollector.PrivateSymbols, "private", removableSymbolsCollector.FieldLikeSymbols)
                                  .Concat(GetDiagnosticsForUsedButUnreadFields(usageCollector, removableSymbolsCollector.PrivateSymbols));
                foreach (var diagnostic in diagnostics)
                {
                    cc.ReportDiagnosticIfNonGenerated(diagnostic, cc.Compilation);
                }
            },
                SymbolKind.NamedType);

            c.RegisterCompilationEndAction(
                cc =>
            {
                var foundInternalsVisibleTo = cc.Compilation.Assembly.HasAttribute(KnownType.System_Runtime_CompilerServices_InternalsVisibleToAttribute);
                if (foundInternalsVisibleTo || removableInternalTypes.Count == 0)
                {
                    return;
                }

                var usageCollector = new CSharpSymbolUsageCollector(c.Compilation, removableInternalTypes.ToHashSet());
                foreach (var syntaxTree in c.Compilation.SyntaxTrees.Where(tree => !tree.IsGenerated(CSharpGeneratedCodeRecognizer.Instance, c.Compilation)))
                {
                    usageCollector.SafeVisit(syntaxTree.GetRoot());
                }

                var diagnostics = GetDiagnosticsForUnusedPrivateMembers(usageCollector, removableInternalTypes.ToHashSet(), "internal", new BidirectionalDictionary <ISymbol, SyntaxNode>());
                foreach (var diagnostic in diagnostics)
                {
                    cc.ReportDiagnosticIfNonGenerated(diagnostic, cc.Compilation);
                }
            });
        });
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                compilationStartContext =>
                {
                    var allNamedTypeSymbols = compilationStartContext.Compilation.GlobalNamespace.GetAllNamedTypes();
                    var allInterfacesWithImplementationsOverridenEquals =
                        allNamedTypeSymbols
                            .Where(t => t.AllInterfaces.Any() && HasEqualsOverride(t))
                            .SelectMany(t => t.AllInterfaces)
                            .ToImmutableHashSet();

                    compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                        c =>
                        {
                            var binary = (BinaryExpressionSyntax)c.Node;
                            if (!IsBinaryCandidateForReporting(binary, c.SemanticModel))
                            {
                                return;
                            }

                            var typeLeft = c.SemanticModel.GetTypeInfo(binary.Left).Type;
                            var typeRight = c.SemanticModel.GetTypeInfo(binary.Right).Type;
                            if (typeLeft == null ||
                                typeRight == null ||
                                IsAllowedType(typeLeft) ||
                                IsAllowedType(typeRight))
                            {
                                return;
                            }

                            if (MightOverrideEquals(typeLeft, allInterfacesWithImplementationsOverridenEquals) ||
                                MightOverrideEquals(typeRight, allInterfacesWithImplementationsOverridenEquals))
                            {
                                c.ReportDiagnostic(Diagnostic.Create(Rule, binary.OperatorToken.GetLocation()));
                            }
                        },
                        SyntaxKind.EqualsExpression,
                        SyntaxKind.NotEqualsExpression);
                });
        }
コード例 #35
0
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterCompilationStartAction(
                compilationStartContext =>
            {
                var symbolsWhereTypeIsCreated =
                    new ConcurrentBag <SyntaxNodeWithSymbol <ObjectCreationExpressionSyntax, ISymbol> >();
                var symbolsWhereLocaleIsSet = new ConcurrentBag <ISymbol>();

                compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var objectCreation = (ObjectCreationExpressionSyntax)c.Node;
                    var objectType     = c.SemanticModel.GetSymbolInfo(objectCreation.Type).Symbol as ITypeSymbol;

                    if (objectType == null ||
                        !objectType.IsAny(checkedTypes))
                    {
                        return;
                    }

                    var variableSyntax = GetAssignmentTargetVariable(objectCreation);
                    if (variableSyntax == null)
                    {
                        return;
                    }

                    var variableSymbol = variableSyntax is IdentifierNameSyntax
                                ? c.SemanticModel.GetSymbolInfo(variableSyntax).Symbol
                                : c.SemanticModel.GetDeclaredSymbol(variableSyntax);
                    if (variableSymbol != null)
                    {
                        symbolsWhereTypeIsCreated.Add(variableSymbol.ToSymbolWithSyntax(objectCreation));
                    }
                }, SyntaxKind.ObjectCreationExpression);

                compilationStartContext.RegisterSyntaxNodeActionInNonGenerated(
                    c =>
                {
                    var assignmentExpression = (AssignmentExpressionSyntax)c.Node;
                    var propertySymbol       = GetPropertySymbol(assignmentExpression, c.SemanticModel);

                    if (propertySymbol != null &&
                        propertySymbol.ContainingType.IsAny(checkedTypes) &&
                        propertySymbol.Name == "Locale")
                    {
                        var variableSymbol = GetAccessedVariable(assignmentExpression, c.SemanticModel);
                        if (variableSymbol != null)
                        {
                            symbolsWhereLocaleIsSet.Add(variableSymbol);
                        }
                    }
                }, SyntaxKind.SimpleAssignmentExpression);

                compilationStartContext.RegisterCompilationEndAction(
                    c =>
                {
                    var invalidDataTypeCreation = symbolsWhereTypeIsCreated
                                                  .Where(x => !symbolsWhereLocaleIsSet.Contains(x.Symbol));

                    foreach (var invalidCreation in invalidDataTypeCreation)
                    {
                        var typeName = invalidCreation.Symbol.GetSymbolType()?.Name;
                        if (typeName == null)
                        {
                            continue;
                        }

                        c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, invalidCreation.Syntax.GetLocation(),
                                                                       typeName));
                    }
                });
            });
        }