forked from phoedos/pmd
added Antlr visitor infrastructure and swift implementation
This commit is contained in:
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.antlr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
import org.antlr.v4.runtime.tree.RuleNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.ast.AntlrBaseNode;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.AbstractRule;
|
||||
|
||||
public abstract class AbstractAntlrVisitor<T> extends AbstractRule implements ParseTreeVisitor<T> {
|
||||
|
||||
protected RuleContext data;
|
||||
|
||||
@Override
|
||||
public void start(RuleContext ctx) {
|
||||
data = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(ParseTree tree) {
|
||||
return tree.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visitChildren(RuleNode node) {
|
||||
T result = this.defaultResult();
|
||||
int n = node.getChildCount();
|
||||
|
||||
for (int i = 0; i < n && this.shouldVisitNextChild(node, result); ++i) {
|
||||
ParseTree c = node.getChild(i);
|
||||
T childResult = c.accept(this);
|
||||
result = this.aggregateResult(result, childResult);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visitTerminal(TerminalNode node) {
|
||||
return this.defaultResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visitErrorNode(ErrorNode node) {
|
||||
return this.defaultResult();
|
||||
}
|
||||
|
||||
protected T defaultResult() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected T aggregateResult(T aggregate, T nextResult) {
|
||||
return nextResult;
|
||||
}
|
||||
|
||||
protected boolean shouldVisitNextChild(RuleNode node, T currentResult) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(List<? extends Node> nodes, RuleContext ctx) {
|
||||
visitAll(nodes);
|
||||
}
|
||||
|
||||
protected void visitAll(List<? extends Node> nodes) {
|
||||
for (Node n : nodes) {
|
||||
AntlrBaseNode node = (AntlrBaseNode) n;
|
||||
visit(node);
|
||||
}
|
||||
}
|
||||
|
||||
public Object visit(final AntlrBaseNode node) {
|
||||
return node.accept(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.antlr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.ast.AntlrBaseNode;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
|
||||
public class AntlrRuleChainVisitor extends AbstractRuleChainVisitor {
|
||||
@Override
|
||||
protected void visit(Rule rule, Node node, RuleContext ctx) {
|
||||
if (rule instanceof AbstractAntlrVisitor) {
|
||||
((AntlrBaseNode) node).accept((AbstractAntlrVisitor) rule);
|
||||
} else {
|
||||
((XPathRule) rule).evaluate(node, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void indexNodes(List<Node> nodes, RuleContext ctx) {
|
||||
final AbstractAntlrVisitor antlrVisitor = new AbstractAntlrVisitor<Object>() {
|
||||
// Perform a visitation of the AST to index nodes which need
|
||||
// visiting by type
|
||||
@Override
|
||||
public Object visit(final AntlrBaseNode node) {
|
||||
indexNode(node);
|
||||
return super.visit(node);
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
antlrVisitor.visit((AntlrBaseNode) nodes.get(i));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.antlr;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.RuleViolation;
|
||||
import net.sourceforge.pmd.lang.ast.AntlrBaseNode;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.AbstractRuleViolationFactory;
|
||||
import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
public final class AntlrRuleViolationFactory extends AbstractRuleViolationFactory {
|
||||
public static final RuleViolationFactory INSTANCE = new AntlrRuleViolationFactory();
|
||||
|
||||
private AntlrRuleViolationFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RuleViolation createRuleViolation(final Rule rule, final RuleContext ruleContext, final Node node,
|
||||
final String message) {
|
||||
return new ParametricRuleViolation<>(rule, ruleContext, (AntlrBaseNode) node, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RuleViolation createRuleViolation(final Rule rule, final RuleContext ruleContext, final Node node,
|
||||
final String message, final int beginLine, final int endLine) {
|
||||
final ParametricRuleViolation<AntlrBaseNode> violation = new ParametricRuleViolation<>(rule, ruleContext,
|
||||
(AntlrBaseNode) node, message);
|
||||
violation.setLines(beginLine, endLine);
|
||||
return violation;
|
||||
}
|
||||
}
|
@ -1,10 +1,17 @@
|
||||
<project name="pmd" default="antlr4" basedir="../../../../">
|
||||
|
||||
<property name="target-package-dir" value="${target}/net/sourceforge/pmd/lang/swift/antlr4" />
|
||||
|
||||
<target name="antlr4" description="Generates all Antlr4 aspects within PMD">
|
||||
<replace file="${target-package-dir}/SwiftParser.java"
|
||||
token="extends ParserRuleContext"
|
||||
value="extends net.sourceforge.pmd.lang.ast.AntlrBaseNode" />
|
||||
<replace file="${target-package-dir}/SwiftBaseVisitor.java"
|
||||
token="extends AbstractParseTreeVisitor"
|
||||
value="extends AbstractAntlrVisitor" />
|
||||
<replace file="${target-package-dir}/SwiftBaseVisitor.java"
|
||||
token="public class SwiftBaseVisitor"
|
||||
value="public abstract class SwiftBaseVisitor" />
|
||||
<replace file="${target-package-dir}/SwiftBaseVisitor.java"
|
||||
token="import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;"
|
||||
value="import net.sourceforge.pmd.lang.antlr.AbstractAntlrVisitor;" />
|
||||
</target>
|
||||
</project>
|
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.swift;
|
||||
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.swift.antlr4.SwiftBaseVisitor;
|
||||
|
||||
public abstract class AbstractSwiftRule<T> extends SwiftBaseVisitor<T> {
|
||||
public AbstractSwiftRule() {
|
||||
super.setLanguage(LanguageRegistry.getLanguage(SwiftLanguageModule.NAME));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user