go.tools/go/loader: simplify command-line syntax.
Previously, each word could be a package import path or a
comma-separated list of *.go file names. Now, if the
first word ends with ".go", all words are assumed to be
Go source files. This makes it impossible to specify
two ad-hoc packages from source files, but no-one needs that.
FromArgs also takes a boolean indicating whether tests
are wanted or not.
Also: ssadump: add -test flag to set that boolean.
For the oracle it's always true.
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/61470047
diff --git a/go/loader/importer_test.go b/go/loader/importer_test.go
index be6a470..54aec5b 100644
--- a/go/loader/importer_test.go
+++ b/go/loader/importer_test.go
@@ -14,7 +14,7 @@
func loadFromArgs(args []string) (prog *loader.Program, rest []string, err error) {
conf := &loader.Config{}
- rest, err = conf.FromArgs(args)
+ rest, err = conf.FromArgs(args, true)
if err == nil {
prog, err = conf.Load()
}
@@ -39,11 +39,10 @@
}
// Successful load.
- args = []string{"fmt", "errors", "testdata/a.go,testdata/b.go", "--", "surplus"}
+ args = []string{"fmt", "errors", "--", "surplus"}
prog, rest, err := loadFromArgs(args)
if err != nil {
- t.Errorf("loadFromArgs(%q) failed: %s", args, err)
- return
+ t.Fatalf("loadFromArgs(%q) failed: %s", args, err)
}
if got, want := fmt.Sprint(rest), "[surplus]"; got != want {
t.Errorf("loadFromArgs(%q) rest: got %s, want %s", args, got, want)
@@ -54,7 +53,7 @@
pkgnames = append(pkgnames, info.Pkg.Path())
}
// Only the first import path (currently) contributes tests.
- if got, want := fmt.Sprint(pkgnames), "[fmt_test P]"; got != want {
+ if got, want := fmt.Sprint(pkgnames), "[fmt_test]"; got != want {
t.Errorf("Created: got %s, want %s", got, want)
}
@@ -82,3 +81,25 @@
}
}
}
+
+func TestLoadFromArgsSource(t *testing.T) {
+ // mixture of *.go/non-go.
+ args := []string{"testdata/a.go", "fmt"}
+ prog, _, err := loadFromArgs(args)
+ if err == nil {
+ t.Errorf("loadFromArgs(%q) succeeded, want failure", args)
+ } else {
+ // "named files must be .go files: fmt": ok
+ }
+
+ // successful load
+ args = []string{"testdata/a.go", "testdata/b.go"}
+ prog, _, err = loadFromArgs(args)
+ if err != nil {
+ t.Errorf("loadFromArgs(%q) failed: %s", args, err)
+ return
+ }
+ if len(prog.Created) != 1 || prog.Created[0].Pkg.Path() != "P" {
+ t.Errorf("loadFromArgs(%q): got %v, want [P]", prog.Created)
+ }
+}
diff --git a/go/loader/loader.go b/go/loader/loader.go
index 06c2603..3fcd7f8 100644
--- a/go/loader/loader.go
+++ b/go/loader/loader.go
@@ -23,7 +23,7 @@
// // Use the command-line arguments to specify
// // a set of initial packages to load from source.
// // See FromArgsUsage for help.
-// rest, err := conf.FromArgs(os.Args[1:])
+// rest, err := conf.FromArgs(os.Args[1:], wantTests)
//
// // Parse the specified files and create an ad-hoc package with path "foo".
// // All files must have the same 'package' declaration.
@@ -228,15 +228,14 @@
// FromArgs may wish to include in their -help output.
const FromArgsUsage = `
<args> is a list of arguments denoting a set of initial packages.
-Each argument may take one of two forms:
+It may take one of two forms:
-1. A comma-separated list of *.go source files.
+1. A list of *.go source files.
All of the specified files are loaded, parsed and type-checked
- as a single package.
- All the files must belong to the same directory.
+ as a single package. All the files must belong to the same directory.
-2. An import path.
+2. A list of import paths, each denoting a package.
The package's directory is found relative to the $GOROOT and
$GOPATH using similar logic to 'go build', and the *.go files in
@@ -248,9 +247,8 @@
the non-*_test.go files are included in the primary package. Test
files whose package declaration ends with "_test" are type-checked
as another package, the 'external' test package, so that a single
- import path may denote two packages. This behaviour may be
- disabled by prefixing the import path with "notest:",
- e.g. "notest:fmt".
+ import path may denote two packages. (Whether this behaviour is
+ enabled is tool-specific, and may depend on additional flags.)
Due to current limitations in the type-checker, only the first
import path of the command line will contribute any tests.
@@ -266,33 +264,40 @@
// set of initial packages to be specified; see FromArgsUsage message
// for details.
//
-func (conf *Config) FromArgs(args []string) (rest []string, err error) {
- for len(args) > 0 {
- arg := args[0]
- args = args[1:]
+func (conf *Config) FromArgs(args []string, xtest bool) (rest []string, err error) {
+ for i, arg := range args {
if arg == "--" {
+ rest = args[i+1:]
+ args = args[:i]
break // consume "--" and return the remaining args
}
+ }
- if strings.HasSuffix(arg, ".go") {
- // Assume arg is a comma-separated list of *.go files
- // denoting a single ad-hoc package.
- err = conf.CreateFromFilenames("", strings.Split(arg, ",")...)
- } else {
- // Assume arg is a directory name denoting a
- // package, perhaps plus an external test
- // package unless prefixed by "notest:".
- if path := strings.TrimPrefix(arg, "notest:"); path != arg {
- conf.Import(path)
- } else {
- err = conf.ImportWithTests(path)
+ if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
+ // Assume args is a list of a *.go files
+ // denoting a single ad-hoc package.
+ for _, arg := range args {
+ if !strings.HasSuffix(arg, ".go") {
+ return nil, fmt.Errorf("named files must be .go files: %s", arg)
}
}
- if err != nil {
- return nil, err
+ err = conf.CreateFromFilenames("", args...)
+ } else {
+ // Assume args are directories each denoting a
+ // package and (perhaps) an external test, iff xtest.
+ for _, arg := range args {
+ if xtest {
+ err = conf.ImportWithTests(arg)
+ if err != nil {
+ break
+ }
+ } else {
+ conf.Import(arg)
+ }
}
}
- return args, nil
+
+ return
}
// CreateFromFilenames is a convenience function that parses the
@@ -371,7 +376,8 @@
if conf.ImportPkgs == nil {
conf.ImportPkgs = make(map[string]bool)
}
- conf.ImportPkgs[path] = false // unaugmented source package
+ // Subtle: adds value 'false' unless value is already true.
+ conf.ImportPkgs[path] = conf.ImportPkgs[path] // unaugmented source package
}
// PathEnclosingInterval returns the PackageInfo and ast.Node that
diff --git a/go/ssa/stdlib_test.go b/go/ssa/stdlib_test.go
index e3ae81c..b09be7e 100644
--- a/go/ssa/stdlib_test.go
+++ b/go/ssa/stdlib_test.go
@@ -53,7 +53,7 @@
t0 := time.Now()
var conf loader.Config
- if _, err := conf.FromArgs(allPackages()); err != nil {
+ if _, err := conf.FromArgs(allPackages(), true); err != nil {
t.Errorf("FromArgs failed: %v", err)
return
}