Search in sources :

Example 6 with SemanticModel

use of org.sonar.java.resolve.SemanticModel 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();
}
Also used : MethodTree(org.sonar.plugins.java.api.tree.MethodTree) ArrayList(java.util.ArrayList) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) ProgramState(org.sonar.java.se.ProgramState) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) SECheck(org.sonar.java.se.checks.SECheck) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) ClassTree(org.sonar.plugins.java.api.tree.ClassTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) MethodSymbol(org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) File(java.io.File) Test(org.junit.Test)

Example 7 with SemanticModel

use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.

the class BytecodeEGWalkerExecuteTest method athrow_should_not_be_linked_to_next_label.

@Test
public void athrow_should_not_be_linked_to_next_label() throws Exception {
    CompilationUnitTree tree = (CompilationUnitTree) JavaParser.createParser().parse("class A {int field;}");
    SquidClassLoader classLoader = new SquidClassLoader(Collections.singletonList(new File("src/test/JsrRet")));
    SemanticModel semanticModel = SemanticModel.createFor(tree, classLoader);
    BehaviorCache behaviorCache = new BehaviorCache(classLoader);
    behaviorCache.setFileContext(null, semanticModel);
    BytecodeEGWalker walker = new BytecodeEGWalker(behaviorCache, semanticModel);
    MethodBehavior methodBehavior = walker.getMethodBehavior("org.apache.commons.io.FileUtils#readFileToString(Ljava/io/File;)Ljava/lang/String;", classLoader);
    assertThat(methodBehavior.happyPathYields().collect(Collectors.toList())).hasSize(1);
    assertThat(methodBehavior.exceptionalPathYields().collect(Collectors.toList())).hasSize(2);
}
Also used : CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) SemanticModel(org.sonar.java.resolve.SemanticModel) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) File(java.io.File) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) Test(org.junit.Test)

Example 8 with SemanticModel

use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.

the class ExceptionalYieldTest method exceptional_yields.

@Test
public void exceptional_yields() {
    Pair<SymbolicExecutionVisitor, SemanticModel> sevAndSemantic = createSymbolicExecutionVisitorAndSemantic("src/test/files/se/ExceptionalYields.java");
    SymbolicExecutionVisitor sev = sevAndSemantic.a;
    SemanticModel semanticModel = sevAndSemantic.b;
    MethodBehavior mb = getMethodBehavior(sev, "myMethod");
    assertThat(mb.yields()).hasSize(4);
    List<ExceptionalYield> exceptionalYields = mb.exceptionalPathYields().collect(Collectors.toList());
    assertThat(exceptionalYields).hasSize(3);
    // runtime exception
    Optional<ExceptionalYield> runtimeException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).isUnknown()).findFirst();
    assertThat(runtimeException.isPresent()).isTrue();
    MethodYield runtimeExceptionYield = runtimeException.get();
    assertThat(runtimeExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.FALSE);
    // exception from other method call
    Optional<ExceptionalYield> implicitException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException2")).findFirst();
    assertThat(implicitException.isPresent()).isTrue();
    MethodYield implicitExceptionYield = implicitException.get();
    assertThat(implicitExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.FALSE);
    // explicitly thrown exception
    Optional<ExceptionalYield> explicitException = exceptionalYields.stream().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException1")).findFirst();
    assertThat(explicitException.isPresent()).isTrue();
    MethodYield explicitExceptionYield = explicitException.get();
    assertThat(explicitExceptionYield.parametersConstraints.get(0).get(BooleanConstraint.class)).isEqualTo(BooleanConstraint.TRUE);
}
Also used : JavaParser(org.sonar.java.ast.parser.JavaParser) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) SETestUtils(org.sonar.java.se.SETestUtils) Set(java.util.Set) Test(org.junit.Test) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) Optional(java.util.Optional) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Example 9 with SemanticModel

use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.

the class ExceptionalYieldTest method test_equals.

@Test
public void test_equals() {
    MethodBehavior methodBehavior = mockMethodBehavior();
    ExceptionalYield yield = new ExceptionalYield(methodBehavior);
    ExceptionalYield otherYield = new ExceptionalYield(methodBehavior);
    assertThat(yield).isNotEqualTo(null);
    assertThat(yield).isEqualTo(yield);
    assertThat(yield).isEqualTo(otherYield);
    otherYield.setExceptionType("java.lang.Exception");
    assertThat(yield).isNotEqualTo(otherYield);
    yield.setExceptionType("java.lang.Exception");
    assertThat(yield).isEqualTo(otherYield);
    SemanticModel semanticModel = SemanticModel.createFor((CompilationUnitTree) JavaParser.createParser().parse("class A{}"), new SquidClassLoader(new ArrayList<>()));
    assertThat(yield.exceptionType(semanticModel)).isEqualTo(otherYield.exceptionType(semanticModel));
    // same arity and parameters but happy yield
    assertThat(yield).isNotEqualTo(new HappyPathYield(methodBehavior));
}
Also used : SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) ArrayList(java.util.ArrayList) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) Test(org.junit.Test)

Example 10 with SemanticModel

use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.

the class MethodBehaviorTest method method_behavior_handling_finally.

@Test
public void method_behavior_handling_finally() {
    Pair<SymbolicExecutionVisitor, SemanticModel> visitorAndSemantic = createSymbolicExecutionVisitorAndSemantic("src/test/resources/se/ReturnAndFinally.java");
    SymbolicExecutionVisitor sev = visitorAndSemantic.a;
    SemanticModel semanticModel = visitorAndSemantic.b;
    assertThat(sev.behaviorCache.behaviors.entrySet()).hasSize(5);
    MethodBehavior foo = getMethodBehavior(sev, "foo");
    assertThat(foo.yields()).hasSize(4);
    assertThat(foo.happyPathYields()).hasSize(2);
    assertThat(foo.exceptionalPathYields()).hasSize(2);
    MethodBehavior qix = getMethodBehavior(sev, "qix");
    List<MethodYield> qixYield = qix.yields();
    assertThat(qixYield.stream().filter(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) != ObjectConstraint.NULL).allMatch(y -> y instanceof ExceptionalYield)).isTrue();
    assertThat(qixYield.stream().filter(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) == ObjectConstraint.NULL && y instanceof ExceptionalYield).count()).isEqualTo(2);
    assertThat(qixYield.stream().filter(y -> y instanceof HappyPathYield).allMatch(y -> y.parametersConstraints.get(0).get(ObjectConstraint.class) == ObjectConstraint.NULL)).isTrue();
    MethodBehavior returnInFinally = getMethodBehavior(sev, "returnInFinally");
    assertThat(returnInFinally.yields()).hasSize(1);
    assertThat(returnInFinally.happyPathYields()).hasSize(1);
    MethodBehavior returningException = getMethodBehavior(sev, "returningException");
    assertThat(returningException.yields()).hasSize(3);
    assertThat(returningException.happyPathYields()).hasSize(2);
    assertThat(returningException.exceptionalPathYields()).hasSize(1);
    MethodBehavior rethrowingException = getMethodBehavior(sev, "rethrowingException");
    assertThat(rethrowingException.yields()).hasSize(4);
    assertThat(rethrowingException.happyPathYields()).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields()).hasSize(3);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).is("java.lang.Exception"))).hasSize(1);
    assertThat(rethrowingException.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).is("org.foo.MyException"))).hasSize(1);
}
Also used : ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Collectors(java.util.stream.Collectors) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) List(java.util.List) Pair(org.sonar.java.se.Pair) SemanticModel(org.sonar.java.resolve.SemanticModel) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) SETestUtils.createSymbolicExecutionVisitorAndSemantic(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitorAndSemantic) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) Nullable(javax.annotation.Nullable) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.getMethodBehavior(org.sonar.java.se.SETestUtils.getMethodBehavior) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SymbolicExecutionVisitor(org.sonar.java.se.SymbolicExecutionVisitor) Test(org.junit.Test)

Aggregations

SemanticModel (org.sonar.java.resolve.SemanticModel)19 Test (org.junit.Test)13 SquidClassLoader (org.sonar.java.bytecode.loader.SquidClassLoader)9 ArrayList (java.util.ArrayList)8 List (java.util.List)8 CompilationUnitTree (org.sonar.plugins.java.api.tree.CompilationUnitTree)8 File (java.io.File)7 Collectors (java.util.stream.Collectors)7 SETestUtils.createSymbolicExecutionVisitor (org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor)7 SETestUtils.getMethodBehavior (org.sonar.java.se.SETestUtils.getMethodBehavior)7 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)7 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)6 SETestUtils.mockMethodBehavior (org.sonar.java.se.SETestUtils.mockMethodBehavior)5 SymbolicExecutionVisitor (org.sonar.java.se.SymbolicExecutionVisitor)5 BehaviorCache (org.sonar.java.se.xproc.BehaviorCache)5 MethodBehavior (org.sonar.java.se.xproc.MethodBehavior)5 ImmutableList (com.google.common.collect.ImmutableList)4 Lists (com.google.common.collect.Lists)4 Set (java.util.Set)4 Nullable (javax.annotation.Nullable)4