Add insertChild

This commit is contained in:
Clément Fournier
2020-04-26 18:28:47 +02:00
parent 3e892e1323
commit 13e414c73d
3 changed files with 56 additions and 18 deletions

View File

@ -22,6 +22,14 @@ abstract class AbstractApexNode<T extends AstNode> extends AbstractNodeWithTextC
this.node = node;
}
protected void addChild(AbstractApexNode<?> child, int index) {
super.addChild(child, index);
}
protected void insertChild(AbstractApexNode<?> child, int index) {
super.insertChild(child, index);
}
/* package */ void calculateLineNumbers(SourceCodePositioner positioner, int startOffset, int endOffset) {
// end column will be interpreted as inclusive, while endOffset/endIndex
// is exclusive

View File

@ -16,7 +16,6 @@ import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Token;
import net.sourceforge.pmd.lang.apex.ApexParserOptions;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
import apex.jorje.data.Location;
@ -283,8 +282,7 @@ final class ApexTreeBuilder extends AstVisitor<AdditionalPassScope> {
// Append to parent
AbstractApexNode<?> parent = nodes.isEmpty() ? null : nodes.peek();
if (parent != null) {
parent.jjtAddChild(node, parent.getNumChildren());
node.setParent(parent);
parent.addChild(node, parent.getNumChildren());
}
// Build the children...
@ -304,27 +302,20 @@ final class ApexTreeBuilder extends AstVisitor<AdditionalPassScope> {
private void addFormalComments() {
for (ApexDocTokenLocation tokenLocation : apexDocTokenLocations) {
ApexNode<?> parent = tokenLocation.nearestNode;
AbstractApexNode<?> parent = tokenLocation.nearestNode;
if (parent != null) {
ASTFormalComment comment = new ASTFormalComment(tokenLocation.token);
comment.calculateLineNumbers(sourceCodePositioner, tokenLocation.index,
tokenLocation.index + tokenLocation.token.getText().length());
// move existing nodes so that we can insert the comment as the first node
for (int i = parent.getNumChildren(); i > 0; i--) {
parent.jjtAddChild(parent.getChild(i - 1), i);
}
parent.jjtAddChild(comment, 0);
comment.setParent(parent);
parent.insertChild(comment, 0);
}
}
}
private void buildFormalComment(AstNode node) {
if (parents.peek() == node) {
ApexNode<?> parent = (ApexNode<?>) nodes.peek();
assignApexDocTokenToNode(node, parent);
assignApexDocTokenToNode(node, nodes.peek());
}
}
@ -337,7 +328,7 @@ final class ApexTreeBuilder extends AstVisitor<AdditionalPassScope> {
* @param jorjeNode the original node
* @param node the potential parent node, to which the comment could belong
*/
private void assignApexDocTokenToNode(AstNode jorjeNode, ApexNode<?> node) {
private void assignApexDocTokenToNode(AstNode jorjeNode, AbstractApexNode<?> node) {
Location loc = jorjeNode.getLoc();
if (!Locations.isReal(loc)) {
// Synthetic nodes such as "<clinit>" don't have a location in the
@ -411,7 +402,7 @@ final class ApexTreeBuilder extends AstVisitor<AdditionalPassScope> {
private static class ApexDocTokenLocation {
int index;
Token token;
ApexNode<?> nearestNode;
AbstractApexNode<?> nearestNode;
int nearestNodeDistance;
ApexDocTokenLocation(int index, Token token) {

View File

@ -67,24 +67,63 @@ public abstract class AbstractNode<T extends GenericNode<T>> implements GenericN
}
/**
* This method tells the node to add its argument to the node's list of children.
* Note that it is more efficient to add children in reverse (from right to left),
* because the array is resized only once.
* Set the child at the given index to the given node. This resizes
* the children array to be able to contain the given index. Implementations
* must take care that this does not leave any "holes" in the array.
* This method throws if there is already a child at the given index.
*
* <p>Note that it is more efficient to add children in reverse
* (from right to left), because the array is resized only the
* first time.
*
* <p>This method also calls {@link #setParent(AbstractNode)}.
*
* @param child The child to add
* @param index The index to which the child will be added
*/
protected void addChild(final AbstractNode<T> child, final int index) {
assert index >= 0 : "Invalid index " + index;
assert index >= children.length || children[index] == null : "There is already a child at index " + index;
if (index >= children.length) {
final Node[] newChildren = new Node[index + 1];
System.arraycopy(children, 0, newChildren, 0, children.length);
children = newChildren;
}
children[index] = child;
child.setChildIndex(index);
child.setParent(this);
}
/**
* Insert a child at the given index, shifting all the following
* children to the right.
*
* @param child New child
* @param index Index (must be 0 <= index <= getNumChildren()), ie
* you can insert a node beyond the end, because that
* would leave holes in the array
*/
protected void insertChild(final AbstractNode<T> child, final int index) {
assert index >= 0 && index <= children.length
: "Invalid index for insertion into array of length " + children.length + ": " + index;
Node[] newChildren = new Node[index + 1];
if (index != 0) {
System.arraycopy(children, 0, newChildren, 0, index);
}
if (index != children.length) {
System.arraycopy(children, index, newChildren, index + 1, children.length - index);
}
newChildren[index] = child;
child.setParent(this);
for (int i = index; i < newChildren.length; i++) {
((AbstractNode<?>) newChildren[i]).setChildIndex(i);
}
this.children = newChildren;
}
@SafeVarargs