use of org.sonar.java.se.xproc.MethodYield in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method test_enqueueing_of_catch_blocks2.
@Test
public void test_enqueueing_of_catch_blocks2() {
MethodBehavior mb = getMethodBehavior(ExceptionEnqueue.class, "testCatchBlockEnqueue2()Z");
List<MethodYield> yields = mb.yields();
assertThat(yields).hasSize(1);
// result should have TRUE constraint, but wrong yield with FALSE constraint is also created
// and two yields are reduced subsequently
assertThat(mb.happyPathYields().findFirst().get().resultConstraint()).isNull();
assertThat(mb.exceptionalPathYields().findFirst().isPresent()).isFalse();
}
use of org.sonar.java.se.xproc.MethodYield in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method test_method_throwing_exception.
@Test
public void test_method_throwing_exception() throws Exception {
MethodBehavior methodBehavior = getMethodBehavior("throw_exception()V");
assertThat(methodBehavior.yields()).hasSize(1);
MethodYield methodYield = methodBehavior.yields().get(0);
assertThat(methodYield).isInstanceOf(ExceptionalYield.class);
}
use of org.sonar.java.se.xproc.MethodYield in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method test_enqueueing_of_exit_block.
@Test
public void test_enqueueing_of_exit_block() {
MethodBehavior mb = getMethodBehavior(ExceptionEnqueue.class, "enqueueExitBlock()Z");
List<MethodYield> yields = mb.yields();
assertThat(yields).hasSize(1);
assertThat(mb.happyPathYields().findFirst().isPresent()).isFalse();
ExceptionalYield exceptionalYield = mb.exceptionalPathYields().findFirst().get();
Type exceptionType = exceptionalYield.exceptionType(semanticModel);
assertThat(exceptionType.is("java.io.FileNotFoundException")).isTrue();
}
use of org.sonar.java.se.xproc.MethodYield in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method method_returning_new_should_have_not_null_result.
@Test
public void method_returning_new_should_have_not_null_result() {
MethodBehavior mb = walker.getMethodBehavior(BytecodeEGWalkerExecuteTest.class.getCanonicalName() + "#newObject()Ljava/lang/Object;", squidClassLoader);
List<MethodYield> yields = mb.yields();
assertThat(yields).hasSize(1);
MethodYield yield = yields.get(0);
assertThat(yield).isInstanceOf(HappyPathYield.class);
ConstraintsByDomain resultConstraint = ((HappyPathYield) yield).resultConstraint();
assertThat(resultConstraint).isNotNull();
assertThat(resultConstraint.get(ObjectConstraint.class)).isEqualTo(ObjectConstraint.NOT_NULL);
TypedConstraint typeConstraint = (TypedConstraint) resultConstraint.get(TypedConstraint.class);
assertThat(typeConstraint.type.equals("java.lang.String")).isTrue();
}
use of org.sonar.java.se.xproc.MethodYield in project sonar-java by SonarSource.
the class ExplodedGraphWalker method enqueueExceptionalPaths.
private void enqueueExceptionalPaths(ProgramState ps, Symbol methodSymbol, @Nullable MethodYield methodYield) {
Set<CFG.Block> exceptionBlocks = ((CFG.Block) node.programPoint.block).exceptions();
List<CFG.Block> catchBlocks = exceptionBlocks.stream().filter(CFG.Block.IS_CATCH_BLOCK).collect(Collectors.toList());
SymbolicValue peekValue = ps.peekValue();
Preconditions.checkState(peekValue instanceof SymbolicValue.ExceptionalSymbolicValue, "Top of stack should always contains exceptional SV");
SymbolicValue.ExceptionalSymbolicValue exceptionSV = (SymbolicValue.ExceptionalSymbolicValue) peekValue;
// only consider the first match, as order of catch block is important
List<CFG.Block> caughtBlocks = catchBlocks.stream().filter(b -> isCaughtByBlock(exceptionSV.exceptionType(), b)).sorted((b1, b2) -> Integer.compare(b2.id(), b1.id())).collect(Collectors.toList());
if (!caughtBlocks.isEmpty()) {
caughtBlocks.forEach(b -> enqueue(new ProgramPoint(b), ps, methodYield));
return;
}
// branch to any unchecked exception catch
catchBlocks.stream().filter(ExplodedGraphWalker::isCatchingUncheckedException).forEach(b -> enqueue(new ProgramPoint(b), ps, methodYield));
// store the exception as exit value in case of method exit in next block
ps.storeExitValue();
// use other exceptional blocks, i.e. finally block and exit blocks
List<CFG.Block> otherBlocks = exceptionBlocks.stream().filter(CFG.Block.IS_CATCH_BLOCK.negate().or(b -> methodSymbol.isUnknown())).collect(Collectors.toList());
if (otherBlocks.isEmpty()) {
// explicitly add the exception branching to method exit
CFG.Block methodExit = node.programPoint.block.successors().stream().map(b -> (CFG.Block) b).filter(CFG.Block::isMethodExitBlock).findFirst().orElse(exitBlock);
enqueue(new ProgramPoint(methodExit), ps, true, methodYield);
} else {
otherBlocks.forEach(b -> enqueue(new ProgramPoint(b), ps, true, methodYield));
}
}
Aggregations