(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. Node.js最新Web技术栈(2015年5月)

    https://cnodejs.org/topic/55651bf07d4c64752effb4b1

  2. Fig723.asy

    import settings; outformat="pdf"; tex="xelatex"; usepackage("amsmath") ...

  3. 可移植类库无法使用async、await关键字

    今天遇到了如题所示的问题,平台已经选择了.net 4.5了,可是就是编译不通过,await关键字下出现了红色下划线. 解决方法:安装一个Bcl的补丁包. https://www.nuget.org/p ...

  4. 3D空间中射线与轴向包围盒AABB的交叉检测算法【转】

    引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是 ...

  5. C# 一些代码小结--datGirdView 保存到csv文件

    if (dataGridView1.Rows.Count == 0) { MessageBox.Show("No data available!", "Prompt&qu ...

  6. 2D Polygons( Poygon) CGAL 4.13 -User Manual

    1 Introduction A polygon is a closed chain of edges. Several algorithms are available for polygons. ...

  7. 利用bulk添加百万条数据,进行测试

    (1)连接数据库 public static void BulkToDB(DataTable dt) { //数据库连接 SqlConnection sqlCon = new SqlConnectio ...

  8. 上云、微服务化和DevOps,少走弯路的办法

    本文由  网易云发布. 作者:张亮 如果说一个项目的发展历程就像一段未知的旅程,那<云原生应用架构实践>就像一张地图,基于前人的探索标明了在这段旅途中将会碰到的障碍,并注明了越过这些障碍的 ...

  9. Day44 数据库的操作

    视图操作: 1.左连接查询 select * from person left join dept on person.dept_id = dept.did 2. 右连接 3. 内连接  inner ...

  10. Day 41 线程

    进程只能在同一个时间干一件事情,如果想同时干两件或者多件事情,进程就无能为力了. 进程在执行过程中如果阻塞,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行. 一是由于进程是资源的 ...