4.5.3-1.3a 总体介绍
类型检查分为两个阶段,第一阶段由方法check.packageObjects()
展开,通过递归下降的方式对 check.objMap 中的对象进行类型检查;第二阶段由方法check.processDelayed()
处理,之所以需要该步骤是因为某些逻辑需要在全局申明的类型检查结束后才能进行,例如检查类型合法性(是否有环形依赖)、对函数体进行检查等。
check.packageObjects()
是类型检查的入口,其定义在$GCROOT/compile/internal/types2/resolver.go
中,其逻辑很简单:将 check.objMap 中的 Object 对象按照申明的顺序排序,然后先对非类型别名(通过 type A = B 这种形式申明的类型)的对象进行类型检查,再对类型别名的对象进行类型检查。其代码如下:
对于每个 Object 对象都会调用方法check.objDecl()
进行类型检查,该方法也是类型检查真正开始的地方。根据之前的分析,我们知道每个 Object 对象都与 AST 中的一个 Node 对应,所以从根本上来说, check.objDecl()
将会对该 Node 的所有子节点进行类型检查,而在对子节点进行检查的过程中,可能又会递归调用到check.objDecl()
,下图描述了该图的一个大概调用栈:
check.objDecl() 会根据 Object 对象的不同类别调用对应的方法进行检查,其中右边方框表示的是类型检查的底层方法,这类方法非常多,基本上对于每类 AST 节点都有一个,这里只罗列了核心的几个,事实上整个$GCROOT/compile/internal/types2/
目录下绝大多数逻辑都可以包含在该方框内。
接下来我们对核心逻辑的处理思路进行单独分析。
最后更新于