public List<AbstractNode> findChildren(int opcode) { List<AbstractNode> children = new ArrayList<>(); for (AbstractNode n : this) { if (n.opcode() == opcode) children.add(n); } return !children.isEmpty() ? children : null; }
@SuppressWarnings("unchecked") public <T extends AbstractNode> T first(Class<? extends AbstractNode> clazz) { for (AbstractNode n : this) { if (n.getClass().equals(clazz)) return (T) n; } return null; }
public int total() { int size = 1; for (AbstractNode n : this) { size += n.total(); } return size; }
public AbstractNode preLayer(int... opcodes) { AbstractNode node = this; for (int opcode : opcodes) { node = node.parent(); if (node == null || node.opcode() != opcode) return null; } return node; }
public AbstractNode previous(int opcode, int max) { int i = 0; AbstractNode prev = this; while ((prev = prev.previous()) != null && i++ < max) { if (prev.opcode() == opcode) return prev; } return null; }
public AbstractNode next(int opcode, int max) { int i = 0; AbstractNode next = this; while ((next = next.next()) != null && i++ < max) { if (next.opcode() == opcode) return next; } return null; }
public MethodMemberNode firstMethod() { for (AbstractNode n : this) { if (n instanceof ReferenceNode) { if (n.insn() instanceof MethodInsnNode) return (MethodMemberNode) n; } } return null; }
public FieldMemberNode firstField() { for (AbstractNode n : this) { if (n instanceof ReferenceNode) { if (n.insn() instanceof FieldInsnNode) return (FieldMemberNode) n; } } return null; }
@SuppressWarnings("unchecked") public <T extends AbstractNode> T next(Class<? extends AbstractNode> clazz, int max) { int i = 0; AbstractNode next = this; while ((next = next.next()) != null && i++ < max) { if (next.getClass().equals(clazz)) return (T) next; } return null; }
public AbstractNode find(int opcode, int index) { int i = 0; for (AbstractNode n : this) { if (n.opcode() == opcode) { if (i++ == index) return n; } } return null; }
protected String toString(int tab) { StringBuilder sb = new StringBuilder(); sb.append(Assembly.toString(insn)); for (AbstractNode n : this) { sb.append('\n'); for (int i = 0; i < tab; i++) { sb.append('\t'); } sb.append(n.toString(tab + 1)); } return sb.toString(); }
public AbstractInsnNode[] collapse() { if (instructions != null) { return instructions; } instructions = new AbstractInsnNode[total()]; int i = 0; for (AbstractNode n : this) { AbstractInsnNode[] nodes = n.collapse(); System.arraycopy(nodes, 0, instructions, i, nodes.length); i += nodes.length; } if (instructions.length - i != 1) { throw new RuntimeException(); } instructions[i] = insn(); return instructions; }
public List<AbstractNode> layerAll(int... opcodes) { List<AbstractNode> children = findChildren(opcodes[0]); if (children == null) return null; if (opcodes.length == 1) return children; for (int i = 1; i < opcodes.length; i++) { List<AbstractNode> next = new ArrayList<>(); for (AbstractNode n : children) { List<AbstractNode> match = n.findChildren(opcodes[i]); if (match == null) continue; next.addAll(match); } if (next.isEmpty()) { return null; } else { children.clear(); children.addAll(next); } } return children; }
public AbstractNode first(int opcode) { for (AbstractNode n : this) { if (n.opcode() == opcode) return n; } return null; }