();
}
- LanguageVersion languageVersion = new LanguageVersion(this, languageVersions[0], languageVersionHandler);
+ LanguageVersion languageVersion = new LanguageVersion(this, version, languageVersionHandler);
distinctVersions.add(languageVersion);
- for (String version : languageVersions) {
- versions.put(version, languageVersion);
+ checkNotPresent(version);
+ versions.put(version, languageVersion);
+ for (String alias : versionAliases) {
+ checkNotPresent(alias);
+ versions.put(alias, languageVersion);
}
if (isDefault) {
- assert defaultVersion == null
- : "Default version already set to " + defaultVersion + ", cannot set it to " + languageVersion;
+ if (defaultVersion != null) {
+ throw new IllegalStateException(
+ "Default version already set to " + defaultVersion + ", cannot set it to " + languageVersion);
+ }
defaultVersion = languageVersion;
}
}
+ private void checkNotPresent(String alias) {
+ if (versions.containsKey(alias)) {
+ throw new IllegalArgumentException("Version key '" + alias + "' is duplicated");
+ }
+ }
+
+
+ /**
+ * Adds a non-default version with the given identifier.
+ *
+ * @throws IllegalArgumentException If the string key or any of the
+ * aliases conflict with other already
+ * recorded versions
+ */
+ protected void addVersion(String version, LanguageVersionHandler languageVersionHandler, String... versionAliases) {
+ addVersion(version, languageVersionHandler, false, versionAliases);
+ }
+
+ /**
+ * Adds a version with the given identifier, and sets it as the default.
+ *
+ * @throws IllegalStateException If the default version is already set
+ * @throws IllegalArgumentException If the string key or any of the
+ * aliases conflict with other already
+ * recorded versions
+ */
+ protected void addDefaultVersion(String version, LanguageVersionHandler languageVersionHandler, String... versionAliases) {
+ addVersion(version, languageVersionHandler, true, versionAliases);
+ }
+
+ /**
+ * @deprecated use {@link #addVersion(String, LanguageVersionHandler, String...)} or {@link #addDefaultVersion(String, LanguageVersionHandler, String...)}
+ */
+ @Deprecated
protected void addVersion(String version, LanguageVersionHandler languageVersionHandler, boolean isDefault) {
- addVersions(languageVersionHandler, isDefault, version);
+ addVersion(version, languageVersionHandler, isDefault, new String[0]);
}
@Override
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java
index cba8e671bb..77c18e0a9b 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Parser.java
@@ -6,8 +6,8 @@ package net.sourceforge.pmd.lang;
import java.io.Reader;
-import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.ParseException;
+import net.sourceforge.pmd.lang.ast.RootNode;
/**
* Produces an AST from a source file. Instances of this interface must
@@ -39,7 +39,7 @@ public interface Parser {
* In case the source code could not be parsed, probably due to
* syntactical errors.
*/
- Node parse(String fileName, Reader source) throws ParseException;
+ RootNode parse(String fileName, Reader source) throws ParseException;
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AbstractNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AbstractNode.java
deleted file mode 100644
index d5346f7220..0000000000
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AbstractNode.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/**
- * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
- */
-
-package net.sourceforge.pmd.lang.ast;
-
-import java.util.Objects;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.dfa.DataFlowNode;
-import net.sourceforge.pmd.util.DataMap;
-import net.sourceforge.pmd.util.DataMap.DataKey;
-import net.sourceforge.pmd.util.DataMap.SimpleDataKey;
-
-/**
- * Base class for all implementations of the Node interface.
- *
- * Please use the {@link Node} interface wherever possible and
- * not this class, unless you're compelled to do so.
- *
- *
Note that nearly all methods of the {@link Node} interface
- * will have default implementations with PMD 7.0.0, so that it
- * will not be necessary to extend this class directly.
- */
-public abstract class AbstractNode implements Node {
-
- private static final Node[] EMPTY_ARRAY = new Node[0];
-
- @Deprecated
- public static final SimpleDataKey LEGACY_USER_DATA = DataMap.simpleDataKey("legacy user data");
-
- // lazy initialized, many nodes don't need it
- private @Nullable DataMap> userData;
-
- /**
- * @deprecated Use {@link #getParent()}
- */
- @Deprecated
- protected Node parent;
- // never null, never contains null elements
- protected Node[] children = EMPTY_ARRAY;
- /** @deprecated Use {@link #getIndexInParent()} */
- @Deprecated
- protected int childIndex;
- /** @deprecated Use {@link #jjtGetId()} if you are a jjtree node. */
- @Deprecated
- protected int id;
- /** @deprecated This will be removed to delegate to the tokens for nodes that are backed by tokens. */
- @Deprecated
- protected int beginLine = -1;
- /** @deprecated This will be removed to delegate to the tokens for nodes that are backed by tokens. */
- @Deprecated
- protected int endLine;
- /** @deprecated This will be removed to delegate to the tokens for nodes that are backed by tokens. */
- @Deprecated
- protected int beginColumn = -1;
- /** @deprecated This will be removed to delegate to the tokens for nodes that are backed by tokens. */
- @Deprecated
- protected int endColumn;
- // Those should have been private.
- @Deprecated
- protected GenericToken firstToken;
- @Deprecated
- protected GenericToken lastToken;
- private DataFlowNode dataFlowNode;
- // @Deprecated?
- private String image;
-
- public AbstractNode(final int id) {
- this.id = id;
- }
-
- public AbstractNode(final int id, final int theBeginLine, final int theEndLine, final int theBeginColumn,
- final int theEndColumn) {
- this(id);
-
- beginLine = theBeginLine;
- endLine = theEndLine;
- beginColumn = theBeginColumn;
- endColumn = theEndColumn;
- }
-
-
- @Override
- public Node getParent() {
- return jjtGetParent();
- }
-
- @Override
- public int getIndexInParent() {
- return childIndex;
- }
-
- @Override
- public Node getChild(final int index) {
- if (children == null) {
- throw new IndexOutOfBoundsException();
- }
- return children[index];
- }
-
- @Override
- public int getNumChildren() {
- return jjtGetNumChildren();
- }
-
-
- /**
- * @deprecated This is never used and is trivial, will be removed from this class.
- */
- @Deprecated
- public boolean isSingleLine() {
- return beginLine == endLine;
- }
-
- @Override
- @Deprecated
- @InternalApi
- public void jjtOpen() {
- // to be overridden by subclasses
- }
-
- @Override
- @Deprecated
- @InternalApi
- public void jjtClose() {
- // to be overridden by subclasses
- }
-
- @Override
- @Deprecated
- @InternalApi
- public void jjtSetParent(final Node parent) {
- this.parent = parent;
- }
-
- @Override
- @Deprecated
- public Node jjtGetParent() {
- return parent;
- }
-
- @Override
- @Deprecated
- @InternalApi
- public void jjtAddChild(final Node child, final int 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.jjtSetChildIndex(index);
- child.jjtSetParent(this);
- }
-
- @Override
- @Deprecated
- @InternalApi
- public void jjtSetChildIndex(final int index) {
- childIndex = index;
- }
-
-
- @Override
- @Deprecated
- public Node jjtGetChild(final int index) {
- return children[index];
- }
-
- @Override
- @Deprecated
- public int jjtGetNumChildren() {
- return children.length;
- }
-
-
- /**
- * @deprecated Will be made protected with 7.0.0.
- */
- @Override
- @Deprecated
- public int jjtGetId() {
- return id;
- }
-
- @Override
- public String getImage() {
- return image;
- }
-
- @Override
- @Deprecated
- public void setImage(final String image) {
- this.image = image;
- }
-
- @Override
- public boolean hasImageEqualTo(final String image) {
- return Objects.equals(this.getImage(), image);
- }
-
- @Override
- public int getBeginLine() {
- return beginLine;
- }
-
- /**
- * @deprecated This will be removed with 7.0.0
- */
- @Deprecated
- @InternalApi
- public void testingOnlySetBeginLine(int i) {
- this.beginLine = i;
- }
-
- @Override
- public int getBeginColumn() {
- if (beginColumn == -1) {
- if (children.length > 0) {
- return children[0].getBeginColumn();
- } else {
- throw new RuntimeException("Unable to determine beginning line of Node.");
- }
- } else {
- return beginColumn;
- }
- }
-
- /**
- * @deprecated This will be removed with 7.0.0
- */
- @Deprecated
- @InternalApi
- public void testingOnlySetBeginColumn(final int i) {
- this.beginColumn = i;
- }
-
- @Override
- public int getEndLine() {
- return endLine;
- }
-
- /**
- * @deprecated This will be removed with 7.0.0
- */
- @Deprecated
- @InternalApi
- public void testingOnlySetEndLine(final int i) {
- this.endLine = i;
- }
-
- @Override
- public int getEndColumn() {
- return endColumn;
- }
-
- /**
- * @deprecated This will be removed with 7.0.0
- */
- @Deprecated
- @InternalApi
- public void testingOnlySetEndColumn(final int i) {
- this.endColumn = i;
- }
-
- @Override
- public DataFlowNode getDataFlowNode() {
- if (this.dataFlowNode == null) {
- if (this.parent != null) {
- return parent.getDataFlowNode();
- }
- return null; // TODO wise?
- }
- return dataFlowNode;
- }
-
- @Override
- public void setDataFlowNode(final DataFlowNode dataFlowNode) {
- this.dataFlowNode = dataFlowNode;
- }
-
- /**
- * Returns true if this node has a descendant of any type among the provided types.
- *
- * @param types Types to test
- *
- * @deprecated This is implemented inefficiently, with PMD 7 Node streams
- * will provide a better alternative. We cannot ensure binary compatibility
- * because the methods on 7.0 expect at least one class type, by requiring
- * one Class parameter before the varargs (Effective Java 2nd ed., Item 42).
- */
- @Deprecated
- public final boolean hasDescendantOfAnyType(final Class extends Node>... types) {
- // TODO consider implementing that with a single traversal!
- // -> this is done if you use node streams
- for (final Class extends Node> type : types) {
- if (hasDescendantOfType(type)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- @Deprecated
- public Object getUserData() {
- return getUserMap().get(LEGACY_USER_DATA);
- }
-
- @Override
- @Deprecated
- public void setUserData(final Object userData) {
- getUserMap().set(LEGACY_USER_DATA, userData);
- }
-
- @Override
- public DataMap> getUserMap() {
- if (userData == null) {
- userData = DataMap.newDataMap();
- }
- return userData;
- }
-
- /**
- * @deprecated Not all nodes are based on tokens, and this is an implementation detail
- */
- @Deprecated
- public GenericToken jjtGetFirstToken() {
- return firstToken;
- }
-
- /**
- * @deprecated This is JJTree-specific and will be removed from this superclass.
- */
- @Deprecated
- public void jjtSetFirstToken(final GenericToken token) {
- this.firstToken = token;
- this.beginLine = token.getBeginLine();
- this.beginColumn = token.getBeginColumn();
- }
-
- /**
- * @deprecated Not all nodes are based on tokens, and this is an implementation detail
- */
- @Deprecated
- public GenericToken jjtGetLastToken() {
- return lastToken;
- }
-
- /**
- * @deprecated This is JJTree-specific and will be removed from this superclass.
- */
- @Deprecated
- public void jjtSetLastToken(final GenericToken token) {
- this.lastToken = token;
- this.endLine = token.getEndLine();
- this.endColumn = token.getEndColumn();
- }
-
-
- /**
- * @deprecated This is internal API
- */
- @Deprecated
- @InternalApi
- @Override
- public void remove() {
- // Detach current node of its parent, if any
- final Node parent = getParent();
- if (parent != null) {
- parent.removeChildAtIndex(getIndexInParent());
- jjtSetParent(null);
- }
-
- // TODO [autofix]: Notify action for handling text edition
- }
-
- /**
- * @deprecated This is internal API
- */
- @Deprecated
- @InternalApi
- @Override
- public void removeChildAtIndex(final int childIndex) {
- if (0 <= childIndex && childIndex < getNumChildren()) {
- // Remove the child at the given index
- children = ArrayUtils.remove(children, childIndex);
- // Update the remaining & left-shifted children indexes
- for (int i = childIndex; i < getNumChildren(); i++) {
- getChild(i).jjtSetChildIndex(i);
- }
- }
- }
-
- @Override
- public String toString() {
- return getXPathNodeName();
- }
-
-}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/DocumentUtils.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/DocumentUtils.java
deleted file mode 100644
index 9460b15600..0000000000
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/DocumentUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
- */
-
-package net.sourceforge.pmd.lang.ast;
-
-import java.util.Iterator;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import net.sourceforge.pmd.lang.ast.xpath.Attribute;
-import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
-
-/**
- * Remove when we have Java 9 support, and make all methods private on Node interface
- */
-/* default */ final class DocumentUtils {
-
- private DocumentUtils() {
-
- }
-
- /* default */ static void appendElement(final Node node, final org.w3c.dom.Node parentNode) {
- final DocumentNavigator docNav = new DocumentNavigator();
- Document ownerDocument = parentNode.getOwnerDocument();
- if (ownerDocument == null) {
- // If the parentNode is a Document itself, it's ownerDocument is null
- ownerDocument = (Document) parentNode;
- }
- final String elementName = docNav.getElementName(node);
- final Element element = ownerDocument.createElement(elementName);
- parentNode.appendChild(element);
- for (final Iterator iter = docNav.getAttributeAxisIterator(node); iter.hasNext();) {
- final Attribute attr = iter.next();
- element.setAttribute(attr.getName(), attr.getStringValue());
- }
- for (final Iterator iter = docNav.getChildAxisIterator(node); iter.hasNext();) {
- final AbstractNode child = (AbstractNode) iter.next();
- appendElement(child, element);
- }
- }
-}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
index 0a983e3852..b4aa8f5429 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
@@ -6,17 +6,13 @@ package net.sourceforge.pmd.lang.ast;
import java.util.Iterator;
import java.util.List;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import java.util.Objects;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jaxen.BaseXPath;
import org.jaxen.JaxenException;
-import org.w3c.dom.Document;
-import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.NodeStream.DescendantNodeStream;
import net.sourceforge.pmd.lang.ast.internal.StreamImpl;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
@@ -24,7 +20,6 @@ import net.sourceforge.pmd.lang.ast.xpath.AttributeAxisIterator;
import net.sourceforge.pmd.lang.ast.xpath.internal.ContextualizedNavigator;
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttrLogger;
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
-import net.sourceforge.pmd.lang.dfa.DataFlowNode;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@@ -38,8 +33,6 @@ import net.sourceforge.pmd.util.DataMap.DataKey;
* {@link #getXPathNodeName()}, {@link #getXPathAttributesIterator()}
* Location metadata: eg {@link #getBeginLine()}, {@link #getBeginColumn()}
*
- * Additionally, the {@linkplain #getUserMap() user data map} is an extensibility
- * mechanism with which any client can independently associate values to AST nodes.
*
* Every language implementation must publish a sub-interface of Node
* which serves as a supertype for all nodes of that language (e.g.
@@ -51,131 +44,9 @@ import net.sourceforge.pmd.util.DataMap.DataKey;
* implementations should ensure that every node returned by these methods
* are indeed of the same type. Possibly, a type parameter will be added to
* the Node interface in 7.0.0 to enforce it at compile-time.
- *
- *
A number of methods are deprecated and will be removed in 7.0.0.
- * Most of them are implementation details that clutter this API and
- * make implementation more difficult. Some methods prefixed with {@code jjt}
- * have a more conventional counterpart (e.g. {@link #jjtGetParent()} and
- * {@link #getParent()}) that should be preferred.
*/
public interface Node {
- // COMMENT: is it ok to take the opportunity on PMD 7 to rename this API and take out of there the methods
- // that are only needed for javaCC implementations?
-
-
- /**
- * This method is called after the node has been made the current node. It
- * indicates that child nodes can now be added to it.
- *
- * @deprecated This is JJTree-specific and will be removed from this interface
- */
- @Deprecated
- default void jjtOpen() {
- // do nothing
- }
-
-
- /**
- * This method is called after all the child nodes have been added.
- *
- * @deprecated This is JJTree-specific and will be removed from this interface
- */
- @Deprecated
- default void jjtClose() {
- // do nothing
- }
-
-
- /**
- * Sets the parent of this node.
- *
- * @param parent The parent
- *
- * @deprecated This is JJTree-specific and will be removed from this interface
- */
- @Deprecated
- default void jjtSetParent(Node parent) {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
- /**
- * Returns the parent of this node.
- *
- * @return The parent of the node
- *
- * @deprecated Use {@link #getParent()}
- */
- @Deprecated
- @Nullable
- default Node jjtGetParent() {
- return getParent();
- }
-
-
- /**
- * This method tells the node to add its argument to the node's list of children.
- *
- * @param child The child to add
- * @param index The index to which the child will be added
- *
- * @deprecated This is JJTree-specific and will be removed from this interface
- */
- @Deprecated
- default void jjtAddChild(Node child, int index) {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
- /**
- * Sets the index of this node from the perspective of its parent. This
- * means: this.getParent().getChild(index) == this.
- *
- * @param index the child index
- *
- * @deprecated This is JJTree-specific and will be removed from this interface
- */
- @Deprecated
- default void jjtSetChildIndex(int index) {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
- /**
- * This method returns a child node. The children are numbered from zero, left to right.
- *
- * @param index the child index. Must be nonnegative and less than
- * {@link #jjtGetNumChildren}.
- *
- * @deprecated Use {@link #getChild(int)}
- */
- @Deprecated
- default Node jjtGetChild(int index) {
- return getChild(index);
- }
-
-
- /**
- * Returns the number of children the node has.
- *
- * @deprecated Use {@link #getNumChildren()}
- */
- @Deprecated
- default int jjtGetNumChildren() {
- return getNumChildren();
- }
-
-
- /**
- * @deprecated This is JJTree-specific and will be removed from this interface.
- */
- @Deprecated
- default int jjtGetId() {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
/**
* Returns a string token, usually filled-in by the parser, which describes some textual characteristic of this
* node. This is usually an identifier, but you should check that using the Designer. On most nodes though, this
@@ -186,23 +57,13 @@ public interface Node {
}
- /**
- * @deprecated This is internal API, the image should never be set by developers.
- */
- @InternalApi
- @Deprecated
- default void setImage(String image) {
- throw new UnsupportedOperationException("setImage");
- }
-
-
/**
* Returns true if this node's image is equal to the given string.
*
* @param image The image to check
*/
default boolean hasImageEqualTo(String image) {
- return getImage() != null && getImage().equals(image);
+ return Objects.equals(getImage(), image);
}
@@ -219,25 +80,6 @@ public interface Node {
int getEndColumn();
- /**
- * @deprecated This is Java-specific and will be removed from this interface
- */
- @Deprecated
- default DataFlowNode getDataFlowNode() {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
- /**
- * @deprecated This is Java-specific and will be removed from this interface
- */
- @Deprecated
- default void setDataFlowNode(DataFlowNode dataFlowNode) {
- throw new UnsupportedOperationException("JJTree specific");
- }
-
-
-
/**
* Returns true if this node is considered a boundary by traversal
* methods. Traversal methods such as {@link #descendants()}
@@ -295,27 +137,6 @@ public interface Node {
return this.ancestors(parentType).toList();
}
- /**
- * Gets the first parent that's an instance of any of the given types.
- *
- * @param parentTypes Types to look for
- * @param Most specific common type of the parameters
- * @return The first parent with a matching type. Returns null if there is no such parent
- *
- * @deprecated This method causes an unchecked warning at call sites.
- * PMD 7 will provide a way to do the same thing without the warning.
- */
- @Deprecated
- default T getFirstParentOfAnyType(Class extends T>... parentTypes) {
- return ancestors().map(it -> {
- for (final Class extends T> c : parentTypes) {
- if (c.isInstance(it)) {
- return c.cast(it);
- }
- }
- return null;
- }).first();
- }
/**
* Traverses the children to find all the instances of type childType or one of its subclasses.
@@ -340,20 +161,6 @@ public interface Node {
return this.descendants(targetType).toList();
}
- /**
- * Traverses down the tree to find all the descendant instances of type descendantType.
- *
- * @param targetType class which you want to find.
- * @param results list to store the matching descendants
- * @param crossFindBoundaries if false
, recursion stops for nodes for which {@link #isFindBoundary()}
- * is true
- * @deprecated Use {@link #findDescendantsOfType(Class, boolean)} instead, which
- * returns a result list.
- */
- @Deprecated
- default void findDescendantsOfType(Class extends T> targetType, List super T> results, boolean crossFindBoundaries) {
- this.descendants(targetType).crossFindBoundaries(crossFindBoundaries).forEach(results::add);
- }
/**
* Traverses down the tree to find all the descendant instances of type
@@ -437,91 +244,8 @@ public interface Node {
}
}
- /**
- * Get a DOM Document which contains Elements and Attributes representative of this Node and it's children.
- * Essentially a DOM tree representation of the Node AST, thereby allowing tools which can operate upon DOM to also
- * indirectly operate on the AST.
- *
- * @deprecated Converting a tree to a DOM is not a standard use case.
- * The implementation rethrows a {@link ParserConfigurationException}
- * as a {@link RuntimeException}, but a caller should handle
- * it if he really wants to do this. Another problem is that
- * this is available on any node, yet only the root node of
- * a tree corresponds really to a document. The conversion
- * is easy to implement anyway, and does not have to be part
- * of this API.
- */
- @Deprecated
- default Document getAsDocument() {
- try {
- final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- final DocumentBuilder db = dbf.newDocumentBuilder();
- final Document document = db.newDocument();
- DocumentUtils.appendElement(this, document);
- return document;
- } catch (final ParserConfigurationException pce) {
- throw new RuntimeException(pce);
- }
- }
-
- /**
- * Get the user data associated with this node. By default there is no data, unless it has been set via {@link
- * #setUserData(Object)}.
- *
- * @return The user data set on this node.
- * @deprecated Use {@link #getUserMap()}
- */
- @Deprecated
- Object getUserData();
-
- /**
- * Set the user data associated with this node.
- *
- *
PMD itself will never set user data onto a node. Nor should any Rule
- * implementation, as the AST nodes are shared between concurrently executing Rules (i.e. it is not
- * thread-safe).
- *
- *
This API is most useful for external applications looking to leverage
- * PMD's robust support for AST structures, in which case application specific annotations on the AST nodes can be
- * quite useful.
- *
- * @param userData The data to set on this node.
- * @deprecated Use {@link #getUserMap()}
- */
- @Deprecated
- void setUserData(Object userData);
-
-
- /**
- * Remove the current node from its parent.
- *
- * @deprecated This is internal API and will be removed from this interface with 7.0.0
- */
- @Deprecated
- @InternalApi
- default void remove() {
- throw new UnsupportedOperationException();
- }
-
-
- /**
- * This method tells the node to remove the child node at the given index from the node's list of children, if any;
- * if not, no changes are done.
- *
- * @param childIndex The index of the child to be removed
- *
- * @deprecated This is internal API and will be removed from this interface with 7.0.0
- */
- @Deprecated
- @InternalApi
- default void removeChildAtIndex(int childIndex) {
- throw new UnsupportedOperationException();
- }
-
-
/**
* Returns a data map used to store additional information on this node.
- * This replaces the legacy {@link #getUserData()}/{@link #setUserData(Object)}.
*
* @return The user data map of this node
*/
@@ -531,8 +255,6 @@ public interface Node {
* Returns the parent of this node, or null if this is the {@linkplain RootNode root}
* of the tree.
*
- *
This method should be preferred to {@link #jjtGetParent()}.
- *
* @return The parent of this node
*/
Node getParent();
@@ -565,6 +287,7 @@ public interface Node {
*/
String getXPathNodeName();
+
/**
* Returns an iterator enumerating all the attributes that are available from XPath for this node.
*
@@ -575,6 +298,22 @@ public interface Node {
}
+ /**
+ * Returns the first child of this node, or null if it doesn't exist.
+ */
+ default @Nullable Node getFirstChild() {
+ return getNumChildren() > 0 ? getChild(0) : null;
+ }
+
+
+ /**
+ * Returns the first last of this node, or null if it doesn't exist.
+ */
+ default @Nullable Node getLastChild() {
+ return getNumChildren() > 0 ? getChild(getNumChildren() - 1) : null;
+ }
+
+
/**
* Returns a node stream containing only this node.
* {@link NodeStream#of(Node)} is a null-safe version
@@ -584,7 +323,7 @@ public interface Node {
*
* @see NodeStream#of(Node)
*/
- default NodeStream asStream() {
+ default NodeStream extends Node> asStream() {
return StreamImpl.singleton(this);
}
@@ -609,7 +348,7 @@ public interface Node {
*
* @see NodeStream#descendants()
*/
- default DescendantNodeStream descendants() {
+ default DescendantNodeStream extends Node> descendants() {
return StreamImpl.descendants(this);
}
@@ -622,7 +361,7 @@ public interface Node {
*
* @see NodeStream#descendantsOrSelf()
*/
- default DescendantNodeStream descendantsOrSelf() {
+ default DescendantNodeStream extends Node> descendantsOrSelf() {
return StreamImpl.descendantsOrSelf(this);
}
@@ -636,7 +375,7 @@ public interface Node {
*
* @see NodeStream#ancestors()
*/
- default NodeStream ancestors() {
+ default NodeStream extends Node> ancestors() {
return StreamImpl.ancestors(this);
}
@@ -650,7 +389,7 @@ public interface Node {
*
* @see NodeStream#ancestorsOrSelf()
*/
- default NodeStream ancestorsOrSelf() {
+ default NodeStream extends Node> ancestorsOrSelf() {
return StreamImpl.ancestorsOrSelf(this);
}
@@ -703,14 +442,18 @@ public interface Node {
return StreamImpl.ancestors(this, rClass);
}
+
+ /**
+ * Returns the root of the tree this node is declared in.
+ */
@NonNull
default RootNode getRoot() {
Node r = this;
- while (r != null && !(r instanceof RootNode)) {
+ while (r.getParent() != null) {
r = r.getParent();
}
- if (r == null) {
- throw new IllegalStateException("No root node in tree ?");
+ if (!(r instanceof RootNode)) {
+ throw new AssertionError("Root of the tree should implement RootNode");
}
return (RootNode) r;
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
index af7e73b7d0..7fe8b13654 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
@@ -70,8 +70,8 @@ import net.sourceforge.pmd.lang.ast.internal.StreamImpl;
* node.{@link Node#getParentsOfType(Class) getParentsOfType(t)} === node.{@link Node#descendants(Class) ancestors(t)}.{@link #toList()}
* node.{@link Node#getNthParent(int) getNthParent(n)} === node.{@link Node#ancestors() ancestors()}.{@link #get(int) get(n - 1)}
* node.{@link Node#hasDescendantOfType(Class) hasDescendantOfType(t)} === node.{@link Node#descendants(Class) descendants(t)}.{@link #nonEmpty()}
- * node.{@link Node#getFirstParentOfAnyType(Class[]) getFirstParentOfAnyType(c1, c2)} === node.{@link Node#ancestors() ancestors()}.{@link #firstNonNull(Function) firstNonNull}({@link #asInstanceOf(Class, Class[]) asInstanceOf(c1, c2)})
- * node.{@link AbstractNode#hasDescendantOfAnyType(Class[]) hasDescendantOfAnyType(c1, c2)} === node.{@link Node#descendants() descendants()}.{@link #map(Function) map}({@link #asInstanceOf(Class, Class[]) asInstanceOf(c1, c2)}).{@link #nonEmpty()}
+ * node.getFirstParentOfAnyType(c1, c2) === node.{@link Node#ancestors() ancestors()}.{@link #firstNonNull(Function) firstNonNull}({@link #asInstanceOf(Class, Class[]) asInstanceOf(c1, c2)})
+ * node.hasDescendantOfAnyType(c1, c2) === node.{@link Node#descendants() descendants()}.{@link #map(Function) map}({@link #asInstanceOf(Class, Class[]) asInstanceOf(c1, c2)}).{@link #nonEmpty()}
*
* The new way to write those is as efficient as the old way.
*
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
index f90b65b102..e7be304c5f 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
@@ -11,10 +11,12 @@ import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.annotation.InternalApi;
/**
- * This interface can be used to tag the root node of various ASTs.
+ * This interface identifies the root node of an AST. Each language
+ * implementation must ensure that every AST its parser produces has
+ * a RootNode as its root, and that there is no other RootNode instance
+ * in the tree.
*/
public interface RootNode extends Node {
- // that's only a marker interface.
/**
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
new file mode 100644
index 0000000000..d65d4dd231
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNode.java
@@ -0,0 +1,186 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast.impl;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.util.DataMap;
+import net.sourceforge.pmd.util.DataMap.DataKey;
+
+/**
+ * Base class for implementations of the Node interface whose children
+ * are stored in an array. This class provides the basic utilities to
+ * link children and parent. It's used by most most nodes, but currently
+ * not the antlr nodes, so downcasting {@link Node} to this class may fail
+ * and is very bad practice.
+ *
+ * @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, N extends GenericNode> implements GenericNode {
+
+ private static final Node[] EMPTY_ARRAY = new Node[0];
+
+ // lazy initialized, many nodes don't need it
+ private @Nullable DataMap> userData;
+
+ // never null, never contains null elements
+ private Node[] children = EMPTY_ARRAY;
+ private B parent;
+ private int childIndex;
+
+ protected AbstractNode() {
+ // only for subclassing
+ }
+
+ @Override
+ public N getParent() {
+ return (N) parent;
+ }
+
+ @Override
+ public int getIndexInParent() {
+ return childIndex;
+ }
+
+ @Override
+ public N getChild(final int index) {
+ return (N) children[index];
+ }
+
+ @Override
+ public int getNumChildren() {
+ return children.length;
+ }
+
+ protected void setParent(final B parent) {
+ this.parent = parent;
+ }
+
+ @SuppressWarnings("unchecked")
+ private B asSelf(Node n) {
+ return (B) n;
+ }
+
+ /**
+ * 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.
+ *
+ * Note that it is more efficient to add children in reverse
+ * (from right to left), because the array is resized only the
+ * first time.
+ *
+ *
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 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;
+
+ if (index >= children.length) {
+ final Node[] newChildren = new Node[index + 1];
+ System.arraycopy(children, 0, newChildren, 0, children.length);
+ children = newChildren;
+ }
+
+ setChild(child, index);
+ }
+
+ /**
+ * Set the child at the given index. The difference with {@link #addChild(AbstractNode, int) addChild}
+ * is that the index must exist, while addChild may resizes the array.
+ */
+ protected void setChild(final B child, final int index) {
+ assert index >= 0 && index < children.length : "Invalid index " + index + " for length " + children.length;
+ children[index] = child;
+ child.setChildIndex(index);
+ child.setParent(asSelf(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 B 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[children.length + 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(asSelf(this));
+
+ for (int i = index; i < newChildren.length; i++) {
+ asSelf(newChildren[i]).setChildIndex(i);
+ }
+ this.children = newChildren;
+ }
+
+
+ protected void remove() {
+ // Detach current node of its parent, if any
+ if (parent != null) {
+ parent.removeChildAtIndex(getIndexInParent());
+ setParent(null);
+ }
+
+ // TODO [autofix]: Notify action for handling text edition
+ }
+
+ protected void removeChildAtIndex(final int childIndex) {
+ if (0 <= childIndex && childIndex < getNumChildren()) {
+ // Remove the child at the given index
+ children = ArrayUtils.remove(children, childIndex);
+ // Update the remaining & left-shifted children indexes
+ for (int i = childIndex; i < getNumChildren(); i++) {
+ asSelf(getChild(i)).setChildIndex(i);
+ }
+ }
+ }
+
+ /**
+ * Sets the index of this node from the perspective of its parent. This
+ * means: this.getParent().getChild(index) == this.
+ *
+ * @param index the child index
+ */
+ void setChildIndex(final int index) {
+ childIndex = index;
+ }
+
+ @Override
+ public DataMap> getUserMap() {
+ if (userData == null) {
+ userData = DataMap.newDataMap();
+ }
+ return userData;
+ }
+
+
+ @Override
+ public String toString() {
+ return getXPathNodeName();
+ }
+
+}
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
new file mode 100644
index 0000000000..0b179878b3
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeWithTextCoordinates.java
@@ -0,0 +1,51 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast.impl;
+
+/**
+ * Base class for implementations that need fields to store text
+ * coordinates.
+ */
+public abstract class AbstractNodeWithTextCoordinates, T extends GenericNode> extends AbstractNode {
+
+ protected int beginLine = -1;
+ protected int endLine = -1;
+ protected int beginColumn = -1;
+ protected int endColumn = -1;
+
+ protected AbstractNodeWithTextCoordinates() {
+ // only for subclassing
+ }
+
+ @Override
+ public int getBeginLine() {
+ return beginLine;
+ }
+
+ @Override
+ public int getBeginColumn() {
+ return beginColumn;
+ }
+
+ @Override
+ public int getEndLine() {
+ return endLine;
+ }
+
+ @Override
+ public int getEndColumn() {
+ return endColumn;
+ }
+
+ protected void setCoords(int bline, int bcol, int eline, int ecol) {
+ assert bline >= 1 && bcol >= 1 && eline >= 1 && ecol >= 1 : "coordinates are 1-based";
+ assert bline <= eline && (bline != eline || bcol <= ecol) : "coordinates must be ordered";
+ beginLine = bline;
+ beginColumn = bcol;
+ endLine = eline;
+ endColumn = ecol;
+ }
+
+}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java
new file mode 100644
index 0000000000..9e277b59b0
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java
@@ -0,0 +1,86 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast.impl;
+
+
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.ast.NodeStream;
+import net.sourceforge.pmd.lang.ast.NodeStream.DescendantNodeStream;
+import net.sourceforge.pmd.lang.ast.internal.StreamImpl;
+
+/**
+ * Interface that binds the return type of some node methods to a type
+ * parameter. This enforces that eg all children of such a node are from
+ * the same hierarchy (eg Java nodes only have Java nodes as parent, or
+ * as children).
+ *
+ * Although subinterfaces like JavaNode profit from the added type
+ * information, the Node interface and its usages in language-independent
+ * code would suffer from adding a type parameter directly to {@link Node}.
+ *
+ *
Type safety of the unchecked casts here is the responsibility of
+ * the implementation, it should check that methods like setParent or
+ * addChild add an instance of {@code }.
+ *
+ * @param Self type (eg JavaNode)
+ */
+@SuppressWarnings("unchecked")
+public interface GenericNode> extends Node {
+
+ @Override
+ N getChild(int index);
+
+ @Override
+ N getParent();
+
+ @Override
+ @Nullable
+ default N getFirstChild() {
+ return getNumChildren() > 0 ? getChild(0) : null;
+ }
+
+ @Override
+ @Nullable
+ default N getLastChild() {
+ return getNumChildren() > 0 ? getChild(getNumChildren() - 1) : null;
+ }
+
+ @Override
+ default NodeStream asStream() {
+ return StreamImpl.singleton((N) this);
+ }
+
+ @Override
+ default N getNthParent(int n) {
+ return (N) Node.super.getNthParent(n);
+ }
+
+ @Override
+ default NodeStream extends N> children() {
+ return (NodeStream extends N>) Node.super.children();
+ }
+
+ @Override
+ default DescendantNodeStream descendants() {
+ return (DescendantNodeStream) Node.super.descendants();
+ }
+
+ @Override
+ default DescendantNodeStream descendantsOrSelf() {
+ return (DescendantNodeStream) Node.super.descendantsOrSelf();
+ }
+
+ @Override
+ default NodeStream ancestorsOrSelf() {
+ return (NodeStream) Node.super.ancestorsOrSelf();
+ }
+
+ @Override
+ default NodeStream ancestors() {
+ return (NodeStream) Node.super.ancestors();
+ }
+}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java
index 1dcaf06ab3..5f6e3f52d7 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java
@@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4;
import org.antlr.v4.runtime.ParserRuleContext;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@@ -65,16 +64,6 @@ public abstract class AntlrBaseNode extends ParserRuleContext implements AntlrNo
return stop.getCharPositionInLine(); // This goes from 0 to (n - 1)
}
- @Override
- public Object getUserData() {
- return userData.get(AbstractNode.LEGACY_USER_DATA);
- }
-
- @Override
- public void setUserData(Object userData) {
- this.userData.set(AbstractNode.LEGACY_USER_DATA, userData);
- }
-
@Override
public DataMap> getUserMap() {
return userData;
@@ -95,7 +84,6 @@ public abstract class AntlrBaseNode extends ParserRuleContext implements AntlrNo
return getChildCount();
}
- // TODO: should we make it abstract due to the comment in AbstractNode ?
@Override
public String getXPathNodeName() {
final String simpleName = getClass().getSimpleName();
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java
index 10339ddd89..1f92c96862 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java
@@ -11,8 +11,8 @@ import org.antlr.v4.runtime.Lexer;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
-import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.ParseException;
+import net.sourceforge.pmd.lang.ast.RootNode;
/**
* Generic Antlr parser adapter for all Antlr parsers.
@@ -31,7 +31,7 @@ public abstract class AntlrBaseParser imp
}
@Override
- public Node parse(final String fileName, final Reader source) throws ParseException {
+ public RootNode parse(final String fileName, final Reader source) throws ParseException {
try {
return getRootNode(getParser(getLexer(source)));
} catch (final IOException e) {
@@ -39,7 +39,7 @@ public abstract class AntlrBaseParser imp
}
}
- protected abstract AntlrBaseNode getRootNode(T parser);
+ protected abstract RootNode getRootNode(T parser);
protected abstract Lexer getLexer(Reader source) throws IOException;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java
index c7a8dc5d25..95122c0665 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java
@@ -8,7 +8,6 @@ import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNodeImpl;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@@ -74,16 +73,6 @@ public class PmdAntlrTerminalNode extends TerminalNodeImpl implements AntlrNode
return getBeginColumn() + getSymbol().getText().length();
}
- @Override
- public Object getUserData() {
- return userData.get(AbstractNode.LEGACY_USER_DATA);
- }
-
- @Override
- public void setUserData(Object data) {
- this.userData.set(AbstractNode.LEGACY_USER_DATA, data);
- }
-
@Override
public DataMap> getUserMap() {
return userData;
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 1b1e54baf6..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
@@ -5,11 +5,8 @@
package net.sourceforge.pmd.lang.ast.impl.javacc;
import net.sourceforge.pmd.annotation.Experimental;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
-import net.sourceforge.pmd.lang.ast.GenericToken;
import net.sourceforge.pmd.lang.ast.Node;
-import net.sourceforge.pmd.lang.ast.NodeStream;
-import net.sourceforge.pmd.lang.ast.TextAvailableNode;
+import net.sourceforge.pmd.lang.ast.impl.AbstractNode;
/**
* Base class for node produced by JJTree. JJTree specific functionality
@@ -20,59 +17,117 @@ import net.sourceforge.pmd.lang.ast.TextAvailableNode;
* unforeseeable ways. Don't use it directly, use the node interfaces.
*/
@Experimental
-public abstract class AbstractJjtreeNode extends AbstractNode implements TextAvailableNode {
+public abstract class AbstractJjtreeNode, N extends JjtreeNode> extends AbstractNode implements JjtreeNode {
+ protected final int id;
+ private JavaccToken firstToken;
+ private JavaccToken lastToken;
- public AbstractJjtreeNode(int id) {
- super(id);
+ private String image;
+
+ /**
+ * The id is an index in the constant names array generated by jjtree,
+ * it must be set to some value that depends on the node type, not some
+ * arbitrary "1" or "2", and not necessarily a unique value.
+ */
+ protected AbstractJjtreeNode(int id) {
+ super();
+ this.id = id;
+ }
+
+ @Override
+ public String getImage() {
+ return image;
+ }
+
+ protected void setImage(String image) {
+ this.image = image;
}
@Override
public CharSequence getText() {
- String fullText = jjtGetFirstToken().document.getFullText();
+ String fullText = getFirstToken().document.getFullText();
return fullText.substring(getStartOffset(), getEndOffset());
}
- @Override
- public JavaccToken jjtGetFirstToken() {
- return (JavaccToken) super.jjtGetFirstToken();
+ /**
+ * This method is called after the node has been made the current node. It
+ * indicates that child nodes can now be added to it.
+ */
+ protected void jjtOpen() {
+ // to be overridden
+ }
+
+ /**
+ * This method is called after all the child nodes have been added.
+ */
+ protected void jjtClose() {
+ // to be overridden
+ }
+
+ @Override // override to make it protected
+ protected void addChild(B child, int index) {
+ super.addChild(child, index);
}
@Override
- public JavaccToken jjtGetLastToken() {
- return (JavaccToken) super.jjtGetLastToken();
+ 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;
+ }
+
+ @Override
+ public JavaccToken getLastToken() {
+ return lastToken;
}
// the super methods query line & column, which we want to avoid
- @Override
- public void jjtSetLastToken(GenericToken token) {
+ protected void setLastToken(JavaccToken token) {
this.lastToken = token;
}
- @Override
- public void jjtSetFirstToken(GenericToken token) {
+ protected void setFirstToken(JavaccToken token) {
this.firstToken = token;
}
- @Override
- @SuppressWarnings("unchecked")
- public N getChild(int index) {
- return (N) super.getChild(index);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public N getParent() {
- return (N) super.getParent();
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public NodeStream extends N> children() {
- return (NodeStream) super.children();
- }
-
@Override
public int getBeginLine() {
return firstToken.getBeginLine();
@@ -102,11 +157,10 @@ public abstract class AbstractJjtreeNode extends AbstractNode im
}
private int getStartOffset() {
- return this.jjtGetFirstToken().getStartInDocument();
+ return this.getFirstToken().getStartInDocument();
}
-
private int getEndOffset() {
- return this.jjtGetLastToken().getEndInDocument();
+ return this.getLastToken().getEndInDocument();
}
}
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 9b6e3fc502..7d14321302 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
@@ -10,9 +10,9 @@ import java.util.List;
/**
* Shared implementation of the tree builder generated by JJTree.
*
- * @param Type of node this takes
+ * @param Internal base class for nodes
*/
-public final class JjtreeBuilder> {
+public final class JjtreeBuilder> {
private final List nodes = new ArrayList<>();
private final List marks = new ArrayList<>();
@@ -141,7 +141,7 @@ public final class JjtreeBuilder> {
numPendingInjection = 0;
}
- n.jjtSetFirstToken(firstToken);
+ n.setFirstToken(firstToken);
n.jjtOpen();
}
@@ -160,13 +160,13 @@ public final class JjtreeBuilder> {
int i = num;
while (i-- > 0) {
child = popNode();
- n.jjtAddChild(child, i);
+ n.addChild(child, i);
}
if (child != null && num > a) {
// this node has more children that what was in its node scope
// (ie first token is wrong)
- n.jjtSetFirstToken(child.jjtGetFirstToken());
+ n.setFirstToken(child.getFirstToken());
}
closeImpl(n, lastToken);
@@ -189,7 +189,7 @@ public final class JjtreeBuilder> {
int a = nodeArity();
mk = marks.remove(marks.size() - 1);
while (a-- > 0) {
- n.jjtAddChild(popNode(), a);
+ n.addChild(popNode(), a);
}
closeImpl(n, lastToken);
} else {
@@ -198,16 +198,17 @@ public final class JjtreeBuilder> {
}
}
+
private void closeImpl(N n, JavaccToken lastToken) {
- if (lastToken.getNext() == n.jjtGetFirstToken()) {
+ if (lastToken.getNext() == n.getFirstToken()) {
// this means, that the node has zero length.
// create an implicit token to represent this case.
JavaccToken implicit = JavaccToken.implicitBefore(lastToken.getNext());
- n.jjtSetFirstToken(implicit);
- n.jjtSetLastToken(implicit);
+ n.setFirstToken(implicit);
+ n.setLastToken(implicit);
} else {
- n.jjtSetLastToken(lastToken);
+ n.setLastToken(lastToken);
}
// note that the last token has been set before jjtClose
n.jjtClose();
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeNode.java
new file mode 100644
index 0000000000..461c24584d
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeNode.java
@@ -0,0 +1,24 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast.impl.javacc;
+
+import net.sourceforge.pmd.lang.ast.TextAvailableNode;
+import net.sourceforge.pmd.lang.ast.impl.GenericNode;
+
+/**
+ * Base interface for nodes that are produced by a JJTree parser. Our
+ * JJTree implementation gives {@link TextAvailableNode} for free, access
+ * to tokens is also guaranteed.
+ *
+ * @param Self type
+ */
+public interface JjtreeNode> extends GenericNode, TextAvailableNode {
+
+
+ JavaccToken getFirstToken();
+
+ JavaccToken getLastToken();
+
+}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java
index b8e7c20339..afbf7d3a35 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java
@@ -91,7 +91,7 @@ abstract class IteratorBasedNStream implements NodeStream {
@NonNull
- protected DescendantNodeStream flatMapDescendants(Function> mapper) {
+ protected DescendantNodeStream flatMapDescendants(Function> mapper) {
return new DescendantMapping<>(this, mapper);
}
@@ -254,18 +254,18 @@ abstract class IteratorBasedNStream implements NodeStream {
private static class DescendantMapping extends IteratorBasedNStream implements DescendantNodeStream {
- private final Function> fun;
+ private final Function super T, ? extends DescendantNodeStream extends S>> fun;
private final TreeWalker walker;
private final IteratorBasedNStream upstream;
- private DescendantMapping(IteratorBasedNStream upstream, Function> fun, TreeWalker walker) {
+ private DescendantMapping(IteratorBasedNStream upstream, Function super T, ? extends DescendantNodeStream extends S>> fun, TreeWalker walker) {
this.fun = fun;
this.walker = walker;
this.upstream = upstream;
}
- DescendantMapping(IteratorBasedNStream upstream, Function> fun) {
+ DescendantMapping(IteratorBasedNStream upstream, Function super T, ? extends DescendantNodeStream extends S>> fun) {
this(upstream, fun, TreeWalker.DEFAULT);
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java
index 62addf9e67..535653f401 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java
@@ -181,7 +181,7 @@ public final class StreamImpl {
}
@Override
- protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) {
+ protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) {
return StreamImpl.empty();
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIterator.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIterator.java
index 79fa9ff888..b659590147 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIterator.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIterator.java
@@ -17,8 +17,9 @@ import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.ast.impl.AbstractNode;
+import net.sourceforge.pmd.lang.ast.impl.AbstractNodeWithTextCoordinates;
import net.sourceforge.pmd.lang.ast.xpath.NoAttribute.NoAttrScope;
@@ -110,7 +111,7 @@ public class AttributeAxisIterator implements Iterator {
Class> declaration = method.getDeclaringClass();
if (method.isAnnotationPresent(NoAttribute.class)) {
return true;
- } else if (declaration == Node.class || declaration == AbstractNode.class) {
+ } else if (declaration == Node.class || declaration == AbstractNode.class || declaration == AbstractNodeWithTextCoordinates.class) {
// attributes from Node and AbstractNode are never suppressed
// we don't know what might go wrong if we do suppress them
return false;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/NoAttribute.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/NoAttribute.java
index 2d63dc60ab..a359b844f0 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/NoAttribute.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/NoAttribute.java
@@ -9,8 +9,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.ast.impl.AbstractNode;
/**
* Filters out some methods from the XPath attributes of a node.
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/AbstractDataFlowNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/AbstractDataFlowNode.java
index d5ae23be60..da66a63fc1 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/AbstractDataFlowNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/AbstractDataFlowNode.java
@@ -10,6 +10,8 @@ import java.util.List;
import java.util.Set;
import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.util.DataMap;
+import net.sourceforge.pmd.util.DataMap.SimpleDataKey;
/**
* Each data flow contains a set of DataFlowNodes.
@@ -18,6 +20,8 @@ import net.sourceforge.pmd.lang.ast.Node;
*/
public abstract class AbstractDataFlowNode implements DataFlowNode {
+ static final SimpleDataKey DATAFLOW_KEY = DataMap.simpleDataKey("dataflow.cache");
+
protected Node node;
protected List parents = new ArrayList<>();
@@ -40,7 +44,7 @@ public abstract class AbstractDataFlowNode implements DataFlowNode {
this(dataFlow);
this.node = node;
- node.setDataFlowNode(this);
+ node.getUserMap().set(DATAFLOW_KEY, this);
this.line = node.getBeginLine();
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/DataFlowNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/DataFlowNode.java
index 788edff78d..c0c3219187 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/DataFlowNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/dfa/DataFlowNode.java
@@ -4,6 +4,8 @@
package net.sourceforge.pmd.lang.dfa;
+import static net.sourceforge.pmd.lang.dfa.AbstractDataFlowNode.DATAFLOW_KEY;
+
import java.util.List;
import net.sourceforge.pmd.lang.ast.Node;
@@ -35,4 +37,13 @@ public interface DataFlowNode {
void reverseParentPathsTo(DataFlowNode destination);
+
+ static DataFlowNode get(Node node) {
+ DataFlowNode df = node.getUserMap().get(DATAFLOW_KEY);
+ if (df == null && node.getParent() != null) {
+ return get(node.getParent());
+ } else {
+ return df;
+ }
+ }
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/rules/RuleBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/rules/RuleBuilder.java
index 45ea95de6a..47313a12f7 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/rules/RuleBuilder.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/rules/RuleBuilder.java
@@ -153,7 +153,7 @@ public class RuleBuilder {
if (minimumVersion != null) {
LanguageVersion minimumLanguageVersion = rule.getLanguage().getVersion(minimumVersion);
if (minimumLanguageVersion == null) {
- throwUnknownLanguageVersionException("minimum", minimumVersion);
+ throwUnknownLanguageVersionException("minimum", minimumVersion, rule.getLanguage());
} else {
rule.setMinimumLanguageVersion(minimumLanguageVersion);
}
@@ -162,7 +162,7 @@ public class RuleBuilder {
if (maximumVersion != null) {
LanguageVersion maximumLanguageVersion = rule.getLanguage().getVersion(maximumVersion);
if (maximumLanguageVersion == null) {
- throwUnknownLanguageVersionException("maximum", maximumVersion);
+ throwUnknownLanguageVersionException("maximum", maximumVersion, rule.getLanguage());
} else {
rule.setMaximumLanguageVersion(maximumLanguageVersion);
}
@@ -171,12 +171,12 @@ public class RuleBuilder {
checkLanguageVersionsAreOrdered(rule);
}
- private void throwUnknownLanguageVersionException(String minOrMax, String unknownVersion) {
- throw new IllegalArgumentException("Unknown " + minOrMax + " language version '" + unknownVersion
- + "' for language '" + language.getTerseName()
- + "' for rule " + name
- + "; supported language versions are: "
- + language.getVersions().stream().map(LanguageVersion::getVersion).collect(Collectors.joining(", ")));
+ private void throwUnknownLanguageVersionException(String minOrMax, String unknownVersion, Language lang) {
+ throw new IllegalArgumentException("Unknown " + minOrMax + " Language Version '" + unknownVersion
+ + "' for Language '" + lang.getTerseName()
+ + "' for Rule " + name
+ + "; supported Language Versions are: "
+ + lang.getVersions().stream().map(LanguageVersion::getVersion).collect(Collectors.joining(", ")));
}
public Rule build() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java
index 05d4bcd2c5..978fba72ff 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/DataMap.java
@@ -17,7 +17,7 @@ import java.util.Map;
*/
public final class DataMap {
- private final Map, Object> map = new IdentityHashMap<>();
+ private Map, Object> map;
private DataMap() {
@@ -34,7 +34,7 @@ public final class DataMap {
*/
@SuppressWarnings("unchecked")
public T set(DataKey extends K, ? super T> key, T data) {
- return (T) map.put(key, data);
+ return (T) getMap().put(key, data);
}
/**
@@ -47,7 +47,20 @@ public final class DataMap {
*/
@SuppressWarnings("unchecked")
public T get(DataKey extends K, ? super T> key) {
- return (T) map.get(key);
+ return map == null ? null : (T) map.get(key);
+ }
+
+ private Map, Object> getMap() {
+ // the map is lazily created, it's only needed if set() is called
+ // at least once, but get() might be called many more times, as
+ // sometimes you cache a key sparsely on some nodes, and default
+ // to the first parent for which the key is set. The default expected
+ // max size is also 21, which is *way* bigger than what data maps
+ // typically contain (1/2 keys)
+ if (map == null) {
+ map = new IdentityHashMap<>(1);
+ }
+ return map;
}
/**
@@ -58,7 +71,7 @@ public final class DataMap {
* @return True if some value is set
*/
public boolean isSet(DataKey extends K, ?> key) {
- return map.containsKey(key);
+ return map != null && map.containsKey(key);
}
public static DataMap newDataMap() {
diff --git a/pmd-core/src/main/resources/rulesets/releases/6240.xml b/pmd-core/src/main/resources/rulesets/releases/6240.xml
new file mode 100644
index 0000000000..a7fe86d521
--- /dev/null
+++ b/pmd-core/src/main/resources/rulesets/releases/6240.xml
@@ -0,0 +1,13 @@
+
+
+
+
+This ruleset contains links to rules that are new in PMD v6.24.0
+
+
+
+
+
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
index 847ac33fdf..69850b8c33 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
@@ -76,9 +76,8 @@ public class AbstractRuleTest {
r.setRuleSetName("foo");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginColumn(5);
- s.testingOnlySetBeginLine(5);
+ DummyNode s = new DummyNode();
+ s.setCoords(5, 5, 5, 10);
RuleViolation rv = new ParametricRuleViolation(r, ctx, s, r.getMessage());
assertEquals("Line number mismatch!", 5, rv.getBeginLine());
assertEquals("Filename mismatch!", "filename", rv.getFilename());
@@ -92,9 +91,8 @@ public class AbstractRuleTest {
MyRule r = new MyRule();
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginColumn(5);
- s.testingOnlySetBeginLine(5);
+ DummyNode s = new DummyNode();
+ s.setCoords(5, 5, 5, 10);
RuleViolation rv = new ParametricRuleViolation<>(r, ctx, s, "specificdescription");
assertEquals("Line number mismatch!", 5, rv.getBeginLine());
assertEquals("Filename mismatch!", "filename", rv.getFilename());
@@ -112,7 +110,7 @@ public class AbstractRuleTest {
ctx.setReport(new Report());
ctx.setSourceCodeFile(new File("filename"));
DummyNode s = new DummyRoot();
- s.setCoords(5, 1, 6, 0);
+ s.setCoords(5, 1, 6, 1);
s.setImage("TestImage");
r.addViolation(ctx, s);
RuleViolation rv = ctx.getReport().getViolationTree().iterator().next();
@@ -127,7 +125,7 @@ public class AbstractRuleTest {
m.put(5, "");
ctx.setSourceCodeFile(new File("filename"));
DummyRoot n = new DummyRoot(m);
- n.setCoords(5, 1, 6, 0);
+ n.setCoords(5, 1, 6, 1);
DefaultRuleViolationFactory.defaultInstance().addViolation(ctx, r, n, "specificdescription", new Object[0]);
assertTrue(ctx.getReport().isEmpty());
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ReportTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ReportTest.java
index 473d5375b1..b6ac200e8f 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/ReportTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/ReportTest.java
@@ -96,8 +96,8 @@ public class ReportTest implements ThreadSafeReportListener {
r.addRuleViolation(new ParametricRuleViolation<>(mr, ctx, s2, mr.getMessage()));
Map summary = r.getSummary();
assertEquals(summary.keySet().size(), 2);
- assertTrue(summary.values().contains(Integer.valueOf(1)));
- assertTrue(summary.values().contains(Integer.valueOf(2)));
+ assertTrue(summary.containsValue(1));
+ assertTrue(summary.containsValue(2));
}
@Test
@@ -128,21 +128,18 @@ public class ReportTest implements ThreadSafeReportListener {
}
private static Node getNode(int line, int column) {
- DummyNode s = new DummyNode(2);
- DummyNode parent = new DummyNode(1);
- parent.testingOnlySetBeginLine(line);
- parent.testingOnlySetBeginColumn(column);
- s.jjtSetParent(parent);
- s.testingOnlySetBeginLine(line);
- s.testingOnlySetBeginColumn(column);
+ DummyNode s = new DummyNode();
+ DummyNode parent = new DummyNode();
+ parent.setCoords(line, column, line, column + 1);
+ parent.addChild(s, 0);
+ s.setCoords(line, column, line, column + 1);
return s;
}
private static Node getNode(int line, int column, boolean nextLine) {
DummyNode s = (DummyNode) getNode(line, column);
if (nextLine) {
- s.testingOnlySetBeginLine(line + 1);
- s.testingOnlySetBeginColumn(column + 4);
+ s.setCoords(line + 1, column + 4, line + 4, 1);
}
return s;
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
index 61726f393b..def2261c04 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryTest.java
@@ -600,6 +600,23 @@ public class RuleSetFactoryTest {
loadFirstRule(INCORRECT_MINIMUM_LANGUAGE_VERSION);
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testIncorrectMinimumLanugageVersionWithLanguageSetInJava() throws RuleSetNotFoundException {
+ loadFirstRule("\n"
+ + "\n"
+ + " TODO \n"
+ + "\n"
+ + " \n"
+ + " TODO \n"
+ + " 2 \n"
+ + " \n"
+ + "\n"
+ + " ");
+ }
+
@Test
public void testMaximumLanguageVersion() throws RuleSetNotFoundException {
Rule r = loadFirstRule(MAXIMUM_LANGUAGE_VERSION);
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java
index e0643c0e01..45d3571c5c 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java
@@ -33,23 +33,23 @@ public class RuleViolationComparatorTest {
int index = 0;
// Different begin line
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file1", 10, "desc1", 0, 20, 80);
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file1", 20, "desc1", 0, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file1", 10, "desc1", 1, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file1", 20, "desc1", 1, 20, 80);
// Different description
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file2", 10, "desc1", 0, 20, 80);
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file2", 10, "desc2", 0, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file2", 10, "desc1", 1, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file2", 10, "desc2", 1, 20, 80);
// Different begin column
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file3", 10, "desc1", 0, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file3", 10, "desc1", 1, 20, 80);
expectedOrder[index++] = createJavaRuleViolation(rule1, "file3", 10, "desc1", 10, 20, 80);
// Different end line
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file4", 10, "desc1", 0, 20, 80);
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file4", 10, "desc1", 0, 30, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file4", 10, "desc1", 1, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file4", 10, "desc1", 1, 30, 80);
// Different end column
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file5", 10, "desc1", 0, 20, 80);
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file5", 10, "desc1", 0, 20, 90);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file5", 10, "desc1", 1, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file5", 10, "desc1", 1, 20, 90);
// Different rule name
- expectedOrder[index++] = createJavaRuleViolation(rule1, "file6", 10, "desc1", 0, 20, 80);
- expectedOrder[index++] = createJavaRuleViolation(rule2, "file6", 10, "desc1", 0, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule1, "file6", 10, "desc1", 1, 20, 80);
+ expectedOrder[index++] = createJavaRuleViolation(rule2, "file6", 10, "desc1", 1, 20, 80);
// Randomize
List ruleViolations = new ArrayList<>(Arrays.asList(expectedOrder));
@@ -73,12 +73,8 @@ public class RuleViolationComparatorTest {
int beginColumn, int endLine, int endColumn) {
RuleContext ruleContext = new RuleContext();
ruleContext.setSourceCodeFile(new File(fileName));
- DummyNode simpleNode = new DummyNode(1);
- simpleNode.testingOnlySetBeginLine(beginLine);
- simpleNode.testingOnlySetBeginColumn(beginColumn);
- simpleNode.testingOnlySetEndLine(endLine);
- simpleNode.testingOnlySetEndColumn(endColumn);
- RuleViolation ruleViolation = new ParametricRuleViolation(rule, ruleContext, simpleNode, description);
- return ruleViolation;
+ DummyNode simpleNode = new DummyNode();
+ simpleNode.setCoords(beginLine, beginColumn, endLine, endColumn);
+ return new ParametricRuleViolation(rule, ruleContext, simpleNode, description);
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java
index 9fd8554203..d9717e3e4c 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java
@@ -26,9 +26,8 @@ public class RuleViolationTest {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginLine(2);
- s.testingOnlySetBeginColumn(1);
+ DummyNode s = new DummyNode();
+ s.setCoords(2, 1, 2, 3);
RuleViolation r = new ParametricRuleViolation(rule, ctx, s, rule.getMessage());
assertEquals("object mismatch", rule, r.getRule());
assertEquals("line number is wrong", 2, r.getBeginLine());
@@ -40,9 +39,8 @@ public class RuleViolationTest {
Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginLine(2);
- s.testingOnlySetBeginColumn(1);
+ DummyNode s = new DummyNode();
+ s.setCoords(2, 1, 2, 3);
RuleViolation r = new ParametricRuleViolation(rule, ctx, s, "description");
assertEquals("object mismatch", rule, r.getRule());
assertEquals("line number is wrong", 2, r.getBeginLine());
@@ -56,14 +54,12 @@ public class RuleViolationTest {
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename1"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginLine(10);
- s.testingOnlySetBeginColumn(1);
+ DummyNode s = new DummyNode();
+ s.setCoords(10, 1, 11, 3);
RuleViolation r1 = new ParametricRuleViolation(rule, ctx, s, "description");
ctx.setSourceCodeFile(new File("filename2"));
- DummyNode s1 = new DummyNode(1);
- s1.testingOnlySetBeginLine(10);
- s1.testingOnlySetBeginColumn(1);
+ DummyNode s1 = new DummyNode();
+ s1.setCoords(10, 1, 11, 3);
RuleViolation r2 = new ParametricRuleViolation(rule, ctx, s1, "description");
assertEquals(-1, comp.compare(r1, r2));
assertEquals(1, comp.compare(r2, r1));
@@ -75,12 +71,10 @@ public class RuleViolationTest {
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginLine(10);
- s.testingOnlySetBeginColumn(1);
- DummyNode s1 = new DummyNode(1);
- s1.testingOnlySetBeginLine(20);
- s1.testingOnlySetBeginColumn(1);
+ DummyNode s = new DummyNode();
+ s.setCoords(10, 1, 15, 10);
+ DummyNode s1 = new DummyNode();
+ s1.setCoords(20, 1, 25, 10);
RuleViolation r1 = new ParametricRuleViolation(rule, ctx, s, "description");
RuleViolation r2 = new ParametricRuleViolation(rule, ctx, s1, "description");
assertTrue(comp.compare(r1, r2) < 0);
@@ -94,12 +88,10 @@ public class RuleViolationTest {
RuleViolationComparator comp = RuleViolationComparator.INSTANCE;
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File("filename"));
- DummyNode s = new DummyNode(1);
- s.testingOnlySetBeginLine(10);
- s.testingOnlySetBeginColumn(1);
- DummyNode s1 = new DummyNode(1);
- s1.testingOnlySetBeginLine(10);
- s1.testingOnlySetBeginColumn(1);
+ DummyNode s = new DummyNode();
+ s.setCoords(10, 1, 15, 10);
+ DummyNode s1 = new DummyNode();
+ s.setCoords(10, 1, 15, 10);
RuleViolation r1 = new ParametricRuleViolation(rule, ctx, s, "description");
RuleViolation r2 = new ParametricRuleViolation(rule, ctx, s1, "description");
assertEquals(1, comp.compare(r1, r2));
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeAxisIteratorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeAxisIteratorTest.java
index 311963f2b5..a8b5939a26 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeAxisIteratorTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeAxisIteratorTest.java
@@ -13,9 +13,7 @@ public class AttributeAxisIteratorTest {
@Test(expected = UnsupportedOperationException.class)
public void testRemove() {
- DummyNode n = new DummyNode(0);
- n.testingOnlySetBeginColumn(1);
- n.testingOnlySetBeginLine(1);
+ DummyNode n = new DummyNode();
AttributeAxisIterator iter = new AttributeAxisIterator(n);
iter.remove();
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeTest.java
index 7d5b28091d..eec54c965d 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/AttributeTest.java
@@ -17,13 +17,14 @@ public class AttributeTest {
@Test
public void testConstructor() {
- DummyNode p = new DummyNode(1);
- p.testingOnlySetBeginLine(5);
+ DummyNode p = new DummyNode();
+ p.setCoords(5, 5, 5, 10);
+
Method[] methods = p.getClass().getMethods();
Method m = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().equals("getBeginLine")) {
- m = methods[i];
+ for (Method method : methods) {
+ if (method.getName().equals("getBeginLine")) {
+ m = method;
break;
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/MatchesFunctionTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/MatchesFunctionTest.java
index 5bbedef6df..c5be1ce2c5 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/MatchesFunctionTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/jaxen/MatchesFunctionTest.java
@@ -13,17 +13,18 @@ import org.jaxen.Context;
import org.jaxen.FunctionCallException;
import org.junit.Test;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
+import net.sourceforge.pmd.lang.ast.impl.AbstractNodeWithTextCoordinates;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import net.sourceforge.pmd.lang.xpath.MatchesFunction;
public class MatchesFunctionTest {
- public static class MyNode extends AbstractNode {
+ public static class MyNode extends AbstractNodeWithTextCoordinates {
+
private String className;
public MyNode() {
- super(1);
+ super();
}
@Override
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
index bbc6b8522d..f700c527d9 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
@@ -13,7 +13,6 @@ import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.ast.DummyAstStages;
-import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyRoot;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.ParseException;
@@ -35,15 +34,15 @@ public class DummyLanguageModule extends BaseLanguageModule {
public DummyLanguageModule() {
super(NAME, null, TERSE_NAME, DummyRuleChainVisitor.class, "dummy");
- addVersion("1.0", new Handler(), false);
- addVersion("1.1", new Handler(), false);
- addVersion("1.2", new Handler(), false);
- addVersion("1.3", new Handler(), false);
- addVersion("1.4", new Handler(), false);
- addVersions(new Handler(), false, "1.5", "5");
- addVersions(new Handler(), false, "1.6", "6");
- addVersions(new Handler(), true, "1.7", "7");
- addVersions(new Handler(), false, "1.8", "8");
+ addVersion("1.0", new Handler());
+ addVersion("1.1", new Handler());
+ addVersion("1.2", new Handler());
+ addVersion("1.3", new Handler());
+ addVersion("1.4", new Handler());
+ addVersion("1.5", new Handler(), "5");
+ addVersion("1.6", new Handler(), "6");
+ addDefaultVersion("1.7", new Handler(), "7");
+ addVersion("1.8", new Handler(), "8");
}
public static class DummyRuleChainVisitor extends AbstractRuleChainVisitor {
@@ -101,8 +100,8 @@ public class DummyLanguageModule extends BaseLanguageModule {
public Parser getParser(ParserOptions parserOptions) {
return new AbstractParser(parserOptions) {
@Override
- public Node parse(String fileName, Reader source) throws ParseException {
- DummyNode node = new DummyRoot();
+ public DummyRoot parse(String fileName, Reader source) throws ParseException {
+ DummyRoot node = new DummyRoot();
node.setCoords(1, 1, 2, 10);
node.setImage("Foo");
return node;
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
index 4a9c24184a..b3d394903f 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
@@ -14,29 +14,23 @@ import org.junit.Before;
import org.junit.Test;
/**
- * Unit test for {@link AbstractNode} tree traversal methods
+ * Unit test for {@link Node} tree traversal methods
*/
public class BoundaryTraversalTest {
- private int id;
- private Node rootNode;
- private int nextId() {
- return id++;
+ private DummyNode rootNode;
+
+ private DummyNode newDummyNode(boolean boundary) {
+ return new DummyNode(boundary);
}
- private Node newDummyNode(boolean boundary) {
- return new DummyNode(nextId(), boundary);
- }
-
- private Node addChild(final Node parent, final Node child) {
- parent.jjtAddChild(child, parent.getNumChildren()); // Append child at the end
- child.jjtSetParent(parent);
+ private DummyNode addChild(final DummyNode parent, final DummyNode child) {
+ parent.addChild(child, parent.getNumChildren()); // Append child at the end
return parent;
}
@Before
public void setUpSampleNodeTree() {
- id = 0;
rootNode = newDummyNode(false);
}
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 2fa20bcbfb..d87c27be11 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
@@ -7,47 +7,52 @@ package net.sourceforge.pmd.lang.ast;
import java.util.HashMap;
import java.util.Map;
-public class DummyNode extends AbstractNode {
+import net.sourceforge.pmd.lang.ast.impl.AbstractNodeWithTextCoordinates;
+
+public class DummyNode extends AbstractNodeWithTextCoordinates {
+
private final boolean findBoundary;
private final String xpathName;
private final Map userData = new HashMap<>();
-
- public DummyNode(int id) {
- this(id, false);
- }
+ private String image;
public DummyNode() {
- this(0, false);
+ this(false);
}
- public DummyNode(int id, boolean findBoundary) {
- this(id, findBoundary, "dummyNode");
+ public DummyNode(boolean findBoundary) {
+ this(findBoundary, "dummyNode");
}
- public DummyNode(int id, boolean findBoundary, String xpathName) {
- super(id);
+ public DummyNode(boolean findBoundary, String xpathName) {
this.findBoundary = findBoundary;
this.xpathName = xpathName;
}
- public void setBeginColumn(int i) {
- beginColumn = i;
- }
-
- public void setBeginLine(int i) {
- beginLine = i;
+ public void publicSetChildren(DummyNode... children) {
+ assert getNumChildren() == 0;
+ for (int i = children.length - 1; i >= 0; i--) {
+ addChild(children[i], i);
+ }
}
+ @Override
public void setCoords(int bline, int bcol, int eline, int ecol) {
- beginLine = bline;
- beginColumn = bcol;
- endLine = eline;
- endColumn = ecol;
+ super.setCoords(bline, bcol, eline, ecol);
+ }
+
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ @Override
+ public String getImage() {
+ return image;
}
@Override
public String toString() {
- return xpathName;
+ return getImage();
}
@Override
@@ -60,18 +65,22 @@ public class DummyNode extends AbstractNode {
return findBoundary;
}
- @Override
public Map getUserData() {
return userData;
}
+ @Override
+ public void addChild(DummyNode child, int index) {
+ super.addChild(child, index);
+ }
+
+ @Override
+ public DummyNode getChild(int index) {
+ return super.getChild(index);
+ }
public static class DummyNodeTypeB extends DummyNode {
- @Override
- public String toString() {
- return getImage();
- }
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
index 0e5dd20606..81460ce5a3 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
@@ -14,7 +14,7 @@ public class DummyNodeWithDeprecatedAttribute extends DummyNode {
public DummyNodeWithDeprecatedAttribute(int id) {
- super(id);
+ super();
}
// this is the deprecated attribute
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java
index 633d38db87..a8ddf5ca52 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyRoot.java
@@ -12,7 +12,7 @@ public class DummyRoot extends DummyNode implements RootNode {
private final Map suppressMap;
public DummyRoot(Map suppressMap) {
- super(0);
+ super();
this.suppressMap = suppressMap;
}
@@ -25,11 +25,6 @@ public class DummyRoot extends DummyNode implements RootNode {
return suppressMap;
}
- @Override
- public String toString() {
- return "dummyRootNode";
- }
-
@Override
public String getXPathNodeName() {
return "dummyRootNode";
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/AbstractNodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java
similarity index 76%
rename from pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/AbstractNodeTest.java
rename to pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java
index d23db81a28..e9b0f3b513 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/AbstractNodeTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java
@@ -2,13 +2,18 @@
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
-package net.sourceforge.pmd.lang.ast;
+package net.sourceforge.pmd.lang.ast.impl;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.node;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.root;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.tree;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.util.List;
+
import org.jaxen.JaxenException;
import org.junit.Before;
import org.junit.Rule;
@@ -16,6 +21,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import net.sourceforge.pmd.junit.JavaUtilLoggingRule;
+import net.sourceforge.pmd.lang.ast.DummyNode;
+import net.sourceforge.pmd.lang.ast.DummyNodeWithDeprecatedAttribute;
+import net.sourceforge.pmd.lang.ast.DummyRoot;
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.ast.RootNode;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import junitparams.JUnitParamsRunner;
@@ -64,36 +74,25 @@ public class AbstractNodeTest {
return indexes;
}
- private int id;
- private Node rootNode;
-
- private int nextId() {
- return id++;
- }
-
- private Node newDummyNode() {
- return new DummyNode(nextId());
- }
-
- private static Node addChild(final Node parent, final Node child) {
- parent.jjtAddChild(child, parent.getNumChildren()); // Append child at the end
- child.jjtSetParent(parent);
- return parent;
- }
+ private DummyRoot rootNode;
@Before
public void setUpSampleNodeTree() {
- id = 0;
- rootNode = newDummyNode();
+ rootNode = tree(
+ () -> {
+ DummyRoot root = root();
- for (int i = 0; i < NUM_CHILDREN; i++) {
- final Node child = newDummyNode();
- for (int j = 0; j < NUM_GRAND_CHILDREN; j++) {
- final Node grandChild = newDummyNode();
- addChild(child, grandChild);
+ for (int i = 0; i < NUM_CHILDREN; i++) {
+ final DummyNode child = node();
+ for (int j = 0; j < NUM_GRAND_CHILDREN; j++) {
+ child.addChild(node(), j);
+ }
+ root.addChild(child, i);
+ }
+ return root;
}
- addChild(rootNode, child);
- }
+ );
+
}
/**
@@ -102,12 +101,8 @@ public class AbstractNodeTest {
@Test
@Parameters(method = "childrenIndexes")
public void testRemoveChildOfRootNode(final int childIndex) {
- final Node child = rootNode.getChild(childIndex);
- final Node[] grandChildren = new Node[child.getNumChildren()];
- for (int i = 0; i < grandChildren.length; i++) {
- final Node grandChild = child.getChild(i);
- grandChildren[i] = grandChild;
- }
+ final DummyNode child = rootNode.getChild(childIndex);
+ final List extends DummyNode> grandChildren = child.children().toList();
// Do the actual removal
child.remove();
@@ -129,11 +124,7 @@ public class AbstractNodeTest {
@Test
public void testRemoveRootNode() {
// Check that the root node has the expected properties
- final Node[] children = new Node[rootNode.getNumChildren()];
- for (int i = 0; i < children.length; i++) {
- final Node child = rootNode.getChild(i);
- children[i] = child;
- }
+ final List extends DummyNode> children = rootNode.children().toList();
// Do the actual removal
rootNode.remove();
@@ -154,8 +145,8 @@ public class AbstractNodeTest {
@Test
@Parameters(method = "childrenAndGrandChildrenIndexes")
public void testRemoveGrandChildNode(final int childIndex, final int grandChildIndex) {
- final Node child = rootNode.getChild(childIndex);
- final Node grandChild = child.getChild(grandChildIndex);
+ final DummyNode child = rootNode.getChild(childIndex);
+ final DummyNode grandChild = child.getChild(grandChildIndex);
// Do the actual removal
grandChild.remove();
@@ -172,11 +163,7 @@ public class AbstractNodeTest {
@Test
@Parameters(method = "childrenIndexes")
public void testRemoveRootNodeChildAtIndex(final int childIndex) {
- final Node[] originalChildren = new Node[rootNode.getNumChildren()];
-
- for (int i = 0; i < originalChildren.length; i++) {
- originalChildren[i] = rootNode.getChild(i);
- }
+ final List extends DummyNode> originalChildren = rootNode.children().toList();
// Do the actual removal
rootNode.removeChildAtIndex(childIndex);
@@ -189,7 +176,7 @@ public class AbstractNodeTest {
j++;
}
// Check that the nodes have been rightly shifted
- assertEquals(originalChildren[j], rootNode.getChild(i));
+ assertEquals(originalChildren.get(j), rootNode.getChild(i));
// Check that the child index has been updated
assertEquals(i, rootNode.getChild(i).getIndexInParent());
j++;
@@ -218,7 +205,7 @@ public class AbstractNodeTest {
@Parameters(method = "grandChildrenIndexes")
public void testRemoveChildAtIndexOnNodeWithNoChildren(final int grandChildIndex) {
// grandChild does not have any child
- final Node grandChild = rootNode.getChild(grandChildIndex).getChild(grandChildIndex);
+ final DummyNode grandChild = rootNode.getChild(grandChildIndex).getChild(grandChildIndex);
// Do the actual removal
grandChild.removeChildAtIndex(0);
@@ -228,17 +215,18 @@ public class AbstractNodeTest {
assertEquals(0, grandChild.getNumChildren());
}
+
@Test
public void testDeprecatedAttributeXPathQuery() throws JaxenException {
class MyRootNode extends DummyNode implements RootNode {
- private MyRootNode(int id) {
- super(id);
+ private MyRootNode() {
+ super();
}
}
- Node root = addChild(new MyRootNode(nextId()), new DummyNodeWithDeprecatedAttribute(2));
- root.findChildNodesWithXPath("//dummyNode[@Size=1]");
+ tree(() -> root(new DummyNodeWithDeprecatedAttribute(2)))
+ .findChildNodesWithXPath("//dummyNode[@Size=1]");
String log = loggingRule.getLog();
@@ -247,4 +235,5 @@ public class AbstractNodeTest {
assertTrue(log.contains("dummyNode/@Size"));
}
+
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyTreeUtil.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java
similarity index 72%
rename from pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyTreeUtil.java
rename to pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java
index a6b4f86377..d8ead26590 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyTreeUtil.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/DummyTreeUtil.java
@@ -1,15 +1,19 @@
-/**
+/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
-package net.sourceforge.pmd.lang.ast;
+package net.sourceforge.pmd.lang.ast.impl;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyNode.DummyNodeTypeB;
+import net.sourceforge.pmd.lang.ast.DummyRoot;
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.ast.NodeStream;
/**
@@ -23,15 +27,13 @@ public final class DummyTreeUtil {
}
+ public static DummyRoot root(DummyNode... children) {
+ return nodeImpl(new DummyRoot(), children);
+ }
+
/** Creates a dummy node with the given children. */
public static DummyNode node(DummyNode... children) {
- DummyNode node = new DummyNode() {
- @Override
- public String toString() {
- return getImage();
- }
- };
- return nodeImpl(node, children);
+ return nodeImpl(new DummyNode(), children);
}
/** Creates a dummy node with the given children. */
@@ -39,12 +41,8 @@ public final class DummyTreeUtil {
return nodeImpl(new DummyNodeTypeB(), children);
}
- private static DummyNode nodeImpl(DummyNode node, DummyNode... children) {
- node.children = children;
- for (int i = 0; i < children.length; i++) {
- children[i].jjtSetParent(node);
- children[i].jjtSetChildIndex(i);
- }
+ private static T nodeImpl(T node, DummyNode... children) {
+ node.publicSetChildren(children);
return node;
}
@@ -77,14 +75,14 @@ public final class DummyTreeUtil {
* )
*
*/
- public static DummyNode tree(Supplier supplier) {
- DummyNode dummyNode = supplier.get();
+ public static DummyRoot tree(Supplier supplier) {
+ DummyRoot dummyNode = supplier.get();
assignPathImage(dummyNode, "");
return dummyNode;
}
- private static void assignPathImage(Node node, String curPath) {
+ private static void assignPathImage(DummyNode node, String curPath) {
node.setImage(curPath);
for (int i = 0; i < node.getNumChildren(); i++) {
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java
index 5732863c96..0c2994908a 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java
@@ -6,9 +6,10 @@ package net.sourceforge.pmd.lang.ast.internal;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertSame;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.node;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.nodeB;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.tree;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.node;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.nodeB;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.root;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.tree;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,7 +42,8 @@ public class NodeStreamBlanketTest {
private static final List ASTS = Arrays.asList(
tree(
() ->
- node(
+ root(
+
node(
node(),
nodeB(
@@ -55,7 +57,7 @@ public class NodeStreamBlanketTest {
),
tree(
() ->
- node(
+ root(
node(),
node(),
nodeB(
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamTest.java
index f3f2b19d49..10d5af03d1 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamTest.java
@@ -4,10 +4,11 @@
package net.sourceforge.pmd.lang.ast.internal;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.followPath;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.node;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.pathsOf;
-import static net.sourceforge.pmd.lang.ast.DummyTreeUtil.tree;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.followPath;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.node;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.pathsOf;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.root;
+import static net.sourceforge.pmd.lang.ast.impl.DummyTreeUtil.tree;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
import static org.junit.Assert.assertEquals;
@@ -25,6 +26,7 @@ import org.junit.Test;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.NodeStream;
+import net.sourceforge.pmd.lang.ast.NodeStream.DescendantNodeStream;
/**
@@ -35,7 +37,7 @@ public class NodeStreamTest {
private final DummyNode tree1 = tree(
() ->
- node(// ""
+ root(// ""
node(// 0
node(), // 00
node(// 01
@@ -52,7 +54,7 @@ public class NodeStreamTest {
private final DummyNode tree2 = tree(
() ->
- node(
+ root(
node(),
node(),
node(
@@ -186,7 +188,7 @@ public class NodeStreamTest {
@Test
public void testGet() {
// ("0", "00", "01", "010", "011", "012", "013", "1")
- NodeStream stream = tree1.descendants();
+ DescendantNodeStream stream = tree1.descendants();
assertEquals("0", stream.get(0).getImage());
assertEquals("00", stream.get(1).getImage());
@@ -197,7 +199,7 @@ public class NodeStreamTest {
@Test
public void testNodeStreamsCanBeIteratedSeveralTimes() {
- NodeStream stream = tree1.descendants();
+ DescendantNodeStream stream = tree1.descendants();
assertThat(stream.count(), equalTo(8));
assertThat(stream.count(), equalTo(8));
@@ -252,7 +254,7 @@ public class NodeStreamTest {
MutableInt upstreamEvals = new MutableInt();
MutableInt downstreamEvals = new MutableInt();
- NodeStream stream =
+ NodeStream stream =
tree1.descendants()
.filter(n -> n.getImage().matches("0.*"))
.take(4)
@@ -299,7 +301,7 @@ public class NodeStreamTest {
MutableInt tree1Evals = new MutableInt();
- NodeStream unionStream = tree1.descendantsOrSelf().peek(n -> tree1Evals.increment());
+ NodeStream unionStream = tree1.descendantsOrSelf().peek(n -> tree1Evals.increment());
int i = 0;
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIteratorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIteratorTest.java
index a1dda2cb58..8017a09fd6 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIteratorTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/AttributeAxisIteratorTest.java
@@ -32,40 +32,38 @@ public class AttributeAxisIteratorTest {
*/
@Test
public void testAttributeAxisIterator() {
- DummyNode dummyNode = new DummyNode(1);
- dummyNode.testingOnlySetBeginLine(1);
- dummyNode.testingOnlySetBeginColumn(1);
+ DummyNode dummyNode = new DummyNode();
+ dummyNode.setCoords(1, 1, 2, 2);
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
Map atts = toMap(it);
- Assert.assertEquals(7, atts.size());
+ Assert.assertEquals(6, atts.size());
assertTrue(atts.containsKey("BeginColumn"));
assertTrue(atts.containsKey("BeginLine"));
assertTrue(atts.containsKey("FindBoundary"));
assertTrue(atts.containsKey("Image"));
- assertTrue(atts.containsKey("SingleLine"));
assertTrue(atts.containsKey("EndColumn"));
assertTrue(atts.containsKey("EndLine"));
}
@Test
public void testAttributeAxisIteratorWithEnum() {
- DummyNodeWithEnum dummyNode = new DummyNodeWithEnum(1);
+ DummyNodeWithEnum dummyNode = new DummyNodeWithEnum();
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
Map atts = toMap(it);
- Assert.assertEquals(8, atts.size());
+ Assert.assertEquals(7, atts.size());
assertTrue(atts.containsKey("Enum"));
assertEquals(DummyNodeWithEnum.MyEnum.FOO, atts.get("Enum").getValue());
}
@Test
public void testAttributeAxisIteratorWithList() {
- DummyNodeWithList dummyNode = new DummyNodeWithList(1);
+ DummyNodeWithList dummyNode = new DummyNodeWithList();
AttributeAxisIterator it = new AttributeAxisIterator(dummyNode);
Map atts = toMap(it);
- Assert.assertEquals(8, atts.size());
+ Assert.assertEquals(7, atts.size());
assertTrue(atts.containsKey("List"));
assertEquals(Arrays.asList("A", "B"), atts.get("List").getValue());
assertFalse(atts.containsKey("NodeList"));
@@ -82,10 +80,6 @@ public class AttributeAxisIteratorTest {
public static class DummyNodeWithEnum extends DummyNode {
- public DummyNodeWithEnum(int id) {
- super(id);
- }
-
public enum MyEnum {
FOO, BAR
}
@@ -97,10 +91,6 @@ public class AttributeAxisIteratorTest {
public static class DummyNodeWithList extends DummyNode {
- public DummyNodeWithList(int id) {
- super(id);
- }
-
public List getList() {
return Arrays.asList("A", "B");
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/DocumentNavigatorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/DocumentNavigatorTest.java
index aa316e9313..cf57b85a52 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/DocumentNavigatorTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/DocumentNavigatorTest.java
@@ -12,7 +12,6 @@ import org.junit.Test;
import net.sourceforge.pmd.lang.ast.DummyNode;
import net.sourceforge.pmd.lang.ast.DummyRoot;
-import net.sourceforge.pmd.lang.ast.Node;
/**
* Unit test for {@link DocumentNavigator}
@@ -30,10 +29,9 @@ public class DocumentNavigatorTest {
assertNotNull(e);
}
- Node root = new DummyRoot();
- Node n = new DummyNode(1);
- root.jjtAddChild(n, 0);
- n.jjtSetParent(root);
+ DummyNode root = new DummyRoot();
+ DummyNode n = new DummyNode();
+ root.addChild(n, 0);
assertSame(root, nav.getDocumentNode(n));
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/NoAttributeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/NoAttributeTest.java
index 0b5781ce6b..9f9b93e3f6 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/NoAttributeTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/xpath/NoAttributeTest.java
@@ -25,7 +25,7 @@ public class NoAttributeTest {
@Test
public void testNoAttrInherited() {
- Node child = new NodeNoInherited(12);
+ Node child = new NodeNoInherited();
Set attrNames = IteratorUtil.toList(child.getXPathAttributesIterator()).stream().map(Attribute::getName).collect(Collectors.toSet());
@@ -45,7 +45,7 @@ public class NoAttributeTest {
assertTrue(0 < IteratorUtil.count(new NodeAllAttr(12).getXPathAttributesIterator()));
- NodeNoAttrAll child = new NodeNoAttrAll(12);
+ NodeNoAttrAll child = new NodeNoAttrAll();
Set attrNames = IteratorUtil.toList(child.getXPathAttributesIterator()).stream().map(Attribute::getName).collect(Collectors.toSet());
// from Noded, so not suppressed
@@ -57,7 +57,7 @@ public class NoAttributeTest {
@Test
public void testNoAttrAllIsNotInherited() {
- NodeNoAttrAllChild child = new NodeNoAttrAllChild(12);
+ NodeNoAttrAllChild child = new NodeNoAttrAllChild();
Set attrNames = IteratorUtil.toList(child.getXPathAttributesIterator()).stream().map(Attribute::getName).collect(Collectors.toSet());
@@ -70,12 +70,8 @@ public class NoAttributeTest {
private static class DummyNodeParent extends DummyNode {
- DummyNodeParent(int id) {
- super(id);
- }
-
- DummyNodeParent(int id, boolean findBoundary) {
- super(id, findBoundary);
+ DummyNodeParent() {
+ super();
}
public String getSomeName() {
@@ -100,10 +96,6 @@ public class NoAttributeTest {
@NoAttribute(scope = NoAttrScope.INHERITED)
private static class NodeNoInherited extends DummyNodeParent {
- NodeNoInherited(int id) {
- super(id);
- }
-
// getSomeName is inherited and filtered out by NoAttrScope.INHERITED
// getSomeInt is inherited but overridden here, so NoAttrScope.INHERITED has no effect
// getSomeLong is inherited and overridden here,
@@ -140,18 +132,13 @@ public class NoAttributeTest {
private static class NodeAllAttr extends DummyNodeParent {
NodeAllAttr(int id) {
- super(id);
+ super();
}
}
@NoAttribute(scope = NoAttrScope.ALL)
private static class NodeNoAttrAll extends DummyNodeParent {
-
- NodeNoAttrAll(int id) {
- super(id);
- }
-
public int getMySuppressedAttr() {
return 12;
}
@@ -161,11 +148,6 @@ public class NoAttributeTest {
private static class NodeNoAttrAllChild extends NodeNoAttrAll {
-
- NodeNoAttrAllChild(int id) {
- super(id);
- }
-
public int getNotSuppressedAttr() {
return 12;
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/XPathRuleTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/XPathRuleTest.java
index 83e85788c2..41888278c7 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/XPathRuleTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/XPathRuleTest.java
@@ -94,7 +94,7 @@ public class XPathRuleTest {
DummyRoot root = new DummyRoot();
DummyNode dummy = new DummyNodeWithDeprecatedAttribute(2);
dummy.setCoords(1, 1, 1, 2);
- root.jjtAddChild(dummy, 0);
+ root.addChild(dummy, 0);
return root;
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/DummyNodeWithListAndEnum.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/DummyNodeWithListAndEnum.java
index 0ca895486a..d066e3afa3 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/DummyNodeWithListAndEnum.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/DummyNodeWithListAndEnum.java
@@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.ast.DummyNode;
public class DummyNodeWithListAndEnum extends DummyNode {
public DummyNodeWithListAndEnum(int id) {
- super(id);
+ super();
beginLine = 1;
beginColumn = 1;
endLine = 1;
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java
index ead5c73553..0a4cf00195 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java
@@ -15,13 +15,13 @@ public class ElementNodeTest {
@Test
public void testCompareOrder() {
- DummyNode node = new DummyNode(1, false, "dummy");
- DummyNode foo1 = new DummyNode(2, false, "foo");
- foo1.testingOnlySetBeginLine(1);
- DummyNode foo2 = new DummyNode(2, false, "foo");
- foo2.testingOnlySetBeginLine(2);
- node.jjtAddChild(foo1, 0);
- node.jjtAddChild(foo2, 1);
+ DummyNode node = new DummyNode(false, "dummy");
+ DummyNode foo1 = new DummyNode(false, "foo");
+ foo1.setCoords(1, 1, 2, 2);
+ DummyNode foo2 = new DummyNode(false, "foo");
+ foo2.setCoords(2, 1, 2, 2);
+ node.addChild(foo1, 0);
+ node.addChild(foo2, 1);
DocumentNode document = new DocumentNode(node);
ElementNode elementFoo1 = document.nodeToElementNode.get(foo1);
@@ -37,15 +37,13 @@ public class ElementNodeTest {
@Test
public void testCompareOrderSamePosition() {
- DummyNode node = new DummyNode(1, false, "dummy");
- DummyNode foo1 = new DummyNode(2, false, "foo");
- foo1.testingOnlySetBeginLine(1);
- foo1.testingOnlySetBeginColumn(1);
- DummyNode foo2 = new DummyNode(2, false, "foo");
- foo2.testingOnlySetBeginLine(1);
- foo2.testingOnlySetBeginColumn(1);
- node.jjtAddChild(foo1, 0);
- node.jjtAddChild(foo2, 1);
+ DummyNode node = new DummyNode(false, "dummy");
+ DummyNode foo1 = new DummyNode(false, "foo");
+ foo1.setCoords(1, 1, 5, 5);
+ DummyNode foo2 = new DummyNode(false, "foo");
+ foo2.setCoords(1, 1, 5, 5);
+ node.addChild(foo1, 0);
+ node.addChild(foo2, 1);
DocumentNode document = new DocumentNode(node);
ElementNode elementFoo1 = document.nodeToElementNode.get(foo1);
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
index 97e0e6664d..cc959120ea 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
@@ -82,11 +82,8 @@ public abstract class AbstractRendererTest {
}
protected static DummyNode createNode(int endColumn) {
- DummyNode node = new DummyNode(1);
- node.testingOnlySetBeginLine(1);
- node.testingOnlySetBeginColumn(1);
- node.testingOnlySetEndLine(1);
- node.testingOnlySetEndColumn(endColumn);
+ DummyNode node = new DummyNode();
+ node.setCoords(1, 1, 1, endColumn);
return node;
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
index 675574e4ac..c9dab07c9b 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
@@ -75,16 +75,12 @@ public class XMLRendererTest extends AbstractRendererTest {
@Override
public String filter(String expected) {
- String result = expected.replaceAll(" timestamp=\"[^\"]+\">", " timestamp=\"\">");
- return result;
+ return expected.replaceAll(" timestamp=\"[^\"]+\">", " timestamp=\"\">");
}
private RuleViolation createRuleViolation(String description) {
- DummyNode node = new DummyNode(1);
- node.testingOnlySetBeginLine(1);
- node.testingOnlySetBeginColumn(1);
- node.testingOnlySetEndLine(1);
- node.testingOnlySetEndColumn(1);
+ DummyNode node = new DummyNode();
+ node.setCoords(1, 1, 1, 1);
RuleContext ctx = new RuleContext();
ctx.setSourceCodeFile(new File(getSourceCodeFilename()));
return new ParametricRuleViolation(new FooRule(), ctx, node, description);
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
index 200c0fc0e6..2cc3f0c9f4 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
@@ -22,9 +22,8 @@ public class XSLTRendererTest {
public void testDefaultStylesheet() throws Exception {
XSLTRenderer renderer = new XSLTRenderer();
Report report = new Report();
- DummyNode node = new DummyNode(1);
- node.testingOnlySetBeginLine(1);
- node.testingOnlySetBeginColumn(1);
+ DummyNode node = new DummyNode();
+ node.setCoords(1, 1, 1, 2);
RuleViolation rv = new ParametricRuleViolation(new FooRule(), new RuleContext(), node,
"violation message");
report.addRuleViolation(rv);
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/FooRuleWithLanguageSetInJava.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/FooRuleWithLanguageSetInJava.java
new file mode 100644
index 0000000000..2363f63aac
--- /dev/null
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/FooRuleWithLanguageSetInJava.java
@@ -0,0 +1,26 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.util;
+
+import java.util.List;
+
+import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.lang.DummyLanguageModule;
+import net.sourceforge.pmd.lang.LanguageRegistry;
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.rule.AbstractRule;
+
+public class FooRuleWithLanguageSetInJava extends AbstractRule {
+
+ public FooRuleWithLanguageSetInJava() {
+ setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME));
+ }
+
+
+ @Override
+ public void apply(List extends Node> nodes, RuleContext ctx) {
+ // do nothing
+ }
+}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeRenderersTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeRenderersTest.java
index 263f94bbe0..e791d57b59 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeRenderersTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeRenderersTest.java
@@ -85,8 +85,8 @@ public class TreeRenderersTest {
MyDummyNode dummy2 = new MyDummyNode();
- dummy.jjtAddChild(dummy1, 0);
- dummy.jjtAddChild(dummy2, 1);
+ dummy.addChild(dummy1, 0);
+ dummy.addChild(dummy2, 1);
return dummy;
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java
index d327cf8dfb..af6cc024b0 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java
@@ -269,8 +269,8 @@ public class XmlTreeRendererTest {
MyDummyNode dummy2 = new MyDummyNode();
- dummy.jjtAddChild(dummy1, 0);
- dummy.jjtAddChild(dummy2, 1);
+ dummy.addChild(dummy1, 0);
+ dummy.addChild(dummy2, 1);
return dummy;
}
diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
index 4e7ca4754d..c6f1e12878 100644
--- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
+++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
@@ -21,6 +21,8 @@ import net.sourceforge.pmd.PMDVersion;
public class BinaryDistributionIT extends AbstractBinaryDistributionTest {
+ private static final String SUPPORTED_LANGUAGES = "Supported languages: [apex, cpp, cs, dart, ecmascript, fortran, go, groovy, java, jsp, kotlin, lua, matlab, modelica, objectivec, perl, php, plsql, python, ruby, scala, swift, vf, xml]";
+
@Test
public void testFileExistence() {
assertTrue(getBinaryDistribution().exists());
@@ -81,7 +83,7 @@ public class BinaryDistributionIT extends AbstractBinaryDistributionTest {
ExecutionResult result;
result = CpdExecutor.runCpd(tempDir, "-h");
- result.assertExecutionResult(0, "Supported languages: [apex, cpp, cs, dart, ecmascript, fortran, go, groovy, java, jsp, kotlin, lua, matlab, modelica, objectivec, perl, php, plsql, python, ruby, scala, swift, vf]");
+ result.assertExecutionResult(0, SUPPORTED_LANGUAGES);
result = CpdExecutor.runCpd(tempDir, "--minimum-tokens", "10", "--format", "text", "--files", srcDir);
result.assertExecutionResult(4, "Found a 10 line (55 tokens) duplication in the following files:");
diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml
index 9236a3521c..72179a18a3 100644
--- a/pmd-doc/pom.xml
+++ b/pmd-doc/pom.xml
@@ -13,9 +13,6 @@
8
-
- 1.${java.version}
- 1.${java.version}
diff --git a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoLanguage.java b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoLanguage.java
index 124015b67e..2c4f6a4d21 100644
--- a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoLanguage.java
+++ b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoLanguage.java
@@ -5,15 +5,10 @@
package net.sourceforge.pmd.cpd;
/**
- * Implements the Go Language
- *
* @author oinume@gmail.com
*/
public class GoLanguage extends AbstractLanguage {
- /**
- * Creates a new instance of {@link GoLanguage}
- */
public GoLanguage() {
super("Go", "go", new GoTokenizer(), ".go");
}
diff --git a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
index ff99a98129..1369c28a5e 100644
--- a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
+++ b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
@@ -10,9 +10,6 @@ import net.sourceforge.pmd.cpd.internal.AntlrTokenizer;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager;
import net.sourceforge.pmd.lang.go.antlr4.GolangLexer;
-/**
- * The Go tokenizer.
- */
public class GoTokenizer extends AntlrTokenizer {
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java
index 04858ee65e..12f5ea4cc1 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java
@@ -18,20 +18,20 @@ public class JavaLanguageModule extends BaseLanguageModule {
public JavaLanguageModule() {
super(NAME, null, TERSE_NAME, JavaRuleChainVisitor.class, "java");
- addVersion("1.3", new JavaLanguageHandler(3), false);
- addVersion("1.4", new JavaLanguageHandler(4), false);
- addVersions(new JavaLanguageHandler(5), false, "1.5", "5");
- addVersions(new JavaLanguageHandler(6), false, "1.6", "6");
- addVersions(new JavaLanguageHandler(7), false, "1.7", "7");
- addVersions(new JavaLanguageHandler(8), false, "1.8", "8");
- addVersions(new JavaLanguageHandler(9), false, "9", "1.9");
- addVersions(new JavaLanguageHandler(10), false, "10", "1.10");
- addVersion("11", new JavaLanguageHandler(11), false);
- addVersion("12", new JavaLanguageHandler(12), false);
- addVersion("13", new JavaLanguageHandler(13), false);
- addVersion("13-preview", new JavaLanguageHandler(13, true), false);
- addVersion("14", new JavaLanguageHandler(14), true); // 14 is the default
- addVersion("14-preview", new JavaLanguageHandler(14, true), false);
+ addVersion("1.3", new JavaLanguageHandler(3));
+ addVersion("1.4", new JavaLanguageHandler(4));
+ addVersion("1.5", new JavaLanguageHandler(5), "5");
+ addVersion("1.6", new JavaLanguageHandler(6), "6");
+ addVersion("1.7", new JavaLanguageHandler(7), "7");
+ addVersion("1.8", new JavaLanguageHandler(8), "8");
+ addVersion("9", new JavaLanguageHandler(9), "1.9");
+ addVersion("10", new JavaLanguageHandler(10), "1.10");
+ addVersion("11", new JavaLanguageHandler(11));
+ addVersion("12", new JavaLanguageHandler(12));
+ addVersion("13", new JavaLanguageHandler(13));
+ addVersion("13-preview", new JavaLanguageHandler(13, true));
+ addDefaultVersion("14", new JavaLanguageHandler(14)); // 14 is the default
+ addVersion("14-preview", new JavaLanguageHandler(14, true));
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArguments.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArguments.java
index 7739488082..0204618248 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArguments.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArguments.java
@@ -5,6 +5,7 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.InternalApi;
+import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
public class ASTArguments extends AbstractJavaNode {
@@ -29,6 +30,7 @@ public class ASTArguments extends AbstractJavaNode {
* @deprecated for removal. Use {@link #size()} or {@link ASTArgumentList#size()} instead.
*/
@Deprecated
+ @DeprecatedAttribute(replaceWith = "@Size")
public int getArgumentCount() {
return size();
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
index b371dcdecc..b86b857dae 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
@@ -4,7 +4,6 @@
package net.sourceforge.pmd.lang.java.ast;
-import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
@@ -19,9 +18,7 @@ import net.sourceforge.pmd.lang.ast.Node;
*/
public class ASTClassOrInterfaceType extends AbstractJavaTypeNode {
- @InternalApi
- @Deprecated
- public ASTClassOrInterfaceType(int id) {
+ ASTClassOrInterfaceType(int id) {
super(id);
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
index b463754c52..f188c18439 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
@@ -67,7 +67,7 @@ public class ASTCompilationUnit extends AbstractJavaTypeNode implements RootNode
}
@Override
- public ASTCompilationUnit getRoot() {
+ public @NonNull ASTCompilationUnit getRoot() {
return this;
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java
index 628e5f57f8..086047c941 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.InternalApi;
+import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
public class ASTConstructorDeclaration extends AbstractMethodOrConstructorDeclaration {
@@ -57,6 +58,7 @@ public class ASTConstructorDeclaration extends AbstractMethodOrConstructorDeclar
* @deprecated Use {@link #getArity()}
*/
@Deprecated
+ @DeprecatedAttribute(replaceWith = "@Arity")
public int getParameterCount() {
return getArity();
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java
index d91fbaf9aa..13a23aa3ea 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java
@@ -8,6 +8,7 @@ import java.util.Iterator;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.SignedNode;
+import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature;
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
@@ -178,6 +179,7 @@ public class ASTFieldDeclaration extends AbstractJavaAccessTypeNode implements D
* Iterate on the {@linkplain ASTVariableDeclaratorId VariableDeclaratorIds} instead
*/
@Deprecated
+ @DeprecatedAttribute(replaceWith = "VariableDeclaratorId/@Name")
public String getVariableName() {
ASTVariableDeclaratorId decl = getFirstDescendantOfType(ASTVariableDeclaratorId.class);
if (decl != null) {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java
index 5155ce5597..90d39e998d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java
@@ -23,9 +23,7 @@ public class ASTFormalParameter extends AbstractJavaAccessTypeNode implements Di
private boolean isVarargs;
- @InternalApi
- @Deprecated
- public ASTFormalParameter(int id) {
+ ASTFormalParameter(int id) {
super(id);
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java
index 3d84e9a065..e684955e66 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java
@@ -7,14 +7,12 @@ package net.sourceforge.pmd.lang.java.ast;
import java.util.Iterator;
import java.util.List;
-import net.sourceforge.pmd.annotation.InternalApi;
+import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
public class ASTFormalParameters extends AbstractJavaNode implements Iterable {
- @InternalApi
- @Deprecated
- public ASTFormalParameters(int id) {
+ ASTFormalParameters(int id) {
super(id);
}
@@ -28,6 +26,7 @@ public class ASTFormalParameters extends AbstractJavaNode implements Iterable 0) {
- AbstractNode firstChild = (AbstractNode) getChild(0);
- jjtSetFirstToken(firstChild.jjtGetFirstToken());
+ setFirstToken(getFirstChild().getFirstToken());
}
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledExpression.java
index 109f9665a3..70afff9dd0 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledExpression.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledExpression.java
@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
public class ASTSwitchLabeledExpression extends AbstractJavaNode implements ASTSwitchLabeledRule {
@@ -29,8 +28,7 @@ public class ASTSwitchLabeledExpression extends AbstractJavaNode implements ASTS
public void jjtClose() {
super.jjtClose();
if (getNumChildren() > 0) {
- AbstractNode firstChild = (AbstractNode) getChild(0);
- jjtSetFirstToken(firstChild.jjtGetFirstToken());
+ setFirstToken(getFirstChild().getFirstToken());
}
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledThrowStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledThrowStatement.java
index d306fc5228..b52c1b9f83 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledThrowStatement.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabeledThrowStatement.java
@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
public class ASTSwitchLabeledThrowStatement extends AbstractJavaNode implements ASTSwitchLabeledRule {
@@ -29,8 +28,7 @@ public class ASTSwitchLabeledThrowStatement extends AbstractJavaNode implements
public void jjtClose() {
super.jjtClose();
if (getNumChildren() > 0) {
- AbstractNode firstChild = (AbstractNode) getChild(0);
- jjtSetFirstToken(firstChild.jjtGetFirstToken());
+ setFirstToken(getFirstChild().getFirstToken());
}
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java
index 3b7a086ed5..3ad749aa84 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java
@@ -42,9 +42,7 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim
private VariableNameDeclaration nameDeclaration;
private boolean explicitReceiverParameter = false;
- @InternalApi
- @Deprecated
- public ASTVariableDeclaratorId(int id) {
+ ASTVariableDeclaratorId(int id) {
super(id);
}
@@ -96,6 +94,7 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim
*/
@Override
@Deprecated
+ @DeprecatedAttribute(replaceWith = "@ArrayType")
public boolean isArray() {
return arrayDepth > 0;
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardBounds.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardBounds.java
index c5373c131d..8153aae042 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardBounds.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardBounds.java
@@ -29,7 +29,7 @@ public class ASTWildcardBounds extends AbstractJavaTypeNode {
* in {@code extends Integer>}.
*/
public boolean isUpperBound() {
- return jjtGetFirstToken().getImage().equals("extends");
+ return getFirstToken().getImage().equals("extends");
}
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 ec3b3cd2ff..2a4c13c95a 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
@@ -7,13 +7,12 @@ package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode;
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;
@@ -25,33 +24,24 @@ public abstract class AbstractJavaNode extends AbstractJjtreeNode impl
super(id);
}
- @Override
- public Object childrenAccept(JavaParserVisitor visitor, Object data) {
- for (Node child : children()) {
- ((JavaNode) child).jjtAccept(visitor, data);
- }
-
- return data;
- }
-
-
- @Override
- public void childrenAccept(SideEffectingVisitor visitor, T data) {
- for (Node child : children()) {
- ((JavaNode) child).jjtAccept(visitor, data);
- }
-
- }
-
-
@Override
public Scope getScope() {
if (scope == null) {
- return ((JavaNode) parent).getScope();
+ return getParent().getScope();
}
return scope;
}
+ @Override // override to make it accessible to tests that build nodes (which have been removed on java-grammar)
+ protected void addChild(AbstractJavaNode child, int index) {
+ super.addChild(child, index);
+ }
+
+ @Override // override to make it accessible to parser
+ protected void setImage(String image) {
+ super.setImage(image);
+ }
+
@InternalApi
@Deprecated
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java
index fa66566766..22ebe37c10 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Comment.java
@@ -13,10 +13,11 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.PMD;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
+import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode;
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
-public abstract class Comment extends AbstractNode {
+public abstract class Comment extends AbstractJjtreeNode {
+
// single regex, that captures: the start of a multi-line comment (/**|/*), the start of a single line comment (//)
// or the start of line within a multine comment (*). It removes the end of the comment (*/) if existing.
private static final Pattern COMMENT_LINE_COMBINED = Pattern.compile("^(?://|/\\*\\*?|\\*)?(.*?)(?:\\*/|/)?$");
@@ -25,11 +26,11 @@ public abstract class Comment extends AbstractNode {
static final Pattern NEWLINES_PATTERN = Pattern.compile("\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]");
protected Comment(JavaccToken t) {
- super(-1);
+ super(0);
setImage(t.getImage());
- jjtSetFirstToken(t);
- jjtSetLastToken(t);
+ setFirstToken(t);
+ setLastToken(t);
}
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java
index 96aaf0892e..04fe6b5a67 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/DummyJavaNode.java
@@ -20,6 +20,11 @@ public class DummyJavaNode extends AbstractJavaNode {
super(id);
}
+ @Override
+ public void setImage(String image) {
+ super.setImage(image);
+ }
+
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return data;
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java
index 8920d25414..27103bc54a 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/FormalComment.java
@@ -5,11 +5,10 @@
package net.sourceforge.pmd.lang.java.ast;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
import net.sourceforge.pmd.lang.java.javadoc.JavadocTag;
@@ -29,19 +28,21 @@ public class FormalComment extends Comment {
}
private void findJavadocs() {
- Collection kids = new ArrayList<>();
+ List kids = new ArrayList<>();
Matcher javadocTagMatcher = JAVADOC_TAG.matcher(getFilteredComment());
while (javadocTagMatcher.find()) {
JavadocTag tag = JavadocTag.tagFor(javadocTagMatcher.group(1));
int tagStartIndex = javadocTagMatcher.start(1);
if (tag != null) {
- kids.add(new JavadocElement(getBeginLine(), getBeginLine(),
+ kids.add(new JavadocElement(getFirstToken(), getBeginLine(), getBeginLine(),
// TODO valid?
tagStartIndex, tagStartIndex + tag.label.length() + 1, tag));
}
}
- children = kids.toArray(new Node[0]);
+ for (int i = kids.size() - 1; i >= 0; i--) {
+ addChild(kids.get(i), i);
+ }
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java
index 8c1dd08f88..7c7cbbfba4 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java
@@ -5,6 +5,9 @@
package net.sourceforge.pmd.lang.java.ast;
+import java.util.HashSet;
+import java.util.Set;
+
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument;
@@ -17,10 +20,100 @@ import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument;
@InternalApi
public final class InternalApiBridge {
+
+ private static final Set PRIMITIVE_TYPES;
+
+ static {
+ PRIMITIVE_TYPES = new HashSet<>();
+ PRIMITIVE_TYPES.add("boolean");
+ PRIMITIVE_TYPES.add("char");
+ PRIMITIVE_TYPES.add("byte");
+ PRIMITIVE_TYPES.add("short");
+ PRIMITIVE_TYPES.add("int");
+ PRIMITIVE_TYPES.add("long");
+ PRIMITIVE_TYPES.add("float");
+ PRIMITIVE_TYPES.add("double");
+ }
+
private InternalApiBridge() {
}
+ @Deprecated
+ public static ASTVariableDeclaratorId newVarId(String image) {
+ ASTVariableDeclaratorId varid = new ASTVariableDeclaratorId(JavaParserImplTreeConstants.JJTVARIABLEDECLARATORID);
+ varid.setImage(image);
+ return varid;
+ }
+
+
+ /**
+ * Creates a fake method name declaration for built-in methods from Java
+ * like the Enum Method "valueOf".
+ *
+ * @param methodName the method name
+ * @param parameterTypes the reference types of each parameter of the method
+ *
+ * @return a method name declaration
+ */
+ public static ASTMethodDeclarator createBuiltInMethodDeclaration(final String methodName, final String... parameterTypes) {
+ ASTMethodDeclaration methodDeclaration = new ASTMethodDeclaration(0);
+ methodDeclaration.setPublic(true);
+
+ ASTMethodDeclarator methodDeclarator = new ASTMethodDeclarator(0);
+ methodDeclarator.setImage(methodName);
+
+ ASTFormalParameters formalParameters = new ASTFormalParameters(0);
+ methodDeclaration.addChild(methodDeclarator, 0);
+ methodDeclarator.addChild(formalParameters, 0);
+
+ /*
+ * jjtAddChild resizes it's child node list according to known indexes.
+ * Going backwards makes sure the first time it gets the right size avoiding copies.
+ */
+ for (int i = parameterTypes.length - 1; i >= 0; i--) {
+ ASTFormalParameter formalParameter = new ASTFormalParameter(0);
+ formalParameters.addChild(formalParameter, i);
+
+ ASTVariableDeclaratorId variableDeclaratorId = new ASTVariableDeclaratorId(0);
+ variableDeclaratorId.setImage("arg" + i);
+ formalParameter.addChild(variableDeclaratorId, 1);
+
+ ASTType type = new ASTType(0);
+ formalParameter.addChild(type, 0);
+
+ if (PRIMITIVE_TYPES.contains(parameterTypes[i])) {
+ ASTPrimitiveType primitiveType = new ASTPrimitiveType(0);
+ primitiveType.setImage(parameterTypes[i]);
+ type.addChild(primitiveType, 0);
+ } else {
+ ASTReferenceType referenceType = new ASTReferenceType(0);
+ type.addChild(referenceType, 0);
+
+ // TODO : this could actually be a primitive array...
+ ASTClassOrInterfaceType classOrInterfaceType = new ASTClassOrInterfaceType(0);
+ classOrInterfaceType.setImage(parameterTypes[i]);
+ referenceType.addChild(classOrInterfaceType, 0);
+ }
+ }
+
+ return methodDeclarator;
+ }
+
+
+ @Deprecated
+ public static ASTPrimaryPrefix newThisSuperPrefix(String image, boolean isThis) {
+ ASTPrimaryPrefix prefix = new ASTPrimaryPrefix(JavaParserImplTreeConstants.JJTPRIMARYPREFIX);
+ if (isThis) {
+ prefix.setUsesThisModifier();
+ } else {
+ prefix.setUsesSuperModifier();
+ }
+ ASTName name = new ASTName(JavaParserImplTreeConstants.JJTNAME);
+ name.setImage(image);
+ prefix.addChild(name, 0);
+ return prefix;
+ }
public static JavaccTokenDocument javaTokenDoc(String fullText) {
return new JavaTokenDocument(fullText);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java
index b65a1ec9f8..f39565a941 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java
@@ -8,9 +8,7 @@ package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.NodeStream;
-import net.sourceforge.pmd.lang.ast.TextAvailableNode;
-import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
+import net.sourceforge.pmd.lang.ast.impl.javacc.JjtreeNode;
import net.sourceforge.pmd.lang.symboltable.Scope;
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
@@ -18,7 +16,7 @@ import net.sourceforge.pmd.lang.symboltable.ScopedNode;
/**
* Root interface for all Nodes of the Java AST.
*/
-public interface JavaNode extends ScopedNode, TextAvailableNode {
+public interface JavaNode extends ScopedNode, JjtreeNode {
/**
* Calls back the visitor's visit method corresponding to the runtime type of this Node.
@@ -29,24 +27,6 @@ public interface JavaNode extends ScopedNode, TextAvailableNode {
Object jjtAccept(JavaParserVisitor visitor, Object data);
- /**
- * Dispatches the given visitor to the children of this node. This is the default implementation
- * of {@link JavaParserVisitor#visit(JavaNode, Object)}, to which all other default
- * implementations for visit methods delegate. Unless visit methods are overridden without calling
- * {@code super.visit}, the visitor performs a depth-first tree walk.
- *
- * The return value of the visit methods called on children are ignored.
- *
- * @param visitor Visitor to dispatch
- * @param data Visit data
- *
- * @deprecated This method is not useful, the logic for combining
- * children values should be present on the visitor, not the node
- */
- @Deprecated
- Object childrenAccept(JavaParserVisitor visitor, Object data);
-
-
/**
* Calls back the visitor's visit method corresponding to the runtime type of this Node.
*
@@ -57,42 +37,10 @@ public interface JavaNode extends ScopedNode, TextAvailableNode {
void jjtAccept(SideEffectingVisitor visitor, T data);
- /**
- * Dispatches the given visitor to the children of this node. This is the default implementation
- * of {@link SideEffectingVisitor#visit(JavaNode, Object)}, to which all other default
- * implementations for visit methods delegate. Unless visit methods are overridden without calling
- * {@code super.visit}, the visitor performs a depth-first tree walk.
- *
- * @param visitor Visitor to dispatch
- * @param data Visit data
- * @param Type of data
- */
- void childrenAccept(SideEffectingVisitor visitor, T data);
-
-
- @Override
- JavaNode getChild(int index);
-
-
- @Override
- JavaNode getParent();
-
-
- @Override
- NodeStream extends JavaNode> children();
-
-
@InternalApi
@Deprecated
void setScope(Scope scope);
-
- JavaccToken jjtGetFirstToken();
-
-
- JavaccToken jjtGetLastToken();
-
-
@Override
@NonNull ASTCompilationUnit getRoot();
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocElement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocElement.java
index 54f489499f..a233a8f225 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocElement.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocElement.java
@@ -4,25 +4,50 @@
package net.sourceforge.pmd.lang.java.ast;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
+import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
import net.sourceforge.pmd.lang.java.javadoc.JavadocTag;
-public class JavadocElement extends AbstractNode {
+public class JavadocElement extends Comment {
+
+ private final int beginLine;
+ private final int endLine;
+ private final int beginColumn;
+ private final int endColumn;
private final JavadocTag tag;
- public JavadocElement(int theBeginLine, int theEndLine, int theBeginColumn, int theEndColumn, JavadocTag theTag) {
- super(-1, theBeginLine, theEndLine, theBeginColumn, theEndColumn);
-
- tag = theTag;
+ public JavadocElement(JavaccToken t, int theBeginLine, int theEndLine, int theBeginColumn, int theEndColumn, JavadocTag theTag) {
+ super(t);
+ this.tag = theTag;
+ this.beginLine = theBeginLine;
+ this.endLine = theEndLine;
+ this.beginColumn = theBeginColumn;
+ this.endColumn = theEndColumn;
}
public JavadocTag tag() {
return tag;
}
+ @Override
+ public int getBeginLine() {
+ return beginLine;
+ }
+ @Override
+ public int getEndColumn() {
+ return endColumn;
+ }
+ @Override
+ public int getEndLine() {
+ return endLine;
+ }
+
+ @Override
+ public int getBeginColumn() {
+ return beginColumn;
+ }
@Override
public String getXPathNodeName() {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java
index 775ebbf2f0..1883a5b9e7 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/dfa/VariableAccessVisitor.java
@@ -54,7 +54,7 @@ public class VariableAccessVisitor extends JavaParserVisitorAdapter {
private void computeNow(Node node) {
- DataFlowNode inode = node.getDataFlowNode();
+ DataFlowNode inode = DataFlowNode.get(node);
List undefinitions = markUsages(inode);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJUnitRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJUnitRule.java
index 70c06df799..48a5ee69e6 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJUnitRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJUnitRule.java
@@ -24,9 +24,9 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
protected static final String JUNIT4_CLASS_NAME = "org.junit.Test";
protected static final String JUNIT5_CLASS_NAME = "org.junit.jupiter.api.Test";
- private boolean isJUnit3Class;
- private boolean isJUnit4Class;
- private boolean isJUnit5Class;
+ protected boolean isJUnit3Class;
+ protected boolean isJUnit4Class;
+ protected boolean isJUnit5Class;
@Override
public Object visit(ASTCompilationUnit node, Object data) {
@@ -105,10 +105,10 @@ public abstract class AbstractJUnitRule extends AbstractJavaRule {
if (((ASTClassOrInterfaceType) extendsList.getChild(0)).getImage().endsWith("TestCase")) {
return true;
}
- String className = cid.getImage();
+ String className = cid.getSimpleName();
return className.endsWith("Test");
} else if (hasImports(node, JUNIT3_CLASS_NAME)) {
- return cid.getImage().endsWith("Test");
+ return cid.getSimpleName().endsWith("Test");
}
return false;
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java
index 3482bde1d0..0f6e66eabf 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java
@@ -13,7 +13,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
@@ -294,7 +293,7 @@ public class AvoidReassigningLoopVariablesRule extends AbstractOptimizationRule
/**
* Add a violation, if the node image is one of the loop variables.
*/
- private void checkVariable(Object data, Set loopVariables, AbstractNode node) {
+ private void checkVariable(Object data, Set loopVariables, Node node) {
if (node != null && loopVariables.contains(node.getImage())) {
addViolation(data, node, node.getImage());
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java
index 2952d14069..9f1dd81212 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java
@@ -61,6 +61,7 @@ public class JUnitTestsShouldIncludeAssertRule extends AbstractJUnitRule {
if (n instanceof ASTStatementExpression) {
if (isExpectStatement((ASTStatementExpression) n, expectables)
|| isAssertOrFailStatement((ASTStatementExpression) n)
+ || isHamcrestAssert((ASTStatementExpression) n)
|| isVerifyStatement((ASTStatementExpression) n)
|| isSoftAssertionStatement((ASTStatementExpression) n, variables)) {
return true;
@@ -134,43 +135,42 @@ public class JUnitTestsShouldIncludeAssertRule extends AbstractJUnitRule {
return false;
}
- /**
- * Tells if the expression is an assert statement or not.
- */
- private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
+ private String getMethodCallNameOrNull(ASTStatementExpression expression) {
if (expression != null) {
ASTPrimaryExpression pe = expression.getFirstChildOfType(ASTPrimaryExpression.class);
if (pe != null) {
Node name = pe.getFirstDescendantOfType(ASTName.class);
if (name != null) {
- String img = name.getImage();
- if (img != null && (img.startsWith("assert") || img.startsWith("fail")
- || img.startsWith("Assert.assert") || img.startsWith("Assert.fail"))) {
- return true;
- }
+ return name.getImage();
}
}
}
- return false;
+ return null;
+ }
+
+ /**
+ * Tells if the expression is an Hamcrest assert
+ */
+ private boolean isHamcrestAssert(ASTStatementExpression expression) {
+ String img = getMethodCallNameOrNull(expression);
+ return "assertThat".equals(img) || "MatcherAssert.assertThat".equals(img);
+ }
+
+ /**
+ * Tells if the expression is an assert statement or not.
+ */
+ private boolean isAssertOrFailStatement(ASTStatementExpression expression) {
+ String img = getMethodCallNameOrNull(expression);
+ return img != null && (img.startsWith("assert") || img.startsWith("fail")
+ || img.startsWith("Assert.assert") || img.startsWith("Assert.fail"));
}
/**
* Tells if the expression is verify statement or not
*/
private boolean isVerifyStatement(ASTStatementExpression expression) {
- if (expression != null) {
- ASTPrimaryExpression pe = expression.getFirstChildOfType(ASTPrimaryExpression.class);
- if (pe != null) {
- Node name = pe.getFirstDescendantOfType(ASTName.class);
- if (name != null) {
- String img = name.getImage();
- if (img != null && (img.startsWith("verify") || img.startsWith("Mockito.verify"))) {
- return true;
- }
- }
- }
- }
- return false;
+ String img = getMethodCallNameOrNull(expression);
+ return img != null && (img.startsWith("verify") || img.startsWith("Mockito.verify"));
}
private boolean isExpectStatement(ASTStatementExpression expression,
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsRule.java
new file mode 100644
index 0000000000..667240f5d8
--- /dev/null
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsRule.java
@@ -0,0 +1,127 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.java.rule.bestpractices;
+
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
+import net.sourceforge.pmd.lang.java.ast.ASTArguments;
+import net.sourceforge.pmd.lang.java.ast.ASTConditionalAndExpression;
+import net.sourceforge.pmd.lang.java.ast.ASTConditionalOrExpression;
+import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
+import net.sourceforge.pmd.lang.java.ast.ASTExpression;
+import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
+import net.sourceforge.pmd.lang.java.ast.ASTName;
+import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
+import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
+import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
+import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
+import net.sourceforge.pmd.lang.java.ast.JavaNode;
+import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
+
+public class LiteralsFirstInComparisonsRule extends AbstractJavaRule {
+
+ private static final String[] COMPARISON_OPS = {".equals", ".equalsIgnoreCase", ".compareTo", ".compareToIgnoreCase", ".contentEquals"};
+
+ public LiteralsFirstInComparisonsRule() {
+ addRuleChainVisit(ASTPrimaryExpression.class);
+ }
+
+ @Override
+ public Object visit(ASTPrimaryExpression node, Object data) {
+ ASTPrimaryPrefix primaryPrefix = node.getFirstChildOfType(ASTPrimaryPrefix.class);
+ ASTPrimarySuffix primarySuffix = node.getFirstChildOfType(ASTPrimarySuffix.class);
+ if (primaryPrefix != null && primarySuffix != null) {
+ ASTName name = primaryPrefix.getFirstChildOfType(ASTName.class);
+ if (name == null || isIrrelevantImage(name.getImage())) {
+ return data;
+ }
+ if (!isSingleStringLiteralArgument(primarySuffix)) {
+ return data;
+ }
+ if (isWithinNullComparison(node)) {
+ return data;
+ }
+ addViolation(data, node);
+ }
+ return node;
+ }
+
+ private boolean isIrrelevantImage(String image) {
+ for (String comparisonOp : COMPARISON_OPS) {
+ if (image.endsWith(comparisonOp)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isWithinNullComparison(ASTPrimaryExpression node) {
+ for (ASTExpression parentExpr : node.getParentsOfType(ASTExpression.class)) {
+ if (isComparisonWithNull(parentExpr, "==", ASTConditionalOrExpression.class)
+ || isComparisonWithNull(parentExpr, "!=", ASTConditionalAndExpression.class)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Expression/ConditionalAndExpression//EqualityExpression(@Image='!=']//NullLiteral
+ * Expression/ConditionalOrExpression//EqualityExpression(@Image='==']//NullLiteral
+ */
+ private boolean isComparisonWithNull(ASTExpression parentExpr, String equalOperator, Class extends JavaNode> condition) {
+ Node condExpr = null;
+ ASTEqualityExpression eqExpr = null;
+ if (parentExpr != null) {
+ condExpr = parentExpr.getFirstChildOfType(condition);
+ }
+ if (condExpr != null) {
+ eqExpr = condExpr.getFirstDescendantOfType(ASTEqualityExpression.class);
+ }
+ if (eqExpr != null) {
+ return eqExpr.hasImageEqualTo(equalOperator) && eqExpr.hasDescendantOfType(ASTNullLiteral.class);
+ }
+ return false;
+ }
+
+ /*
+ * This corresponds to the following XPath expression:
+ * (../PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral= true()])
+ * and
+ * ( count(../PrimarySuffix/Arguments/ArgumentList/Expression) = 1 )
+ */
+ private boolean isSingleStringLiteralArgument(ASTPrimarySuffix primarySuffix) {
+ if (!primarySuffix.isArguments() || primarySuffix.getArgumentCount() != 1) {
+ return false;
+ }
+ Node node = primarySuffix;
+ node = node.getFirstChildOfType(ASTArguments.class);
+ if (node != null) {
+ node = node.getFirstChildOfType(ASTArgumentList.class);
+ if (node.getNumChildren() != 1) {
+ return false;
+ }
+ }
+ if (node != null) {
+ node = node.getFirstChildOfType(ASTExpression.class);
+ }
+ if (node != null) {
+ node = node.getFirstChildOfType(ASTPrimaryExpression.class);
+ }
+ if (node != null) {
+ node = node.getFirstChildOfType(ASTPrimaryPrefix.class);
+ }
+ if (node != null) {
+ node = node.getFirstChildOfType(ASTLiteral.class);
+ }
+ if (node != null) {
+ ASTLiteral literal = (ASTLiteral) node;
+ if (literal.isStringLiteral()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java
index 09cb006aef..abd54134bf 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java
@@ -4,17 +4,19 @@
package net.sourceforge.pmd.lang.java.rule.codestyle;
+import static net.sourceforge.pmd.lang.ast.NodeStream.asInstanceOf;
+
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
-import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
+import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
import net.sourceforge.pmd.properties.PropertyBuilder.RegexPropertyBuilder;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@@ -50,7 +52,7 @@ public class MethodNamingConventionsRule extends AbstractNamingConventionRule();
couplingCount = 0;
- Object returnObj = cu.childrenAccept(this, data);
+ for (JavaNode child : cu.children()) {
+ child.jjtAccept(this, data);
+ }
if (couplingCount > getProperty(THRESHOLD_DESCRIPTOR)) {
addViolation(data, cu,
"A value of " + couplingCount + " may denote a high amount of coupling within the class");
}
- return returnObj;
+ return data;
}
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java
index 532aa4961e..2ec9076391 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java
@@ -225,7 +225,7 @@ public class CommentRequiredRule extends AbstractCommentRule {
&& field.isStatic()
&& field.isFinal()
&& field.isArray()
- && "ObjectStreamField".equals(field.jjtGetFirstToken().getImage()); // .getType() returns null
+ && "ObjectStreamField".equals(field.getFirstToken().getImage()); // .getType() returns null
}
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java
index 0566a1ee45..495e9bf31c 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java
@@ -91,8 +91,8 @@ public class CloneMethodMustImplementCloneableRule extends AbstractJavaRule {
// Is the clone method just throwing CloneNotSupportedException?
final ASTClassOrInterfaceDeclaration classOrInterface = node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
- if (classOrInterface != null && //Don't analyze enums, which cannot subclass clone()
- (node.isFinal() || classOrInterface.isFinal())) {
+ if (classOrInterface != null //Don't analyze enums, which cannot subclass clone()
+ && (node.isFinal() || classOrInterface.isFinal())) {
if (node.findDescendantsOfType(ASTBlock.class).size() == 1) {
final List blocks = node.findDescendantsOfType(ASTBlockStatement.class);
if (blocks.size() == 1) {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DataflowAnomalyAnalysisRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DataflowAnomalyAnalysisRule.java
index cb41b65f40..94373f6149 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DataflowAnomalyAnalysisRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DataflowAnomalyAnalysisRule.java
@@ -85,7 +85,7 @@ public class DataflowAnomalyAnalysisRule extends AbstractJavaRule implements Exe
rc = (RuleContext) data;
daaRuleViolations = new ArrayList<>();
- final DataFlowNode node = methodDeclaration.getDataFlowNode().getFlow().get(0);
+ final DataFlowNode node = DataFlowNode.get(methodDeclaration).getFlow().get(0);
final DAAPathFinder pathFinder = new DAAPathFinder(node, this, getProperty(MAX_PATH_DESCRIPTOR));
pathFinder.run();
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingRule.java
index 8fd2249133..573b5a1c6d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingRule.java
@@ -12,6 +12,10 @@ public class JUnitSpellingRule extends AbstractJUnitRule {
@Override
public Object visit(ASTMethodDeclaration node, Object data) {
+ if (isJUnit5Class || isJUnit4Class) {
+ return super.visit(node, data);
+ }
+
if (node.getArity() != 0) {
return super.visit(node, data);
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerRule.java
index 96647cea68..2c7bcd023d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerRule.java
@@ -49,7 +49,9 @@ public class MoreThanOneLoggerRule extends AbstractJavaRule {
stack.push(count);
count = NumericConstants.ZERO;
- node.childrenAccept(this, data);
+ for (JavaNode child : node.children()) {
+ child.jjtAccept(this, data);
+ }
if (count > 1) {
addViolation(data, node);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ClassScope.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ClassScope.java
index a409c76d88..a9534b22a3 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ClassScope.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ClassScope.java
@@ -4,6 +4,8 @@
package net.sourceforge.pmd.lang.java.symboltable;
+import static net.sourceforge.pmd.lang.java.ast.InternalApiBridge.createBuiltInMethodDeclaration;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -21,19 +23,13 @@ import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTExtendsList;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
-import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
import net.sourceforge.pmd.lang.java.ast.ASTImplementsList;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
-import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
-import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
-import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
-import net.sourceforge.pmd.lang.java.ast.ASTType;
import net.sourceforge.pmd.lang.java.ast.ASTTypeParameter;
import net.sourceforge.pmd.lang.java.ast.ASTTypeParameters;
-import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.symboltable.Applier;
import net.sourceforge.pmd.lang.symboltable.ImageFinderFunction;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
@@ -46,20 +42,6 @@ import net.sourceforge.pmd.lang.symboltable.Scope;
*/
public class ClassScope extends AbstractJavaScope {
- private static final Set PRIMITIVE_TYPES;
-
- static {
- PRIMITIVE_TYPES = new HashSet<>();
- PRIMITIVE_TYPES.add("boolean");
- PRIMITIVE_TYPES.add("char");
- PRIMITIVE_TYPES.add("byte");
- PRIMITIVE_TYPES.add("short");
- PRIMITIVE_TYPES.add("int");
- PRIMITIVE_TYPES.add("long");
- PRIMITIVE_TYPES.add("float");
- PRIMITIVE_TYPES.add("double");
- }
-
// FIXME - this breaks given sufficiently nested code
private static ThreadLocal anonymousInnerClassCounter = new ThreadLocal() {
@Override
@@ -191,7 +173,9 @@ public class ClassScope extends AbstractJavaScope {
matchMethodDeclaration(occurrence, methodDeclarations.keySet(), hasAuxclasspath, result);
if (isEnum && "valueOf".equals(occurrence.getImage())) {
- result.add(createBuiltInMethodDeclaration("valueOf", "String"));
+ ASTMethodDeclarator declarator = createBuiltInMethodDeclaration("valueOf", "String");
+ declarator.setScope(this);
+ result.add(new MethodNameDeclaration(declarator));
}
if (result.isEmpty()) {
@@ -282,73 +266,6 @@ public class ClassScope extends AbstractJavaScope {
}
}
- /**
- * Creates a fake method name declaration for built-in methods from Java
- * like the Enum Method "valueOf".
- *
- * @param methodName
- * the method name
- * @param parameterTypes
- * the reference types of each parameter of the method
- * @return a method name declaration
- */
- private MethodNameDeclaration createBuiltInMethodDeclaration(final String methodName,
- final String... parameterTypes) {
- ASTMethodDeclaration methodDeclaration = new ASTMethodDeclaration(0);
- methodDeclaration.setPublic(true);
- methodDeclaration.setScope(this);
-
- ASTMethodDeclarator methodDeclarator = new ASTMethodDeclarator(0);
- methodDeclarator.setImage(methodName);
- methodDeclarator.setScope(this);
-
- ASTFormalParameters formalParameters = new ASTFormalParameters(0);
- formalParameters.setScope(this);
-
- methodDeclaration.jjtAddChild(methodDeclarator, 0);
- methodDeclarator.jjtSetParent(methodDeclaration);
- methodDeclarator.jjtAddChild(formalParameters, 0);
- formalParameters.jjtSetParent(methodDeclarator);
-
- /*
- * jjtAddChild resizes it's child node list according to known indexes.
- * Going backwards makes sure the first time it gets the right size avoiding copies.
- */
- for (int i = parameterTypes.length - 1; i >= 0; i--) {
- ASTFormalParameter formalParameter = new ASTFormalParameter(0);
- formalParameters.jjtAddChild(formalParameter, i);
- formalParameter.jjtSetParent(formalParameters);
-
- ASTVariableDeclaratorId variableDeclaratorId = new ASTVariableDeclaratorId(0);
- variableDeclaratorId.setImage("arg" + i);
- formalParameter.jjtAddChild(variableDeclaratorId, 1);
- variableDeclaratorId.jjtSetParent(formalParameter);
-
- ASTType type = new ASTType(0);
- formalParameter.jjtAddChild(type, 0);
- type.jjtSetParent(formalParameter);
-
- if (PRIMITIVE_TYPES.contains(parameterTypes[i])) {
- ASTPrimitiveType primitiveType = new ASTPrimitiveType(0);
- primitiveType.setImage(parameterTypes[i]);
- type.jjtAddChild(primitiveType, 0);
- primitiveType.jjtSetParent(type);
- } else {
- ASTReferenceType referenceType = new ASTReferenceType(0);
- type.jjtAddChild(referenceType, 0);
- referenceType.jjtSetParent(type);
-
- // TODO : this could actually be a primitive array...
- ASTClassOrInterfaceType classOrInterfaceType = new ASTClassOrInterfaceType(0);
- classOrInterfaceType.setImage(parameterTypes[i]);
- referenceType.jjtAddChild(classOrInterfaceType, 0);
- classOrInterfaceType.jjtSetParent(referenceType);
- }
- }
-
- return new MethodNameDeclaration(methodDeclarator);
- }
-
/**
* Provide a list of types of the parameters of the given method
* declaration. The types are simple type images.
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java
index f49d5a3be9..f33c38b4e1 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/ClassTypeResolver.java
@@ -897,7 +897,7 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
// skip children which already have their type assigned
if (currentChild.getType() == null) {
// Last token, because if 'this' is a Suffix, it'll have tokens '.' and 'this'
- if (currentChild.jjtGetLastToken().kind == JavaTokenKinds.THIS) {
+ if (currentChild.getLastToken().kind == JavaTokenKinds.THIS) {
if (previousChild != null) { // Qualified 'this' expression
currentChild.setTypeDefinition(previousChild.getTypeDefinition());
@@ -911,7 +911,7 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
}
// Last token, because if 'super' is a Suffix, it'll have tokens '.' and 'super'
- } else if (currentChild.jjtGetLastToken().kind == JavaTokenKinds.SUPER) {
+ } else if (currentChild.getLastToken().kind == JavaTokenKinds.SUPER) {
if (previousChild != null) { // Qualified 'super' expression
// anonymous classes can't have qualified super expression, thus
@@ -929,7 +929,7 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
String currentChildImage = currentChild.getImage();
if (currentChildImage == null) {
// this.foo(); foo would be in a Suffix and would have a null image
- currentChildImage = currentChild.jjtGetLastToken().getImage();
+ currentChildImage = currentChild.getLastToken().getImage();
}
ASTArguments astArguments = nextChild != null
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/xpath/GetCommentOnFunction.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/xpath/GetCommentOnFunction.java
index 9e79e5328f..2f1dae6f88 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/xpath/GetCommentOnFunction.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/xpath/GetCommentOnFunction.java
@@ -13,7 +13,6 @@ import org.jaxen.SimpleFunctionContext;
import org.jaxen.XPathFunctionContext;
import net.sourceforge.pmd.annotation.InternalApi;
-import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.Comment;
@@ -41,15 +40,13 @@ public class GetCommentOnFunction implements Function {
return Boolean.FALSE;
}
Node n = (Node) context.getNodeSet().get(0);
- if (n instanceof AbstractNode) {
- int codeBeginLine = ((AbstractNode) n).getBeginLine();
- int codeEndLine = ((AbstractNode) n).getEndLine();
+ int codeBeginLine = n.getBeginLine();
+ int codeEndLine = n.getEndLine();
- List commentList = ((AbstractNode) n).getFirstParentOfType(ASTCompilationUnit.class).getComments();
- for (Comment comment : commentList) {
- if (comment.getBeginLine() == codeBeginLine || comment.getEndLine() == codeEndLine) {
- return comment.getImage();
- }
+ List commentList = n.getFirstParentOfType(ASTCompilationUnit.class).getComments();
+ for (Comment comment : commentList) {
+ if (comment.getBeginLine() == codeBeginLine || comment.getEndLine() == codeEndLine) {
+ return comment.getImage();
}
}
return Boolean.FALSE;
diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml
index c9dfa04ff7..6ce8af8d8b 100644
--- a/pmd-java/src/main/resources/category/java/bestpractices.xml
+++ b/pmd-java/src/main/resources/category/java/bestpractices.xml
@@ -875,6 +875,41 @@ public class MyTest {
+
+
+ Position literals first in all String comparisons, if the second argument is null then NullPointerExceptions
+ can be avoided, they will just return false. Note that switching literal positions for compareTo and
+ compareToIgnoreCase may change the result, see examples.
+
+ 3
+
+ 0); // should be: "bar".compareTo(x) < 0
+ }
+ boolean bar(String x) {
+ return (x.compareToIgnoreCase("bar") > 0); // should be: "bar".compareToIgnoreCase(x) < 0
+ }
+ boolean bar(String x) {
+ return x.contentEquals("bar"); // should be "bar".contentEquals(x)
+ }
+}
+]]>
+
+
+
-Some JUnit framework methods are easy to misspell.
+ In JUnit 3, the setUp method is used to set up all data entities required in running tests.
+ The tearDown method is used to clean up all data entities required in running tests.
+ You should not misspell method name if you want your test to set up and clean up everything correctly.
3
diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml
index 57a9f973d7..5b9d911b7a 100644
--- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml
+++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml
@@ -30,12 +30,11 @@
+
-
-
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java
index 7c217d0a25..e8a2bb5506 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java
@@ -35,25 +35,26 @@ public class LanguageVersionTest extends AbstractLanguageVersionTest {
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "1.8",
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.8"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "9",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("9"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("9"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "10",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("10"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("10"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "11",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("11"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("11"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "12",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "12-preview",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12-preview"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12-preview"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "13",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "13-preview",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13-preview"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13-preview"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "14",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14"), },
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "14-preview",
- LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14-preview"), },
+ LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14-preview"), },
// this one won't be found: case sensitive!
- { "JAVA", "JAVA", "1.7", null, }, });
+ { "JAVA", "JAVA", "1.7", null, },
+ });
}
}
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBlockStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBlockStatementTest.java
index b0e682d49a..2dafc666f7 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBlockStatementTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBlockStatementTest.java
@@ -14,14 +14,14 @@ public class ASTBlockStatementTest {
@Test
public void testIsAllocation() {
ASTBlockStatement bs = new ASTBlockStatement(0);
- bs.jjtAddChild(new ASTAllocationExpression(1), 0);
+ bs.addChild(new ASTAllocationExpression(1), 0);
assertTrue(bs.isAllocation());
}
@Test
public void testIsAllocation2() {
ASTBlockStatement bs = new ASTBlockStatement(0);
- bs.jjtAddChild(new ASTAssertStatement(1), 0);
+ bs.addChild(new ASTAssertStatement(1), 0);
assertFalse(bs.isAllocation());
}
}
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclarationTest.java
index 34dd5438f9..e25a9b6a6c 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclarationTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclarationTest.java
@@ -77,9 +77,9 @@ public class ASTFieldDeclarationTest extends BaseParserTest {
ASTType t = new ASTType(id++);
ASTVariableDeclarator decl = new ASTVariableDeclarator(id++);
ASTVariableDeclaratorId declid = new ASTVariableDeclaratorId(id++);
- n.jjtAddChild(t, 0);
- t.jjtAddChild(decl, 0);
- decl.jjtAddChild(declid, 0);
+ n.addChild(t, 0);
+ t.addChild(decl, 0);
+ decl.addChild(declid, 0);
declid.setImage("foo");
assertEquals("foo", n.getVariableName());
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java
index 673f893777..19d289d8fc 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java
@@ -15,6 +15,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import net.sourceforge.pmd.lang.ast.TokenMgrError;
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
@@ -31,6 +32,14 @@ public class ParserCornersTest {
@Rule
public ExpectedException expect = ExpectedException.none();
+
+ @Test
+ public void testInvalidUnicodeEscape() {
+ expect.expect(TokenMgrError.class); // previously Error
+ expect.expectMessage("Lexical error at line 1, column 2. Encountered: Invalid unicode escape");
+ java.parse("\\u00k0");
+ }
+
/**
* #1107 PMD 5.0.4 couldn't parse call of parent outer java class method
* from inner class.
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java
index 0f9e3e15e5..91eebd6cd9 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/SimpleNodeTest.java
@@ -101,15 +101,15 @@ public class SimpleNodeTest extends BaseParserTest {
@Test
public void testFindDescendantsOfType() {
ASTBlock block = new ASTBlock(2);
- block.jjtAddChild(new ASTReturnStatement(1), 0);
+ block.addChild(new ASTReturnStatement(1), 0);
assertEquals(1, block.findDescendantsOfType(ASTReturnStatement.class).size());
}
@Test
public void testFindDescendantsOfTypeMultiple() {
ASTBlock block = new ASTBlock(1);
- block.jjtAddChild(new ASTBlockStatement(2), 0);
- block.jjtAddChild(new ASTBlockStatement(3), 1);
+ block.addChild(new ASTBlockStatement(2), 0);
+ block.addChild(new ASTBlockStatement(3), 1);
List nodes = block.findDescendantsOfType(ASTBlockStatement.class);
assertEquals(2, nodes.size());
}
@@ -118,8 +118,8 @@ public class SimpleNodeTest extends BaseParserTest {
public void testFindDescendantsOfTypeRecurse() {
ASTBlock block = new ASTBlock(1);
ASTBlock childBlock = new ASTBlock(2);
- block.jjtAddChild(childBlock, 0);
- childBlock.jjtAddChild(new ASTMethodDeclaration(3), 0);
+ block.addChild(childBlock, 0);
+ childBlock.addChild(new ASTMethodDeclaration(3), 0);
List nodes = block.findDescendantsOfType(ASTMethodDeclaration.class);
assertEquals(1, nodes.size());
}
@@ -128,8 +128,8 @@ public class SimpleNodeTest extends BaseParserTest {
public void testGetFirstChild() {
ASTBlock block = new ASTBlock(1);
ASTStatement x = new ASTStatement(2);
- block.jjtAddChild(x, 0);
- block.jjtAddChild(new ASTStatement(3), 1);
+ block.addChild(x, 0);
+ block.addChild(new ASTStatement(3), 1);
Node n = block.getFirstDescendantOfType(ASTStatement.class);
assertNotNull(n);
@@ -142,9 +142,9 @@ public class SimpleNodeTest extends BaseParserTest {
ASTBlock block = new ASTBlock(1);
ASTStatement x = new ASTStatement(2);
ASTAssignmentOperator x1 = new ASTAssignmentOperator(4);
- x.jjtAddChild(x1, 0);
- block.jjtAddChild(x, 0);
- block.jjtAddChild(new ASTStatement(3), 1);
+ x.addChild(x1, 0);
+ block.addChild(x, 0);
+ block.addChild(new ASTStatement(3), 1);
Node n = block.getFirstDescendantOfType(ASTAssignmentOperator.class);
assertNotNull(n);
@@ -159,10 +159,10 @@ public class SimpleNodeTest extends BaseParserTest {
ASTAssignmentOperator x1 = new ASTAssignmentOperator(4);
ASTName x2 = new ASTName(5);
- x.jjtAddChild(x1, 0);
- x1.jjtAddChild(x2, 0);
- block.jjtAddChild(x, 0);
- block.jjtAddChild(new ASTStatement(3), 1);
+ x.addChild(x1, 0);
+ x1.addChild(x2, 0);
+ block.addChild(x, 0);
+ block.addChild(new ASTStatement(3), 1);
Node n = block.getFirstDescendantOfType(ASTName.class);
assertNotNull(n);
@@ -258,17 +258,6 @@ public class SimpleNodeTest extends BaseParserTest {
assertFalse(c.hasDescendantMatchingXPath("//MethodDeclaration"));
}
- @Test
- public void testUserData() {
- ASTClassOrInterfaceDeclaration c = java.getNodes(ASTClassOrInterfaceDeclaration.class, HAS_EXPLICIT_EXTENDS)
- .iterator().next();
- assertNull(c.getUserData());
- c.setUserData("foo");
- assertEquals("foo", c.getUserData());
- c.setUserData(null);
- assertNull(c.getUserData());
- }
-
private void verifyNode(Node node, int beginLine, int beginCol, int endLine, int endCol) {
assertEquals("Unexpected beginning line: ", beginLine, node.getBeginLine());
assertEquals("Unexpected beginning column: ", beginCol, node.getBeginColumn());
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java
index ed5f9e89dd..9f0683348f 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/AcceptanceTest.java
@@ -39,7 +39,7 @@ public class AcceptanceTest extends BaseNonParserTest {
private boolean check(int[][] array, List methodNodes) {
for (int i = 0; i < methodNodes.size(); i++) {
ASTMethodDeclarator decl = methodNodes.get(i);
- DataFlowNode inode = decl.getDataFlowNode();
+ DataFlowNode inode = DataFlowNode.get(decl);
for (int j = 0; j < inode.getChildren().size(); j++) {
DataFlowNode child = inode.getChildren().get(j);
if (array[i][j] != child.getIndex() - 1) {
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java
index 2835f27d2b..c1d6aa3633 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/DAAPathFinderTest.java
@@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.dfa;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
+import net.sourceforge.pmd.lang.dfa.DataFlowNode;
import net.sourceforge.pmd.lang.dfa.pathfinder.CurrentPath;
import net.sourceforge.pmd.lang.dfa.pathfinder.DAAPathFinder;
import net.sourceforge.pmd.lang.dfa.pathfinder.Executable;
@@ -18,7 +19,7 @@ public class DAAPathFinderTest {
@Test
public void testTwoUpdateDefs() {
ASTMethodDeclarator meth = JavaParsingHelper.WITH_PROCESSING.getNodes(ASTMethodDeclarator.class, TWO_UPDATE_DEFS).get(0);
- DAAPathFinder a = new DAAPathFinder(meth.getDataFlowNode().getFlow().get(0), new Executable() {
+ DAAPathFinder a = new DAAPathFinder(DataFlowNode.get(meth).getFlow().get(0), new Executable() {
@Override
public void execute(CurrentPath path) {
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java
index 854bad3f1f..437a9927e5 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/GeneralFiddlingTest.java
@@ -33,7 +33,7 @@ public class GeneralFiddlingTest extends BaseNonParserTest {
public void test1() {
ASTCompilationUnit acu = java.parse(TEST1);
ASTMethodDeclarator meth = acu.findDescendantsOfType(ASTMethodDeclarator.class).get(0);
- DataFlowNode n = meth.getDataFlowNode();
+ DataFlowNode n = DataFlowNode.get(meth);
List f = n.getFlow();
assertEquals(6, f.size());
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java
index ce9d9d37eb..99606982f0 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/dfa/StatementAndBraceFinderTest.java
@@ -24,23 +24,23 @@ public class StatementAndBraceFinderTest extends BaseNonParserTest {
@Test
public void testStatementExpressionParentChildLinks() {
ASTStatementExpression se = getOrderedNodes(ASTStatementExpression.class, TEST1).get(0);
- ASTMethodDeclaration seParent = (ASTMethodDeclaration) se.getDataFlowNode().getParents().get(0).getNode();
- assertEquals(se, seParent.getDataFlowNode().getChildren().get(0).getNode());
- assertEquals(seParent, se.getDataFlowNode().getParents().get(0).getNode());
+ ASTMethodDeclaration seParent = (ASTMethodDeclaration) DataFlowNode.get(se).getParents().get(0).getNode();
+ assertEquals(se, DataFlowNode.get(seParent).getChildren().get(0).getNode());
+ assertEquals(seParent, DataFlowNode.get(se).getParents().get(0).getNode());
}
@Test
public void testVariableDeclaratorParentChildLinks() {
ASTVariableDeclarator vd = getOrderedNodes(ASTVariableDeclarator.class, TEST2).get(0);
- ASTMethodDeclaration vdParent = (ASTMethodDeclaration) vd.getDataFlowNode().getParents().get(0).getNode();
- assertEquals(vd, vdParent.getDataFlowNode().getChildren().get(0).getNode());
- assertEquals(vdParent, vd.getDataFlowNode().getParents().get(0).getNode());
+ ASTMethodDeclaration vdParent = (ASTMethodDeclaration) DataFlowNode.get(vd).getParents().get(0).getNode();
+ assertEquals(vd, DataFlowNode.get(vdParent).getChildren().get(0).getNode());
+ assertEquals(vdParent, DataFlowNode.get(vd).getParents().get(0).getNode());
}
@Test
public void testIfStmtHasCorrectTypes() {
ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST3).get(0);
- DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
+ DataFlowNode dfn = DataFlowNode.get(exp).getFlow().get(2);
assertTrue(dfn.isType(NodeType.IF_EXPR));
assertTrue(dfn.isType(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE));
}
@@ -48,7 +48,7 @@ public class StatementAndBraceFinderTest extends BaseNonParserTest {
@Test
public void testWhileStmtHasCorrectTypes() {
ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST4).get(0);
- DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
+ DataFlowNode dfn = DataFlowNode.get(exp).getFlow().get(2);
assertTrue(dfn.isType(NodeType.WHILE_EXPR));
assertTrue(dfn.isType(NodeType.WHILE_LAST_STATEMENT));
}
@@ -56,11 +56,11 @@ public class StatementAndBraceFinderTest extends BaseNonParserTest {
@Test
public void testForStmtHasCorrectTypes() {
ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST5).get(0);
- DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
+ DataFlowNode dfn = DataFlowNode.get(exp).getFlow().get(2);
assertTrue(dfn.isType(NodeType.FOR_INIT));
- dfn = exp.getDataFlowNode().getFlow().get(3);
+ dfn = DataFlowNode.get(exp).getFlow().get(3);
assertTrue(dfn.isType(NodeType.FOR_EXPR));
- dfn = exp.getDataFlowNode().getFlow().get(4);
+ dfn = DataFlowNode.get(exp).getFlow().get(4);
assertTrue(dfn.isType(NodeType.FOR_UPDATE));
assertTrue(dfn.isType(NodeType.FOR_BEFORE_FIRST_STATEMENT));
assertTrue(dfn.isType(NodeType.FOR_END));
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java
new file mode 100644
index 0000000000..afec19e09a
--- /dev/null
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java
@@ -0,0 +1,11 @@
+/**
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.java.rule.bestpractices;
+
+import net.sourceforge.pmd.testframework.PmdRuleTst;
+
+public class LiteralsFirstInComparisonsTest extends PmdRuleTst {
+ // no additional unit tests
+}
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java
index a847fa13ec..c0c305c63d 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ClassScopeTest.java
@@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.ast.DummyJavaNode;
-import net.sourceforge.pmd.lang.java.ast.JavaNode;
+import net.sourceforge.pmd.lang.java.ast.InternalApiBridge;
import net.sourceforge.pmd.lang.java.symboltable.testdata.InnerClass;
import net.sourceforge.pmd.lang.java.symboltable.testdata.InnerClass.TheInnerClass;
import net.sourceforge.pmd.lang.java.symboltable.testdata.InnerClass.TheInnerClass.EnumTest;
@@ -61,8 +61,7 @@ public class ClassScopeTest extends BaseNonParserTest {
public void testContains() {
ClassNameDeclaration classDeclaration = new ClassNameDeclaration(null);
ClassScope s = new ClassScope("Foo", classDeclaration);
- ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
- node.setImage("bar");
+ ASTVariableDeclaratorId node = InternalApiBridge.newVarId("bar");
s.addDeclaration(new VariableNameDeclaration(node));
assertTrue(s.getDeclarations().keySet().iterator().hasNext());
}
@@ -71,7 +70,7 @@ public class ClassScopeTest extends BaseNonParserTest {
public void testCantContainsSuperToString() {
ClassNameDeclaration classDeclaration = new ClassNameDeclaration(null);
ClassScope s = new ClassScope("Foo", classDeclaration);
- JavaNode node = new DummyJavaNode(1);
+ DummyJavaNode node = new DummyJavaNode(1);
node.setImage("super.toString");
assertFalse(s.contains(new JavaNameOccurrence(node, node.getImage())));
}
@@ -80,11 +79,11 @@ public class ClassScopeTest extends BaseNonParserTest {
public void testContainsStaticVariablePrefixedWithClassName() {
ClassNameDeclaration classDeclaration = new ClassNameDeclaration(null);
ClassScope s = new ClassScope("Foo", classDeclaration);
- ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
- node.setImage("X");
+ ASTVariableDeclaratorId node = InternalApiBridge.newVarId("X");
+
s.addDeclaration(new VariableNameDeclaration(node));
- JavaNode node2 = new DummyJavaNode(2);
+ DummyJavaNode node2 = new DummyJavaNode(2);
node2.setImage("Foo.X");
assertTrue(s.contains(new JavaNameOccurrence(node2, node2.getImage())));
}
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ImageFinderFunctionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ImageFinderFunctionTest.java
index fc94a49c65..ad0b042a9b 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ImageFinderFunctionTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ImageFinderFunctionTest.java
@@ -12,6 +12,7 @@ import java.util.List;
import org.junit.Test;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
+import net.sourceforge.pmd.lang.java.ast.InternalApiBridge;
import net.sourceforge.pmd.lang.symboltable.ImageFinderFunction;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
@@ -20,8 +21,10 @@ public class ImageFinderFunctionTest {
@Test
public void testSingleImage() {
ImageFinderFunction f = new ImageFinderFunction("foo");
- ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
- node.setImage("foo");
+ // These tests were completely broken, they built a PrimaryPrefix
+ // that is a child of a Name (not the reverse)
+ // This is an example of why tests should never build nodes manually
+ ASTVariableDeclaratorId node = InternalApiBridge.newVarId("foo");
NameDeclaration decl = new VariableNameDeclaration(node);
f.applyTo(decl);
assertEquals(decl, f.getDecl());
@@ -33,8 +36,7 @@ public class ImageFinderFunctionTest {
imgs.add("Foo.foo");
imgs.add("foo");
ImageFinderFunction f = new ImageFinderFunction(imgs);
- ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
- node.setImage("foo");
+ ASTVariableDeclaratorId node = InternalApiBridge.newVarId("foo");
NameDeclaration decl = new VariableNameDeclaration(node);
f.applyTo(decl);
assertEquals(decl, f.getDecl());
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java
index ca55bace54..c00f697dae 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/LocalScopeTest.java
@@ -16,9 +16,9 @@ import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
-import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
+import net.sourceforge.pmd.lang.java.ast.InternalApiBridge;
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
@@ -27,12 +27,8 @@ public class LocalScopeTest extends BaseNonParserTest {
@Test
public void testNameWithThisOrSuperIsNotFlaggedAsUnused() {
LocalScope scope = new LocalScope();
- ASTName name = new ASTName(1);
- name.setImage("foo");
- ASTPrimaryPrefix prefix = new ASTPrimaryPrefix(2);
- prefix.setUsesThisModifier();
- name.jjtAddChild(prefix, 1);
- JavaNameOccurrence occ = new JavaNameOccurrence(name, "foo");
+ ASTPrimaryPrefix prefix = InternalApiBridge.newThisSuperPrefix("foo", true);
+ JavaNameOccurrence occ = new JavaNameOccurrence(prefix.getFirstChild(), "foo");
scope.addNameOccurrence(occ);
assertFalse(scope.getDeclarations().keySet().iterator().hasNext());
}
@@ -40,12 +36,8 @@ public class LocalScopeTest extends BaseNonParserTest {
@Test
public void testNameWithSuperIsNotFlaggedAsUnused() {
LocalScope scope = new LocalScope();
- ASTName name = new ASTName(1);
- name.setImage("foo");
- ASTPrimaryPrefix prefix = new ASTPrimaryPrefix(2);
- prefix.setUsesSuperModifier();
- name.jjtAddChild(prefix, 1);
- JavaNameOccurrence occ = new JavaNameOccurrence(name, "foo");
+ ASTPrimaryPrefix prefix = InternalApiBridge.newThisSuperPrefix("foo", false);
+ JavaNameOccurrence occ = new JavaNameOccurrence(prefix.getFirstChild(), "foo");
scope.addNameOccurrence(occ);
assertFalse(scope.getDeclarations().keySet().iterator().hasNext());
}
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml
index b59f2caf25..30a157cdf2 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml
@@ -512,4 +512,22 @@ public class DigitalAssetManagerTest {
}
}]]>