use of org.sonar.plugins.java.api.semantic.Symbol 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));
}
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ExplodedGraphWalker method executeIdentifier.
private void executeIdentifier(IdentifierTree tree) {
Symbol symbol = tree.symbol();
SymbolicValue value = programState.getValue(symbol);
if (value == null) {
value = constraintManager.createSymbolicValue(tree);
programState = programState.stackValue(value, symbol);
learnIdentifierConstraints(tree, value);
} else {
programState = programState.stackValue(value, symbol);
}
programState = programState.put(symbol, value);
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ProgramState method resetFieldValues.
ProgramState resetFieldValues(ConstraintManager constraintManager, boolean resetOnlyStaticFields) {
List<Symbol> fields = new ArrayList<>();
values.forEach((symbol, symbolicValue) -> {
if (isField(symbol) && !symbol.isFinal() && (symbol.isStatic() || !resetOnlyStaticFields)) {
fields.add(symbol);
}
});
ProgramState newProgramState = this;
for (Symbol field : fields) {
newProgramState = newProgramState.put(field, constraintManager.createDefaultSymbolicValue());
}
return newProgramState;
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class ProgramState method put.
@VisibleForTesting
public ProgramState put(Symbol symbol, SymbolicValue value) {
if (symbol.isUnknown() || isVolatileField(symbol)) {
return this;
}
SymbolicValue oldValue = values.get(symbol);
if (oldValue == null || oldValue != value) {
PMap<SymbolicValue, Integer> newReferences = references;
if (oldValue != null) {
newReferences = decreaseReference(newReferences, oldValue);
}
newReferences = increaseReference(newReferences, value);
PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value);
return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue);
}
return this;
}
use of org.sonar.plugins.java.api.semantic.Symbol in project sonar-java by SonarSource.
the class SymbolMetadataResolve method metaAnnotations.
private List<Symbol> metaAnnotations(Set<Type> knownTypes) {
List<Symbol> result = new ArrayList<>();
for (AnnotationInstance annotationInstance : annotations) {
Symbol annotationSymbol = annotationInstance.symbol();
Type annotationType = annotationSymbol.type();
if (!knownTypes.contains(annotationType)) {
knownTypes.add(annotationType);
result.add(annotationSymbol);
result.addAll(((SymbolMetadataResolve) annotationSymbol.metadata()).metaAnnotations(knownTypes));
}
}
return new ArrayList<>(result);
}
Aggregations