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 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 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 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 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 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 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 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 visitor, P data) { + if (visitor instanceof SwiftVisitor) { + // some of the generated antlr nodes have no accept method... + return ((SwiftVisitor) 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 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; }