From 1a6d7b393c7ffec54e9dcba523c4cfc075e2c567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 26 Apr 2020 19:04:31 +0200 Subject: [PATCH] Add a type parameter to AbstractNode --- .../pmd/lang/apex/ast/AbstractApexNode.java | 5 ++- .../pmd/lang/ast/impl/AbstractNode.java | 39 ++++++++-------- .../impl/AbstractNodeWithTextCoordinates.java | 2 +- .../ast/impl/javacc/AbstractJjtreeNode.java | 44 ++++++++++++++++++- .../lang/ast/impl/javacc/JjtreeBuilder.java | 2 +- .../sourceforge/pmd/lang/ast/DummyNode.java | 5 ++- .../pmd/lang/ast/impl/DummyTreeUtil.java | 2 +- .../pmd/lang/java/ast/AbstractJavaNode.java | 2 +- .../ast/AbstractEcmascriptNode.java | 3 +- .../pmd/lang/jsp/ast/AbstractJspNode.java | 2 +- .../modelica/ast/AbstractModelicaNode.java | 2 +- .../pmd/lang/plsql/ast/AbstractPLSQLNode.java | 3 +- .../pmd/lang/scala/ast/AbstractScalaNode.java | 11 +++-- .../pmd/lang/vf/ast/AbstractVfNode.java | 2 +- .../pmd/lang/vm/ast/AbstractVmNode.java | 2 +- 15 files changed, 87 insertions(+), 39 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java index ca89400aa6..f56ef63755 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java @@ -14,7 +14,7 @@ import apex.jorje.data.Locations; import apex.jorje.semantic.ast.AstNode; import apex.jorje.semantic.exception.UnexpectedCodePathException; -abstract class AbstractApexNode extends AbstractNodeWithTextCoordinates> implements ApexNode { +abstract class AbstractApexNode extends AbstractNodeWithTextCoordinates, ApexNode> implements ApexNode { protected final T node; @@ -22,10 +22,13 @@ abstract class AbstractApexNode extends AbstractNodeWithTextC this.node = node; } + // overridden to make them visible + @Override protected void addChild(AbstractApexNode child, int index) { super.addChild(child, index); } + @Override protected void insertChild(AbstractApexNode child, int index) { super.insertChild(child, index); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNode.java index 339f230848..2117707655 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNode.java @@ -18,10 +18,13 @@ import net.sourceforge.pmd.util.DataMap.DataKey; * not the antlr nodes, so downcasting {@link Node} to this class may fail * and is very bad practice. * - * @param Public interface for nodes of this language (eg JavaNode + * @param Self type (eg AbstractJavaNode in the java module), this + * must ultimately implement {@code }, though the java type + * system does not allow us to express that + * @param Public interface for nodes of this language (eg JavaNode * in the java module). */ -public abstract class AbstractNode> implements GenericNode { +public abstract class AbstractNode, N extends GenericNode> implements GenericNode { private static final Node[] EMPTY_ARRAY = new Node[0]; @@ -30,7 +33,7 @@ public abstract class AbstractNode> implements GenericN // never null, never contains null elements private Node[] children = EMPTY_ARRAY; - private AbstractNode parent; + private B parent; private int childIndex; protected AbstractNode() { @@ -38,8 +41,8 @@ public abstract class AbstractNode> implements GenericN } @Override - public T getParent() { - return toPublic(parent); + public N getParent() { + return (N) parent; } @Override @@ -48,8 +51,8 @@ public abstract class AbstractNode> implements GenericN } @Override - public T getChild(final int index) { - return toPublic(children[index]); + public N getChild(final int index) { + return (N) children[index]; } @Override @@ -57,13 +60,13 @@ public abstract class AbstractNode> implements GenericN return children.length; } - protected void setParent(final AbstractNode parent) { + protected void setParent(final B parent) { this.parent = parent; } @SuppressWarnings("unchecked") - protected T toPublic(Node n) { - return (T) n; + private B asSelf(Node n) { + return (B) n; } /** @@ -81,7 +84,7 @@ public abstract class AbstractNode> implements GenericN * @param child The child to add * @param index The index to which the child will be added */ - protected void addChild(final AbstractNode child, final int index) { + protected void addChild(final B 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; @@ -93,7 +96,7 @@ public abstract class AbstractNode> implements GenericN children[index] = child; child.setChildIndex(index); - child.setParent(this); + child.setParent(asSelf(this)); } /** @@ -105,7 +108,7 @@ public abstract class AbstractNode> implements GenericN * you can insert a node beyond the end, because that * would leave holes in the array */ - protected void insertChild(final AbstractNode child, final int index) { + protected void insertChild(final B child, final int index) { assert index >= 0 && index <= children.length : "Invalid index for insertion into array of length " + children.length + ": " + index; @@ -117,21 +120,21 @@ public abstract class AbstractNode> implements GenericN System.arraycopy(children, index, newChildren, index + 1, children.length - index); } newChildren[index] = child; - child.setParent(this); + child.setParent(asSelf(this)); for (int i = index; i < newChildren.length; i++) { - ((AbstractNode) newChildren[i]).setChildIndex(i); + asSelf(newChildren[i]).setChildIndex(i); } this.children = newChildren; } @SafeVarargs - protected final void setChildren(AbstractNode... newChildren) { + protected final void setChildren(B... newChildren) { this.children = new Node[newChildren.length]; System.arraycopy(newChildren, 0, this.children, 0, newChildren.length); for (int i = 0; i < newChildren.length; i++) { - newChildren[i].setParent(this); + newChildren[i].setParent(asSelf(this)); newChildren[i].setChildIndex(i); } } @@ -153,7 +156,7 @@ public abstract class AbstractNode> implements GenericN children = ArrayUtils.remove(children, childIndex); // Update the remaining & left-shifted children indexes for (int i = childIndex; i < getNumChildren(); i++) { - ((AbstractNode) getChild(i)).setChildIndex(i); + asSelf(getChild(i)).setChildIndex(i); } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeWithTextCoordinates.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeWithTextCoordinates.java index 6f4154a45e..0b179878b3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeWithTextCoordinates.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeWithTextCoordinates.java @@ -8,7 +8,7 @@ package net.sourceforge.pmd.lang.ast.impl; * Base class for implementations that need fields to store text * coordinates. */ -public abstract class AbstractNodeWithTextCoordinates> extends AbstractNode { +public abstract class AbstractNodeWithTextCoordinates, T extends GenericNode> extends AbstractNode { protected int beginLine = -1; protected int endLine = -1; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java index 84ff06abfd..0e358f7cea 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java @@ -17,7 +17,8 @@ import net.sourceforge.pmd.lang.ast.impl.AbstractNode; * unforeseeable ways. Don't use it directly, use the node interfaces. */ @Experimental -public abstract class AbstractJjtreeNode> extends AbstractNode implements JjtreeNode { +public abstract class AbstractJjtreeNode, N extends JjtreeNode> extends AbstractNode implements JjtreeNode { + protected final int id; private JavaccToken firstToken; private JavaccToken lastToken; @@ -64,10 +65,49 @@ public abstract class AbstractJjtreeNode> extends Abstra // to be overridden } - protected void addChild(AbstractJjtreeNode child, int index) { + @Override // override to make it protected + protected void addChild(B child, int index) { super.addChild(child, index); } + @Override + protected void insertChild(B child, int index) { + super.insertChild(child, index); + fitTokensToChildren(index); + } + + /** + * Ensures that the first (resp. last) token of this node is before + * (resp. after) the first (resp. last) token of the child at the + * given index. The index + */ + protected void fitTokensToChildren(int index) { + if (index == 0) { + enlargeLeft((B) getChild(index)); + } + if (index == getNumChildren()) { + enlargeRight((B) getChild(index)); + } + } + + private void enlargeLeft(B child) { + JavaccToken thisFst = this.getFirstToken(); + JavaccToken childFst = child.getFirstToken(); + + if (childFst.compareTo(thisFst) < 0) { + this.setFirstToken(childFst); + } + } + + private void enlargeRight(B child) { + JavaccToken thisLast = this.getLastToken(); + JavaccToken childLast = child.getLastToken(); + + if (childLast.compareTo(thisLast) > 0) { + this.setLastToken(childLast); + } + } + @Override public JavaccToken getFirstToken() { return firstToken; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeBuilder.java index de7c37f471..6b778542a7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeBuilder.java @@ -13,7 +13,7 @@ import java.util.List; * @param Internal base class for nodes * @param

Public interface for nodes */ -public final class JjtreeBuilder, P extends JjtreeNode

> { +public final class JjtreeBuilder, P extends JjtreeNode

> { private final List nodes = new ArrayList<>(); private final List marks = new ArrayList<>(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java index 31173166f4..fe33533f0b 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java @@ -9,7 +9,7 @@ import java.util.Map; import net.sourceforge.pmd.lang.ast.impl.AbstractNodeWithTextCoordinates; -public class DummyNode extends AbstractNodeWithTextCoordinates { +public class DummyNode extends AbstractNodeWithTextCoordinates { private final boolean findBoundary; private final String xpathName; @@ -29,7 +29,7 @@ public class DummyNode extends AbstractNodeWithTextCoordinates { this.xpathName = xpathName; } - public void setChildren(DummyNode... children) { + public void publicSetChildren(DummyNode... children) { super.setChildren(children); } @@ -66,6 +66,7 @@ public class DummyNode extends AbstractNodeWithTextCoordinates { return userData; } + @Override public void addChild(DummyNode child, int index) { super.addChild(child, index); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java index e90e54adae..d8ead26590 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java @@ -42,7 +42,7 @@ public final class DummyTreeUtil { } private static T nodeImpl(T node, DummyNode... children) { - node.setChildren(children); + node.publicSetChildren(children); return node; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java index 9ad79d93e3..3bfe575c27 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java @@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.symboltable.Scope; @Deprecated @InternalApi -public abstract class AbstractJavaNode extends AbstractJjtreeNode implements JavaNode { +public abstract class AbstractJavaNode extends AbstractJjtreeNode implements JavaNode { private Scope scope; private Comment comment; diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java index 95e85c354f..c90dbe4a8f 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java @@ -9,7 +9,7 @@ import org.mozilla.javascript.ast.AstNode; import net.sourceforge.pmd.lang.ast.SourceCodePositioner; import net.sourceforge.pmd.lang.ast.impl.AbstractNodeWithTextCoordinates; -abstract class AbstractEcmascriptNode extends AbstractNodeWithTextCoordinates> implements EcmascriptNode { +abstract class AbstractEcmascriptNode extends AbstractNodeWithTextCoordinates, EcmascriptNode> implements EcmascriptNode { protected final T node; private String image; @@ -18,6 +18,7 @@ abstract class AbstractEcmascriptNode extends AbstractNodeWit this.node = node; } + @Override protected void addChild(AbstractEcmascriptNode child, int index) { super.addChild(child, index); } diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java index b89ebbf30c..c2584110f9 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.jsp.ast; import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode; -abstract class AbstractJspNode extends AbstractJjtreeNode implements JspNode { +abstract class AbstractJspNode extends AbstractJjtreeNode implements JspNode { protected AbstractJspNode(int id) { super(id); diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java index b91307786f..326340d672 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java @@ -16,7 +16,7 @@ import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope; * * @see ModelicaNode for public API. */ -abstract class AbstractModelicaNode extends AbstractJjtreeNode implements ModelicaNode { +abstract class AbstractModelicaNode extends AbstractJjtreeNode implements ModelicaNode { private ModelicaScope ownScope; diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java index fbe5a9c9b0..c4645be32a 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java @@ -10,7 +10,8 @@ import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode; import net.sourceforge.pmd.lang.symboltable.Scope; @InternalApi -public abstract class AbstractPLSQLNode extends AbstractJjtreeNode implements PLSQLNode { +public abstract class AbstractPLSQLNode extends AbstractJjtreeNode implements PLSQLNode { + protected Object value; protected PLSQLParser parser; protected Scope scope; diff --git a/pmd-scala/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java b/pmd-scala/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java index 240ec21cd0..03b426ffaa 100644 --- a/pmd-scala/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java +++ b/pmd-scala/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java @@ -13,10 +13,10 @@ import scala.meta.inputs.Position; * A Wrapper for translating the Scala Tree Nodes to PMD-compatible Java-base * Nodes. * - * @param - * the type of the Scala tree node + * @param the type of the Scala tree node */ -abstract class AbstractScalaNode extends AbstractNode> implements ScalaNode { +abstract class AbstractScalaNode extends AbstractNode, ScalaNode> implements ScalaNode { + protected final T node; private final Position pos; @@ -32,6 +32,8 @@ abstract class AbstractScalaNode extends AbstractNode child, int index) { super.addChild(child, index); } @@ -61,9 +63,6 @@ abstract class AbstractScalaNode extends AbstractNode R accept(ScalaParserVisitor visitor, D data); - @Override @Deprecated public T getNode() { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNode.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNode.java index d99d94e01d..05ef601efa 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNode.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/vf/ast/AbstractVfNode.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.lang.vf.ast; import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode; -abstract class AbstractVfNode extends AbstractJjtreeNode implements VfNode { +abstract class AbstractVfNode extends AbstractJjtreeNode implements VfNode { protected AbstractVfNode(int id) { super(id); diff --git a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/AbstractVmNode.java b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/AbstractVmNode.java index 4e189a2fff..07795dc818 100644 --- a/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/AbstractVmNode.java +++ b/pmd-vm/src/main/java/net/sourceforge/pmd/lang/vm/ast/AbstractVmNode.java @@ -23,7 +23,7 @@ package net.sourceforge.pmd.lang.vm.ast; import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; -abstract class AbstractVmNode extends AbstractJjtreeNode implements VmNode { +abstract class AbstractVmNode extends AbstractJjtreeNode implements VmNode { protected AbstractVmNode(final int i) { super(i);