use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ClassWithOnlyStaticMethodsInstantiationCheck method visitNode.
@Override
public void visitNode(Tree tree) {
TypeTree identifier = ((NewClassTree) tree).identifier();
Symbol.TypeSymbol newClassTypeSymbol = identifier.symbolType().symbol();
if (!newClassTypeSymbol.isEnum() && hasOnlyStaticMethodsAndFields(newClassTypeSymbol) && !instantiateOwnClass(identifier, newClassTypeSymbol)) {
String message = "Remove this instantiation.";
String name = getNewClassName(identifier);
if (name != null) {
message = "Remove this instantiation of \"{0}\".";
}
reportIssue(identifier, MessageFormat.format(message, name));
}
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ReassignmentFinderTest method ignore_assignation_after_starting_point.
@Test
public void ignore_assignation_after_starting_point() throws Exception {
String code = newCode("int foo() {", " int b = 0;", " doSomething(b);", " b = 1;", "}");
List<StatementTree> statements = methodBody(code);
Tree expectedVariableDeclaration = initializerFromVariableDeclarationStatement(statements.get(0));
MethodInvocationTree startingPoint = (MethodInvocationTree) ((ExpressionStatementTree) statements.get(1)).expression();
Symbol searchedVariable = ((IdentifierTree) startingPoint.arguments().get(0)).symbol();
assertThatLastReassignmentsOfVariableIsEqualTo(searchedVariable, startingPoint, expectedVariableDeclaration);
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ReassignmentFinderTest method ignore_assignation_after_starting_point_same_line.
@Test
public void ignore_assignation_after_starting_point_same_line() throws Exception {
String code = newCode("int foo() {", " int b = 0;", " doSomething(b); b = 1;", "}");
List<StatementTree> statements = methodBody(code);
Tree expectedVariableDeclaration = initializerFromVariableDeclarationStatement(statements.get(0));
MethodInvocationTree startingPoint = (MethodInvocationTree) ((ExpressionStatementTree) statements.get(1)).expression();
Symbol searchedVariable = ((IdentifierTree) startingPoint.arguments().get(0)).symbol();
assertThatLastReassignmentsOfVariableIsEqualTo(searchedVariable, startingPoint, expectedVariableDeclaration);
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ExplodedGraphWalker method startingStates.
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) {
Stream<ProgramState> stateStream = Stream.of(currentState);
boolean isEqualsMethod = EQUALS.matches(tree);
boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol());
boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol());
boolean hasMethodBehavior = methodBehavior != null;
for (final VariableTree variableTree : tree.parameters()) {
// create
final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree);
Symbol variableSymbol = variableTree.symbol();
if (hasMethodBehavior) {
methodBehavior.addParameter(sv);
}
stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv));
if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) {
stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat(sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()));
} else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) {
stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream());
}
}
return stateStream.collect(Collectors.toList());
}
use of org.sonar.plugins.java.api.semantic.Symbol 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);
}
}
Aggregations