use of org.sonar.java.se.Flow in project sonar-java by SonarSource.
the class DebugMethodYieldsOnInvocationsCheck method reportYields.
private void reportYields(MethodInvocationTree mit, CheckerDispatcher checkerDispatcher) {
MethodBehavior mb = checkerDispatcher.peekMethodBehavior((Symbol.MethodSymbol) mit.symbol());
if (mb != null && mb.isComplete()) {
IdentifierTree methodName = getIdentifier(mit.methodSelect());
String message = String.format("Method '%s' has %d method yields.", methodName.name(), mb.yields().size());
Set<Flow> flow = flowFromYield(mb, methodName);
reportIssue(methodName, message, flow);
}
}
use of org.sonar.java.se.Flow in project sonar-java by SonarSource.
the class MethodYieldTest method test_creation_of_flows.
@Test
public void test_creation_of_flows() throws Exception {
SymbolicExecutionVisitor sev = createSymbolicExecutionVisitor("src/test/files/se/XProcYieldsFlows.java");
MethodBehavior mb = getMethodBehavior(sev, "foo");
MethodYield methodYield = mb.happyPathYields().filter(y -> y.resultConstraint() != null && y.resultConstraint().get(ObjectConstraint.class) != ObjectConstraint.NULL).findFirst().get();
Set<Flow> flowReturnValue = methodYield.flow(ImmutableList.of(-1), Lists.newArrayList(ObjectConstraint.class));
assertThat(flowReturnValue.iterator().next().isEmpty()).isFalse();
Set<Flow> flowFirstParam = methodYield.flow(ImmutableList.of(0), Lists.newArrayList(ObjectConstraint.class, BooleanConstraint.class));
assertThat(flowFirstParam.iterator().next().isEmpty()).isFalse();
}
use of org.sonar.java.se.Flow in project sonar-java by SonarSource.
the class StreamNotConsumedCheck method checkEndOfExecutionPath.
@Override
public void checkEndOfExecutionPath(CheckerContext context, ConstraintManager constraintManager) {
if (context.getState().exitValue() instanceof SymbolicValue.ExceptionalSymbolicValue) {
// don't report when exiting on exception
return;
}
ProgramState state = context.getState();
List<SymbolicValue> notConsumed = state.getValuesWithConstraints(NOT_CONSUMED);
notConsumed.forEach(sv -> {
Set<Flow> flows = FlowComputation.flow(context.getNode(), Collections.singleton(sv), NOT_CONSUMED::equals, NOT_CONSUMED::equals, Collections.singletonList(StreamConsumedCheck.StreamPipelineConstraint.class), Collections.emptySet());
Flow flow = flows.iterator().next();
JavaFileScannerContext.Location location = flow.elements().get(0);
reportIssue(location.syntaxNode, "Refactor the code so this stream pipeline is used.");
});
}
use of org.sonar.java.se.Flow in project sonar-java by SonarSource.
the class ExceptionalYieldChecker method reportIssue.
private void reportIssue(ExplodedGraph.Node node, ExceptionalCheckBasedYield yield, SECheck check) {
MethodInvocationTree mit = (MethodInvocationTree) node.programPoint.syntaxTree();
ExpressionTree methodSelect = mit.methodSelect();
String methodName = mit.symbol().name();
Tree reportTree = methodSelect;
if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
reportTree = ((MemberSelectExpressionTree) methodSelect).identifier();
}
JavaFileScannerContext.Location methodInvocationMessage;
int parameterCausingExceptionIndex = yield.parameterCausingExceptionIndex();
IdentifierTree identifierTree = FlowComputation.getArgumentIdentifier(mit, parameterCausingExceptionIndex);
if (identifierTree != null) {
methodInvocationMessage = new JavaFileScannerContext.Location(String.format("'%s' is passed to '%s()'.", identifierTree.name(), methodName), identifierTree);
} else {
methodInvocationMessage = new JavaFileScannerContext.Location(String.format("'%s()' is invoked.", methodName), reportTree);
}
Flow argumentChangingNameFlows = flowsForArgumentsChangingName(yield, mit);
Set<Flow> argumentsFlows = flowsForMethodArguments(node, mit, parameterCausingExceptionIndex);
Set<Flow> exceptionFlows = yield.exceptionFlows();
ImmutableSet.Builder<Flow> flows = ImmutableSet.builder();
for (Flow argumentFlow : argumentsFlows) {
for (Flow exceptionFlow : exceptionFlows) {
flows.add(Flow.builder().addAll(exceptionFlow).addAll(argumentChangingNameFlows).add(methodInvocationMessage).addAll(argumentFlow).build());
}
}
check.reportIssue(reportTree, String.format(message, methodName), flows.build());
}
use of org.sonar.java.se.Flow in project sonar-java by SonarSource.
the class ExceptionalYieldChecker method flowsForMethodArguments.
private static Set<Flow> flowsForMethodArguments(ExplodedGraph.Node node, MethodInvocationTree mit, int parameterCausingExceptionIndex) {
ProgramState programState = node.programState;
List<ProgramState.SymbolicValueSymbol> arguments = Lists.reverse(programState.peekValuesAndSymbols(mit.arguments().size()));
SymbolicValue parameterCausingExceptionSV = arguments.get(parameterCausingExceptionIndex).symbolicValue();
Set<SymbolicValue> argSymbolicValues = new LinkedHashSet<>();
Set<Symbol> argSymbols = new LinkedHashSet<>();
arguments.stream().filter(svs -> parameterCausingExceptionSV == svs.symbolicValue() || hasConstraintOtherThanNonNull(svs, programState)).forEach(svs -> {
argSymbolicValues.add(svs.symbolicValue());
Symbol symbol = svs.symbol();
if (symbol != null) {
argSymbols.add(symbol);
}
});
List<Class<? extends Constraint>> domains = domainsFromArguments(programState, argSymbolicValues);
return FlowComputation.flow(node, argSymbolicValues, c -> true, c -> false, domains, argSymbols);
}
Aggregations