From 80e9f48ed9fd6fbd12797d58abc6e231cb371801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Aug 2020 01:10:10 +0200 Subject: [PATCH] Add a hook for nodes to callback if the visitor is incorrect --- .../pmd/lang/apex/ast/AbstractApexNode.java | 3 ++- .../net/sourceforge/pmd/lang/ast/AstVisitor.java | 16 ++++++++++++++++ .../pmd/lang/java/ast/AbstractJavaNode.java | 3 ++- .../ecmascript/ast/AbstractEcmascriptNode.java | 8 ++++---- .../pmd/lang/jsp/ast/AbstractJspNode.java | 3 ++- .../lang/modelica/ast/AbstractModelicaNode.java | 10 ++++++++++ .../pmd/lang/scala/ast/AbstractScalaNode.java | 3 ++- 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java index 8e94732e4b..b53d0ab72c 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AbstractApexNode.java @@ -42,11 +42,12 @@ abstract class AbstractApexNode extends AbstractNodeWithTextC } @Override + @SuppressWarnings("unchecked") public final R acceptVisitor(AstVisitor visitor, P data) { if (visitor instanceof ApexVisitor) { return this.acceptApexVisitor((ApexVisitor) visitor, data); } - return super.acceptVisitor(visitor, data); + return visitor.cannotVisit(this, data); } protected abstract R acceptApexVisitor(ApexVisitor visitor, P data); 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 index b121cd6357..1d6ceab7cb 100644 --- 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 @@ -21,6 +21,22 @@ package net.sourceforge.pmd.lang.ast; */ public interface AstVisitor { + + /** + * Called by a node when it detects that the visitor is not of the + * language it is used to visiting. If a visitor wants to visit nodes + * for several languages, it should provide a useful implementation + * of this method. The default implementation throws + * + * @param node Node calling back this method + * @param param Parameter of the visit + * + * @return A value (or may throw) + */ + default R cannotVisit(Node node, P param) { + throw new UnsupportedOperationException("Cannot visit " + node); + } + /** * Visit a node. This method is dispatched statically, you should * use {@link Node#acceptVisitor(AstVisitor, Object)} if you want 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 14890cf7db..b4b1f9ea6f 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 @@ -34,11 +34,12 @@ public abstract class AbstractJavaNode extends AbstractJjtreeNode R acceptVisitor(AstVisitor visitor, P data) { if (visitor instanceof JavaVisitor) { return this.acceptVisitor((JavaVisitor) visitor, data); } - return super.acceptVisitor(visitor, data); + return visitor.cannotVisit(this, data); } protected abstract R acceptVisitor(JavaVisitor visitor, P data); diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java index f3c2386f8b..09a020d0f0 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/AbstractEcmascriptNode.java @@ -50,11 +50,11 @@ abstract class AbstractEcmascriptNode extends AbstractNodeWit @Override @SuppressWarnings("unchecked") - public R acceptVisitor(AstVisitor visitor, P data) { - if (!(visitor instanceof EcmascriptVisitor)) { - return super.acceptVisitor(visitor, data); + public final R acceptVisitor(AstVisitor visitor, P data) { + if (visitor instanceof EcmascriptVisitor) { + return acceptJsVisitor((EcmascriptVisitor) visitor, data); } - return acceptJsVisitor((EcmascriptVisitor) visitor, data); + return visitor.cannotVisit(this, data); } protected abstract R acceptJsVisitor(EcmascriptVisitor visitor, P data); diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java index a0c2c53c57..afd0ea2441 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNode.java @@ -14,11 +14,12 @@ abstract class AbstractJspNode extends AbstractJjtreeNode R acceptVisitor(AstVisitor visitor, P data) { if (visitor instanceof JspVisitor) { return this.acceptVisitor((JspVisitor) visitor, data); } - return super.acceptVisitor(visitor, data); + return visitor.cannotVisit(this, data); } protected abstract R acceptVisitor(JspVisitor visitor, P data); diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java index d2cfbdd646..091f23ffb9 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.modelica.ast; +import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.ast.impl.javacc.AbstractJjtreeNode; import net.sourceforge.pmd.lang.modelica.resolver.ModelicaScope; @@ -31,6 +32,15 @@ abstract class AbstractModelicaNode extends AbstractJjtreeNode R acceptVisitor(AstVisitor visitor, P data) { + if (visitor instanceof ModelicaVisitor) { + return acceptModelicaVisitor((ModelicaVisitor) visitor, data); + } + return visitor.cannotVisit(this, data); + } + protected abstract R acceptModelicaVisitor(ModelicaVisitor visitor, P data); @Override diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java index 3f4810296a..026b5640be 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/AbstractScalaNode.java @@ -34,11 +34,12 @@ abstract class AbstractScalaNode extends AbstractNode R acceptVisitor(AstVisitor visitor, P data) { if (visitor instanceof ScalaParserVisitor) { return this.acceptVisitor((ScalaParserVisitor) visitor, data); } - return super.acceptVisitor(visitor, data); + return visitor.cannotVisit(this, data); } protected abstract R acceptVisitor(ScalaParserVisitor visitor, P data);