cmd/stringer: use source importer when available

This means that running stringer should always
have the intended effect, without having to
go install the package first, which was a common
source of confusion.

The source importer is marginally slower,
but stringer is run infrequently,
and we're only typechecking one package (and fmt),
not an entire tree, as vet does.

Fixes golang/go#10249

Change-Id: Ib8cde29bd6cc596964dbe7348065932dd59075fc
Reviewed-on: https://go-review.googlesource.com/40403
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/cmd/stringer/endtoend_test.go b/cmd/stringer/endtoend_test.go
index d71a6c1..a1db27a 100644
--- a/cmd/stringer/endtoend_test.go
+++ b/cmd/stringer/endtoend_test.go
@@ -33,7 +33,7 @@
 	defer os.RemoveAll(dir)
 	// Create stringer in temporary directory.
 	stringer := filepath.Join(dir, "stringer.exe")
-	err = run("go", "build", "-o", stringer, "stringer.go")
+	err = run("go", "build", "-o", stringer)
 	if err != nil {
 		t.Fatalf("building stringer: %s", err)
 	}
diff --git a/cmd/stringer/importer18.go b/cmd/stringer/importer18.go
new file mode 100644
index 0000000..fd21873
--- /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 0000000..deddadb
--- /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 78d7299..f741d98 100644
--- a/cmd/stringer/stringer.go
+++ b/cmd/stringer/stringer.go
@@ -66,7 +66,6 @@
 	"go/build"
 	exact "go/constant"
 	"go/format"
-	"go/importer"
 	"go/parser"
 	"go/token"
 	"go/types"
@@ -258,7 +257,7 @@
 // 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{Importer: importer.Default(), FakeImportC: true}
+	config := types.Config{Importer: defaultImporter(), FakeImportC: true}
 	info := &types.Info{
 		Defs: pkg.defs,
 	}