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>
diff --git a/cmd/callgraph/main.go b/cmd/callgraph/main.go
index 17ee462..0411395 100644
--- a/cmd/callgraph/main.go
+++ b/cmd/callgraph/main.go
@@ -153,10 +153,7 @@
 var stdout io.Writer = os.Stdout
 
 func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []string) error {
-	conf := loader.Config{
-		Build:         ctxt,
-		SourceImports: true,
-	}
+	conf := loader.Config{Build: ctxt}
 
 	if len(args) == 0 {
 		fmt.Fprintln(os.Stderr, Usage)
diff --git a/cmd/eg/eg.go b/cmd/eg/eg.go
index cc3ea64..0ad4331 100644
--- a/cmd/eg/eg.go
+++ b/cmd/eg/eg.go
@@ -55,9 +55,8 @@
 	}
 
 	conf := loader.Config{
-		Fset:          token.NewFileSet(),
-		ParserMode:    parser.ParseComments,
-		SourceImports: true,
+		Fset:       token.NewFileSet(),
+		ParserMode: parser.ParseComments,
 	}
 
 	// The first Created package is the template.
diff --git a/cmd/ssadump/main.go b/cmd/ssadump/main.go
index 8ca6aa4..2f847ab 100644
--- a/cmd/ssadump/main.go
+++ b/cmd/ssadump/main.go
@@ -79,8 +79,8 @@
 	args := flag.Args()
 
 	conf := loader.Config{
-		Build:         &build.Default,
-		SourceImports: !*importbinFlag,
+		Build:            &build.Default,
+		ImportFromBinary: *importbinFlag,
 	}
 	// TODO(adonovan): make go/types choose its default Sizes from
 	// build.Default or a specified *build.Context.
diff --git a/go/callgraph/cha/cha_test.go b/go/callgraph/cha/cha_test.go
index 3648f4d..56c7c1f 100644
--- a/go/callgraph/cha/cha_test.go
+++ b/go/callgraph/cha/cha_test.go
@@ -51,8 +51,7 @@
 		}
 
 		conf := loader.Config{
-			SourceImports: true,
-			ParserMode:    parser.ParseComments,
+			ParserMode: parser.ParseComments,
 		}
 		f, err := conf.ParseFile(filename, content)
 		if err != nil {
diff --git a/go/callgraph/rta/rta_test.go b/go/callgraph/rta/rta_test.go
index 03e16b0..11fa1a5 100644
--- a/go/callgraph/rta/rta_test.go
+++ b/go/callgraph/rta/rta_test.go
@@ -55,8 +55,7 @@
 		}
 
 		conf := loader.Config{
-			SourceImports: true,
-			ParserMode:    parser.ParseComments,
+			ParserMode: parser.ParseComments,
 		}
 		f, err := conf.ParseFile(filename, content)
 		if err != nil {
diff --git a/go/loader/loader.go b/go/loader/loader.go
index 209b49a..74ac6ee 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -234,24 +234,30 @@
 	// checked.
 	TypeCheckFuncBodies func(string) bool
 
-	// SourceImports determines whether to satisfy dependencies by
-	// loading Go source code.
+	// ImportFromBinary determines whether to satisfy dependencies by
+	// loading gc export data instead of Go source code.
 	//
-	// If true, the entire program---the initial packages and
-	// their transitive closure of dependencies---will be loaded,
-	// parsed and type-checked.  This is required for
+	// If false, the entire program---the initial packages and their
+	// transitive closure of dependencies---will be loaded from
+	// source, parsed, and type-checked.  This is required for
 	// whole-program analyses such as pointer analysis.
 	//
-	// 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, it will not yield a whole program.  It is intended
-	// for analyses that perform modular analysis of a
-	// single package, e.g. traditional compilation.
+	// If true, the go/gcimporter mechanism is used instead to read
+	// the binary export-data files written by the gc toolchain.
+	// They supply only the types of package-level declarations and
+	// values of constants, but no code, this option will not yield
+	// a whole program.  It is intended for analyses that perform
+	// 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
 	// 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.
 	// Otherwise &build.Default is used.
@@ -1031,7 +1037,7 @@
 	var info *PackageInfo
 	var err error
 	// 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)
 	} else {
 		info, err = imp.importFromBinary(path)
diff --git a/go/loader/loader_test.go b/go/loader/loader_test.go
index 2972ff5..4e9f7d3 100644
--- a/go/loader/loader_test.go
+++ b/go/loader/loader_test.go
@@ -238,10 +238,7 @@
 		"a": `package a; import _ "b"`,
 		"b": `package b; import _ "c"`,
 	}
-	conf := loader.Config{
-		SourceImports: true,
-		Build:         fakeContext(pkgs),
-	}
+	conf := loader.Config{Build: fakeContext(pkgs)}
 	conf.Import("a")
 
 	const wantErr = "couldn't load packages due to errors: b"
@@ -292,9 +289,8 @@
 		},
 	} {
 		conf := loader.Config{
-			AllowErrors:   true,
-			SourceImports: true,
-			Build:         fakeContext(test.pkgs),
+			AllowErrors: true,
+			Build:       fakeContext(test.pkgs),
 		}
 		conf.Import("a")
 
@@ -347,9 +343,8 @@
 		"e": `package e; import _ "d"`,
 	}
 	conf := loader.Config{
-		AllowErrors:   true,
-		SourceImports: true,
-		Build:         fakeContext(pkgs),
+		AllowErrors: true,
+		Build:       fakeContext(pkgs),
 	}
 	conf.Import("a")
 
@@ -398,9 +393,8 @@
 		"b": `package b; 'syntax error!`,
 	}
 	conf := loader.Config{
-		AllowErrors:   true,
-		SourceImports: true,
-		Build:         fakeContext(pkgs),
+		AllowErrors: true,
+		Build:       fakeContext(pkgs),
 	}
 	var mu sync.Mutex
 	var allErrors []error
@@ -509,9 +503,8 @@
 		// },
 	} {
 		conf := loader.Config{
-			AllowErrors:   true,
-			SourceImports: true,
-			Build:         test.ctxt,
+			AllowErrors: true,
+			Build:       test.ctxt,
 		}
 		var mu sync.Mutex
 		var allErrors []error
diff --git a/go/pointer/analysis.go b/go/pointer/analysis.go
index 8887a86..f3b70f1 100644
--- a/go/pointer/analysis.go
+++ b/go/pointer/analysis.go
@@ -255,7 +255,7 @@
 		// (This only checks that the package scope is complete,
 		// not that func bodies exist, but it's a good signal.)
 		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())
 		}
 	}
 
diff --git a/go/pointer/example_test.go b/go/pointer/example_test.go
index f6cca48..5f2e940 100644
--- a/go/pointer/example_test.go
+++ b/go/pointer/example_test.go
@@ -41,8 +41,7 @@
 	i.f(x) // dynamic method call
 }
 `
-	// Construct a loader.
-	conf := loader.Config{SourceImports: true}
+	var conf loader.Config
 
 	// Parse the input file, a string.
 	// (Command-line tools should use conf.FromArgs.)
diff --git a/go/pointer/pointer_test.go b/go/pointer/pointer_test.go
index 30662e9..1daf9c3 100644
--- a/go/pointer/pointer_test.go
+++ b/go/pointer/pointer_test.go
@@ -153,7 +153,7 @@
 }
 
 func doOneInput(input, filename string) bool {
-	conf := loader.Config{SourceImports: true}
+	var conf loader.Config
 
 	// Parsing.
 	f, err := conf.ParseFile(filename, input)
diff --git a/go/pointer/stdlib_test.go b/go/pointer/stdlib_test.go
index 214cdfc..6365279 100644
--- a/go/pointer/stdlib_test.go
+++ b/go/pointer/stdlib_test.go
@@ -35,10 +35,7 @@
 	// Load, parse and type-check the program.
 	ctxt := build.Default // copy
 	ctxt.GOPATH = ""      // disable GOPATH
-	conf := loader.Config{
-		SourceImports: true,
-		Build:         &ctxt,
-	}
+	conf := loader.Config{Build: &ctxt}
 	if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil {
 		t.Errorf("FromArgs failed: %v", err)
 		return
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go
index dc7434f..cb30ef6 100644
--- a/go/ssa/builder_test.go
+++ b/go/ssa/builder_test.go
@@ -21,7 +21,7 @@
 
 // Tests that programs partially loaded from gc object files contain
 // functions with no code for the external portions, but are otherwise ok.
-func TestExternalPackages(t *testing.T) {
+func TestImportFromBinary(t *testing.T) {
 	test := `
 package main
 
@@ -43,7 +43,7 @@
 `
 
 	// Create a single-file main package.
-	var conf loader.Config
+	conf := loader.Config{ImportFromBinary: true}
 	f, err := conf.ParseFile("<input>", test)
 	if err != nil {
 		t.Error(err)
@@ -212,7 +212,7 @@
 	}
 	for _, test := range tests {
 		// Create a single-file main package.
-		var conf loader.Config
+		conf := loader.Config{ImportFromBinary: true}
 		f, err := conf.ParseFile("<input>", test.input)
 		if err != nil {
 			t.Errorf("test %q: %s", test.input[:15], err)
diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go
index 19f2ca0..569d9ea 100644
--- a/go/ssa/interp/interp_test.go
+++ b/go/ssa/interp/interp_test.go
@@ -188,7 +188,7 @@
 		inputs = append(inputs, i)
 	}
 
-	conf := loader.Config{SourceImports: true}
+	var conf loader.Config
 	if _, err := conf.FromArgs(inputs, true); err != nil {
 		t.Errorf("FromArgs(%s) failed: %s", inputs, err)
 		return false
diff --git a/go/ssa/stdlib_test.go b/go/ssa/stdlib_test.go
index 5e12aeb..63d031e 100644
--- a/go/ssa/stdlib_test.go
+++ b/go/ssa/stdlib_test.go
@@ -38,10 +38,7 @@
 	// Load, parse and type-check the program.
 	ctxt := build.Default // copy
 	ctxt.GOPATH = ""      // disable GOPATH
-	conf := loader.Config{
-		SourceImports: true,
-		Build:         &ctxt,
-	}
+	conf := loader.Config{Build: &ctxt}
 	if _, err := conf.FromArgs(buildutil.AllPackages(conf.Build), true); err != nil {
 		t.Errorf("FromArgs failed: %v", err)
 		return
diff --git a/godoc/analysis/analysis.go b/godoc/analysis/analysis.go
index 4d7e1ea..1f59a4a 100644
--- a/godoc/analysis/analysis.go
+++ b/godoc/analysis/analysis.go
@@ -338,8 +338,7 @@
 //
 func Run(pta bool, result *Result) {
 	conf := loader.Config{
-		SourceImports: true,
-		AllowErrors:   true,
+		AllowErrors: true,
 	}
 
 	// Silence the default error handler.
diff --git a/oracle/oracle.go b/oracle/oracle.go
index 4bb8a9d..3cff219 100644
--- a/oracle/oracle.go
+++ b/oracle/oracle.go
@@ -193,7 +193,7 @@
 // Clients that intend to perform multiple queries against the same
 // 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) ...
 //	iprog, err := conf.Load()
 //	if err != nil { ... }
@@ -223,7 +223,7 @@
 		return nil, fmt.Errorf("invalid mode type: %q", mode)
 	}
 
-	conf := loader.Config{Build: buildContext, SourceImports: true}
+	conf := loader.Config{Build: buildContext}
 
 	// Determine initial packages.
 	args, err := conf.FromArgs(args, true)
diff --git a/oracle/oracle_test.go b/oracle/oracle_test.go
index 9775d6f..bbceb60 100644
--- a/oracle/oracle_test.go
+++ b/oracle/oracle_test.go
@@ -272,7 +272,7 @@
 	// Loader
 	var buildContext = build.Default
 	buildContext.GOPATH = "testdata"
-	conf := loader.Config{Build: &buildContext, SourceImports: true}
+	conf := loader.Config{Build: &buildContext}
 	filename := "testdata/src/main/multi.go"
 	conf.CreateFromFilenames("", filename)
 	iprog, err := conf.Load()
diff --git a/refactor/eg/eg_test.go b/refactor/eg/eg_test.go
index bb96faf..c44256c 100644
--- a/refactor/eg/eg_test.go
+++ b/refactor/eg/eg_test.go
@@ -36,9 +36,8 @@
 	}
 
 	conf := loader.Config{
-		Fset:          token.NewFileSet(),
-		ParserMode:    parser.ParseComments,
-		SourceImports: true,
+		Fset:       token.NewFileSet(),
+		ParserMode: parser.ParseComments,
 	}
 
 	// Each entry is a single-file package.
diff --git a/refactor/lexical/lexical_test.go b/refactor/lexical/lexical_test.go
index 1b772d6..fd237ce 100644
--- a/refactor/lexical/lexical_test.go
+++ b/refactor/lexical/lexical_test.go
@@ -32,10 +32,7 @@
 		"golang.org/x/tools/refactor/lexical")
 
 	// Load, parse and type-check the program.
-	conf := loader.Config{
-		Build:         &ctxt,
-		SourceImports: true,
-	}
+	conf := loader.Config{Build: &ctxt}
 	for _, path := range pkgs {
 		conf.ImportWithTests(path)
 	}
diff --git a/refactor/rename/rename.go b/refactor/rename/rename.go
index fc76b32..2f86e2e 100644
--- a/refactor/rename/rename.go
+++ b/refactor/rename/rename.go
@@ -339,9 +339,8 @@
 // context.  Only packages in pkgs will have their functions bodies typechecked.
 func loadProgram(ctxt *build.Context, pkgs map[string]bool) (*loader.Program, error) {
 	conf := loader.Config{
-		Build:         ctxt,
-		SourceImports: true,
-		ParserMode:    parser.ParseComments,
+		Build:      ctxt,
+		ParserMode: parser.ParseComments,
 
 		// TODO(adonovan): enable this.  Requires making a lot of code more robust!
 		AllowErrors: false,