// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// This file implements NewPackage.package astimport ()type pkgBuilder struct { fset *token.FileSet errors scanner.ErrorList}func ( *pkgBuilder) ( token.Pos, string) { .errors.Add(.fset.Position(), )}func ( *pkgBuilder) ( token.Pos, string, ...any) { .error(, fmt.Sprintf(, ...))}func ( *pkgBuilder) (, *Scope, *Object) { := .Insert()if == nil && != nil {// see if there is a conflicting declaration in altScope = .Lookup(.Name) }if != nil { := ""if := .Pos(); .IsValid() { = fmt.Sprintf("\n\tprevious declaration at %s", .fset.Position()) } .error(.Pos(), fmt.Sprintf("%s redeclared in this block%s", .Name, )) }}func resolve( *Scope, *Ident) bool {for ; != nil; = .Outer {if := .Lookup(.Name); != nil { .Obj = returntrue } }returnfalse}// An Importer resolves import paths to package Objects.// The imports map records the packages already imported,// indexed by package id (canonical import path).// An Importer must determine the canonical import path and// check the map to see if it is already present in the imports map.// If so, the Importer can return the map entry. Otherwise, the// Importer should load the package data for the given path into// a new *[Object] (pkg), record pkg in the imports map, and then// return pkg.//// Deprecated: use the type checker [go/types] instead; see [Object].typeImporterfunc(imports map[string]*Object, path string) (pkg *Object, err error)// NewPackage creates a new [Package] node from a set of [File] nodes. It resolves// unresolved identifiers across files and updates each file's Unresolved list// accordingly. If a non-nil importer and universe scope are provided, they are// used to resolve identifiers not declared in any of the package files. Any// remaining unresolved identifiers are reported as undeclared. If the files// belong to different packages, one package name is selected and files with// different package names are reported and then ignored.// The result is a package node and a [scanner.ErrorList] if there were errors.//// Deprecated: use the type checker [go/types] instead; see [Object].func ( *token.FileSet, map[string]*File, Importer, *Scope) (*Package, error) {varpkgBuilder .fset = // complete package scope := "" := NewScope()for , := range {// package names must matchswitch := .Name.Name; {case == "": = case != : .errorf(.Package, "package %s; expected %s", , )continue// ignore this file }// collect top-level file objects in package scopefor , := range .Scope.Objects { .declare(, nil, ) } }// package global mapping of imported package ids to package objects := make(map[string]*Object)// complete file scopes with imports and resolve identifiersfor , := range {// ignore file if it belongs to a different package // (error has already been reported)if .Name.Name != {continue }// build file scope by processing all imports := false := NewScope()for , := range .Imports {if == nil { = truecontinue } , := strconv.Unquote(.Path.Value) , := (, )if != nil { .errorf(.Path.Pos(), "could not import %s (%s)", , ) = truecontinue }// TODO(gri) If a local package name != "." is provided, // global identifier resolution could proceed even if the // import failed. Consider adjusting the logic here a bit.// local name overrides imported package name := .Nameif .Name != nil { = .Name.Name }// add import to file scopeif == "." {// merge imported scope with file scopefor , := range .Data.(*Scope).Objects { .declare(, , ) } } elseif != "_" {// declare imported package object in file scope // (do not re-use pkg in the file scope but create // a new object instead; the Decl field is different // for different files) := NewObj(Pkg, ) .Decl = .Data = .Data .declare(, , ) } }// resolve identifiersif {// don't use the universe scope without correct imports // (objects in the universe may be shadowed by imports; // with missing imports, identifiers might get resolved // incorrectly to universe objects) .Outer = nil } := 0for , := range .Unresolved {if !resolve(, ) { .errorf(.Pos(), "undeclared name: %s", .Name) .Unresolved[] = ++ } } .Unresolved = .Unresolved[0:] .Outer = // reset universe scope } .errors.Sort()return &Package{, , , }, .errors.Err()}
The pages are generated with Goldsv0.7.3. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.