javac的访问者模式
这一篇重点来总结下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的访问者模式的更多相关文章
- javac的访问者模式2
(5)Printer /** * A combined type/symbol visitor for generating non-trivial(有意义的) localized string * ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- 访问者模式(visitorpattern)
/** * 访问者模式 * @author TMAC-J * 在客户端和元素之间添加一个访问者 * 当你需要添加一些和元素关系不大的需求时,可以直接放在访问者里面 * 或者是元素之间有一些公共的代码块 ...
- C#设计模式-访问者模式
一. 访问者(Vistor)模式 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结 ...
- C#设计模式系列:访问者模式(Visitor)
1.访问者模式简介 1.1>.定义 作用于某个对象群中各个对象的操作,可以使在不改变对象本身的情况下,定义作用于对象的新操作. 1.2>.使用频率 低 2.访问者模式结构 2.1> ...
- php实现设计模式之 访问者模式
<?php /** * 访问者模式 * 封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. * 行为类模式 */ /** 抽象访问者:抽象类或 ...
- 十一个行为模式之访问者模式(Visitor Pattern)
定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...
- 访问者模式(Visitor Pattern)
定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. Visitor 抽象访问者角色:为该对象结构中具体元素角色声明一个访问操作接口.该操作接口 ...
- JAVA 设计模式 访问者模式
用途 访问者模式 (Visitor) 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式是一种行为型模式. 用途
随机推荐
- Task的运行原理和工作窃取(work stealing)
在net4.0以前,当调用ThreadPool.QueueUserWorkItem方法往线程池中插入作业时,会把作业内容(其实就是一个委托)放到线程池中的一个全局队列中,然后线程池中的线程按照先进先出 ...
- 更改mysql默认字符集 (转载)
1. service mysqld stop,停用mysql. 2. cp /etc/my.cnf /etc/my.cnf.bak,修改前做备份,这是个好习惯. 修改my.cnfvi /etc/my. ...
- [Oracle]Oracle数据库数据被修改或者删除恢复数据
1.SELECT * FROM CT_FIN_RiskItem--先查询表,确定数据的确不对(cfstatus第一行缺少)2.select * from CT_FIN_RiskItem as of t ...
- .NetCore分布式部署中的DataProtection密钥安全性
在.NetCore中默认使用DataProtection来保护数据,例如Cooike等.一般情况下DataProtection生成的密钥会被加密后存储,例如默认的文件存储 可以看到使用了Windows ...
- Mysql 优化与测试
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 以下的测试数据根据环境的不同所耗费的时间有所不同,例如我在腾讯云上的测试 ...
- centos7安装nginx(自定义安装文件夹)
一.安装所需要的依赖软件 1.gcc:nginx编译依赖gcc环境 #yum install gcc-c++ 2.pcre:(Perl Compatible Regular Expressions)是 ...
- spring利用注解方式实现Java读取properties属性值
1. 建立properties文件:我在resource下面建立一个config文件夹,config文件夹里面有mytest.properties文件,文件内容如下: sam.username=sam ...
- [arc079f] Namori Grundy 分类讨论
Description 给给全有一个NN个点NN条边的有向图,点的的编号从11到NN 给给全的图有NN条边,形如:(p1,1),(p2,2),...,(pN,N)(p1,1),(p2,2),...,( ...
- LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)
题面 传送门 题解 首先先把所有权值取个相反数来求最大收益,因为最小收益很奇怪 然后建图如下:\(S\to\)药,容量\(\inf+p_i\),药\(\to\)药材,容量\(\inf\),药材\(\t ...
- Jquery选择器 选择一个不存在的元素 为什么不会返回 false
不管找没找到,$()函数都会返回一个jquery对象,这个jquery对象有个length属性,表示找到多少个匹配的DOM元素,为0就是没找到.