diff --git a/cmd/ssadump/main.go b/cmd/ssadump/main.go index def7215b..a3b7fd59 100644 --- a/cmd/ssadump/main.go +++ b/cmd/ssadump/main.go @@ -73,7 +73,10 @@ func main() { flag.Parse() args := flag.Args() - impctx := importer.Config{Build: &build.Default} + impctx := importer.Config{ + Build: &build.Default, + SourceImports: true, + } // TODO(adonovan): make go/types choose its default Sizes from // build.Default or a specified *build.Context. var wordSize int64 = 8 @@ -103,7 +106,7 @@ func main() { case 'N': mode |= ssa.NaiveForm case 'G': - impctx.Build = nil + impctx.SourceImports = false case 'L': mode |= ssa.BuildSerially default: @@ -147,8 +150,8 @@ func main() { // The interpreter needs the runtime package. if *runFlag { - if _, err := imp.LoadPackage("runtime"); err != nil { - log.Fatalf("LoadPackage(runtime) failed: %s", err) + if _, err := imp.ImportPackage("runtime"); err != nil { + log.Fatalf("ImportPackage(runtime) failed: %s", err) } } diff --git a/importer/importer.go b/importer/importer.go index daf94bac..bff5051a 100644 --- a/importer/importer.go +++ b/importer/importer.go @@ -50,7 +50,6 @@ import ( "go/token" "os" "strings" - "sync" "code.google.com/p/go.tools/astutil" "code.google.com/p/go.tools/go/exact" @@ -60,32 +59,28 @@ import ( // An Importer's exported methods are not thread-safe. type Importer struct { - Fset *token.FileSet // position info for all files seen - config *Config // the client configuration, unmodified - importfn types.Importer // client's type import function - augment map[string]bool // packages to be augmented by TestFiles when imported - allPackagesMu sync.Mutex // guards 'allPackages' during internal concurrency - allPackages []*PackageInfo // all packages, including non-importable ones - importedMu sync.Mutex // guards 'imported' - imported map[string]*importInfo // all imported packages (incl. failures) by import path + Fset *token.FileSet // position info for all files seen + Config *Config // the client configuration, unmodified + importfn types.Importer // client's type import function + srcpkgs map[string]bool // for each package to load from source, whether to augment + allPackages []*PackageInfo // all packages, including non-importable ones + imported map[string]*importInfo // all imported packages (incl. failures) by import path } // importInfo holds internal information about each import path. type importInfo struct { - path string // import path - info *PackageInfo // results of typechecking (including type errors) - err error // reason for failure to construct a package - ready chan struct{} // channel close is notification of ready state + path string // import path + info *PackageInfo // results of typechecking (including type errors) + err error // reason for failure to construct a package } // Config specifies the configuration for the importer. +// The zero value for Config is a ready-to-use default configuration. type Config struct { // TypeChecker contains options relating to the type checker. // // The supplied IgnoreFuncBodies is not used; the effective // value comes from the TypeCheckFuncBodies func below. - // - // All callbacks must be thread-safe. TypeChecker types.Config // TypeCheckFuncBodies is a predicate over package import @@ -94,23 +89,35 @@ type Config struct { // its function bodies; this can be used to quickly load // dependencies from source. If nil, all func bodies are type // checked. - // - // Must be thread-safe. - // TypeCheckFuncBodies func(string) bool - // If Build is non-nil, it is used to satisfy imports. + // SourceImports determines whether to satisfy all imports by + // loading Go source code. // - // If it is nil, binary object files produced by the gc - // compiler will be loaded instead of source code for all - // imported packages. Such files supply only the types of + // If false, the TypeChecker.Import mechanism will be used + // instead. Since that typically supplies only the types of // package-level declarations and values of constants, but no - // code, so this mode will not yield a whole program. It is - // intended for analyses that perform intraprocedural analysis - // of a single package. + // code, it will not yield a whole program. It is intended + // for analyses that perform intraprocedural analysis of a + // single package. + // + // The importer's initial packages are always loaded from + // source, regardless of this flag's setting. + SourceImports bool + + // If Build is non-nil, it is used to locate source packages. + // Otherwise &build.Default is used. Build *build.Context } +// build returns the effective build context. +func (c *Config) build() *build.Context { + if c.Build != nil { + return c.Build + } + return &build.Default +} + // New returns a new, empty Importer using configuration options // specified by config. // @@ -129,27 +136,27 @@ func New(config *Config) *Importer { imp := &Importer{ Fset: token.NewFileSet(), - config: config, + Config: config, importfn: importfn, - augment: make(map[string]bool), + srcpkgs: make(map[string]bool), imported: make(map[string]*importInfo), } return imp } -// AllPackages returns a new slice containing all packages loaded by -// importer imp. +// AllPackages returns a new slice containing all complete packages +// loaded by importer imp. +// +// This returns only packages that were loaded from source or directly +// imported from a source package. It does not include packages +// indirectly referenced by a binary package; they are found in +// config.TypeChecker.Packages. +// TODO(adonovan): rethink this API. // func (imp *Importer) AllPackages() []*PackageInfo { return append([]*PackageInfo(nil), imp.allPackages...) } -func (imp *Importer) addPackage(info *PackageInfo) { - imp.allPackagesMu.Lock() - imp.allPackages = append(imp.allPackages, info) - imp.allPackagesMu.Unlock() -} - // doImport imports the package denoted by path. // It implements the types.Importer prototype. // @@ -163,40 +170,7 @@ func (imp *Importer) addPackage(info *PackageInfo) { // the types.Config.Error callback (the first of which is also saved // in the package's PackageInfo). // -// Idempotent and thread-safe. -// -// -// TODO(gri): The imports map (an alias for TypeChecker.Packages) must -// not be concurrently accessed. Today, the only (non-test) accesses -// of this map are in the client-supplied implementation of the -// importer function, i.e. the function below. But this is a fragile -// API because if go/types ever starts to access this map, it and its -// clients will have to agree to use the same mutex. -// Two better ideas: -// -// (1) require that the importer functions be stateful and have this -// map be part of that internal state. -// Pro: good encapsulation. -// Con: we can't have different importers collaborate, e.g. -// we can't use a source importer for some packages and -// GcImport for others since they'd each have a distinct map. -// -// (2) have there be a single map in go/types.Config, but expose -// lookup and update behind an interface and pass that interface -// to the importer implementations. -// Pro: sharing of the map among importers. -// -// This is idempotent but still doesn't address the issue of -// atomicity: when loading packages concurrently, we want to avoid -// the benign but suboptimal situation of two goroutines both -// importing "fmt", finding it not present, doing all the work, and -// double-updating the map. -// The interface to the map needs to express the idea that when a -// caller requests an import from the map and finds it not present, -// then it (and no other goroutine) becomes responsible for loading -// the package and updating the map; other goroutines should block -// until then. That's exactly what doImport0 below does; I think -// some of that logic should migrate into go/types.check.resolveFiles. +// Idempotent. // func (imp *Importer) doImport(imports map[string]*types.Package, path string) (*types.Package, error) { // Package unsafe is handled specially, and has no PackageInfo. @@ -205,99 +179,67 @@ func (imp *Importer) doImport(imports map[string]*types.Package, path string) (* return types.Unsafe, nil } - info, err := imp.doImport0(imports, path) + info, err := imp.ImportPackage(path) if err != nil { return nil, err } - if imports != nil { - // Update the package's imports map, whether success or failure. - // - // types.Package.Imports() is used by PackageInfo.Imports and - // thence by ssa.builder. - // TODO(gri): given that it doesn't specify whether it - // contains direct or transitive dependencies, it probably - // shouldn't be exposed. This package can make its own - // arrangements to implement PackageInfo.Imports(). - importsMu.Lock() - imports[path] = info.Pkg - importsMu.Unlock() - } + // Update the type checker's package map on success. + imports[path] = info.Pkg return info.Pkg, nil } -var importsMu sync.Mutex // hack; see comment at doImport - -// Like doImport, but returns a PackageInfo. +// ImportPackage imports the package whose import path is path, plus +// its necessary dependencies. +// // Precondition: path != "unsafe". -func (imp *Importer) doImport0(imports map[string]*types.Package, path string) (*PackageInfo, error) { - imp.importedMu.Lock() +// +func (imp *Importer) ImportPackage(path string) (*PackageInfo, error) { ii, ok := imp.imported[path] if !ok { - ii = &importInfo{path: path, ready: make(chan struct{})} + ii = &importInfo{path: path} imp.imported[path] = ii - } - imp.importedMu.Unlock() - if !ok { // Find and create the actual package. - if imp.config.Build != nil { - imp.importSource(path, ii) + if augment, ok := imp.srcpkgs[ii.path]; ok || imp.Config.SourceImports { + which := "g" // load *.go files + if augment { + which = "gt" // augment package by in-package *_test.go files + } + imp.loadFromSource(ii, which) } else { - imp.importBinary(imports, ii) + imp.loadFromBinary(ii) } if ii.info != nil { ii.info.Importable = true } - - close(ii.ready) // enter ready state and wake up waiters - } else { - <-ii.ready // wait for ready condition } - // Invariant: ii is ready. - return ii.info, ii.err } -// importBinary implements package loading from the client-supplied +// loadFromBinary implements package loading from the client-supplied // external source, e.g. object files from the gc compiler. // -func (imp *Importer) importBinary(imports map[string]*types.Package, ii *importInfo) { - pkg, err := imp.importfn(imports, ii.path) +func (imp *Importer) loadFromBinary(ii *importInfo) { + pkg, err := imp.importfn(imp.Config.TypeChecker.Packages, ii.path) if pkg != nil { ii.info = &PackageInfo{Pkg: pkg} - imp.addPackage(ii.info) + imp.allPackages = append(imp.allPackages, ii.info) } else { ii.err = err } } -// importSource implements package loading by parsing Go source files -// located by go/build. +// loadFromSource implements package loading by parsing Go source files +// located by go/build. which indicates which files to include in the +// package. // -func (imp *Importer) importSource(path string, ii *importInfo) { - which := "g" // load *.go files - if imp.augment[path] { - which = "gt" // augment package by in-package *_test.go files - } - if files, err := parsePackageFiles(imp.config.Build, imp.Fset, path, which); err == nil { - // Prefetch the imports asynchronously. - for path := range importsOf(path, files) { - go func(path string) { imp.doImport(nil, path) }(path) - } - +func (imp *Importer) loadFromSource(ii *importInfo, which string) { + if files, err := parsePackageFiles(imp.Config.build(), imp.Fset, ii.path, which); err == nil { // Type-check the package. - ii.info = imp.CreatePackage(path, files...) - - // We needn't wait for the prefetching goroutines to - // finish. Each one either runs quickly and populates - // the imported map, in which case the type checker - // will wait for the map entry to become ready; or, it - // runs slowly, even after we return, but then becomes - // just another map waiter, in which case it won't - // mutate anything. + ii.info = imp.CreatePackage(ii.path, files...) } else { ii.err = err } @@ -335,9 +277,9 @@ func (imp *Importer) CreatePackage(path string, files ...*ast.File) *PackageInfo } // Use a copy of the types.Config so we can vary IgnoreFuncBodies. - tc := imp.config.TypeChecker + tc := imp.Config.TypeChecker tc.IgnoreFuncBodies = false - if f := imp.config.TypeCheckFuncBodies; f != nil { + if f := imp.Config.TypeCheckFuncBodies; f != nil { tc.IgnoreFuncBodies = !f(path) } if tc.Error == nil { @@ -345,7 +287,7 @@ func (imp *Importer) CreatePackage(path string, files ...*ast.File) *PackageInfo } tc.Import = imp.doImport // doImport wraps the user's importfn, effectively info.Pkg, info.Err = tc.Check(path, imp.Fset, files, &info.Info) - imp.addPackage(info) + imp.allPackages = append(imp.allPackages, info) return info } @@ -418,6 +360,7 @@ func (imp *Importer) LoadInitialPackages(args []string) ([]*PackageInfo, []strin // Pass 1: parse the sets of files for each package. var pkgs []*initialPkg + var seenAugmented bool for len(args) > 0 { arg := args[0] args = args[1:] @@ -444,28 +387,24 @@ func (imp *Importer) LoadInitialPackages(args []string) ([]*PackageInfo, []strin continue // ignore; has no PackageInfo } - pkg := &initialPkg{ + pkgs = append(pkgs, &initialPkg{ path: path, importable: true, - } - pkgs = append(pkgs, pkg) + }) + imp.srcpkgs[path] = false // unaugmented source package if path != arg { continue // had "notest:" prefix } - if imp.config.Build == nil { - continue // can't locate *_test.go files - } - // TODO(adonovan): due to limitations of the current type // checker design, we can augment at most one package. - if len(imp.augment) > 0 { + if seenAugmented { continue // don't attempt a second } // Load the external test package. - xtestFiles, err := parsePackageFiles(imp.config.Build, imp.Fset, path, "x") + xtestFiles, err := parsePackageFiles(imp.Config.build(), imp.Fset, path, "x") if err != nil { return nil, nil, err } @@ -479,24 +418,22 @@ func (imp *Importer) LoadInitialPackages(args []string) ([]*PackageInfo, []strin // Mark the non-xtest package for augmentation with // in-package *_test.go files when we import it below. - imp.augment[pkg.path] = true + imp.srcpkgs[path] = true + seenAugmented = true } } // Pass 2: type-check each set of files to make a package. var infos []*PackageInfo - imports := make(map[string]*types.Package) // keep importBinary happy for _, pkg := range pkgs { var info *PackageInfo if pkg.importable { - // import package var err error - info, err = imp.doImport0(imports, pkg.path) + info, err = imp.ImportPackage(pkg.path) if err != nil { return nil, nil, err // e.g. parse error (but not type error) } } else { - // create package info = imp.CreatePackage(pkg.path, pkg.files...) } infos = append(infos, info) @@ -509,17 +446,9 @@ func (imp *Importer) LoadInitialPackages(args []string) ([]*PackageInfo, []strin return infos, args, nil } -// LoadPackage loads and type-checks the package whose import path is -// path, plus its necessary dependencies. -// -func (imp *Importer) LoadPackage(path string) (*PackageInfo, error) { - imports := make(map[string]*types.Package) // keep importBinary happy - return imp.doImport0(imports, path) -} - type initialPkg struct { path string // the package's import path - importable bool // add package to import map false for main and xtests) + importable bool // add package to import map (false for main and xtests) files []*ast.File // set of files (non-importable packages only) } diff --git a/importer/importer_test.go b/importer/importer_test.go index 59d6b8c1..0c868b55 100644 --- a/importer/importer_test.go +++ b/importer/importer_test.go @@ -6,18 +6,15 @@ package importer_test import ( "fmt" - "go/build" "testing" "code.google.com/p/go.tools/importer" ) func TestLoadInitialPackages(t *testing.T) { - ctxt := &importer.Config{Build: &build.Default} - // Failed load: bad first import path causes parsePackageFiles to fail. args := []string{"nosuchpkg", "errors"} - if _, _, err := importer.New(ctxt).LoadInitialPackages(args); err == nil { + if _, _, err := importer.New(&importer.Config{}).LoadInitialPackages(args); err == nil { t.Errorf("LoadInitialPackages(%q) succeeded, want failure", args) } else { // cannot find package: ok. @@ -25,7 +22,7 @@ func TestLoadInitialPackages(t *testing.T) { // Failed load: bad second import path proceeds to doImport0, which fails. args = []string{"errors", "nosuchpkg"} - if _, _, err := importer.New(ctxt).LoadInitialPackages(args); err == nil { + if _, _, err := importer.New(&importer.Config{}).LoadInitialPackages(args); err == nil { t.Errorf("LoadInitialPackages(%q) succeeded, want failure", args) } else { // cannot find package: ok @@ -33,7 +30,7 @@ func TestLoadInitialPackages(t *testing.T) { // Successful load. args = []string{"fmt", "errors", "testdata/a.go,testdata/b.go", "--", "surplus"} - imp := importer.New(ctxt) + imp := importer.New(&importer.Config{}) infos, rest, err := imp.LoadInitialPackages(args) if err != nil { t.Errorf("LoadInitialPackages(%q) failed: %s", args, err) diff --git a/importer/source_test.go b/importer/source_test.go index c761409a..84a1b4c0 100644 --- a/importer/source_test.go +++ b/importer/source_test.go @@ -82,7 +82,7 @@ func TestEnclosingFunction(t *testing.T) { "900", "func@2.27"}, } for _, test := range tests { - imp := importer.New(new(importer.Config)) // (NB: no go/build.Config) + imp := importer.New(&importer.Config{}) f, start, end := findInterval(t, imp.Fset, test.input, test.substr) if f == nil { continue diff --git a/oracle/oracle.go b/oracle/oracle.go index 4be88cec..c3596a0c 100644 --- a/oracle/oracle.go +++ b/oracle/oracle.go @@ -192,7 +192,7 @@ func (res *Result) Serial() *serial.Result { // Clients that intend to perform multiple queries against the same // analysis scope should use this pattern instead: // -// imp := importer.New(&importer.Config{Build: buildContext}) +// imp := importer.New(&importer.Config{Build: buildContext, SourceImports: true}) // o, err := oracle.New(imp, args, nil) // if err != nil { ... } // for ... { @@ -219,7 +219,7 @@ func Query(args []string, mode, pos string, ptalog io.Writer, buildContext *buil return nil, fmt.Errorf("invalid mode type: %q", mode) } - impcfg := importer.Config{Build: buildContext} + impcfg := importer.Config{Build: buildContext, SourceImports: true} // For queries needing only a single typed package, // reduce the analysis scope to that package. diff --git a/pointer/example_test.go b/pointer/example_test.go index 024dea42..2af0c318 100644 --- a/pointer/example_test.go +++ b/pointer/example_test.go @@ -6,7 +6,6 @@ package pointer_test import ( "fmt" - "go/build" "go/parser" "sort" @@ -41,8 +40,7 @@ func main() { } ` // Construct an importer. - // Imports will be loaded as if by 'go build'. - imp := importer.New(&importer.Config{Build: &build.Default}) + imp := importer.New(&importer.Config{SourceImports: true}) // Parse the input file. file, err := parser.ParseFile(imp.Fset, "myprog.go", myprog, 0) diff --git a/pointer/pointer_test.go b/pointer/pointer_test.go index cf543368..de0e00da 100644 --- a/pointer/pointer_test.go +++ b/pointer/pointer_test.go @@ -12,7 +12,6 @@ import ( "bytes" "errors" "fmt" - "go/build" "go/parser" "go/token" "io/ioutil" @@ -152,7 +151,7 @@ func findProbe(prog *ssa.Program, probes map[*ssa.CallCommon]pointer.Pointer, e } func doOneInput(input, filename string) bool { - impctx := &importer.Config{Build: &build.Default} + impctx := &importer.Config{SourceImports: true} imp := importer.New(impctx) // Parsing. diff --git a/ssa/builder.go b/ssa/builder.go index 9c8f3b66..4d9da76e 100644 --- a/ssa/builder.go +++ b/ssa/builder.go @@ -810,9 +810,6 @@ func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) { c.Method = obj } else { // "Call"-mode call. - // TODO(adonovan): fix: in -build=G - // mode, declaredFunc panics for - // cross-package calls. c.Value = fn.Prog.declaredFunc(obj) c.Args = append(c.Args, v) } diff --git a/ssa/builder_test.go b/ssa/builder_test.go index fe7546d1..757a1710 100644 --- a/ssa/builder_test.go +++ b/ssa/builder_test.go @@ -40,7 +40,7 @@ func main() { w.Write(nil) // interface invoke of external declared method } ` - imp := importer.New(new(importer.Config)) // no go/build.Context; uses GC importer + imp := importer.New(&importer.Config{}) f, err := parser.ParseFile(imp.Fset, "", test, 0) if err != nil { @@ -58,10 +58,16 @@ func main() { mainPkg := prog.Package(mainInfo.Pkg) mainPkg.Build() - // Only the main package and its immediate dependencies are loaded. - deps := []string{"bytes", "io", "testing"} + // The main package, its direct and indirect dependencies are loaded. + deps := []string{ + // directly imported dependencies: + "bytes", "io", "testing", + // indirect dependencies (partial list): + "errors", "fmt", "os", "runtime", + } + all := prog.AllPackages() - if len(all) != 1+len(deps) { + if len(all) <= len(deps) { t.Errorf("unexpected set of loaded packages: %q", all) } for _, path := range deps { @@ -198,7 +204,7 @@ func TestTypesWithMethodSets(t *testing.T) { }, } for i, test := range tests { - imp := importer.New(new(importer.Config)) // no go/build.Context; uses GC importer + imp := importer.New(&importer.Config{}) f, err := parser.ParseFile(imp.Fset, "", test.input, 0) if err != nil { diff --git a/ssa/create.go b/ssa/create.go index d8b04838..951400f8 100644 --- a/ssa/create.go +++ b/ssa/create.go @@ -250,6 +250,8 @@ func (prog *Program) CreatePackage(info *importer.PackageInfo) *Package { // func (prog *Program) CreatePackages(imp *importer.Importer) error { var errpkgs []string + + // Create source packages and directly imported packages. for _, info := range imp.AllPackages() { if info.Err != nil { errpkgs = append(errpkgs, info.Pkg.Path()) @@ -257,6 +259,15 @@ func (prog *Program) CreatePackages(imp *importer.Importer) error { prog.CreatePackage(info) } } + + // Create indirectly imported packages. + for _, obj := range imp.Config.TypeChecker.Packages { + prog.CreatePackage(&importer.PackageInfo{ + Pkg: obj, + Importable: true, + }) + } + if errpkgs != nil { return fmt.Errorf("couldn't create these SSA packages due to type errors: %s", strings.Join(errpkgs, ", ")) diff --git a/ssa/example_test.go b/ssa/example_test.go index 1a92dfc7..a9d98c94 100644 --- a/ssa/example_test.go +++ b/ssa/example_test.go @@ -6,7 +6,6 @@ package ssa_test import ( "fmt" - "go/build" "go/parser" "os" @@ -42,8 +41,8 @@ func main() { fmt.Println(message) } ` - // Construct an importer. Imports will be loaded as if by 'go build'. - imp := importer.New(&importer.Config{Build: &build.Default}) + // Construct an importer. + imp := importer.New(&importer.Config{}) // Parse the input file. file, err := parser.ParseFile(imp.Fset, "hello.go", hello, 0) diff --git a/ssa/interp/interp_test.go b/ssa/interp/interp_test.go index ceacbbe6..e712f999 100644 --- a/ssa/interp/interp_test.go +++ b/ssa/interp/interp_test.go @@ -168,7 +168,7 @@ func run(t *testing.T, dir, input string, success successPredicate) bool { inputs = append(inputs, dir+i) } - imp := importer.New(&importer.Config{Build: &build.Default}) + imp := importer.New(&importer.Config{SourceImports: true}) // TODO(adonovan): use LoadInitialPackages, then un-export ParseFiles. // Then add the following packages' tests, which pass: // "flag", "unicode", "unicode/utf8", "testing", "log", "path". @@ -194,8 +194,8 @@ func run(t *testing.T, dir, input string, success successPredicate) bool { hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build code.google.com/p/go.tools/cmd/ssadump && ./ssadump -build=CFP %s\n", input) mainInfo := imp.CreatePackage(files[0].Name.Name, files...) - if _, err := imp.LoadPackage("runtime"); err != nil { - t.Errorf("LoadPackage(runtime) failed: %s", err) + if _, err := imp.ImportPackage("runtime"); err != nil { + t.Errorf("ImportPackage(runtime) failed: %s", err) } prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions) @@ -321,7 +321,7 @@ func TestTestmainPackage(t *testing.T) { // CreateTestMainPackage should return nil if there were no tests. func TestNullTestmainPackage(t *testing.T) { - imp := importer.New(&importer.Config{Build: &build.Default}) + imp := importer.New(&importer.Config{}) files, err := importer.ParseFiles(imp.Fset, ".", "testdata/b_test.go") if err != nil { t.Fatalf("ParseFiles failed: %s", err) diff --git a/ssa/source_test.go b/ssa/source_test.go index 0e7118f3..e3d94b8f 100644 --- a/ssa/source_test.go +++ b/ssa/source_test.go @@ -24,7 +24,7 @@ import ( ) func TestObjValueLookup(t *testing.T) { - imp := importer.New(new(importer.Config)) // (uses GCImporter) + imp := importer.New(&importer.Config{}) f, err := parser.ParseFile(imp.Fset, "testdata/objlookup.go", nil, parser.ParseComments) if err != nil { t.Error(err) @@ -186,7 +186,7 @@ func checkVarValue(t *testing.T, prog *ssa.Program, pkg *ssa.Package, ref []ast. // Ensure that, in debug mode, we can determine the ssa.Value // corresponding to every ast.Expr. func TestValueForExpr(t *testing.T) { - imp := importer.New(new(importer.Config)) // (uses GCImporter) + imp := importer.New(&importer.Config{}) f, err := parser.ParseFile(imp.Fset, "testdata/valueforexpr.go", nil, parser.ParseComments) if err != nil { t.Error(err) diff --git a/ssa/ssautil/switch_test.go b/ssa/ssautil/switch_test.go index 4e5119a9..b7cce89f 100644 --- a/ssa/ssautil/switch_test.go +++ b/ssa/ssautil/switch_test.go @@ -15,7 +15,7 @@ import ( ) func TestSwitches(t *testing.T) { - imp := importer.New(new(importer.Config)) // (uses GCImporter) + imp := importer.New(&importer.Config{}) f, err := parser.ParseFile(imp.Fset, "testdata/switches.go", nil, parser.ParseComments) if err != nil { t.Error(err) diff --git a/ssa/stdlib_test.go b/ssa/stdlib_test.go index 908ad47b..a99ec2f5 100644 --- a/ssa/stdlib_test.go +++ b/ssa/stdlib_test.go @@ -10,7 +10,6 @@ package ssa_test // Run test with GOMAXPROCS=8. import ( - "go/build" "go/token" "os" "path/filepath" @@ -52,12 +51,10 @@ func allPackages() []string { } func TestStdlib(t *testing.T) { - impctx := importer.Config{Build: &build.Default} - // Load, parse and type-check the program. t0 := time.Now() - imp := importer.New(&impctx) + imp := importer.New(&importer.Config{}) if _, _, err := imp.LoadInitialPackages(allPackages()); err != nil { t.Errorf("LoadInitialPackages failed: %s", err)