Search in sources :

Example 11 with SemanticModel

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);
}
Also used : SemanticModel(org.sonar.java.resolve.SemanticModel)

Example 12 with SemanticModel

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");
}
Also used : BytecodeTestClass(org.sonar.java.bytecode.se.testdata.BytecodeTestClass) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) Iterables(com.google.common.collect.Iterables) BeforeClass(org.junit.BeforeClass) ProgramState(org.sonar.java.se.ProgramState) MethodYield(org.sonar.java.se.xproc.MethodYield) CompilationUnitTree(org.sonar.plugins.java.api.tree.CompilationUnitTree) ExceptionEnqueue(org.sonar.java.bytecode.se.testdata.ExceptionEnqueue) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) Lists(com.google.common.collect.Lists) Assertions.assertThat(org.fest.assertions.Assertions.assertThat) FinalBytecodeTestClass(org.sonar.java.bytecode.se.testdata.FinalBytecodeTestClass) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) JavaParser(org.sonar.java.ast.parser.JavaParser) Collection(java.util.Collection) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) MaxRelationBytecode(org.sonar.java.bytecode.se.testdata.MaxRelationBytecode) FileUtils(org.apache.commons.io.FileUtils) Test(org.junit.Test) Type(org.sonar.plugins.java.api.semantic.Type) Collectors(java.util.stream.Collectors) File(java.io.File) List(java.util.List) Rule(org.junit.Rule) LogTester(org.sonar.api.utils.log.LogTester) SemanticModel(org.sonar.java.resolve.SemanticModel) ByteStreams(com.google.common.io.ByteStreams) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Constraint(org.sonar.java.se.constraint.Constraint) ExceptionalYield(org.sonar.java.se.xproc.ExceptionalYield) HappyPathYield(org.sonar.java.se.xproc.HappyPathYield) LoggerLevel(org.sonar.api.utils.log.LoggerLevel) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) Test(org.junit.Test)

Example 13 with SemanticModel

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);
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) SemanticModel(org.sonar.java.resolve.SemanticModel) SETestUtils.mockMethodBehavior(org.sonar.java.se.SETestUtils.mockMethodBehavior) 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)

Example 14 with SemanticModel

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);
    }
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) ExpressionUtils(org.sonar.java.model.ExpressionUtils) MethodYield(org.sonar.java.se.xproc.MethodYield) Loggers(org.sonar.api.utils.log.Loggers) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) SECheck(org.sonar.java.se.checks.SECheck) RedundantAssignmentsCheck(org.sonar.java.se.checks.RedundantAssignmentsCheck) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) Map(java.util.Map) MethodMatcher(org.sonar.java.matcher.MethodMatcher) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) ImmutableSet(com.google.common.collect.ImmutableSet) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) Collection(java.util.Collection) Set(java.util.Set) JavaTree(org.sonar.java.model.JavaTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Collectors(java.util.stream.Collectors) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) DebugCheck(org.sonar.java.DebugCheck) StreamConsumedCheck(org.sonar.java.se.checks.StreamConsumedCheck) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) Joiner(com.google.common.base.Joiner) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) NullableAnnotationUtils.isAnnotatedNonNull(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNonNull) HashMap(java.util.HashMap) Deque(java.util.Deque) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNullable(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNullable) ArrayList(java.util.ArrayList) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) JavaType(org.sonar.java.resolve.JavaType) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) ConstraintManager(org.sonar.java.se.constraint.ConstraintManager) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) NoWayOutLoopCheck(org.sonar.java.se.checks.NoWayOutLoopCheck) LiveVariables(org.sonar.java.cfg.LiveVariables) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) LinkedList(java.util.LinkedList) MethodMatcherCollection(org.sonar.java.matcher.MethodMatcherCollection) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) Logger(org.sonar.api.utils.log.Logger) UnclosedResourcesCheck(org.sonar.java.se.checks.UnclosedResourcesCheck) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) Types(org.sonar.java.resolve.Types) Iterator(java.util.Iterator) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) OptionalGetBeforeIsPresentCheck(org.sonar.java.se.checks.OptionalGetBeforeIsPresentCheck) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) NonNullSetToNullCheck(org.sonar.java.se.checks.NonNullSetToNullCheck) CFG(org.sonar.java.cfg.CFG) SemanticModel(org.sonar.java.resolve.SemanticModel) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) CheckForNull(javax.annotation.CheckForNull) LocksNotUnlockedCheck(org.sonar.java.se.checks.LocksNotUnlockedCheck) NullableAnnotationUtils.isAnnotatedNullable(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNullable) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) HashMap(java.util.HashMap) JavaSymbol(org.sonar.java.resolve.JavaSymbol) Symbol(org.sonar.plugins.java.api.semantic.Symbol) JavaType(org.sonar.java.resolve.JavaType) Type(org.sonar.plugins.java.api.semantic.Type) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 15 with SemanticModel

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]);
}
Also used : MethodTree(org.sonar.plugins.java.api.tree.MethodTree) SemanticModel(org.sonar.java.resolve.SemanticModel) ArrayList(java.util.ArrayList) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) SETestUtils.createSymbolicExecutionVisitor(org.sonar.java.se.SETestUtils.createSymbolicExecutionVisitor) SquidClassLoader(org.sonar.java.bytecode.loader.SquidClassLoader) 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