Add a hook for nodes to callback if the visitor is incorrect

This commit is contained in:
Clément Fournier
2020-08-25 01:10:10 +02:00
parent 9ed0da4ed5
commit 80e9f48ed9
7 changed files with 38 additions and 8 deletions

View File

@@ -42,11 +42,12 @@ abstract class AbstractApexNode<T extends AstNode> extends AbstractNodeWithTextC
}
@Override
@SuppressWarnings("unchecked")
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof ApexVisitor) {
return this.acceptApexVisitor((ApexVisitor<? super P, ? extends R>) visitor, data);
}
return super.acceptVisitor(visitor, data);
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptApexVisitor(ApexVisitor<? super P, ? extends R> visitor, P data);

View File

@@ -21,6 +21,22 @@ package net.sourceforge.pmd.lang.ast;
*/
public interface AstVisitor<P, R> {
/**
* 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

View File

@@ -34,11 +34,12 @@ public abstract class AbstractJavaNode extends AbstractJjtreeNode<AbstractJavaNo
}
@Override
@SuppressWarnings("unchecked")
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof JavaVisitor) {
return this.acceptVisitor((JavaVisitor<? super P, ? extends R>) visitor, data);
}
return super.acceptVisitor(visitor, data);
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptVisitor(JavaVisitor<? super P, ? extends R> visitor, P data);

View File

@@ -50,11 +50,11 @@ abstract class AbstractEcmascriptNode<T extends AstNode> extends AbstractNodeWit
@Override
@SuppressWarnings("unchecked")
public <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (!(visitor instanceof EcmascriptVisitor)) {
return super.acceptVisitor(visitor, data);
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof EcmascriptVisitor) {
return acceptJsVisitor((EcmascriptVisitor<? super P, ? extends R>) visitor, data);
}
return acceptJsVisitor((EcmascriptVisitor<? super P, ? extends R>) visitor, data);
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptJsVisitor(EcmascriptVisitor<? super P, ? extends R> visitor, P data);

View File

@@ -14,11 +14,12 @@ abstract class AbstractJspNode extends AbstractJjtreeNode<AbstractJspNode, JspNo
}
@Override
@SuppressWarnings("unchecked")
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof JspVisitor) {
return this.acceptVisitor((JspVisitor<? super P, ? extends R>) visitor, data);
}
return super.acceptVisitor(visitor, data);
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptVisitor(JspVisitor<? super P, ? extends R> visitor, P data);

View File

@@ -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<AbstractModelicaN
}
@Override
@SuppressWarnings("unchecked")
public final <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof ModelicaVisitor) {
return acceptModelicaVisitor((ModelicaVisitor<? super P, ? extends R>) visitor, data);
}
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptModelicaVisitor(ModelicaVisitor<? super P, ? extends R> visitor, P data);
@Override

View File

@@ -34,11 +34,12 @@ abstract class AbstractScalaNode<T extends Tree> extends AbstractNode<AbstractSc
}
@Override
@SuppressWarnings("unchecked")
public <P, R> R acceptVisitor(AstVisitor<? super P, ? extends R> visitor, P data) {
if (visitor instanceof ScalaParserVisitor) {
return this.acceptVisitor((ScalaParserVisitor<P, R>) visitor, data);
}
return super.acceptVisitor(visitor, data);
return visitor.cannotVisit(this, data);
}
protected abstract <P, R> R acceptVisitor(ScalaParserVisitor<? super P, ? extends R> visitor, P data);