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) 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式是一种行为型模式. 用途
随机推荐
- 企业搜索引擎开发之连接器connector(二十五)
下面开始具体分析连接器是怎么与连接器实例交互的,这里主要是分析连接器怎么从连接器实例获取数据的(前面文章有涉及基于http协议与连接器的xml格式的交互,连接器对连接器实例的设置都是通过配置文件操作的 ...
- 编译语言 vs 解释语言
编译语言 vs 解释语言 阅读: 评论: 作者:Rybby 日期: 来源:rybby.com 一直以为,编译语言的性能绝对比解释语言快,因为就理论而言,解释语言要一边解释(将脚本语言翻译成计算 ...
- 关于数组以及c#学习问题
第二次作业我没注意看群通告,看到都3月8号,开始着手想用c#试着写写,才发现一些问题. a.鞠老的要求中必须原数据需要csv文件,csv文件不是太了解,网上简单查阅了一下------csv意思是逗号分 ...
- TSQL--NULL值和三值逻辑
在SQL SERVER 中逻辑表达式存在三种值:TRUE+FALSE+UNKNOWN.UNKNOW可以理解为不确定,既不是TRUE又不是FALSE的表达式,主要由与NULL相关的逻辑判断引起,值为NU ...
- 使用testNGListenter来自定义日志
背景 用testNG写用例的时候,只是打印了请求的日志,没有打印这个用例的开始和结束的标识,想加上这个标识这样更好的排查问题 这种日志是加在用例开始执行和结束,相当于spring中的AOP功能,今天翻 ...
- ASP.NET 常用的字符串加密
字符串常用的加密有三种 1.MD5加密,这个常用于密码,单向加密,不可解密,有些在线解密的可以解大部份,用代码不能实现,如果不想让人解密,加密后随便截取一段就好了: 2.Base64位加密,通常加密后 ...
- UWP开发入门(一)——SplitView
接下来会写一个UWP(Universal Windows Platform)开发入门的系列,自己学习到哪里,有什么心得总结,就会写到哪里.本篇对适用于顶层导航的SplitView控件展开讨论. 首先S ...
- 有效单词词广场——算法面试刷题5(for google),考察数学
给定一个单词序列,检查它是否构成一个有效单词广场.一个有效的单词广场应满足以下条件:对于满足0≤k<max(numRows numColumns)的k,第k行和第k列对应的字符串应该相同,. 给 ...
- 2018-2019 20165219 网络对抗 Exp5 MSF基础
实验内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 1.1一个主动攻击实践,如ms08_067; (1分) 1.2 一个针对浏览器的攻击,如ms ...
- “全栈2019”Java多线程第十四章:线程与堆栈详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...