// resolve identifiers
imp := ctxt.Import
if imp == nil {
- // wrap GcImport to import packages only once by default.
- // TODO(gri) move this into resolve
- imported := make(map[string]bool)
- imp = func(imports map[string]*Package, path string) (*Package, error) {
- if imported[path] && imports[path] != nil {
- return imports[path], nil
- }
- pkg, err := GcImport(imports, path)
- if err == nil {
- imported[path] = true
- }
- return pkg, err
- }
+ imp = GcImport
}
pkg, methods := check.resolve(imp)
check.pkg = pkg
// adds the corresponding package object to the imports map indexed by id,
// and returns the object.
//
-// The imports map must contains all packages already imported, and no map
-// entry with id as the key must be present. The data reader position must
-// be the beginning of the export data section. The filename is only used
-// in error messages.
+// The imports map must contains all packages already imported. The data
+// reader position must be the beginning of the export data section. The
+// filename is only used in error messages.
+//
+// If imports[id] contains the completely imported package, that package
+// can be used directly, and there is no need to call this function (but
+// there is also no harm but for extra time used).
//
func GcImportData(imports map[string]*Package, filename, id string, data *bufio.Reader) (pkg *Package, err error) {
// support for gcParser error handling
return
}
- // Note: imports[id] may already contain a partially imported package.
- // We must continue doing the full import here since we don't
- // know if something is missing.
- // TODO: There's no need to re-import a package if we know that we
- // have done a full import before. At the moment we cannot
- // tell from the available information in this function alone.
+ // no need to re-import if the package was imported completely before
+ if pkg = imports[id]; pkg != nil && pkg.Complete {
+ return
+ }
// open file
f, err := os.Open(filename)
p.errorf("expected no scanner errors, got %d", n)
}
+ // package was imported completely and without errors
+ pkg.Complete = true
+
return pkg
}
// A Package represents the contents (objects) of a Go package.
type Package struct {
- Name string
- Path string // import path, "" for current (non-imported) package
- Scope *Scope // package-level scope
- Imports map[string]*Package // map of import paths to imported packages
+ Name string
+ Path string // import path, "" for current (non-imported) package
+ Scope *Scope // package-level scope
+ Imports map[string]*Package // map of import paths to imported packages
+ Complete bool // if set, this package was imported completely
spec *ast.ImportSpec
}