use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.
the class SimpleClassNameCheck method checkImports.
private void checkImports(List<ImportTree> imports) {
SemanticModel semanticModel = (SemanticModel) context.getSemanticModel();
imports.stream().map(semanticModel::getSymbol).filter(Objects::nonNull).forEach(this::checkSymbol);
}
use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method unchecked_exceptions_should_be_enqueued.
@Test
public void unchecked_exceptions_should_be_enqueued() {
MethodBehavior mb = getMethodBehavior(ExceptionEnqueue.class, "test(Lorg/sonar/java/bytecode/se/testdata/ExceptionEnqueue;)Ljava/lang/Object;");
List<Constraint> resultConstraint = mb.happyPathYields().map(y -> y.resultConstraint().get(ObjectConstraint.class)).collect(Collectors.toList());
assertThat(resultConstraint).contains(ObjectConstraint.NOT_NULL, ObjectConstraint.NULL);
List<String> exceptions = mb.exceptionalPathYields().map(y -> y.exceptionType(semanticModel).fullyQualifiedName()).collect(Collectors.toList());
assertThat(exceptions).contains("org.sonar.java.bytecode.se.testdata.ExceptionEnqueue$ExceptionCatch", "org.sonar.java.bytecode.se.testdata.ExceptionEnqueue$ThrowableCatch", "org.sonar.java.bytecode.se.testdata.ExceptionEnqueue$ErrorCatch");
}
use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.
the class ExceptionalCheckBasedYieldTest method creation_of_new_yield.
@Test
public void creation_of_new_yield() {
String methodName = "method";
SymbolicExecutionVisitor sev;
MethodBehavior mb;
Pair<SymbolicExecutionVisitor, SemanticModel> visitorAndSemantic = createSymbolicExecutionVisitorAndSemantic(FILENAME);
sev = visitorAndSemantic.a;
SemanticModel semanticModel = visitorAndSemantic.b;
mb = getMethodBehavior(sev, methodName);
// no creation of custom yields, 3 method yields
assertThat(mb.yields()).hasSize(3);
assertThat(mb.happyPathYields()).hasSize(1);
assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == null)).hasSize(1);
assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(0);
assertThat(mb.happyPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(0);
assertThat(mb.exceptionalPathYields()).hasSize(2);
assertThat(mb.exceptionalPathYields()).as("All the exceptional yields are runtime exceptions").allMatch(y -> y.exceptionType(semanticModel).isUnknown());
assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE)).hasSize(1);
assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
// new rule discard any call to plantFlowers(true) by creating a new yield
SECheck check = new TestSECheck();
sev = createSymbolicExecutionVisitor(FILENAME, check);
mb = getMethodBehavior(sev, methodName);
assertThat(mb.yields()).hasSize(4);
// 2nd param can never be null
assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(0).isEmpty() && y.parametersConstraints.get(1).get(ObjectConstraint.class) == ObjectConstraint.NULL)).hasSize(1);
assertThat(mb.yields().stream().filter(y -> y.parametersConstraints.get(1).get(ObjectConstraint.class) != ObjectConstraint.NULL)).hasSize(3);
// happyPath with first parameter being true is discarded
assertThat(mb.happyPathYields()).hasSize(2);
// still 2 exceptional path
assertThat(mb.exceptionalPathYields()).hasSize(2);
assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isUnknown())).hasSize(1);
assertThat(mb.exceptionalPathYields().filter(y -> y.exceptionType(semanticModel).isClass())).hasSize(1);
assertThat(mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.FALSE)).hasSize(1);
ExceptionalYield exceptionalYield = mb.exceptionalPathYields().filter(y -> y.parametersConstraints.get(0).get(BooleanConstraint.class) == BooleanConstraint.TRUE).findFirst().get();
assertThat(exceptionalYield).isInstanceOf(ExceptionalCheckBasedYield.class);
ExceptionalCheckBasedYield seCheckExceptionalYield = (ExceptionalCheckBasedYield) exceptionalYield;
assertThat(seCheckExceptionalYield.check()).isEqualTo(TestSECheck.class);
assertThat(seCheckExceptionalYield.exceptionType(semanticModel)).isNotNull();
assertThat(seCheckExceptionalYield.exceptionType(semanticModel).is("java.lang.UnsupportedOperationException")).isTrue();
assertThat(seCheckExceptionalYield.exceptionType(semanticModel).isSubtypeOf("java.lang.RuntimeException")).isTrue();
assertThat(seCheckExceptionalYield.generatedByCheck(check)).isTrue();
assertThat(seCheckExceptionalYield.generatedByCheck(new SECheck() {
})).isFalse();
assertThat(seCheckExceptionalYield.parameterCausingExceptionIndex()).isEqualTo(0);
}
use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.
the class ExplodedGraphWalker method executeMethodInvocation.
private void executeMethodInvocation(MethodInvocationTree mit) {
setSymbolicValueOnFields(mit);
// unstack arguments and method identifier
ProgramState.Pop unstack = programState.unstackValue(mit.arguments().size() + 1);
logState(mit);
programState = unstack.state;
// get method behavior for method with known declaration (ie: within the same file)
MethodBehavior methodInvokedBehavior = null;
Symbol methodSymbol = mit.symbol();
if (methodSymbol.isMethodSymbol()) {
methodInvokedBehavior = behaviorCache.get((Symbol.MethodSymbol) methodSymbol);
}
// Enqueue additional exceptional paths corresponding to unchecked exceptions, for instance OutOfMemoryError
enqueueUncheckedExceptionalPaths(methodSymbol);
final SymbolicValue resultValue = constraintManager.createMethodSymbolicValue(mit, unstack.valuesAndSymbols);
if (methodInvokedBehavior != null && methodInvokedBehavior.isComplete() && !EQUALS_METHODS.anyMatch(mit)) {
List<SymbolicValue> invocationArguments = invocationArguments(unstack.values);
List<Type> invocationTypes = mit.arguments().stream().map(ExpressionTree::symbolType).collect(Collectors.toList());
Map<Type, SymbolicValue.ExceptionalSymbolicValue> thrownExceptionsByExceptionType = new HashMap<>();
// Enqueue exceptional paths from exceptional yields
methodInvokedBehavior.exceptionalPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> thrownExceptionsByExceptionType.computeIfAbsent(yield.exceptionType(semanticModel), constraintManager::createExceptionalSymbolicValue)).forEach(psYield -> enqueueExceptionalPaths(psYield, methodSymbol, yield)));
// Enqueue happy paths
methodInvokedBehavior.happyPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> resultValue).map(psYield -> handleSpecialMethods(psYield, mit)).forEach(psYield -> enqueueHappyPath(psYield, mit, yield)));
} else {
// Enqueue exceptional paths from thrown exceptions
enqueueThrownExceptionalPaths(methodSymbol);
// Enqueue happy paths
programState = handleSpecialMethods(programState.stackValue(resultValue), mit);
checkerDispatcher.executeCheckPostStatement(mit);
clearStack(mit);
}
}
use of org.sonar.java.resolve.SemanticModel in project sonar-java by SonarSource.
the class ExplodedGraphWalkerTest method test_cleanup_state.
@Test
public void test_cleanup_state() {
final int[] steps = new int[2];
JavaCheckVerifier.verifyNoIssue("src/test/files/se/SeEngineTestCleanupState.java", new SymbolicExecutionVisitor(Collections.emptyList(), new BehaviorCache(new SquidClassLoader(new ArrayList<>()))) {
@Override
public void visitNode(Tree tree) {
ExplodedGraphWalker explodedGraphWalker = new ExplodedGraphWalker(this.behaviorCache, (SemanticModel) context.getSemanticModel(), false);
explodedGraphWalker.visitMethod((MethodTree) tree, methodBehaviorForSymbol(((MethodTree) tree).symbol()));
steps[0] += explodedGraphWalker.steps;
}
});
JavaCheckVerifier.verifyNoIssue("src/test/files/se/SeEngineTestCleanupState.java", new SymbolicExecutionVisitor(Collections.emptyList(), new BehaviorCache(new SquidClassLoader(new ArrayList<>()))) {
@Override
public void visitNode(Tree tree) {
ExplodedGraphWalker explodedGraphWalker = new ExplodedGraphWalker(this.behaviorCache, (SemanticModel) context.getSemanticModel());
MethodTree methodTree = (MethodTree) tree;
explodedGraphWalker.visitMethod(methodTree, methodBehaviorForSymbol(methodTree.symbol()));
steps[1] += explodedGraphWalker.steps;
}
});
assertThat(steps[0]).isPositive();
assertThat(steps[0]).isGreaterThan(steps[1]);
}
Aggregations