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 ast

import (
	
	
	
	
)

type pkgBuilder struct {
	fset   *token.FileSet
	errors scanner.ErrorList
}

func ( *pkgBuilder) ( token.Pos,  string) {
	.errors.Add(.fset.Position(), )
}

func ( *pkgBuilder) ( token.Pos,  string,  ...interface{}) {
	.error(, fmt.Sprintf(, ...))
}

func ( *pkgBuilder) (,  *Scope,  *Object) {
	 := .Insert()
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 ( *Scope,  *Ident) bool {
	for ;  != nil;  = .Outer {
		if  := .Lookup(.Name);  != nil {
			.Obj = 
			return true
		}
	}
	return false
}
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.
type Importer func(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.
func ( *token.FileSet,  map[string]*File,  Importer,  *Scope) (*Package, error) {
	var  pkgBuilder
	.fset = 
complete package scope
	 := ""
	 := NewScope()
package names must match
		switch  := .Name.Name; {
		case  == "":
			 = 
		case  != :
			.errorf(.Package, "package %s; expected %s", , )
			continue // ignore this file
		}
collect top-level file objects in package scope
		for ,  := 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 identifiers
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 {
				 = true
				continue
			}
			,  := strconv.Unquote(.Path.Value)
			,  := (, )
			if  != nil {
				.errorf(.Path.Pos(), "could not import %s (%s)", , )
				 = true
				continue
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
			 := .Name
			if .Name != nil {
				 = .Name.Name
			}
add import to file scope
merge imported scope with file scope
				for ,  := range .Data.(*Scope).Objects {
					.declare(, , )
				}
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 identifiers
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
		}
		 := 0
		for ,  := range .Unresolved {
			if !resolve(, ) {
				.errorf(.Pos(), "undeclared name: %s", .Name)
				.Unresolved[] = 
				++
			}

		}
		.Unresolved = .Unresolved[0:]
		.Outer =  // reset universe scope
	}

	.errors.Sort()
	return &Package{, , , }, .errors.Err()