go.tools/go/loader: add Config.ParserMode configuration parameter.

Existing tools use the default value of zero; their behaviour is unchanged.
(*Config).ParseFile is used only from tests.

LGTM=crawshaw, rsc, gri
R=crawshaw, gri, rsc
CC=golang-codereviews
https://golang.org/cl/79290044
diff --git a/go/loader/loader.go b/go/loader/loader.go
index 970fd6d..04b54cb 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -145,6 +145,10 @@
 	// method of Config.
 	Fset *token.FileSet
 
+	// ParserMode specifies the mode to be used by the parser when
+	// loading source packages.
+	ParserMode parser.Mode
+
 	// TypeChecker contains options relating to the type checker.
 	//
 	// The supplied IgnoreFuncBodies is not used; the effective
@@ -255,8 +259,8 @@
 // ParseFile is a convenience function that invokes the parser using
 // the Config's FileSet, which is initialized if nil.
 //
-func (conf *Config) ParseFile(filename string, src interface{}, mode parser.Mode) (*ast.File, error) {
-	return parser.ParseFile(conf.fset(), filename, src, mode)
+func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) {
+	return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode)
 }
 
 // FromArgsUsage is a partial usage message that applications calling
@@ -340,7 +344,7 @@
 // conf.CreatePkgs.
 //
 func (conf *Config) CreateFromFilenames(path string, filenames ...string) error {
-	files, err := parseFiles(conf.fset(), conf.build(), nil, ".", filenames...)
+	files, err := parseFiles(conf.fset(), conf.build(), nil, ".", filenames, conf.ParserMode)
 	if err != nil {
 		return err
 	}
@@ -638,7 +642,7 @@
 	default:
 		panic(which)
 	}
-	return parseFiles(conf.fset(), &ctxt, conf.DisplayPath, bp.Dir, filenames...)
+	return parseFiles(conf.fset(), &ctxt, conf.DisplayPath, bp.Dir, filenames, conf.ParserMode)
 }
 
 // doImport imports the package denoted by path.
diff --git a/go/loader/util.go b/go/loader/util.go
index a772f02..df19b7d 100644
--- a/go/loader/util.go
+++ b/go/loader/util.go
@@ -21,7 +21,7 @@
 // I/O is done via ctxt, which may specify a virtual file system.
 // displayPath is used to transform the filenames attached to the ASTs.
 //
-func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files ...string) ([]*ast.File, error) {
+func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, error) {
 	if displayPath == nil {
 		displayPath = func(path string) string { return path }
 	}
@@ -56,7 +56,7 @@
 				errors[i] = err
 				return
 			}
-			parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, 0)
+			parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode)
 		}(i, file)
 	}
 	wg.Wait()
diff --git a/go/pointer/example_test.go b/go/pointer/example_test.go
index 14b16e4..3606ed6 100644
--- a/go/pointer/example_test.go
+++ b/go/pointer/example_test.go
@@ -45,7 +45,7 @@
 	conf := loader.Config{SourceImports: true}
 
 	// Parse the input file.
-	file, err := conf.ParseFile("myprog.go", myprog, 0)
+	file, err := conf.ParseFile("myprog.go", myprog)
 	if err != nil {
 		fmt.Print(err) // parse error
 		return
diff --git a/go/pointer/pointer_test.go b/go/pointer/pointer_test.go
index 8ee42e7..ea83220 100644
--- a/go/pointer/pointer_test.go
+++ b/go/pointer/pointer_test.go
@@ -154,7 +154,7 @@
 	conf := loader.Config{SourceImports: true}
 
 	// Parsing.
-	f, err := conf.ParseFile(filename, input, 0)
+	f, err := conf.ParseFile(filename, input)
 	if err != nil {
 		fmt.Println(err)
 		return false
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go
index 8a81d3a..d69ca85 100644
--- a/go/ssa/builder_test.go
+++ b/go/ssa/builder_test.go
@@ -42,7 +42,7 @@
 
 	// Create a single-file main package.
 	var conf loader.Config
-	f, err := conf.ParseFile("<input>", test, 0)
+	f, err := conf.ParseFile("<input>", test)
 	if err != nil {
 		t.Error(err)
 		return
@@ -211,7 +211,7 @@
 	for _, test := range tests {
 		// Create a single-file main package.
 		var conf loader.Config
-		f, err := conf.ParseFile("<input>", test.input, 0)
+		f, err := conf.ParseFile("<input>", test.input)
 		if err != nil {
 			t.Errorf("test %q: %s", test.input[:15], err)
 			continue
diff --git a/go/ssa/example_test.go b/go/ssa/example_test.go
index 71ec90c..c2d3a8f 100644
--- a/go/ssa/example_test.go
+++ b/go/ssa/example_test.go
@@ -43,7 +43,7 @@
 	var conf loader.Config
 
 	// Parse the input file.
-	file, err := conf.ParseFile("hello.go", hello, 0)
+	file, err := conf.ParseFile("hello.go", hello)
 	if err != nil {
 		fmt.Print(err) // parse error
 		return
diff --git a/go/ssa/source_test.go b/go/ssa/source_test.go
index ee371c8..0ad9820 100644
--- a/go/ssa/source_test.go
+++ b/go/ssa/source_test.go
@@ -24,8 +24,8 @@
 )
 
 func TestObjValueLookup(t *testing.T) {
-	var conf loader.Config
-	f, err := conf.ParseFile("testdata/objlookup.go", nil, parser.ParseComments)
+	conf := loader.Config{ParserMode: parser.ParseComments}
+	f, err := conf.ParseFile("testdata/objlookup.go", nil)
 	if err != nil {
 		t.Error(err)
 		return
@@ -186,8 +186,8 @@
 // Ensure that, in debug mode, we can determine the ssa.Value
 // corresponding to every ast.Expr.
 func TestValueForExpr(t *testing.T) {
-	var conf loader.Config
-	f, err := conf.ParseFile("testdata/valueforexpr.go", nil, parser.ParseComments)
+	conf := loader.Config{ParserMode: parser.ParseComments}
+	f, err := conf.ParseFile("testdata/valueforexpr.go", nil)
 	if err != nil {
 		t.Error(err)
 		return
diff --git a/go/ssa/ssautil/switch_test.go b/go/ssa/ssautil/switch_test.go
index a68f464..86d5bfb 100644
--- a/go/ssa/ssautil/switch_test.go
+++ b/go/ssa/ssautil/switch_test.go
@@ -15,8 +15,8 @@
 )
 
 func TestSwitches(t *testing.T) {
-	var conf loader.Config
-	f, err := conf.ParseFile("testdata/switches.go", nil, parser.ParseComments)
+	conf := loader.Config{ParserMode: parser.ParseComments}
+	f, err := conf.ParseFile("testdata/switches.go", nil)
 	if err != nil {
 		t.Error(err)
 		return