use of org.sonar.plugins.java.api.tree.IdentifierTree in project sonar-java by SonarSource.
the class MethodYieldTest method constraints_on_varargs.
@Test
public void constraints_on_varargs() throws Exception {
ActionParser<Tree> p = JavaParser.createParser();
CompilationUnitTree cut = (CompilationUnitTree) p.parse(new File("src/test/files/se/VarArgsYields.java"));
SemanticModel semanticModel = SemanticModel.createFor(cut, new SquidClassLoader(new ArrayList<>()));
SymbolicExecutionVisitor sev = new SymbolicExecutionVisitor(Lists.newArrayList(new SECheck[] {}), new BehaviorCache(new SquidClassLoader(new ArrayList<>())));
JavaFileScannerContext context = mock(JavaFileScannerContext.class);
when(context.getTree()).thenReturn(cut);
when(context.getSemanticModel()).thenReturn(semanticModel);
sev.scanFile(context);
MethodSymbol methodSymbol = ((MethodTree) ((ClassTree) cut.types().get(0)).members().get(0)).symbol();
MethodBehavior mb = getMethodBehavior(sev, "varArgMethod");
List<MethodYield> yields = mb.yields();
assertThat(yields).hasSize(5);
assertThat(mb.exceptionalPathYields()).hasSize(4);
MethodYield yield = mb.happyPathYields().findFirst().get();
// check that we have NOT_NULL constraint on the first argument
assertThat(yield.parametersConstraints.get(0).get(ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
// check that we have NOT_NULL constraint on the variadic argument
assertThat(yield.parametersConstraints.get(1).get(ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
List<IdentifierTree> usages = methodSymbol.usages();
assertThat(usages).hasSize(6);
List<List<Type>> arguments = usages.stream().map(MethodYieldTest::getMethodIncoationArgumentsTypes).collect(Collectors.toList());
ProgramState ps = ProgramState.EMPTY_STATE;
ProgramState psResult;
SymbolicValue svFirstArg = new SymbolicValue();
SymbolicValue svVarArg1 = new SymbolicValue();
SymbolicValue svVarArg2 = new SymbolicValue();
SymbolicValue svResult = new SymbolicValue();
// apply constraint NotNull to parameter
Collection<ProgramState> arrayOfA = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(0), ps, () -> svResult).collect(Collectors.toList());
assertThat(arrayOfA).hasSize(1);
psResult = arrayOfA.iterator().next();
assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
// apply constraint NotNull to parameter (B[] is a subtype of A[])
Collection<ProgramState> arrayOfB = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(1), ps, () -> svResult).collect(Collectors.toList());
assertThat(arrayOfB).hasSize(1);
psResult = arrayOfB.iterator().next();
assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
// no constraint, as 'a' is not an array
Collection<ProgramState> objectA = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(2), ps, () -> svResult).collect(Collectors.toList());
assertThat(objectA).hasSize(1);
psResult = objectA.iterator().next();
assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isNull();
// no constraint, as 'a' and 'b' can not receive the constraint of the array
Collection<ProgramState> objectsAandB = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1, svVarArg2), arguments.get(3), ps, () -> svResult).collect(Collectors.toList());
assertThat(objectsAandB).hasSize(1);
psResult = objectsAandB.iterator().next();
assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
assertThat(psResult.getConstraint(svVarArg1, ObjectConstraint.class)).isNull();
assertThat(psResult.getConstraint(svVarArg2, ObjectConstraint.class)).isNull();
// no param, we only learn something about the argument which is not variadic
Collection<ProgramState> noParam = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg), arguments.get(4), ps, () -> svResult).collect(Collectors.toList());
assertThat(noParam).hasSize(1);
psResult = noParam.iterator().next();
assertThat(psResult.getConstraint(svFirstArg, ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
// null param, contradiction, no resulting program state
ps = ProgramState.EMPTY_STATE.addConstraint(svFirstArg, ObjectConstraint.NULL);
Collection<ProgramState> nullParam = yield.statesAfterInvocation(Lists.newArrayList(svFirstArg, svVarArg1), arguments.get(5), ps, () -> svResult).collect(Collectors.toList());
assertThat(nullParam).isEmpty();
}
use of org.sonar.plugins.java.api.tree.IdentifierTree in project sonar-java by SonarSource.
the class TypeSubstitutionSolverTest method substitute_thrown_types.
@Test
public void substitute_thrown_types() throws Exception {
Result result = Result.createForJavaFile("src/test/files/sym/ThrownTypeVariables");
IdentifierTree fooInvocation = result.referenceTree(6, 34);
assertThat(((MethodJavaType) fooInvocation.symbolType()).thrown).hasSize(1);
assertThat(((MethodJavaType) fooInvocation.symbolType()).thrown.get(0).is("java.io.IOException")).isTrue();
IdentifierTree barInvocation1 = result.referenceTree(23, 21);
assertThat(((MethodJavaType) barInvocation1.symbolType()).thrown).hasSize(1);
assertThat(((MethodJavaType) barInvocation1.symbolType()).thrown.get(0).is("java.util.NoSuchElementException")).isTrue();
IdentifierTree barInvocation2 = result.referenceTree(24, 21);
assertThat(((MethodJavaType) barInvocation2.symbolType()).thrown).hasSize(1);
assertThat(((MethodJavaType) barInvocation2.symbolType()).thrown.get(0).is("java.io.IOException")).isTrue();
}
use of org.sonar.plugins.java.api.tree.IdentifierTree in project sonar-java by SonarSource.
the class WaitInWhileLoopCheck method onMethodInvocationFound.
@Override
protected void onMethodInvocationFound(MethodInvocationTree mit) {
if (!inWhileLoop.peek()) {
IdentifierTree identifierTree = ExpressionUtils.methodName(mit);
reportIssue(identifierTree, "Remove this call to \"" + identifierTree.name() + "\" or move it into a \"while\" loop.");
}
}
use of org.sonar.plugins.java.api.tree.IdentifierTree in project sonar-java by SonarSource.
the class ReassignmentFinder method getClosestReassignmentOrDeclarationExpression.
@CheckForNull
public static ExpressionTree getClosestReassignmentOrDeclarationExpression(Tree startingPoint, Symbol referenceSymbol) {
Tree result = referenceSymbol.declaration();
List<IdentifierTree> usages = referenceSymbol.usages();
if (usages.size() != 1) {
List<AssignmentExpressionTree> reassignments = getReassignments(referenceSymbol.owner().declaration(), usages);
SyntaxToken startPointToken = startingPoint.firstToken();
Tree lastReassignment = getClosestReassignment(startPointToken, reassignments);
if (lastReassignment != null) {
result = lastReassignment;
}
}
ExpressionTree initializerOrExpression = getInitializerOrExpression(result);
if (initializerOrExpression == startingPoint) {
return getClosestReassignmentOrDeclarationExpression(result, referenceSymbol);
}
return initializerOrExpression;
}
use of org.sonar.plugins.java.api.tree.IdentifierTree in project sonar-java by SonarSource.
the class ReassignmentFinder method checkAssignment.
private static Optional<AssignmentExpressionTree> checkAssignment(IdentifierTree usage) {
Tree previousTree = usage;
Tree nonParenthesisParent = previousTree.parent();
while (nonParenthesisParent.is(Tree.Kind.PARENTHESIZED_EXPRESSION)) {
previousTree = nonParenthesisParent;
nonParenthesisParent = previousTree.parent();
}
if (nonParenthesisParent instanceof AssignmentExpressionTree) {
AssignmentExpressionTree assignment = (AssignmentExpressionTree) nonParenthesisParent;
if (assignment.variable().equals(previousTree)) {
return Optional.of(assignment);
}
}
return Optional.empty();
}
Aggregations