diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml
index a5e0e541c8..e0c8afe559 100644
--- a/antlr4-wrapper.xml
+++ b/antlr4-wrapper.xml
@@ -15,29 +15,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java
new file mode 100644
index 0000000000..ea3e675a28
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java
@@ -0,0 +1,12 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast;
+
+// The AstVisitor of #2589
+public interface AstVisitor
{
+
+ R visitNode(Node node, P param);
+
+}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitorBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitorBase.java
new file mode 100644
index 0000000000..af4fa49fbd
--- /dev/null
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitorBase.java
@@ -0,0 +1,22 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.ast;
+
+// The AstVisitorBase of #2589 (simplified, keep the other instead)
+public abstract class AstVisitorBase
implements AstVisitor
{
+
+ protected R visitChildren(Node node, P data) {
+ for (Node child : node.children()) {
+ child.acceptVisitor(this, data);
+ }
+ return null;
+ }
+
+ @Override
+ public R visitNode(Node node, P param) {
+ return visitChildren(node, param);
+ }
+
+}
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 b4aa8f5429..fd6f36700f 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
@@ -244,6 +244,7 @@ public interface Node {
}
}
+
/**
* Returns a data map used to store additional information on this node.
*
@@ -251,6 +252,13 @@ public interface Node {
*/
DataMap> getUserMap();
+
+ // The acceptVisitor of #2589
+ default R acceptVisitor(AstVisitor super P, ? extends R> visitor, P data) {
+ return visitor.visitNode(this, data);
+ }
+
+
/**
* Returns the parent of this node, or null if this is the {@linkplain RootNode root}
* of the tree.
@@ -259,6 +267,7 @@ public interface Node {
*/
Node getParent();
+
/**
* Returns the child of this node at the given index.
*
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java
index 19b0bf8c85..db2cd3fa26 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java
@@ -6,9 +6,8 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4;
import java.util.List;
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
-
import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.lang.ast.AstVisitor;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.AbstractRule;
@@ -23,13 +22,11 @@ public abstract class AntlrBaseRule extends AbstractRule {
@Override
public void apply(List extends Node> nodes, RuleContext ctx) {
- ParseTreeVisitor visitor = buildVisitor(ctx);
+ AstVisitor visitor = buildVisitor();
assert visitor != null : "Rule should provide a non-null visitor";
for (Node node : nodes) {
- assert node instanceof BaseAntlrNode : "Incorrect node type " + node + " passed to " + this;
-
- ((BaseAntlrNode, ?>) node).accept(visitor);
+ node.acceptVisitor(visitor, ctx);
}
}
@@ -38,10 +35,8 @@ public abstract class AntlrBaseRule extends AbstractRule {
* This visitor should explore the nodes it's interested in and report
* violations on the given rule context.
*
- * @param ruleCtx Object that accumulates rule violations
- *
* @return A visitor bound to the given rule context
*/
- public abstract ParseTreeVisitor buildVisitor(RuleContext ruleCtx);
+ public abstract AstVisitor buildVisitor();
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java
index 9f2292570b..e3f81f77a9 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java
@@ -4,8 +4,6 @@
package net.sourceforge.pmd.lang.ast.impl.antlr4;
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
-
import net.sourceforge.pmd.lang.ast.impl.GenericNode;
/**
@@ -13,6 +11,4 @@ import net.sourceforge.pmd.lang.ast.impl.GenericNode;
*/
public interface AntlrNode> extends GenericNode {
- T accept(ParseTreeVisitor extends T> visitor);
-
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java
index f3d54455d3..33babb7eac 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java
@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.ast.impl.antlr4;
import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.checkerframework.checker.nullness.qual.NonNull;
public abstract class BaseAntlrErrorNode> extends BaseAntlrTerminalNode {
@@ -20,12 +19,6 @@ public abstract class BaseAntlrErrorNode> extends BaseAnt
}
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- return visitor.visitErrorNode(asAntlrNode());
- }
-
-
@Override
public @NonNull String getText() {
return getFirstAntlrToken().getText();
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java
index bc0e50b142..4daab3ed6e 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java
@@ -102,12 +102,6 @@ public abstract class BaseAntlrInnerNode> extends BaseAnt
// default does nothing
}
-
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- return visitor.visitChildren(asAntlrNode());
- }
-
protected static class PmdAsAntlrInnerNode> extends ParserRuleContext implements RuleNode, AntlrToPmdParseTreeAdapter {
private final BaseAntlrInnerNode pmdNode;
@@ -154,9 +148,7 @@ public abstract class BaseAntlrInnerNode> extends BaseAnt
@Override
public T accept(ParseTreeVisitor extends T> visitor) {
- // note: this delegate to the PMD node, giving
- // control of the visit back to the first-class nodes
- return pmdNode.accept(visitor);
+ throw new UnsupportedOperationException("Cannot visit the underlying antlr nodes");
}
}
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java
index 3f53bde770..8b265ff528 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java
@@ -62,11 +62,6 @@ public abstract class BaseAntlrTerminalNode>
return 0;
}
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- return visitor.visitTerminal(asAntlrNode());
- }
-
protected int getTokenKind() {
return antlrNode.symbol.getTokenIndex();
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrVisitor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrVisitor.java
deleted file mode 100644
index 599c0f76a8..0000000000
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrVisitor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
- */
-
-package net.sourceforge.pmd.lang.ast.impl.antlr4;
-
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
-import org.antlr.v4.runtime.tree.RuleNode;
-
-/**
- * Interface for parse tree visitors that can also visit PMD nodes. The
- * antlr rewrite makes the generated visitor interface extend this.
- */
-public interface PmdAntlrVisitor extends ParseTreeVisitor {
-
- @Override
- T visitChildren(RuleNode node);
-
-
- /**
- * This is added for compatibility.
- */
- default T visitChildren(BaseAntlrInnerNode> node) {
- return visitChildren(node.asAntlrNode());
- }
-
-}
diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4
index 715121b5ee..45699d16d3 100644
--- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4
+++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4
@@ -35,6 +35,7 @@ grammar Swift;
@header {
import net.sourceforge.pmd.lang.ast.impl.antlr4.*;
+import net.sourceforge.pmd.lang.ast.AstVisitor;
}
diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java
index b97644cd24..11199a0239 100644
--- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java
+++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java
@@ -4,9 +4,8 @@
package net.sourceforge.pmd.lang.swift;
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
-
import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.lang.ast.AstVisitor;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseRule;
public abstract class AbstractSwiftRule extends AntlrBaseRule {
@@ -16,5 +15,5 @@ public abstract class AbstractSwiftRule extends AntlrBaseRule {
}
@Override
- public abstract ParseTreeVisitor buildVisitor(RuleContext ruleCtx);
+ public abstract AstVisitor buildVisitor();
}
diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java
index 19f9e0ca9e..ea082bfbdc 100644
--- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java
+++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.swift.ast;
import org.antlr.v4.runtime.ParserRuleContext;
+import net.sourceforge.pmd.lang.ast.AstVisitor;
import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrInnerNode;
public abstract class SwiftInnerNode
@@ -19,6 +20,16 @@ public abstract class SwiftInnerNode
super(parent, invokingStateNumber);
}
+ @Override
+ public R acceptVisitor(AstVisitor super P, ? extends R> visitor, P data) {
+ if (visitor instanceof SwiftVisitor) {
+ // some of the generated antlr nodes have no accept method...
+ return ((SwiftVisitor super P, ? extends R>) visitor).visitSwiftNode(this, data);
+ }
+ return visitor.visitNode(this, data);
+ }
+
+
@Override // override to make visible in package
protected PmdAsAntlrInnerNode asAntlrNode() {
return super.asAntlrNode();
diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java
index 693f0b7239..2329adcdff 100644
--- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java
+++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java
@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.swift.ast;
import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrTerminalNode;
@@ -28,8 +27,4 @@ public final class SwiftTerminalNode extends BaseAntlrTerminalNode im
return SwiftParser.DICO.getXPathNameOfToken(getFirstAntlrToken().getType());
}
- @Override
- public T accept(ParseTreeVisitor extends T> visitor) {
- return visitor.visitTerminal(asAntlrNode());
- }
}
diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java
new file mode 100644
index 0000000000..b875929589
--- /dev/null
+++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java
@@ -0,0 +1,14 @@
+/*
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.swift.ast;
+
+import net.sourceforge.pmd.lang.ast.AstVisitorBase;
+
+/**
+ * Base class for swift visitors.
+ */
+public abstract class SwiftVisitorBase extends AstVisitorBase
implements SwiftVisitor
{
+
+}
diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java
index d690627cf6..3224ab29ad 100644
--- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java
+++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java
@@ -7,11 +7,12 @@ package net.sourceforge.pmd.lang.swift.rule.bestpractices;
import java.util.List;
import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.lang.ast.AstVisitor;
import net.sourceforge.pmd.lang.swift.AbstractSwiftRule;
-import net.sourceforge.pmd.lang.swift.ast.SwiftBaseVisitor;
import net.sourceforge.pmd.lang.swift.ast.SwiftParser;
import net.sourceforge.pmd.lang.swift.ast.SwiftParser.FunctionDeclarationContext;
import net.sourceforge.pmd.lang.swift.ast.SwiftParser.InitializerDeclarationContext;
+import net.sourceforge.pmd.lang.swift.ast.SwiftVisitorBase;
public class UnavailableFunctionRule extends AbstractSwiftRule {
@@ -25,11 +26,11 @@ public class UnavailableFunctionRule extends AbstractSwiftRule {
}
@Override
- public SwiftBaseVisitor buildVisitor(RuleContext ruleCtx) {
- return new SwiftBaseVisitor() {
+ public AstVisitor buildVisitor() {
+ return new SwiftVisitorBase() {
@Override
- public Void visitFunctionDeclaration(final FunctionDeclarationContext ctx) {
+ public Void visitFunctionDeclaration(final FunctionDeclarationContext ctx, RuleContext ruleCtx) {
if (ctx == null) {
return null;
}
@@ -45,7 +46,7 @@ public class UnavailableFunctionRule extends AbstractSwiftRule {
}
@Override
- public Void visitInitializerDeclaration(final InitializerDeclarationContext ctx) {
+ public Void visitInitializerDeclaration(final InitializerDeclarationContext ctx, RuleContext ruleCtx) {
if (ctx == null) {
return null;
}