这一篇重点来总结下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()方法都有实现。

  

javac的访问者模式的更多相关文章

  1. javac的访问者模式2

    (5)Printer /** * A combined type/symbol visitor for generating non-trivial(有意义的) localized string * ...

  2. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  3. 访问者模式(visitorpattern)

    /** * 访问者模式 * @author TMAC-J * 在客户端和元素之间添加一个访问者 * 当你需要添加一些和元素关系不大的需求时,可以直接放在访问者里面 * 或者是元素之间有一些公共的代码块 ...

  4. C#设计模式-访问者模式

    一. 访问者(Vistor)模式 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结 ...

  5. C#设计模式系列:访问者模式(Visitor)

    1.访问者模式简介 1.1>.定义 作用于某个对象群中各个对象的操作,可以使在不改变对象本身的情况下,定义作用于对象的新操作. 1.2>.使用频率   低 2.访问者模式结构 2.1> ...

  6. php实现设计模式之 访问者模式

    <?php /** * 访问者模式 * 封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. * 行为类模式 */ /** 抽象访问者:抽象类或 ...

  7. 十一个行为模式之访问者模式(Visitor Pattern)

    定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...

  8. 访问者模式(Visitor Pattern)

    定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. Visitor 抽象访问者角色:为该对象结构中具体元素角色声明一个访问操作接口.该操作接口 ...

  9. JAVA 设计模式 访问者模式

    用途 访问者模式 (Visitor) 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式是一种行为型模式. 用途

随机推荐

  1. VC 调试技术与异常(错误)处理 VC 调试技术与异常(错误)处理

    调试技术与异常(错误)处理 (1)   转载自 52PK游戏论坛 跟踪与中间过程输出 也许一个开发人员一半以上的时间都是在面对错误,所以好的调试/查错方法(工具)会减轻我们工作的负担,也可以让枯燥的D ...

  2. Oracle E-Business Suite R12.2的新技术特点

    Oracle公司的系统研发开发与执行效率,让人不得不佩服.从2008年1月收购BEA到现在短短几年时间,就把Bea WebLogic产品融合到了Oracle公司自己的原研发产品之庞大的Oracle E ...

  3. java写入换行符

    写入一个文件,生成文本文档,里面写入1000行字符,但是写出来的没有换行.所以纠结,百度了下,一行完事. String crlf=System.getProperty("line.separ ...

  4. openstack kolla 部署---不同的节点采用不同的物理接口

    在 /etc/kolla/globals.yml 文件中删除 neutron_external_interface  tunnel_interface  api_interface  storage_ ...

  5. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)

    题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...

  7. spring-mybatis源码追踪

    启用一个扫描类 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propert ...

  8. PHP开始1 php的命名规范

    常量 php 中有一些预定义常量,我们常常称他们为'魔术常量'. __LINE__          返回文件中的当前行号 __FILE__           返回该文件的完整路径和文件名 __DI ...

  9. rpm小结

    包括安装.卸载.升级.查询.校验.数据库维护     一. 安装: 常用方法:rpm -ivh 包名 ,其中“i”表示安装, "v"表示显示安装过程,“h"表示以#显示程 ...

  10. vue二级路由跳转后外部引入js失效问题解决方案

    vue路由可以通过children嵌套,于是可以形成二级路由等等... 案例如下: routes: [ { path: '/', name: 'dy', component: dy, children ...