private static boolean evaluateCondition(ExpressionTree condition, int leftOperand, int rightOperand) { boolean conditionValue; switch (condition.kind()) { case GREATER_THAN: conditionValue = leftOperand > rightOperand; break; case GREATER_THAN_OR_EQUAL_TO: conditionValue = leftOperand >= rightOperand; break; case LESS_THAN: conditionValue = leftOperand < rightOperand; break; case LESS_THAN_OR_EQUAL_TO: conditionValue = leftOperand <= rightOperand; break; default: conditionValue = true; } return conditionValue; }
private static Optional<Symbol> symbol(ExpressionTree tree) { switch (tree.kind()) { case IDENTIFIER: return Optional.of(((IdentifierTree) tree).symbol()); case MEMBER_SELECT: return Optional.of(((MemberSelectExpressionTree) tree).identifier().symbol()); default: return Optional.empty(); } }
private static Optional<Symbol> symbol(ExpressionTree tree) { switch (tree.kind()) { case IDENTIFIER: return Optional.of(((IdentifierTree) tree).symbol()); case MEMBER_SELECT: return Optional.of(((MemberSelectExpressionTree) tree).identifier().symbol()); default: return Optional.empty(); } }
private boolean isResourceInitialized(VariableTree tree) { return tree.initializer() != null && tree.initializer().kind() != Kind.NULL_LITERAL; }
private boolean isResourceNullCheckOfType(IfStatementTree tree, String ifType) { boolean result = false; if (ifType.equals(tree.condition().kind().name())) { result = isResourceNullCheck(tree); } return result; }
private static boolean isDefault(ExpressionTree expression, boolean isPrimitive) { if(!isPrimitive) { return expression.is(Kind.NULL_LITERAL); } switch (expression.kind()) { case CHAR_LITERAL: String charValue = ((LiteralTree) expression).value(); return "'\\u0000'".equals(charValue) || "'\\0'".equals(charValue); case BOOLEAN_LITERAL: return LiteralUtils.isFalse(expression); case INT_LITERAL: case LONG_LITERAL: Long value = LiteralUtils.longLiteralValue(expression); return value != null && value == 0; case FLOAT_LITERAL: case DOUBLE_LITERAL: return Double.doubleToLongBits(Double.valueOf(((LiteralTree) expression).value())) == 0; default: return false; } }
private static boolean isDefault(ExpressionTree expression, boolean isPrimitive) { if(!isPrimitive) { return expression.is(Kind.NULL_LITERAL); } switch (expression.kind()) { case CHAR_LITERAL: String charValue = ((LiteralTree) expression).value(); return "'\\u0000'".equals(charValue) || "'\\0'".equals(charValue); case BOOLEAN_LITERAL: return LiteralUtils.isFalse(expression); case INT_LITERAL: case LONG_LITERAL: Long value = LiteralUtils.longLiteralValue(expression); return value != null && value == 0; case FLOAT_LITERAL: case DOUBLE_LITERAL: return Double.doubleToLongBits(Double.valueOf(((LiteralTree) expression).value())) == 0; default: return false; } }
@CheckForNull public static IdentifierTree getArgumentIdentifier(MethodInvocationTree mit, int index) { Arguments arguments = mit.arguments(); if (index < 0 || index > arguments.size()) { throw new IllegalArgumentException("index must be within arguments range."); } ExpressionTree expr = ExpressionUtils.skipParentheses(arguments.get(index)); switch (expr.kind()) { case MEMBER_SELECT: return ((MemberSelectExpressionTree) expr).identifier(); case IDENTIFIER: return ((IdentifierTree) expr); default: return null; } }
@CheckForNull public static IdentifierTree getArgumentIdentifier(MethodInvocationTree mit, int index) { Arguments arguments = mit.arguments(); if (index < 0 || index > arguments.size()) { throw new IllegalArgumentException("index must be within arguments range."); } ExpressionTree expr = ExpressionUtils.skipParentheses(arguments.get(index)); switch (expr.kind()) { case MEMBER_SELECT: return ((MemberSelectExpressionTree) expr).identifier(); case IDENTIFIER: return ((IdentifierTree) expr); default: return null; } }
private static boolean isUsualDefaultValue(ExpressionTree tree) { ExpressionTree expr = ExpressionUtils.skipParentheses(tree); switch (expr.kind()) { case BOOLEAN_LITERAL: case NULL_LITERAL: return true; case STRING_LITERAL: return LiteralUtils.isEmptyString(expr); case INT_LITERAL: String value = ((LiteralTree) expr).value(); return "0".equals(value) || "1".equals(value); case UNARY_MINUS: case UNARY_PLUS: return isUsualDefaultValue(((UnaryExpressionTree) expr).expression()); default: return false; } }
private static boolean isUsualDefaultValue(ExpressionTree tree) { ExpressionTree expr = ExpressionUtils.skipParentheses(tree); switch (expr.kind()) { case BOOLEAN_LITERAL: case NULL_LITERAL: return true; case STRING_LITERAL: return LiteralUtils.isEmptyString(expr); case INT_LITERAL: String value = ((LiteralTree) expr).value(); return "0".equals(value) || "1".equals(value); case UNARY_MINUS: case UNARY_PLUS: return isUsualDefaultValue(((UnaryExpressionTree) expr).expression()); default: return false; } }
@CheckForNull private static Tree getAssignedVariable(ExpressionTree expression) { IdentifierTree identifier; switch (expression.kind()) { case ARRAY_ACCESS_EXPRESSION: return getAssignedVariable(((ArrayAccessExpressionTree) expression).expression()); case TYPE_CAST: return getAssignedVariable(((TypeCastTree) expression).expression()); case PARENTHESIZED_EXPRESSION: return getAssignedVariable(((ParenthesizedTree) expression).expression()); case IDENTIFIER: identifier = (IdentifierTree) expression; break; case MEMBER_SELECT: identifier = ((MemberSelectExpressionTree) expression).identifier(); break; default: throw new IllegalStateException("Unexpected expression " + expression.kind().name() + " at: " + ((JavaTree) expression).getLine()); } return identifier.symbol().declaration(); } }
@Override public void visitIfStatement(IfStatementTree tree) { super.visitIfStatement(tree); ExpressionTree condition = tree.condition(); if (condition.is(Tree.Kind.ASSIGNMENT) && EQUALITY_RELATIONAL_OPERATORS.contains(((AssignmentExpressionTree) condition).expression().kind())) { raiseIssue(((AssignmentExpressionTree) condition).operatorToken().line(), tree); } }
@Override public void visitIfStatement(IfStatementTree tree) { super.visitIfStatement(tree); ExpressionTree condition = tree.condition(); if (condition.is(Tree.Kind.ASSIGNMENT) && EQUALITY_RELATIONAL_OPERATORS.contains(((AssignmentExpressionTree) condition).expression().kind())) { raiseIssue(((AssignmentExpressionTree) condition).operatorToken().line(), tree); } }
@Override public void visitIfStatement(IfStatementTree tree) { super.visitIfStatement(tree); ExpressionTree condition = tree.condition(); if (condition.is(Tree.Kind.ASSIGNMENT) && EQUALITY_RELATIONAL_OPERATORS.contains(((AssignmentExpressionTree) condition).expression().kind())) { raiseIssue(((AssignmentExpressionTree) condition).operatorToken().line(), tree); } }
private void checkExpression(Type varType, @Nullable ExpressionTree expr) { if (isVarTypeErrorProne(varType) && expr != null && expressionIsOperationToIntOrLong(expr)) { BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) expr; if(binaryExpressionTree.is(Tree.Kind.DIVIDE) && varType.isPrimitive(Type.Primitives.LONG)) { // widening the result of an int division is harmless return; } if (varType.isPrimitive(Type.Primitives.LONG) && expr.symbolType().isPrimitive(Type.Primitives.LONG)) { return; } context.reportIssue(this, binaryExpressionTree.operatorToken(), "Cast one of the operands of this " + OPERATION_BY_KIND.get(expr.kind()) + " operation to a \"" + varType.name() + "\"."); } }
private void checkExpression(Type varType, @Nullable ExpressionTree expr) { if (isVarTypeErrorProne(varType) && expr != null && expressionIsOperationToIntOrLong(expr)) { BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) expr; if(binaryExpressionTree.is(Tree.Kind.DIVIDE) && varType.isPrimitive(Type.Primitives.LONG)) { // widening the result of an int division is harmless return; } if (varType.isPrimitive(Type.Primitives.LONG) && expr.symbolType().isPrimitive(Type.Primitives.LONG)) { return; } context.reportIssue(this, binaryExpressionTree.operatorToken(), "Cast one of the operands of this " + OPERATION_BY_KIND.get(expr.kind()) + " operation to a \"" + varType.name() + "\"."); } }
private static boolean isConstant(ExpressionTree operand) { switch (operand.kind()) { case BOOLEAN_LITERAL: case CHAR_LITERAL: case DOUBLE_LITERAL: case FLOAT_LITERAL: case INT_LITERAL: case LONG_LITERAL: case STRING_LITERAL: case NULL_LITERAL: return true; case IDENTIFIER: return isConstant(((IdentifierTree) operand).symbol()); case MEMBER_SELECT: MemberSelectExpressionTree mset = (MemberSelectExpressionTree) operand; return isConstant(mset.identifier().symbol()); default: return false; } }
@Override public void visitNode(Tree tree) { UnaryExpressionTree exprTree = (UnaryExpressionTree) tree; if (alreadyReported(exprTree)) { return; } ExpressionTree expr = ExpressionUtils.skipParentheses(exprTree.expression()); if (exprTree.is(expr.kind())) { UnaryExpressionTree child = (UnaryExpressionTree) expr; if (child.is(Tree.Kind.BITWISE_COMPLEMENT) && !ExpressionUtils.skipParentheses(child.expression()).is(Tree.Kind.BITWISE_COMPLEMENT)) { return; } prefixSet.add(child); reportIssue(exprTree.operatorToken(), child.operatorToken(), "Remove multiple operator prefixes."); } }
@Override public void visitNode(Tree tree) { UnaryExpressionTree exprTree = (UnaryExpressionTree) tree; if (alreadyReported(exprTree)) { return; } ExpressionTree expr = ExpressionUtils.skipParentheses(exprTree.expression()); if (exprTree.is(expr.kind())) { UnaryExpressionTree child = (UnaryExpressionTree) expr; if (child.is(Tree.Kind.BITWISE_COMPLEMENT) && !ExpressionUtils.skipParentheses(child.expression()).is(Tree.Kind.BITWISE_COMPLEMENT)) { return; } prefixSet.add(child); reportIssue(exprTree.operatorToken(), child.operatorToken(), "Remove multiple operator prefixes."); } }