diff --git a/cmd/stringer/endtoend_test.go b/cmd/stringer/endtoend_test.go index 91f34092..273f29bd 100644 --- a/cmd/stringer/endtoend_test.go +++ b/cmd/stringer/endtoend_test.go @@ -9,7 +9,6 @@ package main import ( - "bytes" "fmt" "go/build" "io" @@ -27,8 +26,17 @@ import ( // binary panics if the String method for X is not correct, including for error cases. func TestEndToEnd(t *testing.T) { - dir, stringer := buildStringer(t) + dir, err := ioutil.TempDir("", "stringer") + if err != nil { + t.Fatal(err) + } defer os.RemoveAll(dir) + // Create stringer in temporary directory. + stringer := filepath.Join(dir, "stringer.exe") + err = run("go", "build", "-o", stringer) + if err != nil { + t.Fatalf("building stringer: %s", err) + } // Read the testdata directory. fd, err := os.Open("testdata") if err != nil { @@ -45,10 +53,6 @@ func TestEndToEnd(t *testing.T) { t.Errorf("%s is not a Go file", name) continue } - if strings.HasPrefix(name, "tag_") { - // This file is used for tag processing in TestTags, below. - continue - } if name == "cgo.go" && !build.Default.CgoEnabled { t.Logf("cgo is not enabled for %s", name) continue @@ -59,69 +63,9 @@ func TestEndToEnd(t *testing.T) { } } -// TestTags verifies that the -tags flag works as advertised. -func TestTags(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) - var ( - protectedConst = []byte("TagProtected") - output = filepath.Join(dir, "const_string.go") - ) - for _, file := range []string{"tag_main.go", "tag_tag.go"} { - - err := copy(filepath.Join(dir, file), filepath.Join("testdata", file)) - if err != nil { - t.Fatal(err) - } - - } - err := run(stringer, "-type", "Const", dir) - if err != nil { - t.Fatal(err) - } - result, err := ioutil.ReadFile(output) - if err != nil { - t.Fatal(err) - } - if bytes.Contains(result, protectedConst) { - t.Fatal("tagged variable appears in untagged run") - } - err = os.Remove(output) - if err != nil { - t.Fatal(err) - } - err = run(stringer, "-type", "Const", "-tags", "tag", dir) - if err != nil { - t.Fatal(err) - } - result, err = ioutil.ReadFile(output) - if err != nil { - t.Fatal(err) - } - if !bytes.Contains(result, protectedConst) { - t.Fatal("tagged variable does not appear in tagged run") - } -} - -// buildStringer creates a temporary directory and installs stringer there. -func buildStringer(t *testing.T) (dir string, stringer string) { - t.Helper() - dir, err := ioutil.TempDir("", "stringer") - if err != nil { - t.Fatal(err) - } - stringer = filepath.Join(dir, "stringer.exe") - err = run("go", "build", "-o", stringer, "stringer.go") - if err != nil { - t.Fatalf("building stringer: %s", err) - } - return dir, stringer -} - // stringerCompileAndRun runs stringer for the named file and compiles and // runs the target binary in directory dir. That binary will panic if the String method is incorrect. func stringerCompileAndRun(t *testing.T, dir, stringer, typeName, fileName string) { - t.Helper() t.Logf("run: %s %s\n", fileName, typeName) source := filepath.Join(dir, fileName) err := copy(source, filepath.Join("testdata", fileName)) diff --git a/cmd/stringer/importer18.go b/cmd/stringer/importer18.go new file mode 100644 index 00000000..fd21873c --- /dev/null +++ b/cmd/stringer/importer18.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.9 + +package main + +import ( + "go/importer" + "go/types" +) + +func defaultImporter() types.Importer { + return importer.Default() +} diff --git a/cmd/stringer/importer19.go b/cmd/stringer/importer19.go new file mode 100644 index 00000000..deddadb1 --- /dev/null +++ b/cmd/stringer/importer19.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.9 + +package main + +import ( + "go/importer" + "go/types" +) + +func defaultImporter() types.Importer { + return importer.For("source", nil) +} diff --git a/cmd/stringer/stringer.go b/cmd/stringer/stringer.go index bed6b6b4..4b8d1ba4 100644 --- a/cmd/stringer/stringer.go +++ b/cmd/stringer/stringer.go @@ -66,7 +66,6 @@ import ( "go/build" exact "go/constant" "go/format" - "go/importer" "go/parser" "go/token" "go/types" @@ -83,7 +82,6 @@ var ( output = flag.String("output", "", "output file name; default srcdir/_string.go") trimprefix = flag.String("trimprefix", "", "trim the `prefix` from the generated constant names") linecomment = flag.Bool("linecomment", false, "use line comment text as printed text when present") - buildTags = flag.String("tags", "", "comma-separated list of build tags to apply") ) // Usage is a replacement usage function for the flags package. @@ -107,10 +105,6 @@ func main() { os.Exit(2) } types := strings.Split(*typeNames, ",") - var tags []string - if len(*buildTags) > 0 { - tags = strings.Split(*buildTags, ",") - } // We accept either one directory or a list of files. Which do we have? args := flag.Args() @@ -127,11 +121,8 @@ func main() { } if len(args) == 1 && isDirectory(args[0]) { dir = args[0] - g.parsePackageDir(args[0], tags) + g.parsePackageDir(args[0]) } else { - if len(tags) != 0 { - log.Fatal("-tags option applies only to directories, not when files are specified") - } dir = filepath.Dir(args[0]) g.parsePackageFiles(args) } @@ -206,15 +197,9 @@ type Package struct { typesPkg *types.Package } -func buildContext(tags []string) *build.Context { - ctx := build.Default - ctx.BuildTags = tags - return &ctx -} - // parsePackageDir parses the package residing in the directory. -func (g *Generator) parsePackageDir(directory string, tags []string) { - pkg, err := buildContext(tags).ImportDir(directory, 0) +func (g *Generator) parsePackageDir(directory string) { + pkg, err := build.Default.ImportDir(directory, 0) if err != nil { log.Fatalf("cannot process directory %s: %s", directory, err) } @@ -276,17 +261,14 @@ func (g *Generator) parsePackage(directory string, names []string, text interfac g.pkg.name = astFiles[0].Name.Name g.pkg.files = files g.pkg.dir = directory - g.pkg.typeCheck(fs, astFiles) + // Type check the package. + g.pkg.check(fs, astFiles) } -// check type-checks the package so we can evaluate contants whose values we are printing. -func (pkg *Package) typeCheck(fs *token.FileSet, astFiles []*ast.File) { +// check type-checks the package. The package must be OK to proceed. +func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) { pkg.defs = make(map[*ast.Ident]types.Object) - config := types.Config{ - IgnoreFuncBodies: true, // We only need to evaluate constants. - Importer: importer.Default(), - FakeImportC: true, - } + config := types.Config{Importer: defaultImporter(), FakeImportC: true} info := &types.Info{ Defs: pkg.defs, } diff --git a/cmd/stringer/testdata/tag_main.go b/cmd/stringer/testdata/tag_main.go deleted file mode 100644 index 449ea0d4..00000000 --- a/cmd/stringer/testdata/tag_main.go +++ /dev/null @@ -1,11 +0,0 @@ -// No build tag in this file. - -package main - -type Const int - -const ( - A Const = iota - B - C -) diff --git a/cmd/stringer/testdata/tag_tag.go b/cmd/stringer/testdata/tag_tag.go deleted file mode 100644 index 6844cb00..00000000 --- a/cmd/stringer/testdata/tag_tag.go +++ /dev/null @@ -1,7 +0,0 @@ -// This file has a build tag "tag" - -// +build tag - -package main - -const TagProtected Const = C + 1