87 content.add(rule.produce()); 88 } catch (ProductionFailedException e) { 89 } 90 } 91 } 92 ensureMinDepth(content); 93 ensureMaxDepth(content); 94 return new ClassDefinitionBlock(content, level); 95 } 96 97 private void ensureMinDepth(Collection<IRNode> content) throws ProductionFailedException { 98 int minDepth = ProductionParams.minCfgDepth.value(); 99 List<IRNode> childs = content.stream() 100 .filter(c -> c instanceof Klass) 101 .collect(Collectors.toList()); 102 addMoreChildren(childs, content, minDepth); 103 } 104 105 private void addMoreChildren(List<IRNode> childs, Collection<IRNode> content, int minDepth) 106 throws ProductionFailedException { 107 while (!childs.isEmpty() && IRNode.countDepth(content) < minDepth) { 108 PseudoRandom.shuffle(childs); 109 IRNode randomChild = childs.get(0); 110 List<IRNode> leaves = randomChild.getStackableLeaves(); 111 if (!leaves.isEmpty()) { 112 Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size())); 113 TypeKlass owner = randomChild.getOwner(); 114 int newLevel = randomLeaf.getLevel() + 1; 115 Type retType = randomLeaf.getResultType(); 116 IRNodeBuilder b = new IRNodeBuilder() 117 .setOwnerKlass(owner) 118 .setResultType(retType) 119 .setComplexityLimit(complexityLimit) 120 .setStatementLimit(statementLimit) 121 .setOperatorLimit(operatorLimit) 122 .setLevel(newLevel); 123 IRNode newBlock = b.getBlockFactory().produce(); 124 List<IRNode> siblings = randomLeaf.getChildren(); 125 // to avoid break; 126 int index = PseudoRandom.randomNotZero(siblings.size() - 1); 127 siblings.add(index, newBlock); 128 } 129 } 130 } 131 132 private void ensureMaxDepth(Collection<IRNode> content) { 133 int maxDepth = ProductionParams.maxCfgDepth.value(); 134 List<IRNode> childs = content.stream() 135 .filter(c -> c instanceof Klass && c.countDepth() > maxDepth) 136 .collect(Collectors.toList()); 137 for (IRNode ch : childs) { 138 List<IRNode> leaves; 139 do { 140 long depth = Math.max(ch.countDepth(), maxDepth + 1); 141 leaves = ch.getDeviantBlocks(depth); 142 if(leaves.size() > 0) { 143 leaves.get(0).removeSelf(); 144 } 145 } while (!leaves.isEmpty() && ch.countDepth() > maxDepth); 146 } 147 } 148 } | 87 content.add(rule.produce()); 88 } catch (ProductionFailedException e) { 89 } 90 } 91 } 92 ensureMinDepth(content); 93 ensureMaxDepth(content); 94 return new ClassDefinitionBlock(content, level); 95 } 96 97 private void ensureMinDepth(Collection<IRNode> content) throws ProductionFailedException { 98 int minDepth = ProductionParams.minCfgDepth.value(); 99 List<IRNode> childs = content.stream() 100 .filter(c -> c instanceof Klass) 101 .collect(Collectors.toList()); 102 addMoreChildren(childs, content, minDepth); 103 } 104 105 private void addMoreChildren(List<IRNode> childs, Collection<IRNode> content, int minDepth) 106 throws ProductionFailedException { 107 /* check situation when no stackable leaves available in all childs */ 108 if (childs.stream().filter(c -> c.getStackableLeaves().size() > 0).count() == 0) { 109 return; 110 } 111 /* not let's try to add children */ 112 while (!childs.isEmpty() && IRNode.countDepth(content) < minDepth) { 113 PseudoRandom.shuffle(childs); 114 IRNode randomChild = childs.get(0); 115 List<IRNode> leaves = randomChild.getStackableLeaves(); 116 if (!leaves.isEmpty()) { 117 Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size())); 118 TypeKlass owner = randomChild.getOwner(); 119 int newLevel = randomLeaf.getLevel() + 1; 120 Type retType = randomLeaf.getResultType(); 121 IRNodeBuilder b = new IRNodeBuilder() 122 .setOwnerKlass(owner) 123 .setResultType(retType) 124 .setComplexityLimit(complexityLimit) 125 .setStatementLimit(statementLimit) 126 .setOperatorLimit(operatorLimit) 127 .setLevel(newLevel); 128 IRNode newBlock = b.getBlockFactory().produce(); 129 List<IRNode> siblings = randomLeaf.getChildren(); 130 // to avoid break; 131 int index = PseudoRandom.randomNotZero(siblings.size() - 1); 132 siblings.add(index, newBlock); 133 } 134 } 135 } 136 137 private void ensureMaxDepth(Collection<IRNode> content) { 138 int maxDepth = ProductionParams.maxCfgDepth.value(); 139 List<IRNode> childClasses = content.stream() 140 .filter(c -> c instanceof Klass && c.countDepth() > maxDepth) 141 .collect(Collectors.toList()); 142 /* Now attempt to reduce depth by removing optional parts of control deviation 143 blocks in case IRTree has oversized depth */ 144 for (IRNode child : childClasses) { 145 for (IRNode leaf : child.getDeviantBlocks(Math.max(child.countDepth(), maxDepth + 1))) { 146 if (child.countDepth() > maxDepth) { 147 leaf.removeSelf(); // Doesn't remove control deviation block. Just some parts. 148 } 149 } 150 } 151 } 152 } |