Example #1
0
 private void buildMethodInvocation(MethodInvocationTree tree) {
   MethodInvocationTree mit = tree;
   currentBlock.elements.add(mit);
   build(mit.methodSelect());
   for (ExpressionTree arg : Lists.reverse(mit.arguments())) {
     build(arg);
   }
 }
 public static IdentifierTree methodName(MethodInvocationTree mit) {
   IdentifierTree id;
   if (mit.methodSelect().is(Tree.Kind.IDENTIFIER)) {
     id = (IdentifierTree) mit.methodSelect();
   } else {
     id = ((MemberSelectExpressionTree) mit.methodSelect()).identifier();
   }
   return id;
 }
  @Test
  public void ignore_assignation_after_starting_point_same_line() throws Exception {
    String code = newCode("int foo() {", "  int b = 0;", "  doSomething(b); b = 1;", "}");

    List<StatementTree> statements = methodBody(code);
    Tree expectedVariableDeclaration =
        initializerFromVariableDeclarationStatement(statements.get(0));
    MethodInvocationTree startingPoint =
        (MethodInvocationTree) ((ExpressionStatementTree) statements.get(1)).expression();
    Symbol searchedVariable = ((IdentifierTree) startingPoint.arguments().get(0)).symbol();
    assertThatLastReassignmentsOfVariableIsEqualTo(
        searchedVariable, startingPoint, expectedVariableDeclaration);
  }
 private static boolean isEqualsMethod(MethodInvocationTree syntaxNode) {
   if (syntaxNode.arguments().size() == 1) {
     ExpressionTree methodSelect = syntaxNode.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree expression = (MemberSelectExpressionTree) methodSelect;
       if ("equals".equals(expression.identifier().name())
           && syntaxNode.symbol().isMethodSymbol()) {
         Symbol.MethodSymbol symbol = (Symbol.MethodSymbol) syntaxNode.symbol();
         return symbol.parameterTypes().get(0).is("java.lang.Object");
       }
     }
   }
   return false;
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree syntaxNode) {
   if (syntaxNode.methodSelect().is(Tree.Kind.MEMBER_SELECT)
       && needsClosing(syntaxNode.symbolType())) {
     final ExpressionTree targetExpression =
         ((MemberSelectExpressionTree) syntaxNode.methodSelect()).expression();
     if (targetExpression.is(Tree.Kind.IDENTIFIER)
         && !isWithinTryHeader(syntaxNode)
         && (syntaxNode.symbol().isStatic() || isJdbcResourceCreation(targetExpression))) {
       programState =
           programState.addConstraint(
               programState.peekValue(),
               new ObjectConstraint(false, false, syntaxNode, Status.OPENED));
     }
   }
 }
 @Override
 protected void onMethodInvocationFound(MethodInvocationTree mit) {
   Type symbolType = mit.arguments().get(0).symbolType();
   if (!(symbolType.is("long") || symbolType.is("java.lang.Long"))) {
     reportIssue(MethodsHelper.methodName(mit), "Remove this \"Double.longBitsToDouble\" call.");
   }
 }
 private void checkForBoxing(ExpressionTree expression) {
   if (expression.is(Tree.Kind.NEW_CLASS)) {
     NewClassTree newClassTree = (NewClassTree) expression;
     Symbol.TypeSymbol classSymbol = wrapperClassSymbol(newClassTree);
     if (classSymbol != null) {
       ExpressionTree boxingArg = newClassTree.arguments().get(0);
       if (boxingArg.symbolType().isPrimitive()) {
         addBoxingIssue(newClassTree, classSymbol, boxingArg);
       }
     }
   } else if (expression.is(Tree.Kind.METHOD_INVOCATION)) {
     MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expression;
     if (isValueOfInvocation(methodInvocationTree)) {
       ExpressionTree boxingArg = methodInvocationTree.arguments().get(0);
       addBoxingIssue(expression, methodInvocationTree.symbol().owner(), boxingArg);
     }
   }
 }
 private void visitMethodInvocationTree(MethodInvocationTree methodInvocationTree) {
   if (isValueOfInvocation(methodInvocationTree)) {
     checkForUnboxing(methodInvocationTree.arguments().get(0));
   } else if (isUnboxingMethodInvocation(methodInvocationTree)) {
     ExpressionTree methodSelect = methodInvocationTree.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree memberSelectExpressionTree =
           (MemberSelectExpressionTree) methodSelect;
       checkForBoxing(memberSelectExpressionTree.expression());
     }
   } else {
     Symbol symbol = methodInvocationTree.symbol();
     if (symbol.isMethodSymbol()) {
       List<Type> parametersTypes = ((Symbol.MethodSymbol) symbol).parameterTypes();
       checkMethodInvocationArguments(methodInvocationTree, parametersTypes);
     }
   }
 }
 private void checkForUnboxing(ExpressionTree expressionTree) {
   if (!expressionTree.is(Tree.Kind.METHOD_INVOCATION)) {
     return;
   }
   MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree;
   if (isUnboxingMethodInvocation(methodInvocationTree)) {
     ExpressionTree methodSelect = methodInvocationTree.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree memberSelectExpressionTree =
           (MemberSelectExpressionTree) methodSelect;
       ExpressionTree unboxedExpression = memberSelectExpressionTree.expression();
       String unboxingResultTypeName = methodInvocationTree.symbolType().fullyQualifiedName();
       if (unboxingResultTypeName.equals(
           PRIMITIVE_TYPES_BY_WRAPPER.get(unboxedExpression.symbolType().fullyQualifiedName()))) {
         addUnboxingIssue(expressionTree, unboxedExpression);
       }
     }
   }
 }
 private void checkMethodInvocationArguments(
     MethodInvocationTree methodInvocationTree, List<Type> parametersTypes) {
   List<ExpressionTree> arguments = methodInvocationTree.arguments();
   int position = 0;
   for (Type paramType : parametersTypes) {
     if (arguments.size() > position) {
       checkExpression(arguments.get(position), paramType);
     }
     position++;
   }
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree tree) {
   if (TO_STRING_MATCHERS.anyMatch(tree)) {
     ExpressionTree abstractTypedTree =
         ((MemberSelectExpressionTree) tree.methodSelect()).expression();
     if (abstractTypedTree.is(Kind.NEW_CLASS) || isValueOfInvocation(abstractTypedTree)) {
       String typeName = abstractTypedTree.symbolType().toString();
       createIssue(tree, typeName);
     }
   }
   super.visitMethodInvocation(tree);
 }
 private SymbolicValue getTargetValue(MethodInvocationTree syntaxNode) {
   final ExpressionTree targetExpression =
       ((MemberSelectExpressionTree) syntaxNode.methodSelect()).expression();
   final SymbolicValue value;
   if (targetExpression.is(Tree.Kind.IDENTIFIER)) {
     final IdentifierTree identifier = (IdentifierTree) targetExpression;
     value = programState.getValue(identifier.symbol());
   } else {
     value = programState.peekValue();
   }
   return value;
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree syntaxNode) {
   final ExpressionTree methodSelect = syntaxNode.methodSelect();
   if (isClosingResource(syntaxNode.symbol())) {
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       final ExpressionTree targetExpression =
           ((MemberSelectExpressionTree) methodSelect).expression();
       if (targetExpression.is(Tree.Kind.IDENTIFIER)) {
         final IdentifierTree identifier = (IdentifierTree) targetExpression;
         programState = closeResource(programState, programState.getValue(identifier.symbol()));
       } else {
         programState = closeResource(programState, programState.peekValue());
       }
     }
   } else if (syntaxNode.methodSelect().is(Tree.Kind.MEMBER_SELECT)
       && isOpeningResultSet(syntaxNode.symbol())) {
     final SymbolicValue value = getTargetValue(syntaxNode);
     constraintManager.setValueFactory(new WrappedValueFactory(value));
   } else if (isClosingResultSets(syntaxNode.symbol())) {
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       final SymbolicValue value = getTargetValue(syntaxNode);
       closeResultSetsRelatedTo(value);
     }
   } else {
     closeArguments(syntaxNode.arguments(), 1);
   }
 }
 public SymbolicValue createMethodSymbolicValue(
     MethodInvocationTree syntaxNode, List<SymbolicValue> values) {
   SymbolicValue result;
   if (isEqualsMethod(syntaxNode) || isObjectsMethod(syntaxNode.symbol(), "equals")) {
     result = new RelationalSymbolicValue(counter, RelationalSymbolicValue.Kind.METHOD_EQUALS);
     SymbolicValue leftOp = values.get(1);
     SymbolicValue rightOp = values.get(0);
     result.computedFrom(ImmutableList.of(rightOp, leftOp));
   } else if (isObjectsMethod(syntaxNode.symbol(), "isNull")) {
     result = new NullCheckSymbolicValue(counter, true);
     SymbolicValue operand = values.get(0);
     result.computedFrom(ImmutableList.of(operand));
   } else if (isObjectsMethod(syntaxNode.symbol(), "nonNull")) {
     result = new NullCheckSymbolicValue(counter, false);
     SymbolicValue operand = values.get(0);
     result.computedFrom(ImmutableList.of(operand));
   } else {
     result = createDefaultSymbolicValue();
   }
   counter++;
   return result;
 }
 @Override
 protected void onMethodInvocationFound(MethodInvocationTree mit) {
   Tree parent = mit.parent();
   while (parent != null && !parent.is(Tree.Kind.METHOD)) {
     parent = parent.parent();
   }
   if (parent != null && THREAD_RUN_METHOD_MATCHER.matches((MethodTree) parent)) {
     return;
   }
   reportIssue(
       MethodsHelper.methodName(mit),
       "Call the method Thread.start() to execute the content of the run() method in a dedicated thread.");
 }
 @Override
 public void visitNode(Tree tree) {
   MethodInvocationTree methodTree = (MethodInvocationTree) tree;
   boolean isHibernateCall = isHibernateCall(methodTree);
   if (isHibernateCall
       || isExecuteQueryOrPrepareStatement(methodTree)
       || isEntityManagerCreateNativeQuery(methodTree)) {
     // We want to check the argument for the three methods.
     ExpressionTree arg = methodTree.arguments().get(0);
     parameterName = "";
     if (isDynamicString(methodTree, arg, null, true)) {
       String message =
           "\""
               + parameterName
               + "\" is provided externally to the method and not sanitized before use.";
       if (isHibernateCall) {
         message = "Use Hibernate's parameter binding instead of concatenation.";
       }
       reportIssue(MethodsHelper.methodName(methodTree), message);
     }
   }
 }
  @Override
  protected void onMethodInvocationFound(MethodInvocationTree tree) {
    Type argumentType = tree.arguments().get(0).symbolType();
    Type collectionType = getMethodOwner(tree);
    // can be null when using raw types
    Type collectionParameterType = getTypeParameter(collectionType);

    if (collectionParameterType != null
        && !collectionParameterType.isUnknown()
        && !isArgumentCompatible(argumentType, collectionParameterType)) {
      addIssue(
          tree,
          MessageFormat.format(
              "A \"{0}<{1}>\" cannot contain a \"{2}\"",
              collectionType, collectionParameterType, argumentType));
    }
  }
 @Nullable
 private State checkAndAdvanceState(
     MethodInvocationTree mit, State requiredState, State nextState) {
   ExpressionTree methodSelect = mit.methodSelect();
   if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
     ExpressionTree expressionTree = ((MemberSelectExpressionTree) methodSelect).expression();
     if (expressionTree.is(Tree.Kind.IDENTIFIER)) {
       Symbol symbol = ((IdentifierTree) expressionTree).symbol();
       Map<Symbol, State> symbolStateMap = symbolStack.peek();
       if (symbolStateMap != null
           && symbolStateMap.containsKey(symbol)
           && requiredState.equals(symbolStateMap.get(symbol))) {
         symbolStateMap.put(symbol, nextState);
         return nextState;
       }
     }
   }
   return null;
 }
 private static Type getMethodOwner(MethodInvocationTree mit) {
   if (mit.methodSelect().is(Kind.MEMBER_SELECT)) {
     return ((MemberSelectExpressionTree) mit.methodSelect()).expression().symbolType();
   }
   return mit.symbol().owner().type();
 }
 private static boolean isExecuteQueryOrPrepareStatement(MethodInvocationTree methodTree) {
   return !methodTree.arguments().isEmpty()
       && (STATEMENT_EXECUTE_QUERY_MATCHER.matches(methodTree)
           || CONNECTION_MATCHERS.anyMatch(methodTree));
 }