85 } 86 // TODO: Add enums 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 } | 85 } 86 // TODO: Add enums 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> children, Collection<IRNode> content, int minDepth) 106 throws ProductionFailedException { 107 /* check situation when no stackable leaves available in all children */ 108 if (IRNode.getModifiableNodesCount(children) == 0L) { 109 return; 110 } 111 /* now let's try to add children */ 112 while (!children.isEmpty() && IRNode.countDepth(content) < minDepth) { 113 PseudoRandom.shuffle(children); 114 IRNode randomChild = children.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> childrenClasses = 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 IRNode.tryToReduceNodesDepth(childrenClasses, maxDepth); 145 } 146 } |