protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>(cbc => { var unusedLocals = new List <ISymbol>(); cbc.RegisterSyntaxNodeAction(c => { unusedLocals.AddRange( ((LocalDeclarationStatementSyntax)c.Node).Declaration.Variables .Select(variable => c.SemanticModel.GetDeclaredSymbol(variable)) .Where(symbol => symbol != null)); }, SyntaxKind.LocalDeclarationStatement); cbc.RegisterSyntaxNodeAction(c => { var symbolsToNotReportOn = GetUsedSymbols(c.Node, c.SemanticModel); foreach (var symbol in symbolsToNotReportOn) { unusedLocals.Remove(symbol); } }, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction(c => { foreach (var unused in unusedLocals) { c.ReportDiagnostic(Diagnostic.Create(Rule, unused.Locations.First(), unused.Name)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cbc => { var methodDeclaration = cbc.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null || methodDeclaration.Identifier.Text != "ToString") { return; } cbc.RegisterSyntaxNodeAction(c => { var returnStatement = (ReturnStatementSyntax)c.Node; var nullExpression = returnStatement.Expression as LiteralExpressionSyntax; if (nullExpression != null && nullExpression.IsKind(SyntaxKind.NullLiteralExpression)) { c.ReportDiagnostic(Diagnostic.Create(Rule, returnStatement.GetLocation())); } }, SyntaxKind.ReturnStatement); }); }
protected sealed override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cb => { var methodDeclaration = cb.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null) { return; } var methodSymbol = cb.OwningSymbol as IMethodSymbol; if (methodSymbol == null || !GetHashCodeEqualsOverride.MethodIsRelevant(methodSymbol, MethodNames)) { return; } cb.RegisterSyntaxNodeAction( c => { CheckInvocationInsideMethod(c, methodSymbol); }, SyntaxKind.InvocationExpression); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cb => { var methodDeclaration = cb.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null) { return; } var methodSymbol = cb.OwningSymbol as IMethodSymbol; if (methodSymbol == null || !GetHashCodeEqualsOverride.MethodIsRelevant(methodSymbol, MethodNames)) { return; } cb.RegisterSyntaxNodeAction( c => { CheckInvocationInsideMethod(c, methodSymbol); }, SyntaxKind.InvocationExpression); }); }
protected sealed override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>(cbc => { var declaredLocals = new HashSet <ISymbol>(); var usedLocals = new HashSet <ISymbol>(); cbc.RegisterSyntaxNodeAction(c => { declaredLocals.UnionWith( ((LocalDeclarationStatementSyntax)c.Node).Declaration.Variables .Select(variable => c.SemanticModel.GetDeclaredSymbol(variable)) .Where(symbol => symbol != null)); }, SyntaxKind.LocalDeclarationStatement); cbc.RegisterSyntaxNodeAction(c => { usedLocals.UnionWith(GetUsedSymbols(c.Node, c.SemanticModel)); }, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction(c => { declaredLocals.ExceptWith(usedLocals); foreach (var unused in declaredLocals) { c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, unused.Locations.First(), unused.Name)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cbc => { var methodDeclaration = cbc.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null || methodDeclaration.Identifier.Text != "ToString") { return; } cbc.RegisterSyntaxNodeAction(c => { var returnStatement = (ReturnStatementSyntax)c.Node; var nullExpression = returnStatement.Expression as LiteralExpressionSyntax; if (nullExpression != null && nullExpression.IsKind(SyntaxKind.NullLiteralExpression)) { c.ReportDiagnostic(Diagnostic.Create(Rule, returnStatement.GetLocation())); } }, SyntaxKind.ReturnStatement); }); }
protected sealed override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cbc => { if (cbc.SemanticModel.Compilation.IsTest()) { return; } var accessorDeclaration = cbc.CodeBlock as AccessorDeclarationSyntax; if (accessorDeclaration == null || accessorDeclaration.IsKind(SyntaxKind.GetAccessorDeclaration) || accessorDeclaration.Body == null) { return; } if (accessorDeclaration.Body.Statements.Count == 1 && accessorDeclaration.Body.Statements[0] is ThrowStatementSyntax) { return; } var interfaceMember = cbc.SemanticModel.GetDeclaredSymbol(accessorDeclaration) .GetInterfaceMember(); if (interfaceMember != null && accessorDeclaration.Body.Statements.Count == 0) { return; } var foundValueReference = false; cbc.RegisterSyntaxNodeAction( c => { var identifier = (IdentifierNameSyntax)c.Node; var parameter = c.SemanticModel.GetSymbolInfo(identifier).Symbol as IParameterSymbol; if (identifier.Identifier.ValueText == "value" && parameter != null && parameter.IsImplicitlyDeclared) { foundValueReference = true; } }, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction( c => { if (!foundValueReference) { var accessorType = GetAccessorType(accessorDeclaration); c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, accessorDeclaration.Keyword.GetLocation(), accessorType)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) => context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>(cbc => { var collector = new UnusedLocalsCollector(); cbc.RegisterSyntaxNodeAction(collector.CollectDeclarations, SyntaxKind.LocalDeclarationStatement); cbc.RegisterSyntaxNodeAction(collector.CollectUsages, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction(collector.GetReportUnusedVariablesAction(rule)); });
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cbc => { if (!IsInstanceConstructor(cbc.CodeBlock)) { return; } cbc.RegisterSyntaxNodeAction( c => { var invocation = (InvocationExpressionSyntax)c.Node; if (invocation.ArgumentList == null) { return; } var thisExpression = invocation.ArgumentList.Arguments .Select(a => a.Expression) .FirstOrDefault(IsThisExpression); if (thisExpression != null && !IsClassMember(invocation.Expression) && c.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol is IMethodSymbol) { c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, thisExpression.GetLocation())); } }, SyntaxKind.InvocationExpression); cbc.RegisterSyntaxNodeAction( c => { var assignment = (AssignmentExpressionSyntax)c.Node; var right = assignment.Right.RemoveParentheses(); if (IsThisExpression(right) && !IsClassMember(assignment.Left) && c.SemanticModel.GetSymbolInfo(assignment.Left).Symbol is IPropertySymbol) { c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, right.GetLocation())); } }, SyntaxKind.SimpleAssignmentExpression); }); }
protected sealed override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cb => { var methodDeclaration = cb.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null) { return; } var methodSymbol = cb.OwningSymbol as IMethodSymbol; if (methodSymbol == null || !MethodIsRelevant(methodSymbol, MethodNames)) { return; } var locations = new List <Location>(); cb.RegisterSyntaxNodeAction( c => { Location location; if (TryGetLocationFromInvocationInsideMethod(c, methodSymbol, out location)) { locations.Add(location); } }, SyntaxKind.InvocationExpression); cb.RegisterCodeBlockEndAction( c => { if (!locations.Any()) { return; } var firstPosition = locations.Select(loc => loc.SourceSpan.Start).Min(); var location = locations.First(loc => loc.SourceSpan.Start == firstPosition); c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location, methodSymbol.Name)); }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cbc => { SyntaxNode declaration = cbc.CodeBlock as MethodDeclarationSyntax; var declarationType = "method"; if (declaration == null) { declaration = cbc.CodeBlock as AccessorDeclarationSyntax; declarationType = "property"; if (declaration == null) { return; } } var methodOrPropertySymbol = cbc.OwningSymbol; if (methodOrPropertySymbol == null || methodOrPropertySymbol.IsStatic) { return; } var locationsForFields = new Dictionary<IFieldSymbol, List<Location>>(); cbc.RegisterSyntaxNodeAction( c => { var assignment = (AssignmentExpressionSyntax)c.Node; var expression = assignment.Left; var fieldSymbol = c.SemanticModel.GetSymbolInfo(expression).Symbol as IFieldSymbol; if (IsStatic(fieldSymbol)) { var location = Location.Create(expression.SyntaxTree, new TextSpan(expression.SpanStart, assignment.OperatorToken.Span.End - expression.SpanStart)); AddFieldLocation(fieldSymbol, location, locationsForFields); } }, SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.SubtractAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PrefixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PostfixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression); cbc.RegisterCodeBlockEndAction( c => { var messageFormat = methodOrPropertySymbol.IsChangeable() ? MessageFormatMultipleOptions : MessageFormatRemoveSet; var message = string.Format(messageFormat, declarationType); foreach (var locations in locationsForFields.Values) { var firstPosition = locations.Select(loc => loc.SourceSpan.Start).Min(); var location = locations.First(loc => loc.SourceSpan.Start == firstPosition); c.ReportDiagnostic(Diagnostic.Create(Rule, location, message)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cbc => { if (cbc.SemanticModel.Compilation.IsTest()) { return; } var accessorDeclaration = cbc.CodeBlock as AccessorDeclarationSyntax; if (accessorDeclaration == null || accessorDeclaration.IsKind(SyntaxKind.GetAccessorDeclaration)) { return; } if (accessorDeclaration.Body.Statements.Count == 1 && accessorDeclaration.Body.Statements.Single() is ThrowStatementSyntax) { return; } var foundValueReference = false; cbc.RegisterSyntaxNodeAction( c => { var identifier = (IdentifierNameSyntax)c.Node; var parameter = c.SemanticModel.GetSymbolInfo(identifier).Symbol as IParameterSymbol; if (identifier.Identifier.ValueText == "value" && parameter != null && parameter.IsImplicitlyDeclared) { foundValueReference = true; } }, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction( c => { if (!foundValueReference) { var accessorType = GetAccessorType(accessorDeclaration); c.ReportDiagnostic(Diagnostic.Create(Rule, accessorDeclaration.Keyword.GetLocation(), accessorType)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>(cbc => { var unusedLocals = new List<ISymbol>(); cbc.RegisterSyntaxNodeAction(c => { unusedLocals.AddRange( ((LocalDeclarationStatementSyntax) c.Node).Declaration.Variables .Select(variable => c.SemanticModel.GetDeclaredSymbol(variable)) .Where(symbol => symbol != null)); }, SyntaxKind.LocalDeclarationStatement); cbc.RegisterSyntaxNodeAction(c => { var symbolsToNotReportOn = GetUsedSymbols(c.Node, c.SemanticModel); foreach (var symbol in symbolsToNotReportOn) { unusedLocals.Remove(symbol); } }, SyntaxKind.IdentifierName); cbc.RegisterCodeBlockEndAction(c => { foreach (var unused in unusedLocals) { c.ReportDiagnostic(Diagnostic.Create(Rule, unused.Locations.First(), unused.Name)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cbc => { SyntaxNode declaration = cbc.CodeBlock as MethodDeclarationSyntax; var declarationType = "method"; if (declaration == null) { declaration = cbc.CodeBlock as AccessorDeclarationSyntax; declarationType = "property"; if (declaration == null) { return; } } var methodOrPropertySymbol = cbc.OwningSymbol; if (methodOrPropertySymbol == null || methodOrPropertySymbol.IsStatic) { return; } var messageFormat = methodOrPropertySymbol.IsChangeable() ? MessageFormatMultipleOptions : MessageFormatRemoveSet; cbc.RegisterSyntaxNodeAction( c => { var assignment = (AssignmentExpressionSyntax)c.Node; var expression = assignment.Left; if (IsStaticFieldModification(expression, c.SemanticModel)) { var location = Location.Create(expression.SyntaxTree, new TextSpan(expression.SpanStart, assignment.OperatorToken.Span.End - expression.SpanStart)); var message = string.Format(messageFormat, declarationType); c.ReportDiagnostic(Diagnostic.Create(Rule, location, message)); } }, SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.SubtractAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PrefixUnaryExpressionSyntax)c.Node; var expression = unary.Operand; if (IsStaticFieldModification(expression, c.SemanticModel)) { var message = string.Format(messageFormat, declarationType); c.ReportDiagnostic(Diagnostic.Create(Rule, expression.GetLocation(), message)); } }, SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PostfixUnaryExpressionSyntax)c.Node; var expression = unary.Operand; if (IsStaticFieldModification(expression, c.SemanticModel)) { var message = string.Format(messageFormat, declarationType); c.ReportDiagnostic(Diagnostic.Create(Rule, expression.GetLocation(), message)); } }, SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression); }); }
protected sealed override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cbc => { if (!IsValidCodeBlockContext(cbc.CodeBlock, cbc.OwningSymbol)) { return; } var locationsForFields = new Dictionary <IFieldSymbol, List <Location> >(); cbc.RegisterSyntaxNodeAction( c => { var assignment = (AssignmentExpressionSyntax)c.Node; var expression = assignment.Left; var fieldSymbol = c.SemanticModel.GetSymbolInfo(expression).Symbol as IFieldSymbol; if (IsStatic(fieldSymbol)) { var location = Location.Create(expression.SyntaxTree, new TextSpan(expression.SpanStart, assignment.OperatorToken.Span.End - expression.SpanStart)); AddFieldLocation(fieldSymbol, location, locationsForFields); } }, SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.SubtractAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PrefixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PostfixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression); cbc.RegisterCodeBlockEndAction(c => { foreach (var fieldWithLocations in locationsForFields) { var firstPosition = fieldWithLocations.Value.Select(loc => loc.SourceSpan.Start).Min(); var location = fieldWithLocations.Value.First(loc => loc.SourceSpan.Start == firstPosition); var message = GetDiagnosticMessageArgument(cbc.CodeBlock, cbc.OwningSymbol, fieldWithLocations.Key); var secondaryLocations = fieldWithLocations.Key.DeclaringSyntaxReferences .Select(x => x.GetSyntax().GetLocation()); c.ReportDiagnostic(Diagnostic.Create(Rule, location, additionalLocations: secondaryLocations, messageArgs: message)); } }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated<SyntaxKind>( cb => { var methodDeclaration = cb.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null) { return; } var methodSymbol = cb.OwningSymbol as IMethodSymbol; if (methodSymbol == null || !MethodIsRelevant(methodSymbol, MethodNames)) { return; } var locations = new List<Location>(); cb.RegisterSyntaxNodeAction( c => { Location location; if (TryGetLocationFromInvocationInsideMethod(c, methodSymbol, out location)) { locations.Add(location); } }, SyntaxKind.InvocationExpression); cb.RegisterCodeBlockEndAction( c => { if (!locations.Any()) { return; } var firstPosition = locations.Select(loc => loc.SourceSpan.Start).Min(); var location = locations.First(loc => loc.SourceSpan.Start == firstPosition); c.ReportDiagnostic(Diagnostic.Create(Rule, location, methodSymbol.Name)); }); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCodeBlockStartActionInNonGenerated <SyntaxKind>( cbc => { SyntaxNode declaration = cbc.CodeBlock as MethodDeclarationSyntax; var declarationType = "method"; if (declaration == null) { declaration = cbc.CodeBlock as AccessorDeclarationSyntax; declarationType = "property"; if (declaration == null) { return; } } var methodOrPropertySymbol = cbc.OwningSymbol; if (methodOrPropertySymbol == null || methodOrPropertySymbol.IsStatic) { return; } var locationsForFields = new Dictionary <IFieldSymbol, List <Location> >(); cbc.RegisterSyntaxNodeAction( c => { var assignment = (AssignmentExpressionSyntax)c.Node; var expression = assignment.Left; var fieldSymbol = c.SemanticModel.GetSymbolInfo(expression).Symbol as IFieldSymbol; if (IsStatic(fieldSymbol)) { var location = Location.Create(expression.SyntaxTree, new TextSpan(expression.SpanStart, assignment.OperatorToken.Span.End - expression.SpanStart)); AddFieldLocation(fieldSymbol, location, locationsForFields); } }, SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.SubtractAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PrefixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); cbc.RegisterSyntaxNodeAction( c => { var unary = (PostfixUnaryExpressionSyntax)c.Node; CollectLocationOfStaticField(unary.Operand, locationsForFields, c); }, SyntaxKind.PostDecrementExpression, SyntaxKind.PostIncrementExpression); cbc.RegisterCodeBlockEndAction( c => { var messageFormat = methodOrPropertySymbol.IsChangeable() ? MessageFormatMultipleOptions : MessageFormatRemoveSet; var message = string.Format(messageFormat, declarationType); foreach (var locations in locationsForFields.Values) { var firstPosition = locations.Select(loc => loc.SourceSpan.Start).Min(); var location = locations.First(loc => loc.SourceSpan.Start == firstPosition); c.ReportDiagnostic(Diagnostic.Create(Rule, location, message)); } }); }); }