181 result.addAll(c.getStackableLeaves()); 182 } 183 }); 184 return result; 185 } 186 187 public List<IRNode> getDeviantBlocks(long depth) { 188 List<IRNode> result = new ArrayList<>(); 189 children.stream() 190 .filter(c -> !Objects.isNull(c)) 191 .forEach(c -> { 192 if (depth == c.level && c.isCFDeviation()) { 193 result.add(c); 194 } else { 195 result.addAll(c.getDeviantBlocks(depth)); 196 } 197 }); 198 return result; 199 } 200 201 // TODO: add field instead this function 202 public boolean isCFDeviation() { 203 return this instanceof If || this instanceof Switch 204 || this instanceof For || this instanceof While 205 || this instanceof DoWhile 206 || (this instanceof Block && this.parent instanceof Block); 207 } 208 } | 181 result.addAll(c.getStackableLeaves()); 182 } 183 }); 184 return result; 185 } 186 187 public List<IRNode> getDeviantBlocks(long depth) { 188 List<IRNode> result = new ArrayList<>(); 189 children.stream() 190 .filter(c -> !Objects.isNull(c)) 191 .forEach(c -> { 192 if (depth == c.level && c.isCFDeviation()) { 193 result.add(c); 194 } else { 195 result.addAll(c.getDeviantBlocks(depth)); 196 } 197 }); 198 return result; 199 } 200 201 public static long getModifiableNodesCount(List<IRNode> nodes) { 202 return nodes.stream() 203 .map(IRNode::getStackableLeaves) 204 .mapToInt(List::size) 205 .filter(i -> i > 0) 206 .count(); 207 } 208 209 public static boolean tryToReduceNodesDepth(List<IRNode> nodes, int maxDepth) { 210 boolean allSucceed = true; 211 for (IRNode child : nodes) { 212 for (IRNode leaf : child.getDeviantBlocks(Math.max(child.countDepth(), maxDepth + 1))) { 213 if (child.countDepth() > maxDepth) { 214 // doesn't remove control deviation block. Just some parts. 215 leaf.removeSelf(); 216 boolean successfull = child.countDepth() > maxDepth; 217 allSucceed &= successfull; 218 } else { 219 break; 220 } 221 } 222 } 223 return allSucceed; 224 } 225 226 // TODO: add field instead this function 227 public boolean isCFDeviation() { 228 return this instanceof If || this instanceof Switch 229 || this instanceof For || this instanceof While 230 || this instanceof DoWhile 231 || (this instanceof Block && this.parent instanceof Block); 232 } 233 } |