这一篇重点来总结下javac的访问者模式,其定义的访问者接口为JCTree.Visitor,具体如下:
/** A generic visitor class for trees. */ public static abstract class Visitor { public void visitTopLevel(JCCompilationUnit that) { visitTree(that); } public void visitImport(JCImport that) { visitTree(that); } public void visitClassDefinition(JCClassDeclaration that) { visitTree(that); } public void visitMethodDefinition(JCMethodDeclaration that) { visitTree(that); } public void visitVariableDefinition(JCVariableDeclaration that) { visitTree(that); } public void visitSkip(JCSkip that) { visitTree(that); } public void visitBlock(JCBlock that) { visitTree(that); } public void visitDoLoop(JCDoWhileLoop that) { visitTree(that); } public void visitWhileLoop(JCWhileLoop that) { visitTree(that); } public void visitForLoop(JCForLoop that) { visitTree(that); } public void visitForeachLoop(JCEnhancedForLoop that) { visitTree(that); } public void visitLabelled(JCLabeledStatement that) { visitTree(that); } public void visitSwitch(JCSwitch that) { visitTree(that); } public void visitCase(JCCase that) { visitTree(that); } public void visitSynchronized(JCSynchronized that) { visitTree(that); } public void visitTry(JCTry that) { visitTree(that); } public void visitCatch(JCCatch that) { visitTree(that); } public void visitConditional(JCConditional that) { visitTree(that); } public void visitIf(JCIf that) { visitTree(that); } public void visitExec(JCExpressionStatement that) { visitTree(that); } public void visitBreak(JCBreak that) { visitTree(that); } public void visitContinue(JCContinue that) { visitTree(that); } public void visitReturn(JCReturn that) { visitTree(that); } public void visitThrow(JCThrow that) { visitTree(that); } public void visitAssert(JCAssert that) { visitTree(that); } public void visitApply(JCMethodInvocation that) { visitTree(that); } public void visitNewClass(JCNewClass that) { visitTree(that); } public void visitNewArray(JCNewArray that) { visitTree(that); } public void visitParenthesis(JCParenthesis that) { visitTree(that); } public void visitAssign(JCAssignment that) { visitTree(that); } public void visitAssignOperator(JCAssignOperator that) { visitTree(that); } public void visitUnary(JCUnary that) { visitTree(that); } public void visitBinary(JCBinary that) { visitTree(that); } public void visitTypeCast(JCTypeCast that) { visitTree(that); } public void visitTypeTest(JCInstanceOf that) { visitTree(that); } public void visitIndexed(JCArrayAccess that) { visitTree(that); } public void visitSelect(JCFieldAccess that) { visitTree(that); } public void visitIdentifier(JCIdentifier that) { visitTree(that); } public void visitLiteral(JCLiteral that) { visitTree(that); } public void visitTypeIdentifier(JCPrimitiveTypeTree that) { visitTree(that); } public void visitTypeArray(JCArrayTypeTree that) { visitTree(that); } public void visitTypeApply(JCTypeApply that) { visitTree(that); } public void visitTypeUnion(JCTypeUnion that) { visitTree(that); } public void visitTypeParameter(JCTypeParameter that) { visitTree(that); } public void visitWildcard(JCWildcard that) { visitTree(that); } public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); } public void visitAnnotation(JCAnnotation that) { visitTree(that); } public void visitModifiers(JCModifiers that) { visitTree(that); } public void visitErroneous(JCErroneous that) { visitTree(that); } public void visitLetExpr(LetExpression that) { visitTree(that); } public void visitTree(JCTree that) { Assert.error(); } }
在从Java源代码生成class类的过程中,主要经历的过程
其中实现这个接口的类有:
(1)Enter
visitTree(JCTree)方法是一个空实现,说明了Enter类只处理JCCompilationUnit,JCClassDeclaration和TypeParameter语法节点。
(2)MemberEnter
visitTree(JCTree)方法同样是一个空实现 ,主要处理的语法节点为JCCompilationUnit,JCImport,JCMethodDeclaration与JCVariableDeclaration语法节点。
(3)Attr
在Attr中开始对各个语法节点进行了标记。
(4)TreeScanner(Flow继承实现了 TreeScanner)
这个类就是对各个语法节点进行简单的遍历实现,遍历某个语法节点下的方法如下:
/** Visitor method: Scan a single node. */ public void scan(JCTree tree) { if(tree!=null){ tree.accept(this); } } /** Visitor method: scan a list of nodes. */ public void scan(List<? extends JCTree> trees) { if (trees != null){ for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail){ scan(l.head); } } }
继承这个类进行实现的一些类主要有Flow,还有一些内部类和匿名类。
(5)TreeTranslator
直接继承了这个类的有
1、TranslateTypes This pass translates Generic Java to conventional Java
2、Lower This pass translates away some syntactic sugar: inner classes,class literals, assertions, foreach loops, etc.
主要的实现如下:
public class TreeTranslator extends JCTree.Visitor { /** Visitor result field: a tree */ protected JCTree result; /** Visitor method: Translate a single node. */ @SuppressWarnings("unchecked") public <T extends JCTree> T translate(T tree) { if (tree == null) { return null; } else { tree.accept(this); JCTree result = this.result; this.result = null; return (T)result; // XXX cast } } /** Visitor method: translate a list of nodes. */ public <T extends JCTree> List<T> translate(List<T> trees) { if (trees == null){ return null; } for (List<T> l = trees; l.nonEmpty(); l = l.tail) { l.head = translate(l.head); } return trees; } /** Visitor method: translate a list of variable definitions. */ public List<JCVariableDeclaration> translateVarDefs(List<JCVariableDeclaration> trees) { for (List<JCVariableDeclaration> l = trees; l.nonEmpty(); l = l.tail) l.head = translate(l.head); return trees; } /** Visitor method: translate a list of type parameters. */ public List<JCTypeParameter> translateTypeParams(List<JCTypeParameter> trees) { for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail) l.head = translate(l.head); return trees; } /** Visitor method: translate a list of case parts of switch statements. */ public List<JCCase> translateCases(List<JCCase> trees) { for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail) l.head = translate(l.head); return trees; } /** Visitor method: translate a list of catch clauses in try statements. */ public List<JCCatch> translateCatchers(List<JCCatch> trees) { for (List<JCCatch> l = trees; l.nonEmpty(); l = l.tail) l.head = translate(l.head); return trees; } /** Visitor method: translate a list of catch clauses in try statements. */ public List<JCAnnotation> translateAnnotations(List<JCAnnotation> trees) { for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) l.head = translate(l.head); return trees; } // Visitor Method省略 }
(6)Gen
生成最终的class类时需要访问的一些语法节点。
(7)Type.Visitor<R, S>, Symbol.Visitor<String, Locale>
类型Type中定义的访问者模式:
/** * A visitor for types. A visitor is used to implement operations * (or relations) on types. Most common operations on types are * binary relations and this interface is designed for binary * relations, that is, operations on the form * Type × S → R. * <!-- In plain text: Type x S -> R --> * * @param <R> the return type of the operation implemented by this * visitor; use Void if no return type is needed. * @param <S> the type of the second argument (the first being the * type itself) of the operation implemented by this visitor; use * Void if a second argument is not needed. */ public interface Visitor<R,S> { R visitClassType(ClassType t, S s); R visitWildcardType(WildcardType t, S s); R visitArrayType(ArrayType t, S s); R visitMethodType(MethodType t, S s); R visitPackageType(PackageType t, S s); R visitTypeVar(TypeVar t, S s); R visitCapturedType(CapturedType t, S s); R visitForAll(ForAll t, S s); R visitUndeterminedVar(UndeterminedVar t, S s); R visitErrorType(ErrorType t, S s); R visitType(Type t, S s); }
符号类中定义的访问者模式接口如下:
/** * A visitor for symbols. A visitor is used to implement operations * (or relations) on symbols. Most common operations on types are * binary relations and this interface is designed for binary * relations, that is, operations on the form * Symbol × P → R. * <!-- In plain text: Type x P -> R --> * * @param <R> the return type of the operation implemented by this * visitor; use Void if no return type is needed. * @param <P> the type of the second argument (the first being the * symbol itself) of the operation implemented by this visitor; use * Void if a second argument is not needed. */ public interface Visitor<R,P> { R visitClassSymbol(ClassSymbol s, P arg); R visitMethodSymbol(MethodSymbol s, P arg); R visitPackageSymbol(PackageSymbol s, P arg); R visitOperatorSymbol(OperatorSymbol s, P arg); R visitVarSymbol(VarSymbol s, P arg); R visitTypeSymbol(TypeSymbol s, P arg); R visitSymbol(Symbol s, P arg); }
(8)TreePretty
剩下的(5)和(6)对定义出的visitorXXX()方法都有实现。