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);
}
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()));
}
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);
}
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);
}
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()));
}
Aggregations