Add a dump facade to print out the AST tree
This commit is contained in:
pmd-apex/src
main/java/net/sourceforge/pmd/lang/apex
test/java/net/sourceforge/pmd/lang/apex/ast
@ -3,12 +3,18 @@
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.apex;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import net.sf.saxon.sxpath.IndependentContext;
|
||||
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
import net.sourceforge.pmd.lang.XPathHandler;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.ast.DumpFacade;
|
||||
import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.AbstractASTXPathHandler;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
|
||||
@ -40,4 +46,13 @@ public class ApexHandler extends AbstractLanguageVersionHandler {
|
||||
public Parser getParser(ParserOptions parserOptions) {
|
||||
return new ApexParser(parserOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitorStarter getDumpFacade(Writer writer, String prefix, boolean recurse) {
|
||||
return new VisitorStarter() {
|
||||
public void start(Node rootNode) {
|
||||
new DumpFacade().initializeWith(writer, prefix, recurse, (ApexNode<?>) rootNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.util.StringUtil;
|
||||
|
||||
public class DumpFacade {
|
||||
private PrintWriter writer;
|
||||
private boolean recurse;
|
||||
|
||||
public void initializeWith(Writer writer, String prefix, boolean recurse, ApexNode<?> node) {
|
||||
this.writer = writer instanceof PrintWriter ? (PrintWriter) writer : new PrintWriter(writer);
|
||||
this.recurse = recurse;
|
||||
this.dump(node, prefix);
|
||||
try {
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Problem flushing PrintWriter.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object visit(ApexNode<?> node, Object data) {
|
||||
dump(node, (String) data);
|
||||
if (recurse) {
|
||||
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
||||
visit((ApexNode<?>) node.jjtGetChild(i), data + " ");
|
||||
}
|
||||
return data;
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private void dump(ApexNode<?> node, String prefix) {
|
||||
//
|
||||
// Dump format is generally composed of the following items...
|
||||
//
|
||||
|
||||
// 1) Dump prefix
|
||||
writer.print(prefix);
|
||||
|
||||
// 2) JJT Name of the Node
|
||||
writer.print(node.toString());
|
||||
|
||||
//
|
||||
// If there are any additional details, then:
|
||||
// 1) A colon
|
||||
// 2) The Node.getImage() if it is non-empty
|
||||
// 3) Extras in parentheses
|
||||
//
|
||||
|
||||
// Standard image handling
|
||||
String image = node.getImage();
|
||||
|
||||
// Special image handling (e.g. Nodes with normally null images)
|
||||
image = StringUtil.escapeWhitespace(image);
|
||||
|
||||
// Extras
|
||||
List<String> extras = new ArrayList<>();
|
||||
|
||||
// Output image and extras
|
||||
if (image != null || !extras.isEmpty()) {
|
||||
writer.print(':');
|
||||
if (image != null) {
|
||||
writer.print(image);
|
||||
}
|
||||
for (String extra : extras) {
|
||||
writer.print('(');
|
||||
writer.print(extra);
|
||||
writer.print(')');
|
||||
}
|
||||
}
|
||||
|
||||
writer.println();
|
||||
}
|
||||
}
|
@ -9,15 +9,14 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ApexParserOptions;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParser;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ApexParserOptions;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
public class ApexParserTest {
|
||||
|
||||
private String code1 = "public class HelloWorld { public void foo() {} private static int bar() { return 1; } }";
|
||||
@ -30,6 +29,7 @@ public class ApexParserTest {
|
||||
@Test
|
||||
public void testParse() {
|
||||
ASTUserClass rootNode = parse(code1);
|
||||
dumpNode(rootNode);
|
||||
|
||||
List<ASTMethod> methods = rootNode.findDescendantsOfType(ASTMethod.class);
|
||||
assertEquals(2, methods.size());
|
||||
@ -40,4 +40,12 @@ public class ApexParserTest {
|
||||
Reader reader = new StringReader(code);
|
||||
return (ASTUserClass) parser.parse(reader);
|
||||
}
|
||||
|
||||
private void dumpNode(Node node) {
|
||||
DumpFacade facade = new DumpFacade();
|
||||
StringWriter writer = new StringWriter();
|
||||
facade.initializeWith(writer, "", true, (ApexNode<?>)node);
|
||||
facade.visit((ApexNode<?>)node, "");
|
||||
System.out.println(writer.toString());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user