protected override void Initialize(SonarAnalysisContext context) { context.RegisterSyntaxNodeActionInNonGenerated( c => { var lessThan = (BinaryExpressionSyntax)c.Node; if (ExpressionNumericConverter.TryGetConstantIntValue(lessThan.Left, out var constValue) && constValue == 0 && IsIndexOfCall(lessThan.Right, c.SemanticModel)) { c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, Location.Create(lessThan.SyntaxTree, TextSpan.FromBounds(lessThan.Left.SpanStart, lessThan.OperatorToken.Span.End)))); } }, SyntaxKind.LessThanExpression); context.RegisterSyntaxNodeActionInNonGenerated( c => { var greaterThan = (BinaryExpressionSyntax)c.Node; if (ExpressionNumericConverter.TryGetConstantIntValue(greaterThan.Right, out var constValue) && constValue == 0 && IsIndexOfCall(greaterThan.Left, c.SemanticModel)) { c.ReportDiagnosticWhenActive(Diagnostic.Create(rule, Location.Create(greaterThan.SyntaxTree, TextSpan.FromBounds(greaterThan.OperatorToken.SpanStart, greaterThan.Right.Span.End)))); } }, SyntaxKind.GreaterThanExpression); }
private static bool CheckExpression(ExpressionSyntax constant, ExpressionSyntax modulus, SemanticModel semanticModel, out int constantValue) { return(ExpressionNumericConverter.TryGetConstantIntValue(constant, out constantValue) && constantValue != 0 && ExpressionIsModulus(modulus) && !ExpressionIsNonNegative(modulus, semanticModel)); }
private static void CheckCountOne(ExpressionSyntax one, ExpressionSyntax count, SyntaxNodeAnalysisContext context) { if (ExpressionNumericConverter.TryGetConstantIntValue(one, out var value) && value == 1 && TryGetCountCall(count, context.SemanticModel, out var reportLocation, out var typeArgument)) { context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, reportLocation, typeArgument)); } }
private static void CheckCountZero(ExpressionSyntax zero, ExpressionSyntax count, SyntaxNodeAnalysisContext context) { Location reportLocation; string typeArgument; int value; if (ExpressionNumericConverter.TryGetConstantIntValue(zero, out value) && value == 0 && TryGetCountCall(count, context.SemanticModel, out reportLocation, out typeArgument)) { context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, reportLocation, typeArgument)); } }
private static void CheckCountOne(ExpressionSyntax one, ExpressionSyntax count, SyntaxNodeAnalysisContext c) { Location reportLocation; string typeArgument; int value; if (ExpressionNumericConverter.TryGetConstantIntValue(one, out value) && value == 1 && TryGetCountCall(count, c.SemanticModel, out reportLocation, out typeArgument)) { c.ReportDiagnostic(Diagnostic.Create(Rule, reportLocation, typeArgument)); } }
/// <summary> /// We try to retrieve the integer value of an expression. If the expression is an integer literal, we return its value, otherwise if /// the expression is an identifier, we attempt to retrieve the integer value the variable was initialized with if it exists. /// </summary> /// <param name="variableNameToIntegerValue">A dictionary mapping variable names to the integer value they were initialized with if it exists</param> /// <param name="expression">The expression for which we want to retrieve the integer value</param> /// <param name="intValue">The output parameter that will hold the integer value if it is found</param> /// <returns>true if an integer value was found for the expression, false otherwise</returns> private static bool GetIntValue(IDictionary <string, int> variableNameToIntegerValue, ExpressionSyntax expression, out int intValue) { if (ExpressionNumericConverter.TryGetConstantIntValue(expression, out intValue) || ( expression is SimpleNameSyntax simpleName && variableNameToIntegerValue.TryGetValue(simpleName.Identifier.ValueText, out intValue) )) { return(true); } intValue = default(int); return(false); }
private static void CheckAssignment(SyntaxNodeAnalysisContext context, int constValueToLookFor) { var assignment = (AssignmentExpressionSyntax)context.Node; if (ExpressionNumericConverter.TryGetConstantIntValue(assignment.Right, out var constValue) && constValue == constValueToLookFor) { var location = assignment.Parent is StatementSyntax ? assignment.Parent.GetLocation() : GetReportLocation(assignment.OperatorToken.Span, assignment.Right.Span, assignment.SyntaxTree); context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location)); } }
/// <summary> /// Retrieves the mapping of variable names to their integer value from the variable declaration part of a for loop. /// This will find the mapping for such cases: /// <code> /// for (var i = 0;;) {} /// </code> /// </summary> private static IDictionary <string, int> GetVariableDeclarationMapping(VariableDeclarationSyntax variableDeclarationSyntax) { var loopInitializerValues = new Dictionary <string, int>(); if (variableDeclarationSyntax != null) { foreach (var variableDeclaration in variableDeclarationSyntax.Variables) { if (variableDeclaration.Initializer is EqualsValueClauseSyntax initializer && ExpressionNumericConverter.TryGetConstantIntValue(initializer.Value, out var intValue)) { loopInitializerValues.Add(variableDeclaration.Identifier.ValueText, intValue); } } } return(loopInitializerValues); }
/// <summary> /// Retrieves the mapping of variable names to their integer value from the initializer part of a for loop. /// This will find the mapping for such cases: /// <code> /// int i; /// for (i = 0;;) {} /// </code> /// </summary> private static IDictionary <string, int> GetLoopInitializerMapping(IEnumerable <ExpressionSyntax> initializers) { var loopInitializerValues = new Dictionary <string, int>(); if (initializers != null) { foreach (var initializer in initializers) { if (initializer.IsKind(SyntaxKind.SimpleAssignmentExpression) && initializer is AssignmentExpressionSyntax assignment && assignment.Left is SimpleNameSyntax simpleName && ExpressionNumericConverter.TryGetConstantIntValue(assignment.Right, out var intValue)) { loopInitializerValues.Add(simpleName.Identifier.ValueText, intValue); } } } return(loopInitializerValues); }
private static void CheckBinary(SyntaxNodeAnalysisContext context, int constValueToLookFor) { var binary = (BinaryExpressionSyntax)context.Node; if (ExpressionNumericConverter.TryGetConstantIntValue(binary.Left, out var constValue) && constValue == constValueToLookFor) { var location = GetReportLocation(binary.Left.Span, binary.OperatorToken.Span, binary.SyntaxTree); context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location, ImmutableDictionary <string, string> .Empty.Add(IsReportingOnLeftKey, true.ToString()))); return; } if (ExpressionNumericConverter.TryGetConstantIntValue(binary.Right, out constValue) && constValue == constValueToLookFor) { var location = GetReportLocation(binary.OperatorToken.Span, binary.Right.Span, binary.SyntaxTree); context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, location, ImmutableDictionary <string, string> .Empty.Add(IsReportingOnLeftKey, false.ToString()))); } }
public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeActionInNonGenerated( c => { var expression = (BinaryExpressionSyntax)c.Node; int value; if (expression.IsKind(SyntaxKind.LeftShiftExpression) && ExpressionNumericConverter.TryGetConstantIntValue(expression.Right, out value) && value == 1) { return; } if (EquivalenceChecker.AreEquivalent(expression.Left, expression.Right)) { c.ReportDiagnostic(Diagnostic.Create(Rule, c.Node.GetLocation(), expression.OperatorToken)); } }, SyntaxElementsToCheck); }
private static bool CheckValueTypeDefaultValueInitializer(EqualsValueClauseSyntax initializer, ITypeSymbol type) { if (!type.IsValueType) { return(false); } switch (type.SpecialType) { case SpecialType.System_Boolean: return(EquivalenceChecker.AreEquivalent(initializer.Value, SyntaxHelper.FalseLiteralExpression)); case SpecialType.System_Decimal: case SpecialType.System_Double: case SpecialType.System_Single: { double constantValue; return(ExpressionNumericConverter.TryGetConstantDoubleValue(initializer.Value, out constantValue) && Math.Abs(constantValue - default(double)) < double.Epsilon); } case SpecialType.System_Char: case SpecialType.System_Byte: case SpecialType.System_Int16: case SpecialType.System_Int32: case SpecialType.System_Int64: case SpecialType.System_SByte: case SpecialType.System_UInt16: case SpecialType.System_UInt32: case SpecialType.System_UInt64: { int constantValue; return(ExpressionNumericConverter.TryGetConstantIntValue(initializer.Value, out constantValue) && constantValue == default(int)); } default: return(false); } }
private static bool CheckValueTypeDefaultValueInitializer(VariableDeclaratorSyntax variable, IFieldSymbol variableSymbol) { if (!variableSymbol.Type.IsValueType) { return(false); } switch (variableSymbol.Type.SpecialType) { case SpecialType.System_Boolean: return(EquivalenceChecker.AreEquivalent(variable.Initializer.Value, FalseExpression)); case SpecialType.System_Decimal: case SpecialType.System_Double: case SpecialType.System_Single: { double constantValue; return(ExpressionNumericConverter.TryGetConstantDoubleValue(variable.Initializer.Value, out constantValue) && Math.Abs(constantValue - default(double)) < double.Epsilon); } case SpecialType.System_Char: case SpecialType.System_Byte: case SpecialType.System_Int16: case SpecialType.System_Int32: case SpecialType.System_Int64: case SpecialType.System_SByte: case SpecialType.System_UInt16: case SpecialType.System_UInt32: case SpecialType.System_UInt64: { int constantValue; return(ExpressionNumericConverter.TryGetConstantIntValue(variable.Initializer.Value, out constantValue) && constantValue == default(int)); } default: return(false); } }