func (tc *typechecker) checkPackage(pkg *ast.Package) { // setup package scope tc.topScope = Universe tc.openScope() defer tc.closeScope() // TODO(gri) there's no file scope at the moment since we ignore imports // phase 1: declare all global objects; also collect all function and method declarations var funcs []*ast.FuncDecl for _, file := range pkg.Files { for _, decl := range file.Decls { tc.declGlobal(decl) if f, isFunc := decl.(*ast.FuncDecl); isFunc { funcs = append(funcs, f) } } } // phase 2: bind methods to their receiver base types for _, m := range funcs { if m.Recv != nil { tc.bindMethod(m) } } // phase 3: resolve all global objects tc.cyclemap = make(map[*ast.Object]bool) for _, obj := range tc.globals { tc.resolve(obj) } assert(len(tc.cyclemap) == 0) // 4: sequentially typecheck function and method bodies for _, f := range funcs { ftype, _ := f.Name.Obj.Type.(*Type) tc.checkBlock(f.Body.List, ftype) } pkg.Scope = tc.topScope }