当进行完MemberEnter后就可以调用Attr类的一些标记方法了,如下:

while (!todo.isEmpty()){Environment<AttrContext> a = todo.remove();Environment<AttrContext> b = attribute(a);  // 标注Queue<Environment<AttrContext>> c = flow(b); // 数据流分析Queue<Pair<Environment<AttrContext>, JCClassDeclaration>> d = desugar(c); // 解语法糖generate(d);  // 生成字节码
//                        generate(desugar(flow(attribute(todo.remove()))));
}

在之前的MemberEnter类中visitImport()方法中有如下一个方法调用,如下:

 Type type = attr.attribTree(jcFieldAccess.selected, localEnvironment, protoKind, Type.noType); // protoKind=_TYPE|_PCK,Type.noType=JCNoType

其中JCFieldAccess为java.util.ArrayList,而jcFieldAccess.selected为java.util。  

其中的scope为ImportScope。

在标识前,所有的selected的symbol与type都为null。先要进行JCIdentifier的处理,主要经历的方法有三个:

首先visitIdentifier(),在这个方法中调用resolveIdentifier()方法,接着也会调用checkIndentifier()方法。

resolveIdentifier()中会调用findIdentifier()方法查找到name对应的符号Symbol,这个方法的具体代码实现如下:

 /** Find an unqualified identifier which matches a specified kind set.*  @param environment       The current environment.*  @param name      The identifier's name.*  @param kind      Indicates the possible symbol kinds (a subset of _VAL, _TYP, _PCK).**/public Symbol findIdentifier(Environment<AttrContext> environment, Name name, int kind) {Symbol bestSoFar = typeNotFound;Symbol symbol;if ((kind & _VAR) != 0) {symbol = findVariable(environment, name);if (symbol.exists()){return symbol;}else if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}if ((kind & _TYP) != 0) {symbol = findType(environment, name);if (symbol.exists()){return symbol;}else if (symbol.kind < bestSoFar.kind){ // ??bestSoFar = symbol;}}if ((kind & _PCK) != 0){return classReader.enterPackage(name);}else{return bestSoFar;}}

name除了代表方法的名称外,其余就是变量、类型和包名称了。优先进行变量名的查找,由于变量名有局部变量和全局变量,所以对应的查找方法就有findVariable()与findField()。

其中findVariable()方法如下:

/** Find unqualified variable or field with given name.*  Synthetic fields always skipped.*  @param environment     The current environment.*  @param name    The name of the variable or field.*/Symbol findVariable(Environment<AttrContext> environment, Name name) {Symbol bestSoFar = variableNotFound;Symbol symbol;Environment<AttrContext> env1 = environment;boolean staticOnly = false;while (env1.outer != null) {if (isStatic(env1)){staticOnly = true;}Entry entry = env1.info.scope.lookup(name);while (entry.scope != null &&(entry.symbol.kind != _VAR || (entry.symbol.flags_field & SYNTHETIC) != 0) // 非变量或者是合成的那就需要继续查找){entry = entry.next();}// 走到这里说明entry.symbol.kind==_VAR或者(entry.symbol.flags_field & SYNTHETIC)==0(非合成的变量)// 如果findVariable查找不到就要调用findField进行查找if(entry.scope != null){symbol = entry.symbol;}else{symbol = findField(env1, env1.enclosingClass.classSymbol.type, name, env1.enclosingClass.classSymbol);}if( symbol.exists()) {if( staticOnly &&symbol.kind == _VAR &&symbol.ownerSymbol.kind == _TYP &&(symbol.flags() & STATIC) == 0) {// 静态上下文中引用非静态的变量return new StaticError(symbol, this);}else{return symbol;}} else if (symbol.kind < bestSoFar.kind) {bestSoFar = symbol;}if ((env1.enclosingClass.classSymbol.flags() & STATIC) != 0){staticOnly = true;}env1 = env1.outer;}// end whilesymbol = findField(environment, symbolTable.predefinedClass.type, name, symbolTable.predefinedClass);if (symbol.exists()){return symbol;}if (bestSoFar.exists()){return bestSoFar;}Entry entry = environment.toplevel.namedImportScope.lookup(name);for (; entry.scope != null; entry = entry.next()) {symbol = entry.symbol;Type origin = entry.getOrigin().owner.type;if (symbol.kind == _VAR) {if (entry.symbol.ownerSymbol.type != origin){symbol = symbol.clone(entry.getOrigin().owner);}if(isAccessible(environment, origin, symbol)){return symbol;}else{return new AccessError(environment, origin, symbol, this);}}}Symbol origin = null;entry = environment.toplevel.starImportScope.lookup(name);for (; entry.scope != null; entry = entry.next()) {symbol = entry.symbol;if (symbol.kind != _VAR){continue;}// invariant: classSymbol.kind == _VARif (bestSoFar.kind < _AMBIGUOUS && symbol.ownerSymbol != bestSoFar.ownerSymbol){return new AmbiguityError(bestSoFar, symbol, this);}else if (bestSoFar.kind >= _VAR) {origin = entry.getOrigin().owner;if(isAccessible(environment, origin.type, symbol)){bestSoFar = symbol;}else{bestSoFar = new AccessError(environment, origin.type, symbol, this);}}}// ???if (bestSoFar.kind == _VAR && bestSoFar.ownerSymbol.type != origin.type){return bestSoFar.clone(origin);}else{return bestSoFar;}}

而findField()方法的代码如下:

/** Find field. Synthetic fields are always skipped.*  @param environment The current environment.*  @param site    The original type from where the selection takes place.*  @param name    The name of the field.*  @param typeSymbol The class to search for the field. This is always a superclass or implemented interface of site's class.*/Symbol findField(Environment<AttrContext> environment,Type site,Name name,TypeSymbol typeSymbol) {while (typeSymbol.type.typeTag == TYPEVARIABLE){typeSymbol = typeSymbol.type.getUpperBound().typeSymbol;}Symbol bestSoFar = variableNotFound;Symbol symbol;// 查找本类Entry entry = typeSymbol.members().lookup(name);while (entry.scope != null) {// 符号是变量且不是合成的if (entry.symbol.kind == _VAR && (entry.symbol.flags_field & SYNTHETIC) == 0) {if(isAccessible(environment, site, entry.symbol)){return entry.symbol;}else{return new AccessError(environment, site, entry.symbol,this);}}entry = entry.next();}// 查找父类Type superType = types.supertype(typeSymbol.type);if (superType != null && (superType.typeTag == CLASS || superType.typeTag == TYPEVARIABLE)) {symbol = findField(environment, site, name, superType.typeSymbol); // 递归调用if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}// 查找所有的接口类for (List<Type> l = types.interfaces(typeSymbol.type); bestSoFar.kind != _AMBIGUOUS && l.nonEmpty(); l = l.tail) {symbol = findField(environment, site, name, l.head.typeSymbol); // 递归调用if (bestSoFar.kind < _AMBIGUOUS && symbol.kind < _AMBIGUOUS && symbol.ownerSymbol != bestSoFar.ownerSymbol){bestSoFar = new AmbiguityError(bestSoFar, symbol, this);}else if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}return bestSoFar;}

  

  

  

  

转载于:https://www.cnblogs.com/extjs4/p/6664414.html

关于类的符号输入过程第三篇相关推荐

  1. 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装...

    微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...

  2. <Android开发> Android vold - 第三篇 vold 的NetLinkManager类简介

    本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android ...

  3. 2大学英语四级关于计算机的图表作文,大学英语四级图表类作文模板三篇

    [导语]英语四级作文要想得高分,必背模板是一定少不了的,现在我们就来看看英语四级作文必背模板吧.关注无忧考网英语资源频道,更多备考资料等你挖掘. (1)英语四级作文模板 According to th ...

  4. java类与对象实验报告心得体会_java实习实训报告心得【三篇】

    [导语]Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言.而学习Java的同学java实习实训是必经的过程.以下是无忧考网整理的java实习实训报告心得,欢迎阅读! java实习实训报告心 ...

  5. 步步理解 JAVA 泛型编程 – 共三篇

    http://learning.iteye.com/blog/1295901 FROM: http://unmi.cc/understand-java-generic-3 步步理解 JAVA 泛型编程 ...

  6. C++面试常见问答题看这三篇文章就够了(上)

    目录 1. 标识符的组成结构 2. 动态关联和静态关联的区别 3.  重载(overload)和重写(overried)的区别 4. class和struct的区别 5. 构造方法的特点 6. 面向对 ...

  7. 教学质量分析系统 php,教学质量分析报告【三篇】

    [导语]分析报告的标题一般有两种形式:一是公文式,另一种是新闻报道式.以下是无忧考网整理的教学质量分析报告,欢迎阅读! 篇一 今天,我们在这里召开全校2010--2011学年第二学期教学质量分析会,主 ...

  8. 二年级计算机是学什么内容的,小学二年级上册信息技术教案【三篇】

    中小学信息课程的任务是:培养学生对信息技术的兴趣和意识,让学生了解或掌握信息技术基本知识和技能,使学生具有获取信息.传输信息.处理信息.应用信息技术手段的能力,形成良好的文化素养,为他们适应信息社会的 ...

  9. 小学第三册上计算机wps教案,小学三年级上册信息技术教案【三篇】

    信息技术课程是中小学一门知识性与技能性相结合的基础工具课程.无忧考网小编整理了小学三年级上册信息技术教案[三篇],希望对你有帮助! 第1课信息和信息处理工具 教学目标: 1.了解什么是信息: 2.了解 ...

  10. 初一数学计算机教案,七年级上册数学教案三篇

    [导语]数学是人们对客观世界定性把握和定量刻画逐渐抽象概括.形成方法和理论,并进行广泛应用的过程.无忧考网准备了以下内容,供大家参考! 与数学交朋友 教学目的: 1.使学生初步到数学与现实世界的密切联 ...

最新文章

  1. python小课骗局-Python小课怎么样啊?
  2. Python爬虫应用实战案例-jsonpath在爬虫中的应用,爬取照片信息
  3. Nginx作为静态资源web服务
  4. inrange函数_Python 初学者必备的常用内置函数
  5. flash大作业一分钟源文件_初中生写作业慢的7个原因及对策
  6. 小程序开发语言python_小程序是用什么语言开发的?5种最佳语言分享
  7. Linux下apache与tomcat完美整合笔记
  8. iOS-使用代码约束布局(Masonry)
  9. JavaScript类数组对象参考
  10. Js分割字符串(单个分割符、多个分割符、正则)
  11. 执行董事和董事长有什么区别
  12. spring boot中使用websocket实现点对点通信与服务器推送
  13. android debug SIGABRT (signal SIGABRT)
  14. 嵌入式软件是怎么分类的?
  15. 高等代数 多项式环(第7章)3 一元多项式的根与不可约多项式
  16. linux创建运维账户流程,Linux运维养成记-账户与权限管理
  17. Android LeakCanary使用详细教程
  18. 微信多开软件苹果版_微信最新PC版 无限多开以及消息防撤回
  19. 关于Sql语句中的模糊查询like关键字详解
  20. 自动化测试面试题及答案大全(5)

热门文章

  1. 任务管理器被管理员禁用如何解决
  2. python tests in xxx问题
  3. 极客公园:正版音乐的前路漫漫
  4. 设CPU共有16根地址线,8根数据线,并用MREQ (低电平有效) .作访存控制信号,R/W作读写命令信号(高电平为读,,低电平为写)。
  5. 蜡笔小新鸿蒙系统,盘点蜡笔小新最污的四处剧情,网友:当年太纯洁现在终于看懂!...
  6. built a JNCIS LAB系列:Chapter 1 Autonomous System Paths v1.0
  7. 怎样用c语言实现CPU超频,cpu超频教程【操作流程】
  8. 【Netty源码系列(一)】SpringBoot整合Netty实现多端口绑定
  9. 使用gimp批量处理图片
  10. 58赶集基于 Docker 的自动化部署实践