4.4.5 类型检查器

与类型检查器相关的重要数据结构有三个,本节将分析其代码

4.4.5.1. Config

Config用来配置类型检查器,定义在$GCROOT/compile/internal/types2/api.go中:

type Config struct {
	// GoVersion describes the accepted Go language version. The string
	// must follow the format "go%d.%d" (e.g. "go1.12") or ist must be
	// empty; an empty string indicates the latest language version.
	// If the format is invalid, invoking the type checker will cause a
	// panic.
	GoVersion string

	// If IgnoreFuncBodies is set, function bodies are not
	// type-checked.
	IgnoreFuncBodies bool

	// If FakeImportC is set, `import "C"` (for packages requiring Cgo)
	// declares an empty "C" package and errors are omitted for qualified
	// identifiers referring to package C (which won't find an object).
	// This feature is intended for the standard library cmd/api tool.
	//
	// Caution: Effects may be unpredictable due to follow-on errors.
	//          Do not use casually!
	FakeImportC bool

	// If IgnoreLabels is set, correct label use is not checked.
	// TODO(gri) Consolidate label checking and remove this flag.
	IgnoreLabels bool

	// If CompilerErrorMessages is set, errors are reported using
	// cmd/compile error strings to match $GOROOT/test errors.
	// TODO(gri) Consolidate error messages and remove this flag.
	CompilerErrorMessages bool

	// If go115UsesCgo is set, the type checker expects the
	// _cgo_gotypes.go file generated by running cmd/cgo to be
	// provided as a package source file. Qualified identifiers
	// referring to package C will be resolved to cgo-provided
	// declarations within _cgo_gotypes.go.
	//
	// It is an error to set both FakeImportC and go115UsesCgo.
	go115UsesCgo bool

	// If Trace is set, a debug trace is printed to stdout.
	Trace bool

	// If Error != nil, it is called with each error found
	// during type checking; err has dynamic type Error.
	// Secondary errors (for instance, to enumerate all types
	// involved in an invalid recursive type declaration) have
	// error strings that start with a '\t' character.
	// If Error == nil, type-checking stops with the first
	// error found.
	Error func(err error)

	// An importer is used to import packages referred to from
	// import declarations.
	// If the installed importer implements ImporterFrom, the type
	// checker calls ImportFrom instead of Import.
	// The type checker reports an error if an importer is needed
	// but none was installed.
	Importer Importer

	// If Sizes != nil, it provides the sizing functions for package unsafe.
	// Otherwise SizesFor("gc", "amd64") is used instead.
	Sizes Sizes

	// If DisableUnusedImportCheck is set, packages are not checked
	// for unused imports.
	DisableUnusedImportCheck bool
}

其中各个字段的注释写得非常详细,基本都是一些开关属性。比较重要的是Importer以及Sizes, 前者是包加载器,而后者负责处理各类型的对齐问题。

4.4.5.2. Info

Info用来存放类型检查器的检查结果,定义在$GCROOT/compile/internal/types2/api.go中:

Initializer表示的是当前 package 的初始化顺序,其余的所有属性都是一个以 AST 节点为 key 的 map, 类型检查器会在类型检查的过程中收集对应的对象,Info 包含了所有类型检查的结果,其会在后续生成 IR Tree 时使用。其中涉及到的TypeAndValue以及Inferred都在本文件中定义。

4.4.5.3. Checker

类型检查的整体逻辑由Checker驱动,其定义在文件$GCROOT/compile/internal/types2/check.go中:

Checker定义了非常多的方法,几乎包含了所有的类型检查逻辑,而其属性封装了类型检查需要的各种数据结构,包括用于存放各种中间状态的属性,其中有几个属性还需要单独介绍一下:

  • declInfo

该结构用来封装 package-level 的顶级申明,与 AST 中的“申明(Declaration)”对应。其定义在文件$GCROOT/compile/internal/types2/resolver.go中:

其内部封装了一个申明的各个语法树节点,类型检查主要围绕这个结构体展开。其中deps属性用来保存当前 declInfo 所依赖的对象,用于构建初始化顺序

  • delayed & finals

类型检查是分阶段进行的,有些模块的工作需要依赖其他部分的检查结果,这两个属性用来保存该类工作,所以其是两个函数列表。该属性在类型检查逻辑中会有使用。

最后更新于

这有帮助吗?