1、Javac语义分析简介
语义分析主要是由com.sun.tools.javac.comp.Attr类来完成的,这个类中主要完成的任务有:
(1)名称消解(name resolution)
(2)类型检查
(3)常量折叠
除此之外,还需要针对具体的语法树节点进行独特的语义分析,例如声明在方法内的一个局部变量,要判断这个变量是否有非法修饰符声明,这个变量被本地类引用时变量是否含有final修改符,这个变量在使用前是否进行了初始化,变量是否与方法内的其它变量冲突,如与方法的形式参数名称一样等等,所以如果读者阅读这部分源代码时,很容易陷入细节的汪洋大海中。所以作者在最初阅读源代码时,着重对宏观结构进行分析。由于本书的篇幅有限,也只能着重对一些重点的语义分析点展开分析。
如下涉及到的一些类都在com.sun.tools.javac.comp包下:
1、Check 它用来辅助Attr类检查语法树中变量类型是否正确,如方法返回值是否和接收的引用值类型匹配
(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 混杂的,各种各样的
2、Resolve 用来检查变量,方法或者类的访问是否合法,变量是否是静态变量
(1)Identifier resolution
(2)Symbol lookup
(3)Access checking
(4)Debugging
(5)Name resolution
(6)ResolveError classes, indicating error situations when accessing symbols
3、ConstFold 将一个字符串常量中的多个字符合并成一个字符串
4、Infer 帮助推导泛型方法的参数类型
2、类型引用的消解
在Resolve中提供了三个方法,以便在语义分析阶段进行使用,如下:
(1)public Symbol findType(Env<AttrContext> env,Name name)
Find an unqualified type symbol.
(2)public Symbol findMemberType(Env<AttrContext> env,Type sitetype,Name name,TypeSymbol c)
Find qualified member type.
(3)public Symbol findGlobalType(Env<AttrContext> env,Scope scope,Name name)
Find a global type in given scope and load corresponding class.
三个类中,findType方法中调用findMemberType与findGlobalType来完成任务,而findType主要规定了查找类型的顺序,查找顺序也决定了类型被使用的优先级。
3、变量引用的消解
Resolve中提供了两个对于变量查找的方法,如下:
(1)public Symbol findField(Env<AttrContext> env,Type sitetype,Name name,TypeSymbol c)
Find field. Synthetic fields are always skipped.
(2)public Symbol findVar(Env<AttrContext> env,Name name)
Find unqualified(没有定性) variable or field with given name.Synthetic fields always skipped.
所谓变量的消解就是要将代码中对变量名称的引用关联到其的具体定义,例如:
public class ResolveVar{
int a = 1;
int b = a;
}
在定义b变量时,有对a的引用。所以要用a名称通过符号表查找到int a = 1这条语句,并且还能获取到对这条语句的其它相关信息,如类型、所属范围等。
4、方法引用的消解
对于Java来说,查找方法要相对来说比较复杂。主要体现在Java的多态还有继承上,另外由于在调用过程中还存在自动类型转换,所以相对于变量引用的查找来说,方法要复杂的多。
(1)public Symbol findFun(Env<AttrContext> env,Name name,List<Type> argtypes,List<Type> typeargtypes,boolean allowBoxing,boolean useVarargs)
Find unqualified method matching given name, type and value arguments.
(2)private Symbol findMethod(Env<AttrContext> env,Type sitetype,Name name,List<Type> argtypes,List<Type> typeargtypes,Type intype,boolean abstractok,Symbol bestSoFar,boolean allowBoxing,boolean useVarargs,boolean operator,Set<TypeSymbol> seen)
Find best qualified method matching given name, type and value arguments.
5、实例分析