Search in sources :

Example 11 with MethodInvocationTree

use of org.sonar.plugins.java.api.tree.MethodInvocationTree in project sonar-java by SonarSource.

the class ExplodedGraphWalker method visit.

private void visit(Tree tree, @Nullable Tree terminator) {
    if (!checkerDispatcher.executeCheckPreStatement(tree)) {
        // Some of the check pre statement sink the execution on this node.
        return;
    }
    switch(tree.kind()) {
        case METHOD_INVOCATION:
            MethodInvocationTree mit = (MethodInvocationTree) tree;
            if (SYSTEM_EXIT_MATCHER.matches(mit)) {
                // System exit is a sink of execution
                return;
            }
            executeMethodInvocation(mit);
            return;
        case LABELED_STATEMENT:
        case SWITCH_STATEMENT:
        case EXPRESSION_STATEMENT:
        case PARENTHESIZED_EXPRESSION:
            throw new IllegalStateException("Cannot appear in CFG: " + tree.kind().name());
        case VARIABLE:
            executeVariable((VariableTree) tree, terminator);
            break;
        case TYPE_CAST:
            executeTypeCast((TypeCastTree) tree);
            break;
        case ASSIGNMENT:
        case MULTIPLY_ASSIGNMENT:
        case DIVIDE_ASSIGNMENT:
        case REMAINDER_ASSIGNMENT:
        case PLUS_ASSIGNMENT:
        case MINUS_ASSIGNMENT:
        case LEFT_SHIFT_ASSIGNMENT:
        case RIGHT_SHIFT_ASSIGNMENT:
        case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
            executeAssignment((AssignmentExpressionTree) tree);
            break;
        case AND_ASSIGNMENT:
        case XOR_ASSIGNMENT:
        case OR_ASSIGNMENT:
            executeLogicalAssignment((AssignmentExpressionTree) tree);
            break;
        case ARRAY_ACCESS_EXPRESSION:
            executeArrayAccessExpression((ArrayAccessExpressionTree) tree);
            break;
        case NEW_ARRAY:
            executeNewArray((NewArrayTree) tree);
            break;
        case NEW_CLASS:
            executeNewClass((NewClassTree) tree);
            break;
        case MULTIPLY:
        case DIVIDE:
        case REMAINDER:
        case PLUS:
        case MINUS:
        case LEFT_SHIFT:
        case RIGHT_SHIFT:
        case UNSIGNED_RIGHT_SHIFT:
        case AND:
        case XOR:
        case OR:
        case GREATER_THAN:
        case GREATER_THAN_OR_EQUAL_TO:
        case LESS_THAN:
        case LESS_THAN_OR_EQUAL_TO:
        case EQUAL_TO:
        case NOT_EQUAL_TO:
            executeBinaryExpression(tree);
            break;
        case POSTFIX_INCREMENT:
        case POSTFIX_DECREMENT:
        case PREFIX_INCREMENT:
        case PREFIX_DECREMENT:
        case UNARY_MINUS:
        case UNARY_PLUS:
        case BITWISE_COMPLEMENT:
        case LOGICAL_COMPLEMENT:
        case INSTANCE_OF:
            executeUnaryExpression(tree);
            break;
        case IDENTIFIER:
            executeIdentifier((IdentifierTree) tree);
            break;
        case MEMBER_SELECT:
            executeMemberSelect((MemberSelectExpressionTree) tree);
            break;
        case INT_LITERAL:
        case LONG_LITERAL:
        case FLOAT_LITERAL:
        case DOUBLE_LITERAL:
        case CHAR_LITERAL:
        case STRING_LITERAL:
            SymbolicValue val = constraintManager.createSymbolicValue(tree);
            programState = programState.stackValue(val);
            programState = programState.addConstraint(val, ObjectConstraint.NOT_NULL);
            break;
        case BOOLEAN_LITERAL:
            boolean value = Boolean.parseBoolean(((LiteralTree) tree).value());
            programState = programState.stackValue(value ? SymbolicValue.TRUE_LITERAL : SymbolicValue.FALSE_LITERAL);
            break;
        case NULL_LITERAL:
            programState = programState.stackValue(SymbolicValue.NULL_LITERAL);
            break;
        case LAMBDA_EXPRESSION:
        case METHOD_REFERENCE:
            programState = programState.stackValue(constraintManager.createSymbolicValue(tree));
            break;
        case ASSERT_STATEMENT:
            executeAssertStatement(tree);
            return;
        default:
    }
    checkerDispatcher.executeCheckPostStatement(tree);
    clearStack(tree);
}
Also used : MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 12 with MethodInvocationTree

use of org.sonar.plugins.java.api.tree.MethodInvocationTree in project sonar-java by SonarSource.

the class MapComputeIfAbsentOrPresentCheck method isInsideIfStatementWithNullCheckWithoutElse.

private static boolean isInsideIfStatementWithNullCheckWithoutElse(MethodInvocationTree mit) {
    Tree parent = mit.parent();
    while (parent != null && !parent.is(Tree.Kind.IF_STATEMENT)) {
        parent = parent.parent();
    }
    if (parent == null) {
        return false;
    }
    IfStatementTree ifStatementTree = (IfStatementTree) parent;
    return ifStatementTree.elseStatement() == null && isNullCheck(ExpressionUtils.skipParentheses(ifStatementTree.condition()));
}
Also used : ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree)

Example 13 with MethodInvocationTree

use of org.sonar.plugins.java.api.tree.MethodInvocationTree in project sonar-java by SonarSource.

the class MapComputeIfAbsentOrPresentCheck method checkPreStatement.

@Override
public ProgramState checkPreStatement(CheckerContext context, Tree syntaxNode) {
    if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
        MethodInvocationTree mit = (MethodInvocationTree) syntaxNode;
        if (MAP_PUT.matches(mit) && !isMethodInvocationThrowingCheckedException(mit.arguments().get(1))) {
            ProgramState ps = context.getState();
            SymbolicValue keySV = ps.peekValue(1);
            SymbolicValue mapSV = ps.peekValue(2);
            mapGetInvocations.get(mapSV).stream().filter(getOnSameMap -> getOnSameMap.withSameKey(keySV)).findAny().ifPresent(getOnSameMap -> {
                ObjectConstraint constraint = ps.getConstraint(getOnSameMap.value, ObjectConstraint.class);
                if (constraint != null && isInsideIfStatementWithNullCheckWithoutElse(mit)) {
                    checkIssues.add(new CheckIssue(context.getNode(), getOnSameMap.mit, mit, getOnSameMap.value, constraint));
                }
            });
        }
    }
    return super.checkPreStatement(context, syntaxNode);
}
Also used : MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 14 with MethodInvocationTree

use of org.sonar.plugins.java.api.tree.MethodInvocationTree in project sonar-java by SonarSource.

the class OptionalGetBeforeIsPresentCheck method setOptionalConstraint.

private static List<ProgramState> setOptionalConstraint(CheckerContext context, Tree syntaxNode) {
    ProgramState programState = context.getState();
    if (!syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
        return Collections.singletonList(programState);
    }
    MethodInvocationTree mit = (MethodInvocationTree) syntaxNode;
    SymbolicValue peekValue = programState.peekValue();
    Preconditions.checkNotNull(peekValue);
    if (OPTIONAL_EMPTY.matches(mit)) {
        return peekValue.setConstraint(programState, OptionalConstraint.NOT_PRESENT);
    }
    if (OPTIONAL_OF.matches(mit)) {
        return peekValue.setConstraint(programState, OptionalConstraint.PRESENT);
    }
    if (OPTIONAL_OF_NULLABLE.matches(mit)) {
        ProgramState psPriorMethodInvocation = context.getNode().programState;
        SymbolicValue paramSV = psPriorMethodInvocation.peekValue(0);
        ObjectConstraint paramConstraint = psPriorMethodInvocation.getConstraint(paramSV, ObjectConstraint.class);
        if (paramConstraint != null) {
            // Optional.ofNullable(null) returns an empty Optional
            return peekValue.setConstraint(programState, paramConstraint == ObjectConstraint.NULL ? OptionalConstraint.NOT_PRESENT : OptionalConstraint.PRESENT);
        }
    }
    return Collections.singletonList(programState);
}
Also used : MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 15 with MethodInvocationTree

use of org.sonar.plugins.java.api.tree.MethodInvocationTree in project sonar-java by SonarSource.

the class ParameterNullnessCheck method reportIssue.

private void reportIssue(Tree syntaxNode, ExpressionTree argument, JavaSymbol.MethodJavaSymbol methodSymbol) {
    String declarationMessage = "constructor declaration";
    if (!methodSymbol.isConstructor()) {
        declarationMessage = "method '" + methodSymbol.getName() + "' declaration";
    }
    String message = String.format("Annotate the parameter with @javax.annotation.Nullable in %s, or make sure that null can not be passed as argument.", declarationMessage);
    Tree reportTree;
    if (syntaxNode.is(Tree.Kind.METHOD_INVOCATION)) {
        reportTree = ExpressionUtils.methodName((MethodInvocationTree) syntaxNode);
    } else {
        reportTree = ((NewClassTree) syntaxNode).identifier();
    }
    Flow.Builder secondaryBuilder = Flow.builder();
    MethodTree declarationTree = methodSymbol.declaration();
    if (declarationTree != null) {
        secondaryBuilder.add(new JavaFileScannerContext.Location(StringUtils.capitalize(declarationMessage) + ".", declarationTree.simpleName()));
    }
    secondaryBuilder.add(new JavaFileScannerContext.Location("Argument can be null.", argument));
    reportIssue(reportTree, message, Collections.singleton(secondaryBuilder.build()));
}
Also used : JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) Tree(org.sonar.plugins.java.api.tree.Tree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) Flow(org.sonar.java.se.Flow)

Aggregations

MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)87 ExpressionTree (org.sonar.plugins.java.api.tree.ExpressionTree)44 Test (org.junit.Test)30 MemberSelectExpressionTree (org.sonar.plugins.java.api.tree.MemberSelectExpressionTree)30 IdentifierTree (org.sonar.plugins.java.api.tree.IdentifierTree)29 Symbol (org.sonar.plugins.java.api.semantic.Symbol)26 MethodTree (org.sonar.plugins.java.api.tree.MethodTree)23 Tree (org.sonar.plugins.java.api.tree.Tree)21 Type (org.sonar.plugins.java.api.semantic.Type)14 AssignmentExpressionTree (org.sonar.plugins.java.api.tree.AssignmentExpressionTree)14 VariableTree (org.sonar.plugins.java.api.tree.VariableTree)14 ExpressionStatementTree (org.sonar.plugins.java.api.tree.ExpressionStatementTree)13 BinaryExpressionTree (org.sonar.plugins.java.api.tree.BinaryExpressionTree)11 ClassTree (org.sonar.plugins.java.api.tree.ClassTree)10 NewClassTree (org.sonar.plugins.java.api.tree.NewClassTree)10 ArrayAccessExpressionTree (org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree)9 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)8 ReturnStatementTree (org.sonar.plugins.java.api.tree.ReturnStatementTree)8 CompilationUnitTree (org.sonar.plugins.java.api.tree.CompilationUnitTree)7 ConditionalExpressionTree (org.sonar.plugins.java.api.tree.ConditionalExpressionTree)7