blob: 663eb15167c576a0089617b790dac6298712a85e [file] [log] [blame]
package org.checkerframework.dataflow.cfg.block;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.javacutil.BugInCF;
/** Base class of the {@link Block} implementation hierarchy. */
public class ExceptionBlockImpl extends SingleSuccessorBlockImpl implements ExceptionBlock {
/** The node of this block. */
protected @Nullable Node node;
/** Set of exceptional successors. */
protected final Map<TypeMirror, Set<Block>> exceptionalSuccessors;
/** Create an empty exceptional block. */
public ExceptionBlockImpl() {
super(BlockType.EXCEPTION_BLOCK);
exceptionalSuccessors = new LinkedHashMap<>(2);
}
/** Set the node. */
public void setNode(Node c) {
node = c;
c.setBlock(this);
}
@Override
public Node getNode() {
if (node == null) {
throw new BugInCF("Requested node for exception block before initialization");
}
return node;
}
/**
* {@inheritDoc}
*
* <p>This implementation returns a singleton list.
*/
@Override
public List<Node> getNodes() {
return Collections.singletonList(getNode());
}
@Override
public @Nullable Node getLastNode() {
return null;
}
/**
* Add an exceptional successor.
*
* @param b the successor
* @param cause the exception type that leads to the given block
*/
public void addExceptionalSuccessor(BlockImpl b, TypeMirror cause) {
Set<Block> blocks = exceptionalSuccessors.computeIfAbsent(cause, __ -> new LinkedHashSet<>());
blocks.add(b);
b.addPredecessor(this);
}
@Override
public Map<TypeMirror, Set<Block>> getExceptionalSuccessors() {
if (exceptionalSuccessors == null) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(exceptionalSuccessors);
}
@Override
public Set<Block> getSuccessors() {
Set<Block> result = new LinkedHashSet<>(super.getSuccessors());
for (Set<? extends Block> blocks : getExceptionalSuccessors().values()) {
result.addAll(blocks);
}
return result;
}
@Override
public String toString() {
return "ExceptionBlock(" + node + ")";
}
}