go/loader: rename SourceImports flag to ImportFromBinary and invert sense

...since the zero value is more useful by far.

This is a breaking API change, obviously.  (One or two tests in this
CL have intentional been left using the zero value, i.e., they now
load source.)

Change-Id: I42287bfcdb1afef8ee84e5eac12534dd0a1fd5d2
Reviewed-on: https://go-review.googlesource.com/5653
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Alan Donovan 2015-02-23 17:03:22 -05:00
parent b141c84c2e
commit 69db398fe0
20 changed files with 53 additions and 73 deletions

View File

@ -153,10 +153,7 @@ func main() {
var stdout io.Writer = os.Stdout var stdout io.Writer = os.Stdout
func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []string) error { func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []string) error {
conf := loader.Config{ conf := loader.Config{Build: ctxt}
Build: ctxt,
SourceImports: true,
}
if len(args) == 0 { if len(args) == 0 {
fmt.Fprintln(os.Stderr, Usage) fmt.Fprintln(os.Stderr, Usage)

View File

@ -57,7 +57,6 @@ func doMain() error {
conf := loader.Config{ conf := loader.Config{
Fset: token.NewFileSet(), Fset: token.NewFileSet(),
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
SourceImports: true,
} }
// The first Created package is the template. // The first Created package is the template.

View File

@ -80,7 +80,7 @@ func doMain() error {
conf := loader.Config{ conf := loader.Config{
Build: &build.Default, Build: &build.Default,
SourceImports: !*importbinFlag, ImportFromBinary: *importbinFlag,
} }
// TODO(adonovan): make go/types choose its default Sizes from // TODO(adonovan): make go/types choose its default Sizes from
// build.Default or a specified *build.Context. // build.Default or a specified *build.Context.

View File

@ -51,7 +51,6 @@ func TestCHA(t *testing.T) {
} }
conf := loader.Config{ conf := loader.Config{
SourceImports: true,
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
} }
f, err := conf.ParseFile(filename, content) f, err := conf.ParseFile(filename, content)

View File

@ -55,7 +55,6 @@ func TestRTA(t *testing.T) {
} }
conf := loader.Config{ conf := loader.Config{
SourceImports: true,
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
} }
f, err := conf.ParseFile(filename, content) f, err := conf.ParseFile(filename, content)

View File

@ -234,24 +234,30 @@ type Config struct {
// checked. // checked.
TypeCheckFuncBodies func(string) bool TypeCheckFuncBodies func(string) bool
// SourceImports determines whether to satisfy dependencies by // ImportFromBinary determines whether to satisfy dependencies by
// loading Go source code. // loading gc export data instead of Go source code.
// //
// If true, the entire program---the initial packages and // If false, the entire program---the initial packages and their
// their transitive closure of dependencies---will be loaded, // transitive closure of dependencies---will be loaded from
// parsed and type-checked. This is required for // source, parsed, and type-checked. This is required for
// whole-program analyses such as pointer analysis. // whole-program analyses such as pointer analysis.
// //
// If false, the TypeChecker.Import mechanism will be used // If true, the go/gcimporter mechanism is used instead to read
// instead. Since that typically supplies only the types of // the binary export-data files written by the gc toolchain.
// package-level declarations and values of constants, but no // They supply only the types of package-level declarations and
// code, it will not yield a whole program. It is intended // values of constants, but no code, this option will not yield
// for analyses that perform modular analysis of a // a whole program. It is intended for analyses that perform
// single package, e.g. traditional compilation. // modular analysis of a single package, e.g. traditional
// compilation.
//
// No check is made that the export data files are up-to-date.
// //
// The initial packages (CreatePkgs and ImportPkgs) are always // The initial packages (CreatePkgs and ImportPkgs) are always
// loaded from Go source, regardless of this flag's setting. // loaded from Go source, regardless of this flag's setting.
SourceImports bool //
// NB: there is a bug when loading multiple initial packages with
// this flag enabled: https://github.com/golang/go/issues/9955.
ImportFromBinary bool
// If Build is non-nil, it is used to locate source packages. // If Build is non-nil, it is used to locate source packages.
// Otherwise &build.Default is used. // Otherwise &build.Default is used.
@ -1031,7 +1037,7 @@ func (imp *importer) load(path string, ii *importInfo) {
var info *PackageInfo var info *PackageInfo
var err error var err error
// Find and create the actual package. // Find and create the actual package.
if _, ok := imp.conf.ImportPkgs[path]; ok || imp.conf.SourceImports { if _, ok := imp.conf.ImportPkgs[path]; ok || !imp.conf.ImportFromBinary {
info, err = imp.loadFromSource(path) info, err = imp.loadFromSource(path)
} else { } else {
info, err = imp.importFromBinary(path) info, err = imp.importFromBinary(path)

View File

@ -238,10 +238,7 @@ func TestLoad_MissingIndirectImport(t *testing.T) {
"a": `package a; import _ "b"`, "a": `package a; import _ "b"`,
"b": `package b; import _ "c"`, "b": `package b; import _ "c"`,
} }
conf := loader.Config{ conf := loader.Config{Build: fakeContext(pkgs)}
SourceImports: true,
Build: fakeContext(pkgs),
}
conf.Import("a") conf.Import("a")
const wantErr = "couldn't load packages due to errors: b" const wantErr = "couldn't load packages due to errors: b"
@ -293,7 +290,6 @@ func TestLoad_BadDependency_AllowErrors(t *testing.T) {
} { } {
conf := loader.Config{ conf := loader.Config{
AllowErrors: true, AllowErrors: true,
SourceImports: true,
Build: fakeContext(test.pkgs), Build: fakeContext(test.pkgs),
} }
conf.Import("a") conf.Import("a")
@ -348,7 +344,6 @@ func TestTransitivelyErrorFreeFlag(t *testing.T) {
} }
conf := loader.Config{ conf := loader.Config{
AllowErrors: true, AllowErrors: true,
SourceImports: true,
Build: fakeContext(pkgs), Build: fakeContext(pkgs),
} }
conf.Import("a") conf.Import("a")
@ -399,7 +394,6 @@ func TestErrorReporting(t *testing.T) {
} }
conf := loader.Config{ conf := loader.Config{
AllowErrors: true, AllowErrors: true,
SourceImports: true,
Build: fakeContext(pkgs), Build: fakeContext(pkgs),
} }
var mu sync.Mutex var mu sync.Mutex
@ -510,7 +504,6 @@ func TestCycles(t *testing.T) {
} { } {
conf := loader.Config{ conf := loader.Config{
AllowErrors: true, AllowErrors: true,
SourceImports: true,
Build: test.ctxt, Build: test.ctxt,
} }
var mu sync.Mutex var mu sync.Mutex

View File

@ -255,7 +255,7 @@ func Analyze(config *Config) (result *Result, err error) {
// (This only checks that the package scope is complete, // (This only checks that the package scope is complete,
// not that func bodies exist, but it's a good signal.) // not that func bodies exist, but it's a good signal.)
if !pkg.Object.Complete() { if !pkg.Object.Complete() {
return nil, fmt.Errorf(`pointer analysis requires a complete program yet package %q was incomplete (set loader.Config.SourceImports during loading)`, pkg.Object.Path()) return nil, fmt.Errorf(`pointer analysis requires a complete program yet package %q was incomplete (don't set loader.Config.ImportFromBinary during loading)`, pkg.Object.Path())
} }
} }

View File

@ -41,8 +41,7 @@ func main() {
i.f(x) // dynamic method call i.f(x) // dynamic method call
} }
` `
// Construct a loader. var conf loader.Config
conf := loader.Config{SourceImports: true}
// Parse the input file, a string. // Parse the input file, a string.
// (Command-line tools should use conf.FromArgs.) // (Command-line tools should use conf.FromArgs.)

View File

@ -153,7 +153,7 @@ func findProbe(prog *ssa.Program, probes map[*ssa.CallCommon]bool, queries map[s
} }
func doOneInput(input, filename string) bool { func doOneInput(input, filename string) bool {
conf := loader.Config{SourceImports: true} var conf loader.Config
// Parsing. // Parsing.
f, err := conf.ParseFile(filename, input) f, err := conf.ParseFile(filename, input)

View File

@ -35,10 +35,7 @@ func TestStdlib(t *testing.T) {
// Load, parse and type-check the program. // Load, parse and type-check the program.
ctxt := build.Default // copy ctxt := build.Default // copy
ctxt.GOPATH = "" // disable GOPATH ctxt.GOPATH = "" // disable GOPATH
conf := loader.Config{ conf := loader.Config{Build: &ctxt}
SourceImports: true,
Build: &ctxt,
}
if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil { if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil {
t.Errorf("FromArgs failed: %v", err) t.Errorf("FromArgs failed: %v", err)
return return

View File

@ -21,7 +21,7 @@ func isEmpty(f *ssa.Function) bool { return f.Blocks == nil }
// Tests that programs partially loaded from gc object files contain // Tests that programs partially loaded from gc object files contain
// functions with no code for the external portions, but are otherwise ok. // functions with no code for the external portions, but are otherwise ok.
func TestExternalPackages(t *testing.T) { func TestImportFromBinary(t *testing.T) {
test := ` test := `
package main package main
@ -43,7 +43,7 @@ func main() {
` `
// Create a single-file main package. // Create a single-file main package.
var conf loader.Config conf := loader.Config{ImportFromBinary: true}
f, err := conf.ParseFile("<input>", test) f, err := conf.ParseFile("<input>", test)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -212,7 +212,7 @@ func TestRuntimeTypes(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
// Create a single-file main package. // Create a single-file main package.
var conf loader.Config conf := loader.Config{ImportFromBinary: true}
f, err := conf.ParseFile("<input>", test.input) f, err := conf.ParseFile("<input>", test.input)
if err != nil { if err != nil {
t.Errorf("test %q: %s", test.input[:15], err) t.Errorf("test %q: %s", test.input[:15], err)

View File

@ -188,7 +188,7 @@ func run(t *testing.T, dir, input string, success successPredicate) bool {
inputs = append(inputs, i) inputs = append(inputs, i)
} }
conf := loader.Config{SourceImports: true} var conf loader.Config
if _, err := conf.FromArgs(inputs, true); err != nil { if _, err := conf.FromArgs(inputs, true); err != nil {
t.Errorf("FromArgs(%s) failed: %s", inputs, err) t.Errorf("FromArgs(%s) failed: %s", inputs, err)
return false return false

View File

@ -38,10 +38,7 @@ func TestStdlib(t *testing.T) {
// Load, parse and type-check the program. // Load, parse and type-check the program.
ctxt := build.Default // copy ctxt := build.Default // copy
ctxt.GOPATH = "" // disable GOPATH ctxt.GOPATH = "" // disable GOPATH
conf := loader.Config{ conf := loader.Config{Build: &ctxt}
SourceImports: true,
Build: &ctxt,
}
if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil { if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil {
t.Errorf("FromArgs failed: %v", err) t.Errorf("FromArgs failed: %v", err)
return return

View File

@ -338,7 +338,6 @@ func (a *analysis) posURL(pos token.Pos, len int) string {
// //
func Run(pta bool, result *Result) { func Run(pta bool, result *Result) {
conf := loader.Config{ conf := loader.Config{
SourceImports: true,
AllowErrors: true, AllowErrors: true,
} }

View File

@ -193,7 +193,7 @@ func (res *Result) Serial() *serial.Result {
// Clients that intend to perform multiple queries against the same // Clients that intend to perform multiple queries against the same
// analysis scope should use this pattern instead: // analysis scope should use this pattern instead:
// //
// conf := loader.Config{Build: buildContext, SourceImports: true} // conf := loader.Config{Build: buildContext}
// ... populate config, e.g. conf.FromArgs(args) ... // ... populate config, e.g. conf.FromArgs(args) ...
// iprog, err := conf.Load() // iprog, err := conf.Load()
// if err != nil { ... } // if err != nil { ... }
@ -223,7 +223,7 @@ func Query(args []string, mode, pos string, ptalog io.Writer, buildContext *buil
return nil, fmt.Errorf("invalid mode type: %q", mode) return nil, fmt.Errorf("invalid mode type: %q", mode)
} }
conf := loader.Config{Build: buildContext, SourceImports: true} conf := loader.Config{Build: buildContext}
// Determine initial packages. // Determine initial packages.
args, err := conf.FromArgs(args, true) args, err := conf.FromArgs(args, true)

View File

@ -272,7 +272,7 @@ func TestMultipleQueries(t *testing.T) {
// Loader // Loader
var buildContext = build.Default var buildContext = build.Default
buildContext.GOPATH = "testdata" buildContext.GOPATH = "testdata"
conf := loader.Config{Build: &buildContext, SourceImports: true} conf := loader.Config{Build: &buildContext}
filename := "testdata/src/main/multi.go" filename := "testdata/src/main/multi.go"
conf.CreateFromFilenames("", filename) conf.CreateFromFilenames("", filename)
iprog, err := conf.Load() iprog, err := conf.Load()

View File

@ -38,7 +38,6 @@ func Test(t *testing.T) {
conf := loader.Config{ conf := loader.Config{
Fset: token.NewFileSet(), Fset: token.NewFileSet(),
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
SourceImports: true,
} }
// Each entry is a single-file package. // Each entry is a single-file package.

View File

@ -32,10 +32,7 @@ func TestStdlib(t *testing.T) {
"golang.org/x/tools/refactor/lexical") "golang.org/x/tools/refactor/lexical")
// Load, parse and type-check the program. // Load, parse and type-check the program.
conf := loader.Config{ conf := loader.Config{Build: &ctxt}
Build: &ctxt,
SourceImports: true,
}
for _, path := range pkgs { for _, path := range pkgs {
conf.ImportWithTests(path) conf.ImportWithTests(path)
} }

View File

@ -340,7 +340,6 @@ func Main(ctxt *build.Context, offsetFlag, fromFlag, to string) error {
func loadProgram(ctxt *build.Context, pkgs map[string]bool) (*loader.Program, error) { func loadProgram(ctxt *build.Context, pkgs map[string]bool) (*loader.Program, error) {
conf := loader.Config{ conf := loader.Config{
Build: ctxt, Build: ctxt,
SourceImports: true,
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
// TODO(adonovan): enable this. Requires making a lot of code more robust! // TODO(adonovan): enable this. Requires making a lot of code more robust!