(1)Annotate (300行)

Enter annotations on symbols. Annotations accumulate in a queue,which is processed at the top level of any set of recursive calls requesting it be processed.

(2)Attr (4000行)

This is the main context-dependent analysis phase in GJC(GNU Compiler for the java). It

encompasses name resolution, type checking and constant folding as

subtasks. Some subtasks involve auxiliary classes.

进行语义合法性的检查和进行逻辑判断,如:

(1)变量的类型是否匹配
 (2)变量在使用前是否已经初始化
 (3)能够推导出泛型方法的参数类型
 (4)字符串常量的合并

其中还有其它的一些辅助类来完成一些检查:

(1)Check 检查变量类型是否正确,如二元操作符两边的操作数的类型是否匹配,方法返回的类型是否与接收的引用值类型匹配等
 (2)Resolve 主要检查变量、方法或者类的访问是否合法、变量是否有静态变量、变量是否已经初始化等
 (3)ConstanceFold 常量折叠

(3)Check(3000行)

Type checking helper class for the attribution phase.

(1)Errors and Warnings
(2)duplicate declaration checking
(3)Class name generation
(4)Type Checking
(5)Type Validation
(6)Exception checking
(7)Overriding/Implementation checking
(8)Check annotations
(9)Check for recursive annotation elements.
(10)Check for cycles in the constructor call graph.
(11)Miscellaneous 混杂的,各种各样的

(4)Resolve(2000行)

Helper class for name resolution, used mostly by the attribution phase.

主要检查变量、方法或者类的访问是否合法、变量是否是静态变量、变量是否已经初始化等

(1)Identifier resolution
(2)Symbol lookup
(3)Access checking
(4)Debugging
(5)Name resolution
(6)ResolveError classes, indicating error situations when accessing symbols

(5)Flow(1600行)

JLS参考:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html

This pass implements dataflow analysis for Java programs.

Liveness analysis checks that every statement is reachable.

Exception analysis ensures that every checked exception that is thrown is declared or caught.

Definite(一定的、确定的) assignment analysis ensures that each variable is assigned when used.

eg1:

任何局部变量在使用前要进行初始化,包括基本类型,如下将报错:

int i;
if(i==2){ // 报错,局部变量i未初始化

}

Definite unassignment analysis ensures that no final variable is assigned more than once(不止一次).

eg2:

final int i;
i = 1;
i = 22; // The final local variable i may already have been assigned

The JLS has a number of problems in the specification of these flow analysis problems.This implementation attempts to address those issues.

First, there is no accommodation for a finally clause that cannot complete normally.

1、For liveness analysis, an intervening finally clause can cause a break, continue, or return not to reach its target.

2、For exception analysis, an intervening finally clause can cause any exception to be "caught".

eg1:

什么是intervening finally,就比如finally中有return 、continue等有控制流程转移的语句。

for(int i=0;i<2;i++){
			try{
				System.out.println("a");
				break;
			}catch(Exception ex){

			}finally{ // finally block does not complete normally
				System.out.println("b");
				continue;
			}
}  

输出为:a b a b

@SuppressWarnings("finally")
private boolean isReturnWithinFinally() {
		try {
			if (true)
				throw new RuntimeException();
		} finally {
			return true; // This hides the exception
		}
}

java里面的异常分为可不获和不可捕获两类,即便使用到catch块,也会导致非捕获的错误被finally吃掉。因此,return一定要放到finally外面。

关于try-catch-finally参考文章:https://www.cnblogs.com/extjs4/p/9375400.html

3、For DA/DU analysis, the finally clause can prevent a transfer of control(控制权的转移) from propagating(传播) DA/DU
state to the target. In addition(另外), code in the finally clause can affect the DA/DU status of variables.

4、For try statements, we introduce the idea of a variable being definitely unassigned "everywhere" in a block.
A variable V is "unassigned everywhere" in a block iff(if and only if) it is unassigned at the beginning of the block and there is no reachable assignment to V in the block.An assignment V=e is reachable iff V is not DA after e. Then we can say that V is DU at the beginning of the catch block iff V is DU everywhere in the try block.

Similarly,V is DU at the beginning of the finally block iff V is DU everywhere in the try block and in every catch block.

Specifically, the following bullet is added to 16.2.2

       V is unassigned everywhere in a block if it is
       unassigned before the block and there is no reachable
       assignment to V within the block.
   

In 16.2.15, the third bullet (and all of its sub-bullets) for all try blocks is changed to

       V is definitely unassigned before a catch block iff V is
       definitely unassigned everywhere in the try block.
   

The last bullet (and all of its sub-bullets) for try blocks that have a finally block is changed to

       V is definitely unassigned before the finally block iff
       V is definitely unassigned everywhere in the try block
       and everywhere in each catch block of the try statement.
   

In addition,

       V is definitely assigned at the end of a constructor iff
       V is definitely assigned after the block that is the body
       of the constructor and V is definitely assigned at every
       return that can return from the constructor.

In addition, each continue statement with the loop as its target is treated as a jump to the end of the loop body,and "intervening" finally clauses are treated as follows:

V is DA "due to(归因于) the continue" iff V is DA before the continue statement or V is DA at the end of any intervening finally block.

V is DU "due to the continue" iff any intervening finally cannot complete normally or V is DU at the end of every intervening finally block. This "due to the continue" concept is then used in the spec for the loops.

Similarly, break statements must consider intervening finally blocks.

For liveness analysis, a break statement for which any intervening finally cannot complete normally is not considered to cause the target statement to be
able to complete normally. Then we say V is DA "due to the break" iff V is DA before the break or V is DA
at the end of any intervening finally block. V is DU "due to the break" iff any intervening finally cannot complete normally
or V is DU at the break and at the end of every intervening finally block. (I suspect this latter condition can be simplified.)
This "due to the break" is then used in the spec for all statements that can be "broken".

The return statement is treated similarly. V is DA "due to a return statement" iff V is DA before the return statement
or V is DA at the end of any intervening finally block. Note that we don't have to worry about the return expression because this concept is only used for construcrors.

There is no spec in JLS2 for when a variable is definitely assigned at the end of a constructor, which is needed for
final fields (8.3.1.2). We implement the rule that V is DA at the end of the constructor iff it is DA and the end of
the body of the constructor and V is DA "due to" every return of the constructor.

Intervening finally blocks similarly affect exception analysis. An intervening finally that cannot complete normally allows us to ignore an otherwise uncaught exception.

To implement the semantics of intervening finally clauses, all nonlocal transfers (break, continue, return, throw,
method call that can throw a checked exception, and a constructor invocation that can thrown a checked exception)
are recorded in a queue, and removed from the queue when we complete processing the target of the nonlocal transfer.
This allows us to modify the queue in accordance with the above rules when we encounter a finally clause.
The only exception to this [no pun intended] is that checked exceptions that are known to be caught or declared
to be caught in the enclosing method are not recorded in the queue, but instead are recorded in a global variable
"Set thrown" that records the type of all exceptions that can be thrown.

Other minor issues the treatment of members of other classes (always considered DA except that within an anonymous class constructor, where DA status from the enclosing scope is preserved),

treatment of the case expression (V is DA before the case expression iff V is DA after the switch expression), treatment of variables declared in a
switch block (the implied DA/DU status after the switch expression is DU and not DA for variables defined in a switch block),
the treatment of boolean ?: expressions (The JLS rules only handle b and c non-boolean; the new rule is that
if b and c are boolean valued, then V is (un)assigned after a?b:c when true/false iff V is (un)assigned after b
when true/false and V is (un)assigned after c when true/false).

There is the remaining question of what syntactic forms constitute(组成) a reference to a variable. It is conventional to
allow this.x on the left-hand-side to initialize a final instance field named x, yet this.x isn't considered a "use" when appearing on a right-hand-side in most implementations.

Should parentheses affect what is considered a variable reference?(括号会影响被视为变量引用的内容)The simplest rule would be to allow unqualified forms only, parentheses optional, and phase out support for assigning to a final field via this.x.

(6)Inference(700行)

Helper class for type parameter inference, used by the attribution phase.

(7)Lower(4000行)

This pass translates away some syntactic sugar: inner classes,class literals, assertions, foreach loops, etc.

Global mappings
Tree building blocks
Symbol manipulation utilities
Access methods
Free variables proxies and this$n
Code for .class
Code for enabling/disabling assertions.
Building blocks for let expressions
Translation methods
main method
The following contributed by Borland for bootstrapping purposes

(8)TranslateTypes(1000行)

This pass translates Generic Java to conventional Java.

(9)Types(4000行)

Utility class containing various operations on types.

Unless other names are more illustrative(清晰的,有说明性的), the following naming conventions should be observed in this file:

_type If the first argument to an operation is a type, it should be named _type.
_super Similarly, if the second argument to an operation is a type, it should be named _super.
ts If an operations takes a list of types, the first should be named ts.
ss A second list of types should be named ss.

Instantiating

 The "rvalue conversion". The upper bound of most types is the type itself. Wildcards, on the other hand have upper and lower bounds. 

upperBound
The "lvalue conversion".The lower bound of most types is the type itself.Wildcards, on the other hand have upper and lower bounds. 

lowerBound
Checks that all the arguments to a class are unboundedwildcards or something else that doesn't make any restrictionson the arguments. If a class is Unbounded, a raw super- orsubclass can be cast to it without a warning. 

isUnbounded
Return the least specific subtype of type that starts with symbolclassSymbol.  If none exists, return null.  The least specific subtype is determined as follows:

If there is exactly one parameterized instance of classSymbol that is asubtype of type, that parameterized instance is returned.Otherwise, if the plain type or raw type `classSymbol' is a subtype oftype _type, the type `classSymbol' itself is returned.Otherwise, null is returned. 

asSubtype
Is _type a subtype of or convertible via boxing/unboxing conversion to _super? 

isConvertible
Is _type a subtype of or convertible via boxing/unboxing conversion to _super?
 
isSubtype
Is t a subtype of or convertiable via boxing/unboxing convertions to s?


isSuperType
isSubtypeUnchecked

Is _type an unchecked subtype of _super?There is an unchecked conversion from the raw class or interface type Gto any parameterized type of the form G<T1,...,Tn>
 
isSameType
fromUnknownFun
Contains Type
isCastable
disjointTypes
lowerBoundArgtypes
notSoftSubtype
isReifiable
Array Utils
asSuper
memberType
isAssignable
erasure
makeCompoundType
supertype
interfaces
isDerivedRaw
setBounds
getBounds
classBound
sub signature / override equivalence
subst
hasSameBounds
newInstances
createErrorType
rank
Determining least upper bounds of types
Greatest lower bound
Return-Type-Substitutable
Box/unbox support
Capture conversion
Internal utility methods
adapt
Visitors
Annotation support

javac后期需要重点阅读的类的更多相关文章

  1. Java直接用javac来编译带package的类

    在没有package语句的java类, 我们可以直接使用: javac Test.java 就可以了, 如果Test.java中包含package语句,如:package abc; 编译后,是要求Te ...

  2. 阅读UML类图和时序图

    这里不会将UML的各种元素都提到.我仅仅想讲讲类图中各个类之间的关系. 能看懂类图中各个类之间的线条.箭头代表什么意思后,也就足够应对 日常的工作和交流: 同一时候,我们应该能将类图所表达的含义和终于 ...

  3. pdf2swf+flexpaper解决pdf在线阅读(类百度文库)

    1:工具准备swftools.exe 下载 http://www.swftools.org/download.html 安装至D盘 SWFTools提供了一系列将各种文件转成swf的工具: font2 ...

  4. jdk源码阅读-Object类

    native 关键字 private static native void registerNatives(); static { registerNatives(); } public final ...

  5. Paper | Feedback Networks

    目录 读后总结 动机 故事 ConvLSTM图像分类网络 损失函数 与Episodic Curriculum Learning的结合 实验方法 发表在2017年CVPR. 读后总结 这篇论文旨在说明: ...

  6. 我推荐阅读的微信公众号-IT类

    微信,正深刻影响着我们的生活,每个使用微信的人,从微信这个窗口去了解这个世界. 微信公众号,微信生态圈是核心功能之一,每天都有大量的文章创作.传播.转发出来,海量的信息扑面而来,微信阅读成为微信使用者 ...

  7. java Thread 类的源码阅读(oracle jdk1.8)

    java线程类的源码分析阅读技巧: 首先阅读thread类重点关注一下几个问题: 1.start() ,启动一个线程是如何实现的? 2.java线程状态机的变化过程以及如何实现的? 3. 1.star ...

  8. 第13天 JSTL标签、MVC设计模式、BeanUtils工具类

    第13天 JSTL标签.MVC设计模式.BeanUtils工具类 目录 1.    JSTL的核心标签库使用必须会使用    1 1.1.    c:if标签    1 1.2.    c:choos ...

  9. Java入门 - 语言基础 - 04.对象和类

    原文地址:http://www.work100.net/training/java-object-class.html 更多教程:光束云 - 免费课程 对象和类 序号 文内章节 视频 1 概述 2 J ...

随机推荐

  1. day06(Collection,List,ArrayList,LinkedList,iterator迭代器,增强for)

    Collection   接口    方法实现 boolean  add(Object o);//添加 boolean  remove(Object o);//移除 修改方法   让实现类自己去实现修 ...

  2. MFC中不同对话框间使用SendMessage发送自定义消息的具体实现

    1. 基本知识 SendMessage的基本结构如下: SendMessage(     HWND hWnd,  //消息传递的目标窗口或线程的句柄.     UINT Msg, //消息类别(这里可 ...

  3. hdu 4974 贪心

    http://acm.hdu.edu.cn/showproblem.php?pid=4974 n个人进行选秀,有一个人做裁判,每次有两人进行对决,裁判可以选择为两人打分,可以同时加上1分,或者单独为一 ...

  4. hdu 5040 bfs

    http://acm.hdu.edu.cn/showproblem.php?pid=5040 一个人拿着纸盒子往目的地走  正常情况下一秒走一格  可以原地不动躲在盒子里  也可以套着盒子三秒走一格 ...

  5. 哈希连接(hash join) 原理

    哈希连接(hashjoin)    访问次数:驱动表和被驱动表都只会访问0次或1次.    驱动表是否有顺序:有.    是否要排序:否.    应用场景: 1. 一个大表,一个小表的关联:     ...

  6. CSS 温故而知新

    如何让文字垂直居中 需要设置div的height,line-height 为一样的值,如下所示: <div class="ui-bar ui-bar-e" style=&qu ...

  7. asp .net api 日志

    方法1:继承IExceptionLogger ExceptionLogger是框架提供的表示未处理的异常记录器的抽象类 public class RecordExceptionLogger : Exc ...

  8. 世界各国货币,C#数字货币计算

    货币 CCY(Currency)本质上是一种所有者与市场关于交换权的契约,根本上是所有者相互之间的约定.吾以吾之所有予市场,换吾之所需,货币就是这一过程的约定,它反映的是个体与社会的经济协作关系.货币 ...

  9. SQLite 编译错误 - 试图加载格式不正确的程序

    刚开始用SQLite,刚开始写了一个小程序,连接数据库的时候出现了问题,提示试图加载格式不正确的程序, 原因是我当前工程的目标平台是X86,改成Any CPU之后问题就解决了.如下图:

  10. .NET Entity Framework (with Oracle ODP.NET)

    一.前言 1.Entity Framework是什么? Entity Framework是微软对ORM框架的实现.类似的实现也有其它方式,如DevExpress 的XPO(eXpress Persis ...