javac后期需要重点阅读的类

 

(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 unbounded
wildcards or something else that doesn't make any restrictions
on the arguments. If a class is Unbounded, a raw super- or
subclass can be cast to it without a warning. 

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

If there is exactly one parameterized instance of classSymbol that is a
subtype of type, that parameterized instance is returned.
Otherwise, if the plain type or raw type `classSymbol' is a subtype of
type _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 G
to 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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值