go.tools/importer: honor the client's TypeChecker.{Import,Error} values.
This requires us to make a copy of (not clobber) the supplied config, and retain their Import hook separately so that it can be wrapped by Importer.doImport. Fixes bug 6562. R=gri CC=golang-dev https://golang.org/cl/14523054
This commit is contained in:
parent
e1e9089196
commit
548052f0fa
|
@ -56,10 +56,14 @@ import (
|
||||||
"code.google.com/p/go.tools/go/types"
|
"code.google.com/p/go.tools/go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Alias for type of types.Config.Import function.
|
||||||
|
type importfn func(map[string]*types.Package, string) (*types.Package, error)
|
||||||
|
|
||||||
// An Importer's exported methods are not thread-safe.
|
// An Importer's exported methods are not thread-safe.
|
||||||
type Importer struct {
|
type Importer struct {
|
||||||
Fset *token.FileSet // position info for all files seen
|
Fset *token.FileSet // position info for all files seen
|
||||||
config *Config // the client configuration
|
config Config // the client configuration, modified by us
|
||||||
|
importfn importfn // client's type import function
|
||||||
augment map[string]bool // packages to be augmented by TestFiles when imported
|
augment map[string]bool // packages to be augmented by TestFiles when imported
|
||||||
allPackagesMu sync.Mutex // guards 'allPackages' during internal concurrency
|
allPackagesMu sync.Mutex // guards 'allPackages' during internal concurrency
|
||||||
allPackages []*PackageInfo // all packages, including non-importable ones
|
allPackages []*PackageInfo // all packages, including non-importable ones
|
||||||
|
@ -78,9 +82,7 @@ type importInfo struct {
|
||||||
// Config specifies the configuration for the importer.
|
// Config specifies the configuration for the importer.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// TypeChecker contains options relating to the type checker.
|
// TypeChecker contains options relating to the type checker.
|
||||||
// The Importer will override any user-supplied values for its
|
// All callbacks must be thread-safe.
|
||||||
// Error and Import fields; other fields will be passed
|
|
||||||
// through to the type checker. All callbacks must be thread-safe.
|
|
||||||
TypeChecker types.Config
|
TypeChecker types.Config
|
||||||
|
|
||||||
// If Build is non-nil, it is used to satisfy imports.
|
// If Build is non-nil, it is used to satisfy imports.
|
||||||
|
@ -99,17 +101,25 @@ type Config struct {
|
||||||
// specified by config.
|
// specified by config.
|
||||||
//
|
//
|
||||||
func New(config *Config) *Importer {
|
func New(config *Config) *Importer {
|
||||||
|
importfn := config.TypeChecker.Import
|
||||||
|
if importfn == nil {
|
||||||
|
importfn = types.GcImport
|
||||||
|
}
|
||||||
|
|
||||||
imp := &Importer{
|
imp := &Importer{
|
||||||
Fset: token.NewFileSet(),
|
Fset: token.NewFileSet(),
|
||||||
config: config,
|
config: *config, // copy (don't clobber client input)
|
||||||
|
importfn: importfn,
|
||||||
augment: make(map[string]bool),
|
augment: make(map[string]bool),
|
||||||
imported: make(map[string]*importInfo),
|
imported: make(map[string]*importInfo),
|
||||||
}
|
}
|
||||||
// TODO(adonovan): get typechecker to supply us with a source
|
// TODO(adonovan): get typechecker to supply us with a source
|
||||||
// position, then pass errors back to the application
|
// position, then pass errors back to the application
|
||||||
// (e.g. oracle).
|
// (e.g. oracle).
|
||||||
imp.config.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) }
|
if imp.config.TypeChecker.Error == nil {
|
||||||
imp.config.TypeChecker.Import = imp.doImport
|
imp.config.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) }
|
||||||
|
}
|
||||||
|
imp.config.TypeChecker.Import = imp.doImport // wraps importfn, effectively
|
||||||
return imp
|
return imp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +211,11 @@ func (imp *Importer) doImport0(imports map[string]*types.Package, path string) (
|
||||||
return ii.info, ii.err
|
return ii.info, ii.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// importBinary implements package loading from object files from the
|
// importBinary implements package loading from the client-supplied
|
||||||
// gc compiler.
|
// external source, e.g. object files from the gc compiler.
|
||||||
//
|
//
|
||||||
func (imp *Importer) importBinary(imports map[string]*types.Package, ii *importInfo) {
|
func (imp *Importer) importBinary(imports map[string]*types.Package, ii *importInfo) {
|
||||||
pkg, err := types.GcImport(imports, ii.path)
|
pkg, err := imp.importfn(imports, ii.path)
|
||||||
if pkg != nil {
|
if pkg != nil {
|
||||||
ii.info = &PackageInfo{Pkg: pkg}
|
ii.info = &PackageInfo{Pkg: pkg}
|
||||||
imp.addPackage(ii.info)
|
imp.addPackage(ii.info)
|
||||||
|
|
Loading…
Reference in New Issue