|
Java example source code file (DPrinter.java)
The DPrinter.java Java example source code/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import com.sun.source.util.JavacTask; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; import com.sun.source.util.Trees; import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.code.SymbolMetadata; import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Printer; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Scope.CompoundScope; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.Pretty; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; /** * Debug printer for javac internals, for when toString() just isn't enough. * * <p> * The printer provides an API to generate structured views of javac objects, * such as AST nodes, symbol, types and annotations. Various aspects of the * output can be configured, such as whether to show nulls, empty lists, or * a compressed representation of the source code. Visitors are used to walk * object hierarchies, and can be replaced with custom visitors if the default * visitors are not flexible enough. * * <p> * In general, nodes are printed with an initial line identifying the node * followed by indented lines for the child nodes. Currently, graphs are * represented by printing a spanning subtree. * * <p> * The printer can be accessed via a simple command-line utility, * which makes it easy to see the internal representation of source code, * such as simple test programs, during the compilation pipeline. * * <p>This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ public class DPrinter { protected final PrintWriter out; protected final Trees trees; protected Printer printer; protected boolean showEmptyItems = true; protected boolean showNulls = true; protected boolean showPositions = false; protected boolean showSrc; protected boolean showTreeSymbols; protected boolean showTreeTypes; protected int maxSrcLength = 32; protected Locale locale = Locale.getDefault(); protected static final String NULL = "#null"; // <editor-fold defaultstate="collapsed" desc="Configuration"> public static DPrinter instance(Context context) { DPrinter dp = context.get(DPrinter.class); if (dp == null) { dp = new DPrinter(context); } return dp; } protected DPrinter(Context context) { context.put(DPrinter.class, this); out = context.get(Log.outKey); trees = JavacTrees.instance(context); } public DPrinter(PrintWriter out, Trees trees) { this.out = out; this.trees = trees; } public DPrinter emptyItems(boolean showEmptyItems) { this.showEmptyItems = showEmptyItems; return this; } public DPrinter nulls(boolean showNulls) { this.showNulls = showNulls; return this; } public DPrinter positions(boolean showPositions) { this.showPositions = showPositions; return this; } public DPrinter source(boolean showSrc) { this.showSrc = showSrc; return this; } public DPrinter source(int maxSrcLength) { this.showSrc = true; this.maxSrcLength = maxSrcLength; return this; } public DPrinter treeSymbols(boolean showTreeSymbols) { this.showTreeSymbols = showTreeSymbols; return this; } public DPrinter treeTypes(boolean showTreeTypes) { this.showTreeTypes = showTreeTypes; return this; } public DPrinter typeSymbolPrinter(Printer p) { printer = p; return this; } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Printing"> protected enum Details { /** A one-line non-recursive summary */ SUMMARY, /** Multi-line, possibly recursive. */ FULL }; public void printAnnotations(String label, SymbolMetadata annotations) { printAnnotations(label, annotations, Details.FULL); } protected void printAnnotations(String label, SymbolMetadata annotations, Details details) { if (annotations == null) { printNull(label); } else { // no SUMMARY format currently available to use // use reflection to get at private fields Object DECL_NOT_STARTED = getField(null, SymbolMetadata.class, "DECL_NOT_STARTED"); Object DECL_IN_PROGRESS = getField(null, SymbolMetadata.class, "DECL_IN_PROGRESS"); Object attributes = getField(annotations, SymbolMetadata.class, "attributes"); Object type_attributes = getField(annotations, SymbolMetadata.class, "type_attributes"); if (!showEmptyItems) { if (attributes instanceof List && ((List) attributes).isEmpty() && attributes != DECL_NOT_STARTED && attributes != DECL_IN_PROGRESS && type_attributes instanceof List && ((List) type_attributes).isEmpty()) return; } printString(label, hashString(annotations)); indent(+1); if (attributes == DECL_NOT_STARTED) printString("attributes", "DECL_NOT_STARTED"); else if (attributes == DECL_IN_PROGRESS) printString("attributes", "DECL_IN_PROGRESS"); else if (attributes instanceof List) printList("attributes", (List) attributes); else printObject("attributes", attributes, Details.SUMMARY); if (attributes instanceof List) printList("type_attributes", (List) type_attributes); else printObject("type_attributes", type_attributes, Details.SUMMARY); indent(-1); } } public void printAttribute(String label, Attribute attr) { if (attr == null) { printNull(label); } else { printString(label, attr.getClass().getSimpleName()); indent(+1); attr.accept(attrVisitor); indent(-1); } } public void printFileObject(String label, FileObject fo) { if (fo == null) { printNull(label); } else { printString(label, fo.getName()); } } protected <T> void printImplClass(T item, Class extends T> stdImplClass) { if (item.getClass() != stdImplClass) printString("impl", item.getClass().getName()); } public void printInt(String label, int i) { printString(label, String.valueOf(i)); } public void printList(String label, List<?> list) { if (list == null) { printNull(label); } else if (!list.isEmpty() || showEmptyItems) { printString(label, "[" + list.size() + "]"); indent(+1); int i = 0; for (Object item: list) { printObject(String.valueOf(i++), item, Details.FULL); } indent(-1); } } public void printName(String label, Name name) { if (name == null) { printNull(label); } else { printString(label, name.toString()); } } public void printNull(String label) { if (showNulls) printString(label, NULL); } protected void printObject(String label, Object item, Details details) { if (item == null) { printNull(label); } else if (item instanceof Attribute) { printAttribute(label, (Attribute) item); } else if (item instanceof Symbol) { printSymbol(label, (Symbol) item, details); } else if (item instanceof Type) { printType(label, (Type) item, details); } else if (item instanceof JCTree) { printTree(label, (JCTree) item); } else if (item instanceof List) { printList(label, (List) item); } else if (item instanceof Name) { printName(label, (Name) item); } else { printString(label, String.valueOf(item)); } } public void printScope(String label, Scope scope) { printScope(label, scope, Details.FULL); } public void printScope(String label, Scope scope, Details details) { if (scope == null) { printNull(label); } else { switch (details) { case SUMMARY: { indent(); out.print(label); out.print(": ["); String sep = ""; for (Symbol sym: scope.getElements()) { out.print(sep); out.print(sym.name); sep = ","; } out.println("]"); break; } case FULL: { indent(); out.println(label); indent(+1); printImplClass(scope, Scope.class); printSymbol("owner", scope.owner, Details.SUMMARY); printScope("next", scope.next, Details.SUMMARY); printObject("shared", getField(scope, Scope.class, "shared"), Details.SUMMARY); if (scope instanceof CompoundScope) { printObject("subScopes", getField(scope, CompoundScope.class, "subScopes"), Details.FULL); } else { for (Symbol sym : scope.getElements()) { printSymbol(sym.name.toString(), sym, Details.SUMMARY); } } indent(-1); break; } } } } public void printSource(String label, JCTree tree) { printString(label, Pretty.toSimpleString(tree, maxSrcLength)); } public void printString(String label, String text) { indent(); out.print(label); out.print(": "); out.print(text); out.println(); } public void printSymbol(String label, Symbol symbol) { printSymbol(label, symbol, Details.FULL); } protected void printSymbol(String label, Symbol sym, Details details) { if (sym == null) { printNull(label); } else { switch (details) { case SUMMARY: printString(label, toString(sym)); break; case FULL: indent(); out.print(label); out.println(": " + info(sym.getClass(), String.format("0x%x--%s", sym.kind, Kinds.kindName(sym)), sym.getKind()) + " " + sym.name + " " + hashString(sym)); indent(+1); if (showSrc) { JCTree tree = (JCTree) trees.getTree(sym); if (tree != null) printSource("src", tree); } printString("flags", String.format("0x%x--%s", sym.flags_field, Flags.toString(sym.flags_field))); printObject("completer", sym.completer, Details.SUMMARY); // what if too long? printSymbol("owner", sym.owner, Details.SUMMARY); printType("type", sym.type, Details.SUMMARY); printType("erasure", sym.erasure_field, Details.SUMMARY); sym.accept(symVisitor, null); printAnnotations("annotations", sym.getAnnotations(), Details.SUMMARY); indent(-1); } } } protected String toString(Symbol sym) { return (printer != null) ? printer.visit(sym, locale) : String.valueOf(sym); } protected void printTree(String label, JCTree tree) { if (tree == null) { printNull(label); } else { indent(); String ext; try { ext = tree.getKind().name(); } catch (Throwable t) { ext = "n/a"; } out.print(label + ": " + info(tree.getClass(), tree.getTag(), ext)); if (showPositions) { // We can always get start position, but to get end position // and/or line+offset, we would need a JCCompilationUnit out.print(" pos:" + tree.pos); } if (showTreeTypes && tree.type != null) out.print(" type:" + toString(tree.type)); Symbol sym; if (showTreeSymbols && (sym = TreeInfo.symbolFor(tree)) != null) out.print(" sym:" + toString(sym)); out.println(); indent(+1); if (showSrc) { indent(); out.println("src: " + Pretty.toSimpleString(tree, maxSrcLength)); } tree.accept(treeVisitor); indent(-1); } } public void printType(String label, Type type) { printType(label, type, Details.FULL); } protected void printType(String label, Type type, Details details) { if (type == null) printNull(label); else { switch (details) { case SUMMARY: printString(label, toString(type)); break; case FULL: indent(); out.print(label); out.println(": " + info(type.getClass(), type.getTag(), type.getKind()) + " " + hashString(type)); indent(+1); printSymbol("tsym", type.tsym, Details.SUMMARY); printObject("constValue", type.constValue(), Details.SUMMARY); printObject("annotations", type.getAnnotationMirrors(), Details.SUMMARY); type.accept(typeVisitor, null); indent(-1); } } } protected String toString(Type type) { return (printer != null) ? printer.visit(type, locale) : String.valueOf(type); } protected String hashString(Object obj) { return String.format("#%x", obj.hashCode()); } protected String info(Class<?> clazz, Object internal, Object external) { return String.format("%s,%s,%s", clazz.getSimpleName(), internal, external); } private int indent = 0; protected void indent() { for (int i = 0; i < indent; i++) { out.print(" "); } } protected void indent(int n) { indent += n; } protected Object getField(Object o, Class<?> clazz, String name) { try { Field f = clazz.getDeclaredField(name); boolean prev = f.isAccessible(); f.setAccessible(true); try { return f.get(o); } finally { f.setAccessible(prev); } } catch (ReflectiveOperationException e) { return e; } catch (SecurityException e) { return e; } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="JCTree visitor methods"> protected JCTree.Visitor treeVisitor = new TreeVisitor(); /** * Default visitor class for JCTree (AST) objects. */ public class TreeVisitor extends JCTree.Visitor { @Override public void visitTopLevel(JCCompilationUnit tree) { printList("packageAnnotations", tree.packageAnnotations); printTree("pid", tree.pid); printList("defs", tree.defs); } @Override public void visitImport(JCImport tree) { printTree("qualid", tree.qualid); } @Override public void visitClassDef(JCClassDecl tree) { printName("name", tree.name); printTree("mods", tree.mods); printList("typarams", tree.typarams); printTree("extending", tree.extending); printList("implementing", tree.implementing); printList("defs", tree.defs); } @Override public void visitMethodDef(JCMethodDecl tree) { printName("name", tree.name); printTree("mods", tree.mods); printTree("restype", tree.restype); printList("typarams", tree.typarams); printTree("recvparam", tree.recvparam); printList("params", tree.params); printList("thrown", tree.thrown); printTree("defaultValue", tree.defaultValue); printTree("body", tree.body); } @Override public void visitVarDef(JCVariableDecl tree) { printName("name", tree.name); printTree("mods", tree.mods); printTree("vartype", tree.vartype); printTree("init", tree.init); } @Override public void visitSkip(JCSkip tree) { } @Override public void visitBlock(JCBlock tree) { printList("stats", tree.stats); } @Override public void visitDoLoop(JCDoWhileLoop tree) { printTree("body", tree.body); printTree("cond", tree.cond); } @Override public void visitWhileLoop(JCWhileLoop tree) { printTree("cond", tree.cond); printTree("body", tree.body); } @Override public void visitForLoop(JCForLoop tree) { printList("init", tree.init); printTree("cond", tree.cond); printList("step", tree.step); printTree("body", tree.body); } @Override public void visitForeachLoop(JCEnhancedForLoop tree) { printTree("var", tree.var); printTree("expr", tree.expr); printTree("body", tree.body); } @Override public void visitLabelled(JCLabeledStatement tree) { printTree("body", tree.body); } @Override public void visitSwitch(JCSwitch tree) { printTree("selector", tree.selector); printList("cases", tree.cases); } @Override public void visitCase(JCCase tree) { printTree("pat", tree.pat); printList("stats", tree.stats); } @Override public void visitSynchronized(JCSynchronized tree) { printTree("lock", tree.lock); printTree("body", tree.body); } @Override public void visitTry(JCTry tree) { printList("resources", tree.resources); printTree("body", tree.body); printList("catchers", tree.catchers); printTree("finalizer", tree.finalizer); } @Override public void visitCatch(JCCatch tree) { printTree("param", tree.param); printTree("body", tree.body); } @Override public void visitConditional(JCConditional tree) { printTree("cond", tree.cond); printTree("truepart", tree.truepart); printTree("falsepart", tree.falsepart); } @Override public void visitIf(JCIf tree) { printTree("cond", tree.cond); printTree("thenpart", tree.thenpart); printTree("elsepart", tree.elsepart); } @Override public void visitExec(JCExpressionStatement tree) { printTree("expr", tree.expr); } @Override public void visitBreak(JCBreak tree) { printName("label", tree.label); } @Override public void visitContinue(JCContinue tree) { printName("label", tree.label); } @Override public void visitReturn(JCReturn tree) { printTree("expr", tree.expr); } @Override public void visitThrow(JCThrow tree) { printTree("expr", tree.expr); } @Override public void visitAssert(JCAssert tree) { printTree("cond", tree.cond); printTree("detail", tree.detail); } @Override public void visitApply(JCMethodInvocation tree) { printList("typeargs", tree.typeargs); printTree("meth", tree.meth); printList("args", tree.args); } @Override public void visitNewClass(JCNewClass tree) { printTree("encl", tree.encl); printList("typeargs", tree.typeargs); printTree("clazz", tree.clazz); printList("args", tree.args); printTree("def", tree.def); } @Override public void visitNewArray(JCNewArray tree) { printList("annotations", tree.annotations); printTree("elemtype", tree.elemtype); printList("dims", tree.dims); printList("dimAnnotations", tree.dimAnnotations); printList("elems", tree.elems); } @Override public void visitLambda(JCLambda tree) { printTree("body", tree.body); printList("params", tree.params); } @Override public void visitParens(JCParens tree) { printTree("expr", tree.expr); } @Override public void visitAssign(JCAssign tree) { printTree("lhs", tree.lhs); printTree("rhs", tree.rhs); } @Override public void visitAssignop(JCAssignOp tree) { printTree("lhs", tree.lhs); printTree("rhs", tree.rhs); } @Override public void visitUnary(JCUnary tree) { printTree("arg", tree.arg); } @Override public void visitBinary(JCBinary tree) { printTree("lhs", tree.lhs); printTree("rhs", tree.rhs); } @Override public void visitTypeCast(JCTypeCast tree) { printTree("clazz", tree.clazz); printTree("expr", tree.expr); } @Override public void visitTypeTest(JCInstanceOf tree) { printTree("expr", tree.expr); printTree("clazz", tree.clazz); } @Override public void visitIndexed(JCArrayAccess tree) { printTree("indexed", tree.indexed); printTree("index", tree.index); } @Override public void visitSelect(JCFieldAccess tree) { printTree("selected", tree.selected); } @Override public void visitReference(JCMemberReference tree) { printTree("expr", tree.expr); printList("typeargs", tree.typeargs); } @Override public void visitIdent(JCIdent tree) { printName("name", tree.name); } @Override public void visitLiteral(JCLiteral tree) { printString("value", Pretty.toSimpleString(tree, 32)); } @Override public void visitTypeIdent(JCPrimitiveTypeTree tree) { printString("typetag", tree.typetag.name()); } @Override public void visitTypeArray(JCArrayTypeTree tree) { printTree("elemtype", tree.elemtype); } @Override public void visitTypeApply(JCTypeApply tree) { printTree("clazz", tree.clazz); printList("arguments", tree.arguments); } @Override public void visitTypeUnion(JCTypeUnion tree) { printList("alternatives", tree.alternatives); } @Override public void visitTypeIntersection(JCTypeIntersection tree) { printList("bounds", tree.bounds); } @Override public void visitTypeParameter(JCTypeParameter tree) { printName("name", tree.name); printList("annotations", tree.annotations); printList("bounds", tree.bounds); } @Override public void visitWildcard(JCWildcard tree) { printTree("kind", tree.kind); printTree("inner", tree.inner); } @Override public void visitTypeBoundKind(TypeBoundKind tree) { printString("kind", tree.kind.name()); } @Override public void visitModifiers(JCModifiers tree) { printList("annotations", tree.annotations); printString("flags", String.valueOf(Flags.asFlagSet(tree.flags))); } @Override public void visitAnnotation(JCAnnotation tree) { printTree("annotationType", tree.annotationType); printList("args", tree.args); } @Override public void visitAnnotatedType(JCAnnotatedType tree) { printList("annotations", tree.annotations); printTree("underlyingType", tree.underlyingType); } @Override public void visitErroneous(JCErroneous tree) { printList("errs", tree.errs); } @Override public void visitLetExpr(LetExpr tree) { printList("defs", tree.defs); printTree("expr", tree.expr); } @Override public void visitTree(JCTree tree) { Assert.error(); } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Symbol visitor"> protected Symbol.Visitor<Void,Void> symVisitor = new SymbolVisitor(); /** * Default visitor class for Symbol objects. * Note: each visitXYZ method ends by calling the corresponding * visit method for its superclass. */ class SymbolVisitor implements Symbol.Visitor<Void,Void> { @Override public Void visitClassSymbol(ClassSymbol sym, Void ignore) { printName("fullname", sym.fullname); printName("flatname", sym.flatname); printScope("members", sym.members_field); printFileObject("sourcefile", sym.sourcefile); printFileObject("classfile", sym.classfile); // trans-local? // pool? return visitTypeSymbol(sym, null); } @Override public Void visitMethodSymbol(MethodSymbol sym, Void ignore) { // code printList("params", sym.params); printList("savedParameterNames", sym.savedParameterNames); return visitSymbol(sym, null); } @Override public Void visitPackageSymbol(PackageSymbol sym, Void ignore) { printName("fullname", sym.fullname); printScope("members", sym.members_field); printSymbol("package-info", sym.package_info, Details.SUMMARY); return visitTypeSymbol(sym, null); } @Override public Void visitOperatorSymbol(OperatorSymbol sym, Void ignore) { printInt("opcode", sym.opcode); return visitMethodSymbol(sym, null); } @Override public Void visitVarSymbol(VarSymbol sym, Void ignore) { printInt("pos", sym.pos); printInt("adm", sym.adr); // data is a private field, and the standard accessors may // mutate it as part of lazy evaluation. Therefore, use // reflection to get the raw data. printObject("data", getField(sym, VarSymbol.class, "data"), Details.SUMMARY); return visitSymbol(sym, null); } @Override public Void visitTypeSymbol(TypeSymbol sym, Void ignore) { return visitSymbol(sym, null); } @Override public Void visitSymbol(Symbol sym, Void ignore) { return null; } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Type visitor"> protected Type.Visitor<Void,Void> typeVisitor = new TypeVisitor(); /** * Default visitor class for Type objects. * Note: each visitXYZ method ends by calling the corresponding * visit method for its superclass. */ public class TypeVisitor implements Type.Visitor<Void,Void> { public Void visitAnnotatedType(AnnotatedType type, Void ignore) { printList("typeAnnotations", type.getAnnotationMirrors()); printType("underlyingType", type.unannotatedType(), Details.FULL); return visitType(type, null); } public Void visitArrayType(ArrayType type, Void ignore) { printType("elemType", type.elemtype, Details.FULL); return visitType(type, null); } public Void visitCapturedType(CapturedType type, Void ignore) { printType("wildcard", type.wildcard, Details.FULL); return visitTypeVar(type, null); } public Void visitClassType(ClassType type, Void ignore) { printType("outer", type.getEnclosingType(), Details.SUMMARY); printList("typarams", type.typarams_field); printList("allparams", type.allparams_field); printType("supertype", type.supertype_field, Details.SUMMARY); printList("interfaces", type.interfaces_field); printList("allinterfaces", type.all_interfaces_field); return visitType(type, null); } public Void visitErrorType(ErrorType type, Void ignore) { printType("originalType", type.getOriginalType(), Details.FULL); return visitClassType(type, null); } public Void visitForAll(ForAll type, Void ignore) { printList("tvars", type.tvars); return visitDelegatedType(type); } public Void visitMethodType(MethodType type, Void ignore) { printList("argtypes", type.argtypes); printType("restype", type.restype, Details.FULL); printList("thrown", type.thrown); return visitType(type, null); } public Void visitPackageType(PackageType type, Void ignore) { return visitType(type, null); } public Void visitTypeVar(TypeVar type, Void ignore) { // For TypeVars (and not subtypes), the bound should always be // null or bot. So, only print the bound for subtypes of TypeVar, // or if the bound is (erroneously) not null or bot. if (!type.hasTag(TypeTag.TYPEVAR) || !(type.bound == null || type.bound.hasTag(TypeTag.BOT))) { printType("bound", type.bound, Details.FULL); } printType("lower", type.lower, Details.FULL); return visitType(type, null); } public Void visitUndetVar(UndetVar type, Void ignore) { for (UndetVar.InferenceBound ib: UndetVar.InferenceBound.values()) printList("bounds." + ib, type.getBounds(ib)); printInt("declaredCount", type.declaredCount); printType("inst", type.inst, Details.SUMMARY); return visitDelegatedType(type); } public Void visitWildcardType(WildcardType type, Void ignore) { printType("type", type.type, Details.SUMMARY); printString("kind", type.kind.name()); printType("bound", type.bound, Details.SUMMARY); return visitType(type, null); } protected Void visitDelegatedType(DelegatedType type) { printType("qtype", type.qtype, Details.FULL); return visitType(type, null); } public Void visitType(Type type, Void ignore) { return null; } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Attribute (annotations) visitor"> protected Attribute.Visitor attrVisitor = new AttributeVisitor(); /** * Default visitor class for Attribute (annotation) objects. */ public class AttributeVisitor implements Attribute.Visitor { public void visitConstant(Attribute.Constant a) { printObject("value", a.value, Details.SUMMARY); visitAttribute(a); } public void visitClass(Attribute.Class a) { printObject("classType", a.classType, Details.SUMMARY); visitAttribute(a); } public void visitCompound(Attribute.Compound a) { if (a instanceof Attribute.TypeCompound) { Attribute.TypeCompound ta = (Attribute.TypeCompound) a; // consider a custom printer? printObject("position", ta.position, Details.SUMMARY); } printObject("synthesized", a.isSynthesized(), Details.SUMMARY); printList("values", a.values); visitAttribute(a); } public void visitArray(Attribute.Array a) { printList("values", Arrays.asList(a.values)); visitAttribute(a); } public void visitEnum(Attribute.Enum a) { printSymbol("value", a.value, Details.SUMMARY); visitAttribute(a); } public void visitError(Attribute.Error a) { visitAttribute(a); } public void visitAttribute(Attribute a) { printType("type", a.type, Details.SUMMARY); } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc="Utility front end"> /** * Utility class to invoke DPrinter from the command line. */ static class Main { public static void main(String... args) throws IOException { Main m = new Main(); PrintWriter out = new PrintWriter(System.out); try { if (args.length == 0) m.usage(out); else m.run(out, args); } finally { out.flush(); } } void usage(PrintWriter out) { out.println("Usage:"); out.println(" java " + Main.class.getName() + " mode [options] [javac-options]"); out.print("where mode is one of: "); String sep = ""; for (Handler h: getHandlers().values()) { out.print(sep); out.print(h.name); sep = ", "; } out.println(); out.println("and where options include:"); out.println(" -before PARSE|ENTER|ANALYZE|GENERATE|ANNOTATION_PROCESSING|ANNOTATION_PROCESSING_ROUND"); out.println(" -after PARSE|ENTER|ANALYZE|GENERATE|ANNOTATION_PROCESSING|ANNOTATION_PROCESSING_ROUND"); out.println(" -showPositions"); out.println(" -showSource"); out.println(" -showTreeSymbols"); out.println(" -showTreeTypes"); out.println(" -hideEmptyItems"); out.println(" -hideNulls"); } void run(PrintWriter out, String... args) throws IOException { JavaCompiler c = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); // DPrinter options final Set<TaskEvent.Kind> before = EnumSet.noneOf(TaskEvent.Kind.class); final Set<TaskEvent.Kind> after = EnumSet.noneOf(TaskEvent.Kind.class); boolean showPositions = false; boolean showSource = false; boolean showTreeSymbols = false; boolean showTreeTypes = false; boolean showEmptyItems = true; boolean showNulls = true; // javac options Collection<String> options = new ArrayList Other Java examples (source code examples)Here is a short list of links related to this Java DPrinter.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.