public void freshenParentAndChildIndexes(int offset) { int n = getChildCount(); for (int c = offset; c < n; c++) { PythonTree child = (PythonTree) getChild(c); child.setChildIndex(c); child.setParent(this); } }
/** * Delete children from start to stop and replace with t even if t is a list (nil-root tree). num * of children can increase or decrease. For huge child lists, inserting children can force * walking rest of children to set their childindex; could be slow. */ public void replaceChildren(int startChildIndex, int stopChildIndex, Object t) { /* System.out.println("replaceChildren "+startChildIndex+", "+stopChildIndex+ " with "+((PythonTree)t).toStringTree()); System.out.println("in="+toStringTree()); */ if (children == null) { throw new IllegalArgumentException("indexes invalid; no children in list"); } int replacingHowMany = stopChildIndex - startChildIndex + 1; int replacingWithHowMany; PythonTree newTree = (PythonTree) t; List newChildren = null; // normalize to a list of children to add: newChildren if (newTree.isNil()) { newChildren = newTree.children; } else { newChildren = new ArrayList(1); newChildren.add(newTree); } replacingWithHowMany = newChildren.size(); int numNewChildren = newChildren.size(); int delta = replacingHowMany - replacingWithHowMany; // if same number of nodes, do direct replace if (delta == 0) { int j = 0; // index into new children for (int i = startChildIndex; i <= stopChildIndex; i++) { PythonTree child = (PythonTree) newChildren.get(j); children.set(i, child); child.setParent(this); child.setChildIndex(i); j++; } } else if (delta > 0) { // fewer new nodes than there were // set children and then delete extra for (int j = 0; j < numNewChildren; j++) { children.set(startChildIndex + j, newChildren.get(j)); } int indexToDelete = startChildIndex + numNewChildren; for (int c = indexToDelete; c <= stopChildIndex; c++) { // delete same index, shifting everybody down each time PythonTree killed = (PythonTree) children.remove(indexToDelete); } freshenParentAndChildIndexes(startChildIndex); } else { // more new nodes than were there before // fill in as many children as we can (replacingHowMany) w/o moving data for (int j = 0; j < replacingHowMany; j++) { children.set(startChildIndex + j, newChildren.get(j)); } int numToInsert = replacingWithHowMany - replacingHowMany; for (int j = replacingHowMany; j < replacingWithHowMany; j++) { children.add(startChildIndex + j, newChildren.get(j)); } freshenParentAndChildIndexes(startChildIndex); } // System.out.println("out="+toStringTree()); }
/** * Add t as child of this node. * * <p>Warning: if t has no children, but child does and child isNil then this routine moves * children to t via t.children = child.children; i.e., without copying the array. */ public void addChild(PythonTree t) { // System.out.println("add child "+t.toStringTree()+" "+this.toStringTree()); // System.out.println("existing children: "+children); if (t == null) { return; // do nothing upon addChild(null) } PythonTree childTree = (PythonTree) t; if (childTree.isNil()) { // t is an empty node possibly with children if (this.children != null && this.children == childTree.children) { throw new RuntimeException("attempt to add child list to itself"); } // just add all of childTree's children to this if (childTree.children != null) { if (this.children != null) { // must copy, this has children already int n = childTree.children.size(); for (int i = 0; i < n; i++) { PythonTree c = (PythonTree) childTree.children.get(i); this.children.add(c); // handle double-link stuff for each child of nil root c.setParent(this); c.setChildIndex(children.size() - 1); } } else { // no children for this but t has children; just set pointer // call general freshener routine this.children = childTree.children; this.freshenParentAndChildIndexes(); } } } else { // child is not nil (don't care about children) if (children == null) { children = createChildrenList(); // create children list on demand } children.add(t); childTree.setParent(this); childTree.setChildIndex(children.size() - 1); } // System.out.println("now children are: "+children); }
public void setChild(int i, PythonTree t) { if (t == null) { return; } if (t.isNil()) { throw new IllegalArgumentException("Can't set single child to a list"); } if (children == null) { children = createChildrenList(); } children.set(i, t); t.setParent(this); t.setChildIndex(i); }