Skip to content

Commit

Permalink
Decrease duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardo-pilastri-sonarsource committed May 30, 2024
1 parent 9fcaeb4 commit 54ef591
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 410 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ public final class CollectionUtils {
private CollectionUtils() {
}

private static int size(Iterator<?> iterator) {
int count;
for(count = 0; iterator.hasNext(); ++count) {
iterator.next();
}

return count;
}

@Nullable
public static <T> T getFirst(Iterable<T> iterable, @Nullable T defaultValue) {
Iterator<T> iterator = iterable.iterator();
Expand All @@ -38,13 +47,4 @@ public static int size(Iterable<?> iterable) {
return iterable instanceof Collection<?> collection ? collection.size() : size(iterable.iterator());
}

private static int size(Iterator<?> iterator) {
int count;
for(count = 0; iterator.hasNext(); ++count) {
iterator.next();
}

return count;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,12 @@ private void initialize(Block block, Map<Tree, CFGLoop> container) {
collectWaysOut(container);
}

Collection<Block> successors() {
return new ArrayList<>(successors);
}

public boolean hasNoWayOut() {
return successors.isEmpty();
}

private void collectBlocks(Block block, Map<Tree, CFGLoop> container) {
collectBlocks(block, container, new HashSet<>());
Collection<Block> successors() {
return new ArrayList<>(successors);
}

private boolean collectBlocks(Block block, Map<Tree, CFGLoop> container, Set<Block> visitedBlocks) {
Expand All @@ -78,20 +74,8 @@ private boolean collectBlocks(Block block, Map<Tree, CFGLoop> container, Set<Blo
return answer;
}

private boolean returnsToStart(Block block, Map<Tree, CFGLoop> container, Set<Block> visitedBlocks) {
Set<? extends Block> localSuccessors = localSuccessors(block, container);
if (localSuccessors == null) {
return true;
}
boolean answer = false;
for (Block successor : localSuccessors) {
if (startingBlock.id() == successor.id()) {
answer = true;
} else {
answer |= collectBlocks(successor, container, visitedBlocks);
}
}
return answer;
private void collectBlocks(Block block, Map<Tree, CFGLoop> container) {
collectBlocks(block, container, new HashSet<>());
}

@CheckForNull
Expand All @@ -113,9 +97,20 @@ private static Set<? extends Block> localSuccessors(Block block, Map<Tree, CFGLo
return block.successors();
}

private static boolean isBreak(Block block) {
Tree terminator = block.terminator();
return terminator != null && terminator.is(Tree.Kind.BREAK_STATEMENT);
private boolean returnsToStart(Block block, Map<Tree, CFGLoop> container, Set<Block> visitedBlocks) {
Set<? extends Block> localSuccessors = localSuccessors(block, container);
if (localSuccessors == null) {
return true;
}
boolean answer = false;
for (Block successor : localSuccessors) {
if (startingBlock.id() == successor.id()) {
answer = true;
} else {
answer |= collectBlocks(successor, container, visitedBlocks);
}
}
return answer;
}

private void collectWaysOut(Map<Tree, CFGLoop> container) {
Expand All @@ -131,9 +126,9 @@ private void collectWaysOut(Map<Tree, CFGLoop> container) {
successors.remove(startingBlock);
}

private static boolean isStarting(Block block) {
private static boolean isBreak(Block block) {
Tree terminator = block.terminator();
return terminator != null && terminator.is(Tree.Kind.FOR_STATEMENT, Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT);
return terminator != null && terminator.is(Tree.Kind.BREAK_STATEMENT);
}

public static Map<Tree, CFGLoop> getCFGLoops(ControlFlowGraph cfg) {
Expand All @@ -155,4 +150,9 @@ private static CFGLoop create(Block block, Map<Tree, CFGLoop> container) {
loop.initialize(block, container);
return loop;
}

private static boolean isStarting(Block block) {
Tree terminator = block.terminator();
return terminator != null && terminator.is(Tree.Kind.FOR_STATEMENT, Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,25 @@ private SELiveVariables(ControlFlowGraph cfg, boolean includeFields) {
this.includeFields = includeFields;
}

public Set<Symbol> getOut(ControlFlowGraph.Block block) {
return out.get(block);
private void analyzeControlFlowGraph(Map<ControlFlowGraph.Block, Set<Symbol>> in, Map<ControlFlowGraph.Block, Set<Symbol>> kill, Map<ControlFlowGraph.Block, Set<Symbol>> gen) {
Deque<ControlFlowGraph.Block> workList = new LinkedList<>();
workList.addAll(cfg.reversedBlocks());
while (!workList.isEmpty()) {
ControlFlowGraph.Block block = workList.removeFirst();

Set<Symbol> blockOut = out.computeIfAbsent(block, k -> new HashSet<>());
block.successors().stream().map(in::get).filter(Objects::nonNull).forEach(blockOut::addAll);
block.exceptions().stream().map(in::get).filter(Objects::nonNull).forEach(blockOut::addAll);
// in = gen and (out - kill)
Set<Symbol> newIn = new HashSet<>(gen.get(block));
newIn.addAll(SetUtils.difference(blockOut, kill.get(block)));

if (newIn.equals(in.get(block))) {
continue;
}
in.put(block, newIn);
block.predecessors().forEach(workList::addLast);
}
}

/**
Expand Down Expand Up @@ -93,24 +110,34 @@ private static SELiveVariables analyze(ControlFlowGraph cfg, boolean includeFiel
return liveVariables;
}

private void analyzeControlFlowGraph(Map<ControlFlowGraph.Block, Set<Symbol>> in, Map<ControlFlowGraph.Block, Set<Symbol>> kill, Map<ControlFlowGraph.Block, Set<Symbol>> gen) {
Deque<ControlFlowGraph.Block> workList = new LinkedList<>();
workList.addAll(cfg.reversedBlocks());
while (!workList.isEmpty()) {
ControlFlowGraph.Block block = workList.removeFirst();

Set<Symbol> blockOut = out.computeIfAbsent(block, k -> new HashSet<>());
block.successors().stream().map(in::get).filter(Objects::nonNull).forEach(blockOut::addAll);
block.exceptions().stream().map(in::get).filter(Objects::nonNull).forEach(blockOut::addAll);
// in = gen and (out - kill)
Set<Symbol> newIn = new HashSet<>(gen.get(block));
newIn.addAll(SetUtils.difference(blockOut, kill.get(block)));
public Set<Symbol> getOut(ControlFlowGraph.Block block) {
return out.get(block);
}

if (newIn.equals(in.get(block))) {
continue;
private void processMemberSelect(MemberSelectExpressionTree element, Set<Tree> assignmentLHS, Set<Symbol> blockGen) {
Symbol symbol;
if (!assignmentLHS.contains(element) && includeFields) {
symbol = getField(element);
if (symbol != null) {
blockGen.add(symbol);
}
in.put(block, newIn);
block.predecessors().forEach(workList::addLast);
}
}

private void processAssignment(AssignmentExpressionTree element, Set<Symbol> blockKill, Set<Symbol> blockGen, Set<Tree> assignmentLHS) {
Symbol symbol = null;
ExpressionTree lhs = element.variable();
if (lhs.is(Kind.IDENTIFIER)) {
symbol = ((IdentifierTree) lhs).symbol();

} else if (includeFields && lhs.is(Kind.MEMBER_SELECT)) {
symbol = getField((MemberSelectExpressionTree) lhs);
}

if (symbol != null && includeSymbol(symbol)) {
assignmentLHS.add(lhs);
blockGen.remove(symbol);
blockKill.add(symbol);
}
}

Expand Down Expand Up @@ -154,33 +181,6 @@ private void processIdentifier(IdentifierTree element, Set<Symbol> blockGen, Set
}
}

private void processMemberSelect(MemberSelectExpressionTree element, Set<Tree> assignmentLHS, Set<Symbol> blockGen) {
Symbol symbol;
if (!assignmentLHS.contains(element) && includeFields) {
symbol = getField(element);
if (symbol != null) {
blockGen.add(symbol);
}
}
}

private void processAssignment(AssignmentExpressionTree element, Set<Symbol> blockKill, Set<Symbol> blockGen, Set<Tree> assignmentLHS) {
Symbol symbol = null;
ExpressionTree lhs = element.variable();
if (lhs.is(Kind.IDENTIFIER)) {
symbol = ((IdentifierTree) lhs).symbol();

} else if (includeFields && lhs.is(Kind.MEMBER_SELECT)) {
symbol = getField((MemberSelectExpressionTree) lhs);
}

if (symbol != null && includeSymbol(symbol)) {
assignmentLHS.add(lhs);
blockGen.remove(symbol);
blockKill.add(symbol);
}
}

private boolean includeSymbol(Symbol symbol) {
return symbol.isLocalVariable() || (includeFields && isField(symbol));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ private CFGUtils(){
// utility class
}

public static final Predicate<ControlFlowGraph.Block> IS_CATCH_BLOCK = ControlFlowGraph.Block::isCatchBlock;

public static boolean isMethodExitBlock(ControlFlowGraph.Block block) {
return block.successors().isEmpty();
}

public static final Predicate<ControlFlowGraph.Block> IS_CATCH_BLOCK = ControlFlowGraph.Block::isCatchBlock;

}
Loading

0 comments on commit 54ef591

Please sign in to comment.