aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/api/goapi.go23
-rw-r--r--src/cmd/api/goapi_test.go3
-rw-r--r--src/cmd/godoc/godoc.go28
-rw-r--r--src/cmd/godoc/main.go6
-rw-r--r--src/pkg/exp/types/gcimporter.go12
-rw-r--r--src/pkg/go/build/build.go537
-rw-r--r--src/pkg/go/build/build_test.go110
-rw-r--r--src/pkg/go/build/cgotest/cgotest.c9
-rw-r--r--src/pkg/go/build/cgotest/cgotest.go19
-rw-r--r--src/pkg/go/build/cgotest/cgotest.h5
-rw-r--r--src/pkg/go/build/cmdtest/main.go12
-rw-r--r--src/pkg/go/build/path.go169
-rw-r--r--src/pkg/go/build/pkgtest/pkgtest.go13
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_386.s10
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_386_test.go1
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_amd64.s9
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_amd64_test.go1
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_arm.s10
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_arm_test.go1
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_test.go9
-rw-r--r--src/pkg/go/build/pkgtest/xsqrt_test.go9
-rw-r--r--src/pkg/go/build/syslist_test.go2
-rw-r--r--src/pkg/go/build/testdata/other/file/file.go5
-rw-r--r--src/pkg/go/build/testdata/other/main.go11
24 files changed, 501 insertions, 513 deletions
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index ee0f92328e..fe9c862f4f 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -74,16 +74,10 @@ func main() {
pkgs = strings.Fields(string(stds))
}
- tree, _, err := build.FindTree("os") // some known package
- if err != nil {
- log.Fatalf("failed to find tree: %v", err)
- }
-
var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
for _, context := range contexts {
w := NewWalker()
w.context = context
- w.tree = tree
for _, pkg := range pkgs {
w.wantedPkg[pkg] = true
@@ -95,7 +89,7 @@ func main() {
strings.HasPrefix(pkg, "old/") {
continue
}
- if !tree.HasSrc(pkg) {
+ if fi, err := os.Stat(filepath.Join(w.root, pkg)); err != nil || !fi.IsDir() {
log.Fatalf("no source in tree for package %q", pkg)
}
w.WalkPackage(pkg)
@@ -165,7 +159,7 @@ type pkgSymbol struct {
type Walker struct {
context *build.Context
- tree *build.Tree
+ root string
fset *token.FileSet
scope []string
features map[string]bool // set
@@ -191,6 +185,7 @@ func NewWalker() *Walker {
selectorFullPkg: make(map[string]string),
wantedPkg: make(map[string]bool),
prevConstType: make(map[pkgSymbol]string),
+ root: filepath.Join(build.Default.GOROOT, "src/pkg"),
}
}
@@ -252,15 +247,13 @@ func (w *Walker) WalkPackage(name string) {
defer func() {
w.packageState[name] = loaded
}()
- dir := filepath.Join(w.tree.SrcDir(), filepath.FromSlash(name))
+ dir := filepath.Join(w.root, filepath.FromSlash(name))
- var info *build.DirInfo
- var err error
- if ctx := w.context; ctx != nil {
- info, err = ctx.ScanDir(dir)
- } else {
- info, err = build.ScanDir(dir)
+ ctxt := w.context
+ if ctxt == nil {
+ ctxt = &build.Default
}
+ info, err := ctxt.ImportDir(dir, 0)
if err != nil {
if strings.Contains(err.Error(), "no Go source files") {
return
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
index dbbec46b0d..c7cc601b1a 100644
--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -7,7 +7,6 @@ package main
import (
"flag"
"fmt"
- "go/build"
"io/ioutil"
"os"
"path/filepath"
@@ -36,7 +35,7 @@ func TestGolden(t *testing.T) {
w := NewWalker()
w.wantedPkg[fi.Name()] = true
- w.tree = &build.Tree{Path: "testdata", Goroot: true}
+ w.root = "testdata/src/pkg"
goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
w.WalkPackage(fi.Name())
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index 1f212a0bcd..e5f7a73d4f 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -15,6 +15,7 @@ import (
"go/printer"
"go/token"
"io"
+ "io/ioutil"
"log"
"net/http"
"net/url"
@@ -90,11 +91,11 @@ var (
func initHandlers() {
paths := filepath.SplitList(*pkgPath)
- for _, t := range build.Path {
- if t.Goroot {
- continue
+ gorootSrc := filepath.Join(build.Default.GOROOT, "src", "pkg")
+ for _, p := range build.Default.SrcDirs() {
+ if p != gorootSrc {
+ paths = append(paths, p)
}
- paths = append(paths, t.SrcDir())
}
fsMap.Init(paths)
@@ -1002,11 +1003,13 @@ func fsReadDir(dir string) ([]os.FileInfo, error) {
return fs.ReadDir(dir)
}
-// fsReadFile implements ReadFile for the go/build package.
-func fsReadFile(dir, name string) (path string, data []byte, err error) {
- path = filepath.Join(dir, name)
- data, err = ReadFile(fs, path)
- return
+// fsOpenFile implements OpenFile for the go/build package.
+func fsOpenFile(name string) (r io.ReadCloser, err error) {
+ data, err := ReadFile(fs, name)
+ if err != nil {
+ return nil, err
+ }
+ return ioutil.NopCloser(bytes.NewReader(data)), nil
}
func inList(name string, list []string) bool {
@@ -1039,10 +1042,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
// To use different pair, such as if we allowed the user
// to choose, set ctxt.GOOS and ctxt.GOARCH before
// calling ctxt.ScanDir.
- ctxt := build.DefaultContext
+ ctxt := build.Default
+ ctxt.IsAbsPath = path.IsAbs
ctxt.ReadDir = fsReadDir
- ctxt.ReadFile = fsReadFile
- dir, err := ctxt.ScanDir(abspath)
+ ctxt.OpenFile = fsOpenFile
+ dir, err := ctxt.ImportDir(abspath, 0)
if err == nil {
pkgFiles = append(dir.GoFiles, dir.CgoFiles...)
}
diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go
index ee905bb7a0..5f42105393 100644
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -388,9 +388,9 @@ func main() {
}
relpath := path
abspath := path
- if t, pkg, err := build.FindTree(path); err == nil {
- relpath = pkg
- abspath = filepath.Join(t.SrcDir(), pkg)
+ if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" {
+ relpath = bp.ImportPath
+ abspath = bp.Dir
} else if !filepath.IsAbs(path) {
abspath = absolutePath(path, pkgHandler.fsRoot)
} else {
diff --git a/src/pkg/exp/types/gcimporter.go b/src/pkg/exp/types/gcimporter.go
index 8b28aede1e..cb996f2805 100644
--- a/src/pkg/exp/types/gcimporter.go
+++ b/src/pkg/exp/types/gcimporter.go
@@ -18,6 +18,7 @@ import (
"os"
"path/filepath"
"strconv"
+ "strings"
"text/scanner"
)
@@ -39,11 +40,14 @@ func findPkg(path string) (filename, id string) {
switch path[0] {
default:
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
- tree, pkg, err := build.FindTree(path)
- if err != nil {
+ bp, _ := build.Import(path, "", build.FindOnly)
+ if bp.PkgObj == "" {
return
}
- noext = filepath.Join(tree.PkgDir(), pkg)
+ noext = bp.PkgObj
+ if strings.HasSuffix(noext, ".a") {
+ noext = noext[:len(noext)-2]
+ }
case '.':
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
@@ -742,7 +746,7 @@ func (p *gcParser) parseVarDecl() {
}
// FuncBody = "{" ... "}" .
-//
+//
func (p *gcParser) parseFuncBody() {
p.expect('{')
for i := 1; i > 0; p.next() {
diff --git a/src/pkg/go/build/build.go b/src/pkg/go/build/build.go
index aeb9ad259b..f893ddd0ba 100644
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -48,7 +48,7 @@
// To build a file only when using cgo, and only on Linux and OS X:
//
// // +build linux,cgo darwin,cgo
-//
+//
// Such a file is usually paired with another file implementing the
// default functionality for other systems, which in this case would
// carry the constraint:
@@ -66,12 +66,14 @@ import (
"errors"
"fmt"
"go/ast"
+ "go/doc"
"go/parser"
"go/token"
+ "io"
"io/ioutil"
"log"
"os"
- "path"
+ pathpkg "path"
"path/filepath"
"runtime"
"sort"
@@ -84,56 +86,186 @@ import (
type Context struct {
GOARCH string // target architecture
GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
CgoEnabled bool // whether cgo can be used
BuildTags []string // additional tags to recognize in +build lines
UseAllFiles bool // use files regardless of +build lines, file names
+ Gccgo bool // assume use of gccgo when computing object paths
+
+ // By default, Import uses the operating system's file system calls
+ // to read directories and files. To read from other sources,
+ // callers can set the following functions. They all have default
+ // behaviors that use the local file system, so clients need only set
+ // the functions whose behaviors they wish to change.
+
+ // JoinPath joins the sequence of path fragments into a single path.
+ // If JoinPath is nil, Import uses filepath.Join.
+ JoinPath func(elem ...string) string
+
+ // SplitPathList splits the path list into a slice of individual paths.
+ // If SplitPathList is nil, Import uses filepath.SplitList.
+ SplitPathList func(list string) []string
- // By default, ScanDir uses the operating system's
- // file system calls to read directories and files.
- // Callers can override those calls to provide other
- // ways to read data by setting ReadDir and ReadFile.
- // ScanDir does not make any assumptions about the
- // format of the strings dir and file: they can be
- // slash-separated, backslash-separated, even URLs.
+ // IsAbsPath reports whether path is an absolute path.
+ // If IsAbsPath is nil, Import uses filepath.IsAbs.
+ IsAbsPath func(path string) bool
+
+ // IsDir reports whether the path names a directory.
+ // If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
+ IsDir func(path string) bool
+
+ // HasSubdir reports whether dir is a subdirectory of
+ // (perhaps multiple levels below) root.
+ // If so, HasSubdir sets rel to a slash-separated path that
+ // can be joined to root to produce a path equivalent to dir.
+ // If HasSubdir is nil, Import uses an implementation built on
+ // filepath.EvalSymlinks.
+ HasSubdir func(root, dir string) (rel string, ok bool)
// ReadDir returns a slice of os.FileInfo, sorted by Name,
// describing the content of the named directory.
- // The dir argument is the argument to ScanDir.
- // If ReadDir is nil, ScanDir uses io.ReadDir.
+ // If ReadDir is nil, Import uses io.ReadDir.
ReadDir func(dir string) (fi []os.FileInfo, err error)
- // ReadFile returns the content of the file named file
- // in the directory named dir. The dir argument is the
- // argument to ScanDir, and the file argument is the
- // Name field from an os.FileInfo returned by ReadDir.
- // The returned path is the full name of the file, to be
- // used in error messages.
- //
- // If ReadFile is nil, ScanDir uses filepath.Join(dir, file)
- // as the path and ioutil.ReadFile to read the data.
- ReadFile func(dir, file string) (path string, content []byte, err error)
+ // OpenFile opens a file (not a directory) for reading.
+ // If OpenFile is nil, Import uses os.Open.
+ OpenFile func(path string) (r io.ReadCloser, err error)
+}
+
+// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
+func (ctxt *Context) joinPath(elem ...string) string {
+ if f := ctxt.JoinPath; f != nil {
+ return f(elem...)
+ }
+ return filepath.Join(elem...)
+}
+
+// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
+func (ctxt *Context) splitPathList(s string) []string {
+ if f := ctxt.SplitPathList; f != nil {
+ return f(s)
+ }
+ return filepath.SplitList(s)
+}
+
+// isAbsPath calls ctxt.IsAbsSPath (if not nil) or else filepath.IsAbs.
+func (ctxt *Context) isAbsPath(path string) bool {
+ if f := ctxt.IsAbsPath; f != nil {
+ return f(path)
+ }
+ return filepath.IsAbs(path)
+}
+
+// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
+func (ctxt *Context) isDir(path string) bool {
+ if f := ctxt.IsDir; f != nil {
+ return f(path)
+ }
+ fi, err := os.Stat(path)
+ return err == nil && fi.IsDir()
+}
+
+// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
+// the local file system to answer the question.
+func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
+ if f := ctxt.HasSubdir; f != nil {
+ return f(root, dir)
+ }
+
+ if p, err := filepath.EvalSymlinks(root); err == nil {
+ root = p
+ }
+ if p, err := filepath.EvalSymlinks(dir); err == nil {
+ dir = p
+ }
+ const sep = string(filepath.Separator)
+ root = filepath.Clean(root)
+ if !strings.HasSuffix(root, sep) {
+ root += sep
+ }
+ dir = filepath.Clean(dir)
+ if !strings.HasPrefix(dir, root) {
+ return "", false
+ }
+ return filepath.ToSlash(dir[len(root):]), true
}
-func (ctxt *Context) readDir(dir string) ([]os.FileInfo, error) {
+// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
+func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
if f := ctxt.ReadDir; f != nil {
- return f(dir)
+ return f(path)
+ }
+ return ioutil.ReadDir(path)
+}
+
+// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
+func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
+ if fn := ctxt.OpenFile; fn != nil {
+ return fn(path)
+ }
+
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err // nil interface
+ }
+ return f, nil
+}
+
+// isFile determines whether path is a file by trying to open it.
+// It reuses openFile instead of adding another function to the
+// list in Context.
+func (ctxt *Context) isFile(path string) bool {
+ f, err := ctxt.openFile(path)
+ if err != nil {
+ return false
+ }
+ f.Close()
+ return true
+}
+
+// gopath returns the list of Go path directories.
+func (ctxt *Context) gopath() []string {
+ var all []string
+ for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
+ if p == "" || p == ctxt.GOROOT {
+ // Empty paths are uninteresting.
+ // If the path is the GOROOT, ignore it.
+ // People sometimes set GOPATH=$GOROOT, which is useless
+ // but would cause us to find packages with import paths
+ // like "pkg/math".
+ // Do not get confused by this common mistake.
+ continue
+ }
+ all = append(all, p)
}
- return ioutil.ReadDir(dir)
+ return all
}
-func (ctxt *Context) readFile(dir, file string) (string, []byte, error) {
- if f := ctxt.ReadFile; f != nil {
- return f(dir, file)
+// SrcDirs returns a list of package source root directories.
+// It draws from the current Go root and Go path but omits directories
+// that do not exist.
+func (ctxt *Context) SrcDirs() []string {
+ var all []string
+ if ctxt.GOROOT != "" {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
+ if ctxt.isDir(dir) {
+ all = append(all, dir)
+ }
}
- p := filepath.Join(dir, file)
- content, err := ioutil.ReadFile(p)
- return p, content, err
+ for _, p := range ctxt.gopath() {
+ dir := ctxt.joinPath(p, "src")
+ if ctxt.isDir(dir) {
+ all = append(all, dir)
+ }
+ }
+ return all
}
-// The DefaultContext is the default Context for builds.
-// It uses the GOARCH and GOOS environment variables
-// if set, or else the compiled code's GOARCH and GOOS.
-var DefaultContext Context = defaultContext()
+// Default is the default Context for builds.
+// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
+// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
+var Default Context = defaultContext()
var cgoEnabled = map[string]bool{
"darwin/386": true,
@@ -151,9 +283,10 @@ func defaultContext() Context {
c.GOARCH = envOr("GOARCH", runtime.GOARCH)
c.GOOS = envOr("GOOS", runtime.GOOS)
+ c.GOROOT = runtime.GOROOT()
+ c.GOPATH = envOr("GOPATH", "")
- s := os.Getenv("CGO_ENABLED")
- switch s {
+ switch os.Getenv("CGO_ENABLED") {
case "1":
c.CgoEnabled = true
case "0":
@@ -173,66 +306,203 @@ func envOr(name, def string) string {
return s
}
-type DirInfo struct {
- Package string // Name of package in dir
- PackageComment *ast.CommentGroup // Package comments from GoFiles
- ImportPath string // Import path of package in dir
- Imports []string // All packages imported by GoFiles
- ImportPos map[string][]token.Position // Source code location of imports
+// An ImportMode controls the behavior of the Import method.
+type ImportMode uint
+
+const (
+ // If FindOnly is set, Import stops after locating the directory
+ // that should contain the sources for a package. It does not
+ // read any files in the directory.
+ FindOnly ImportMode = 1 << iota
+
+ // If AllowBinary is set, Import can be satisfied by a compiled
+ // package object without corresponding sources.
+ AllowBinary
+)
+
+// A Package describes the Go package found in a directory.
+type Package struct {
+ Dir string // directory containing package sources
+ Name string // package name
+ Doc string // documentation synopsis
+ ImportPath string // import path of package ("" if unknown)
+ Root string // root of Go tree where this package lives
+ SrcRoot string // package source root directory ("" if unknown)
+ PkgRoot string // package install root directory ("" if unknown)
+ BinDir string // command install directory ("" if unknown)
+ Goroot bool // package found in Go root
+ PkgObj string // installed .a file
// Source files
- GoFiles []string // .go files in dir (excluding CgoFiles, TestGoFiles, XTestGoFiles)
- HFiles []string // .h files in dir
- CFiles []string // .c files in dir
- SFiles []string // .s (and, when using cgo, .S files in dir)
- CgoFiles []string // .go files that import "C"
+ GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+ CgoFiles []string // .go source files that import "C"
+ CFiles []string // .c source files
+ HFiles []string // .h source files
+ SFiles []string // .s source files
// Cgo directives
CgoPkgConfig []string // Cgo pkg-config directives
CgoCFLAGS []string // Cgo CFLAGS directives
CgoLDFLAGS []string // Cgo LDFLAGS directives
+ // Dependency information
+ Imports []string // imports from GoFiles, CgoFiles
+ ImportPos map[string][]token.Position // line information for Imports
+
// Test information
- TestGoFiles []string // _test.go files in package
- XTestGoFiles []string // _test.go files outside package
- TestImports []string // All packages imported by (X)TestGoFiles
- TestImportPos map[string][]token.Position
+ TestGoFiles []string // _test.go files in package
+ TestImports []string // imports from TestGoFiles
+ TestImportPos map[string][]token.Position // line information for TestImports
+ XTestGoFiles []string // _test.go files outside package
+ XTestImports []string // imports from XTestGoFiles
+ XTestImportPos map[string][]token.Position // line information for XTestImports
}
-func (d *DirInfo) IsCommand() bool {
- // TODO(rsc): This is at least a little bogus.
- return d.Package == "main"
+// IsCommand reports whether the package is considered a
+// command to be installed (not just a library).
+// Packages named "main" are treated as commands.
+func (p *Package) IsCommand() bool {
+ return p.Name == "main"
}
-// ScanDir calls DefaultContext.ScanDir.
-func ScanDir(dir string) (info *DirInfo, err error) {
- return DefaultContext.ScanDir(dir)
+// ImportDir is like Import but processes the Go package found in
+// the named directory.
+func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
+ return ctxt.Import(".", dir, mode)
}
-// TODO(rsc): Move this comment to a more appropriate place.
-
-// ScanDir returns a structure with details about the Go package
-// found in the given directory.
+// Import returns details about the Go package named by the import path,
+// interpreting local import paths relative to the src directory. If the path
+// is a local import path naming a package that can be imported using a
+// standard import path, the returned package will set p.ImportPath to
+// that path.
//
-// Most .go, .c, .h, and .s files in the directory are considered part
-// of the package. The exceptions are:
+// In the directory containing the package, .go, .c, .h, and .s files are
+// considered part of the package except for:
//
-// - .go files in package main (unless no other package is found)
// - .go files in package documentation
// - files starting with _ or .
// - files with build constraints not satisfied by the context
//
-func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
- dirs, err := ctxt.readDir(dir)
+// If an error occurs, Import returns a non-nil error also returns a non-nil
+// *Package containing partial information.
+//
+func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) {
+ p := &Package{
+ ImportPath: path,
+ }
+
+ var pkga string
+ if ctxt.Gccgo {
+ dir, elem := pathpkg.Split(p.ImportPath)
+ pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a"
+ } else {
+ pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a"
+ }
+
+ binaryOnly := false
+ if IsLocalImport(path) {
+ if src == "" {
+ return p, fmt.Errorf("import %q: import relative to unknown directory", path)
+ }
+ if !ctxt.isAbsPath(path) {
+ p.Dir = ctxt.joinPath(src, path)
+ }
+ // Determine canonical import path, if any.
+ if ctxt.GOROOT != "" {
+ root := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
+ if sub, ok := ctxt.hasSubdir(root, p.Dir); ok {
+ p.Goroot = true
+ p.ImportPath = sub
+ p.Root = ctxt.GOROOT
+ goto Found
+ }
+ }
+ all := ctxt.gopath()
+ for i, root := range all {
+ rootsrc := ctxt.joinPath(root, "src")
+ if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok {
+ // We found a potential import path for dir,
+ // but check that using it wouldn't find something
+ // else first.
+ if ctxt.GOROOT != "" {
+ if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
+ goto Found
+ }
+ }
+ for _, earlyRoot := range all[:i] {
+ if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
+ goto Found
+ }
+ }
+
+ // sub would not name some other directory instead of this one.
+ // Record it.
+ p.ImportPath = sub
+ p.Root = root
+ goto Found
+ }
+ }
+ // It's okay that we didn't find a root containing dir.
+ // Keep going with the information we have.
+ } else {
+ if strings.HasPrefix(path, "/") {
+ return p, fmt.Errorf("import %q: cannot import absolute path", path)
+ }
+ // Determine directory from import path.
+ if ctxt.GOROOT != "" {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path)
+ isDir := ctxt.isDir(dir)
+ binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+ if isDir || binaryOnly {
+ p.Dir = dir
+ p.Goroot = true
+ p.Root = ctxt.GOROOT
+ goto Found
+ }
+ }
+ for _, root := range ctxt.gopath() {
+ dir := ctxt.joinPath(root, "src", path)
+ isDir := ctxt.isDir(dir)
+ binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(root, pkga))
+ if isDir || binaryOnly {
+ p.Dir = dir
+ p.Root = root
+ goto Found
+ }
+ }
+ return p, fmt.Errorf("import %q: cannot find package", path)
+ }
+
+Found:
+ if p.Root != "" {
+ if p.Goroot {
+ p.SrcRoot = ctxt.joinPath(p.Root, "src", "pkg")
+ } else {
+ p.SrcRoot = ctxt.joinPath(p.Root, "src")
+ }
+ p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
+ p.BinDir = ctxt.joinPath(p.Root, "bin")
+ p.PkgObj = ctxt.joinPath(p.Root, pkga)
+ }
+
+ if mode&FindOnly != 0 {
+ return p, nil
+ }
+ if binaryOnly && (mode&AllowBinary) != 0 {
+ return p, nil
+ }
+
+ dirs, err := ctxt.readDir(p.Dir)
if err != nil {
- return nil, err
+ return p, err
}
var Sfiles []string // files with ".S" (capital S)
- var di DirInfo
var firstFile string
imported := make(map[string][]token.Position)
testImported := make(map[string][]token.Position)
+ xTestImported := make(map[string][]token.Position)
fset := token.NewFileSet()
for _, d := range dirs {
if d.IsDir() {
@@ -247,7 +517,11 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
continue
}
- ext := path.Ext(name)
+ i := strings.LastIndex(name, ".")
+ if i < 0 {
+ i = len(name)
+ }
+ ext := name[i:]
switch ext {
case ".go", ".c", ".s", ".h", ".S":
// tentatively okay
@@ -256,9 +530,15 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
continue
}
- filename, data, err := ctxt.readFile(dir, name)
+ filename := ctxt.joinPath(p.Dir, name)
+ f, err := ctxt.openFile(filename)
if err != nil {
- return nil, err
+ return p, err
+ }
+ data, err := ioutil.ReadAll(f)
+ f.Close()
+ if err != nil {
+ return p, fmt.Errorf("read %s: %v", filename, err)
}
// Look for +build comments to accept or reject the file.
@@ -269,13 +549,13 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
// Going to save the file. For non-Go files, can stop here.
switch ext {
case ".c":
- di.CFiles = append(di.CFiles, name)
+ p.CFiles = append(p.CFiles, name)
continue
case ".h":
- di.HFiles = append(di.HFiles, name)
+ p.HFiles = append(p.HFiles, name)
continue
case ".s":
- di.SFiles = append(di.SFiles, name)
+ p.SFiles = append(p.SFiles, name)
continue
case ".S":
Sfiles = append(Sfiles, name)
@@ -284,7 +564,7 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
if err != nil {
- return nil, err
+ return p, err
}
pkg := string(pf.Name.Name)
@@ -293,22 +573,20 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
}
isTest := strings.HasSuffix(name, "_test.go")
+ isXTest := false
if isTest && strings.HasSuffix(pkg, "_test") {
+ isXTest = true
pkg = pkg[:len(pkg)-len("_test")]
}
- if di.Package == "" {
- di.Package = pkg
+ if p.Name == "" {
+ p.Name = pkg
firstFile = name
- } else if pkg != di.Package {
- return nil, fmt.Errorf("%s: found packages %s (%s) and %s (%s)", dir, di.Package, firstFile, pkg, name)
+ } else if pkg != p.Name {
+ return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir)
}
- if pf.Doc != nil {
- if di.PackageComment != nil {
- di.PackageComment.List = append(di.PackageComment.List, pf.Doc.List...)
- } else {
- di.PackageComment = pf.Doc
- }
+ if pf.Doc != nil && p.Doc == "" {
+ p.Doc = doc.Synopsis(pf.Doc.Text())
}
// Record imports and information about cgo.
@@ -328,22 +606,24 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
if err != nil {
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
}
- if isTest {
+ if isXTest {
+ xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
+ } else if isTest {
testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
} else {
imported[path] = append(imported[path], fset.Position(spec.Pos()))
}
if path == "C" {
if isTest {
- return nil, fmt.Errorf("%s: use of cgo in test not supported", filename)
+ return p, fmt.Errorf("use of cgo in test %s not supported", filename)
}
cg := spec.Doc
if cg == nil && len(d.Specs) == 1 {
cg = d.Doc
}
if cg != nil {
- if err := ctxt.saveCgo(filename, &di, cg); err != nil {
- return nil, err
+ if err := ctxt.saveCgo(filename, p, cg); err != nil {
+ return p, err
}
}
isCgo = true
@@ -352,48 +632,52 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
}
if isCgo {
if ctxt.CgoEnabled {
- di.CgoFiles = append(di.CgoFiles, name)
+ p.CgoFiles = append(p.CgoFiles, name)
}
+ } else if isXTest {
+ p.XTestGoFiles = append(p.XTestGoFiles, name)
} else if isTest {
- if pkg == string(pf.Name.Name) {
- di.TestGoFiles = append(di.TestGoFiles, name)
- } else {
- di.XTestGoFiles = append(di.XTestGoFiles, name)
- }
+ p.TestGoFiles = append(p.TestGoFiles, name)
} else {
- di.GoFiles = append(di.GoFiles, name)
+ p.GoFiles = append(p.GoFiles, name)
}
}
- if di.Package == "" {
- return nil, fmt.Errorf("%s: no Go source files", dir)
- }
- di.Imports = make([]string, len(imported))
- di.ImportPos = imported
- i := 0
- for p := range imported {
- di.Imports[i] = p
- i++
- }
- di.TestImports = make([]string, len(testImported))
- di.TestImportPos = testImported
- i = 0
- for p := range testImported {
- di.TestImports[i] = p
- i++
+ if p.Name == "" {
+ return p, fmt.Errorf("no Go source files in %s", p.Dir)
}
+ p.Imports, p.ImportPos = cleanImports(imported)
+ p.TestImports, p.TestImportPos = cleanImports(testImported)
+ p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
+
// add the .S files only if we are using cgo
// (which means gcc will compile them).
// The standard assemblers expect .s files.
- if len(di.CgoFiles) > 0 {
- di.SFiles = append(di.SFiles, Sfiles...)
- sort.Strings(di.SFiles)
+ if len(p.CgoFiles) > 0 {
+ p.SFiles = append(p.SFiles, Sfiles...)
+ sort.Strings(p.SFiles)
+ }
+
+ return p, nil
+}
+
+func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
+ all := make([]string, 0, len(m))
+ for path := range m {
+ all = append(all, path)
}
+ sort.Strings(all)
+ return all, m
+}
- // File name lists are sorted because ReadDir sorts.
- sort.Strings(di.Imports)
- sort.Strings(di.TestImports)
- return &di, nil
+// Import is shorthand for Default.Import.
+func Import(path, src string, mode ImportMode) (*Package, error) {
+ return Default.Import(path, src, mode)
+}
+
+// ImportDir is shorthand for Default.ImportDir.
+func ImportDir(dir string, mode ImportMode) (*Package, error) {
+ return Default.ImportDir(dir, mode)
}
var slashslash = []byte("//")
@@ -473,7 +757,7 @@ func (ctxt *Context) shouldBuild(content []byte) bool {
//
// TODO(rsc): This duplicates code in cgo.
// Once the dust settles, remove this code from cgo.
-func (ctxt *Context) saveCgo(filename string, di *DirInfo, cg *ast.CommentGroup) error {
+func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
text := cg.Text()
for _, line := range strings.Split(text, "\n") {
orig := line
@@ -711,14 +995,11 @@ func init() {
// ToolDir is the directory containing build tools.
var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
-// isLocalPath returns whether the given path is local (/foo ./foo ../foo . ..)
-// Windows paths that starts with drive letter (c:\foo c:foo) are considered local.
-func isLocalPath(s string) bool {
- const sep = string(filepath.Separator)
- return s == "." || s == ".." ||
- filepath.HasPrefix(s, sep) ||
- filepath.HasPrefix(s, "."+sep) || filepath.HasPrefix(s, ".."+sep) ||
- filepath.VolumeName(s) != ""
+// IsLocalImport reports whether the import path is
+// a local import path, like ".", "..", "./foo", or "../foo".
+func IsLocalImport(path string) bool {
+ return path == "." || path == ".." ||
+ strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
}
// ArchChar returns the architecture character for the given goarch.
diff --git a/src/pkg/go/build/build_test.go b/src/pkg/go/build/build_test.go
index 3c706a46ed..06b8b0e94f 100644
--- a/src/pkg/go/build/build_test.go
+++ b/src/pkg/go/build/build_test.go
@@ -5,83 +5,14 @@
package build
import (
+ "os"
"path/filepath"
- "reflect"
"runtime"
- "sort"
"testing"
)
-func sortstr(x []string) []string {
- sort.Strings(x)
- return x
-}
-
-var buildPkgs = []struct {
- dir string
- info *DirInfo
-}{
- {
- "go/build/pkgtest",
- &DirInfo{
- GoFiles: []string{"pkgtest.go"},
- SFiles: []string{"sqrt_" + runtime.GOARCH + ".s"},
- Package: "pkgtest",
- Imports: []string{"bytes"},
- TestImports: []string{"fmt", "pkgtest"},
- TestGoFiles: sortstr([]string{"sqrt_test.go", "sqrt_" + runtime.GOARCH + "_test.go"}),
- XTestGoFiles: []string{"xsqrt_test.go"},
- },
- },
- {
- "go/build/cmdtest",
- &DirInfo{
- GoFiles: []string{"main.go"},
- Package: "main",
- Imports: []string{"go/build/pkgtest"},
- TestImports: []string{},
- },
- },
- {
- "go/build/cgotest",
- &DirInfo{
- CgoFiles: ifCgo([]string{"cgotest.go"}),
- CFiles: []string{"cgotest.c"},
- HFiles: []string{"cgotest.h"},
- Imports: []string{"C", "unsafe"},
- TestImports: []string{},
- Package: "cgotest",
- },
- },
-}
-
-func ifCgo(x []string) []string {
- if DefaultContext.CgoEnabled {
- return x
- }
- return nil
-}
-
-func TestBuild(t *testing.T) {
- for _, tt := range buildPkgs {
- tree := Path[0] // Goroot
- dir := filepath.Join(tree.SrcDir(), tt.dir)
- info, err := ScanDir(dir)
- if err != nil {
- t.Errorf("ScanDir(%#q): %v", tt.dir, err)
- continue
- }
- // Don't bother testing import positions.
- tt.info.ImportPos, tt.info.TestImportPos = info.ImportPos, info.TestImportPos
- if !reflect.DeepEqual(info, tt.info) {
- t.Errorf("ScanDir(%#q) = %#v, want %#v\n", tt.dir, info, tt.info)
- continue
- }
- }
-}
-
func TestMatch(t *testing.T) {
- ctxt := DefaultContext
+ ctxt := Default
what := "default"
match := func(tag string) {
if !ctxt.match(tag) {
@@ -106,3 +37,40 @@ func TestMatch(t *testing.T) {
match(runtime.GOOS + "," + runtime.GOARCH + ",!bar")
nomatch(runtime.GOOS + "," + runtime.GOARCH + ",bar")
}
+
+func TestDotSlashImport(t *testing.T) {
+ p, err := ImportDir("testdata/other", 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(p.Imports) != 1 || p.Imports[0] != "./file" {
+ t.Fatalf("testdata/other: Imports=%v, want [./file]", p.Imports)
+ }
+
+ p1, err := Import("./file", "testdata/other", 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if p1.Name != "file" {
+ t.Fatalf("./file: Name=%q, want %q", p1.Name, "file")
+ }
+ dir := filepath.Clean("testdata/other/file") // Clean to use \ on Windows
+ if p1.Dir != dir {
+ t.Fatalf("./file: Dir=%q, want %q", p1.Name, dir)
+ }
+}
+
+func TestLocalDirectory(t *testing.T) {
+ cwd, err := os.Getwd()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ p, err := ImportDir(cwd, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if p.ImportPath != "go/build" {
+ t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
+ }
+}
diff --git a/src/pkg/go/build/cgotest/cgotest.c b/src/pkg/go/build/cgotest/cgotest.c
deleted file mode 100644
index b13acb2275..0000000000
--- a/src/pkg/go/build/cgotest/cgotest.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2011 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.
-
-int
-Add(int x, int y, int *sum)
-{
- sum = x+y;
-}
diff --git a/src/pkg/go/build/cgotest/cgotest.go b/src/pkg/go/build/cgotest/cgotest.go
deleted file mode 100644
index 93bbf06883..0000000000
--- a/src/pkg/go/build/cgotest/cgotest.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011 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.
-
-package cgotest
-
-/*
-char* greeting = "hello, world";
-*/
-// #include "cgotest.h"
-import "C"
-import "unsafe"
-
-var Greeting = C.GoString(C.greeting)
-
-func DoAdd(x, y int) (sum int) {
- C.Add(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&sum)))
- return
-}
diff --git a/src/pkg/go/build/cgotest/cgotest.h b/src/pkg/go/build/cgotest/cgotest.h
deleted file mode 100644
index 9c73643b6f..0000000000
--- a/src/pkg/go/build/cgotest/cgotest.h
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2011 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.
-
-extern int Add(int, int, int *);
diff --git a/src/pkg/go/build/cmdtest/main.go b/src/pkg/go/build/cmdtest/main.go
deleted file mode 100644
index bed4f485a0..0000000000
--- a/src/pkg/go/build/cmdtest/main.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2011 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.
-
-package main
-
-import "go/build/pkgtest"
-
-func main() {
- pkgtest.Foo()
- print(int(pkgtest.Sqrt(9)))
-}
diff --git a/src/pkg/go/build/path.go b/src/pkg/go/build/path.go
deleted file mode 100644
index 6115adafeb..0000000000
--- a/src/pkg/go/build/path.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2011 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.
-
-package build
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "runtime"
-)
-
-// Path is a validated list of Trees derived from $GOROOT and $GOPATH at init.
-var Path []*Tree
-
-// Tree describes a Go source tree, either $GOROOT or one from $GOPATH.
-type Tree struct {
- Path string
- Goroot bool
-}
-
-func newTree(p string) (*Tree, error) {
- if !filepath.IsAbs(p) {
- return nil, errors.New("must be absolute")
- }
- ep, err := filepath.EvalSymlinks(p)
- if err != nil {
- return nil, err
- }
- return &Tree{Path: ep}, nil
-}
-
-// SrcDir returns the tree's package source directory.
-func (t *Tree) SrcDir() string {
- if t.Goroot {
- return filepath.Join(t.Path, "src", "pkg")
- }
- return filepath.Join(t.Path, "src")
-}
-
-// PkgDir returns the tree's package object directory.
-func (t *Tree) PkgDir() string {
- goos, goarch := runtime.GOOS, runtime.GOARCH
- if e := os.Getenv("GOOS"); e != "" {
- goos = e
- }
- if e := os.Getenv("GOARCH"); e != "" {
- goarch = e
- }
- return filepath.Join(t.Path, "pkg", goos+"_"+goarch)
-}
-
-// BinDir returns the tree's binary executable directory.
-func (t *Tree) BinDir() string {
- if t.Goroot {
- if gobin := os.Getenv("GOBIN"); gobin != "" {
- return filepath.Clean(gobin)
- }
- }
- return filepath.Join(t.Path, "bin")
-}
-
-// HasSrc returns whether the given package's
-// source can be found inside this Tree.
-func (t *Tree) HasSrc(pkg string) bool {
- fi, err := os.Stat(filepath.Join(t.SrcDir(), pkg))
- if err != nil {
- return false
- }
- return fi.IsDir()
-}
-
-// HasPkg returns whether the given package's
-// object file can be found inside this Tree.
-func (t *Tree) HasPkg(pkg string) bool {
- fi, err := os.Stat(filepath.Join(t.PkgDir(), pkg+".a"))
- if err != nil {
- return false
- }
- return !fi.IsDir()
-}
-
-var (
- ErrNotFound = errors.New("package could not be found locally")
- ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found")
-)
-
-// FindTree takes an import or filesystem path and returns the
-// tree where the package source should be and the package import path.
-func FindTree(path string) (tree *Tree, pkg string, err error) {
- if isLocalPath(path) {
- if path, err = filepath.Abs(path); err != nil {
- return
- }
- if path, err = filepath.EvalSymlinks(path); err != nil {
- return
- }
- for _, t := range Path {
- tpath := t.SrcDir() + string(filepath.Separator)
- if !filepath.HasPrefix(path, tpath) {
- continue
- }
- tree = t
- pkg = filepath.ToSlash(path[len(tpath):])
- return
- }
- err = fmt.Errorf("path %q not inside a GOPATH", path)
- return
- }
- tree = defaultTree
- pkg = filepath.ToSlash(path)
- for _, t := range Path {
- if t.HasSrc(pkg) {
- tree = t
- return
- }
- }
- if tree == nil {
- err = ErrTreeNotFound
- } else {
- err = ErrNotFound
- }
- return
-}
-
-var (
- // argument lists used by the build's gc and ld methods
- gcImportArgs []string
- ldImportArgs []string
-
- // default tree for remote packages
- defaultTree *Tree
-)
-
-// set up Path: parse and validate GOROOT and GOPATH variables
-func init() {
- root := runtime.GOROOT()
- t, err := newTree(root)
- if err == nil {
- t.Goroot = true
- Path = []*Tree{t}
- }
-
- for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
- if p == "" {
- continue
- }
- t, err := newTree(p)
- if err != nil {
- continue
- }
-
- Path = append(Path, t)
- gcImportArgs = append(gcImportArgs, "-I", t.PkgDir())
- ldImportArgs = append(ldImportArgs, "-L", t.PkgDir())
-
- // select first GOPATH entry as default
- if defaultTree == nil {
- defaultTree = t
- }
- }
-
- // use GOROOT if no valid GOPATH specified
- if defaultTree == nil && len(Path) > 0 {
- defaultTree = Path[0]
- }
-}
diff --git a/src/pkg/go/build/pkgtest/pkgtest.go b/src/pkg/go/build/pkgtest/pkgtest.go
deleted file mode 100644
index 08eea1e2bc..0000000000
--- a/src/pkg/go/build/pkgtest/pkgtest.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2011 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.
-
-package pkgtest
-
-import "bytes"
-
-func Foo() *bytes.Buffer {
- return nil
-}
-
-func Sqrt(x float64) float64
diff --git a/src/pkg/go/build/pkgtest/sqrt_386.s b/src/pkg/go/build/pkgtest/sqrt_386.s
deleted file mode 100644
index d0a428d52e..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_386.s
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2009 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.
-
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),7,$0
- FMOVD x+0(FP),F0
- FSQRT
- FMOVDP F0,r+8(FP)
- RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_386_test.go b/src/pkg/go/build/pkgtest/sqrt_386_test.go
deleted file mode 100644
index 26b483fa0b..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_386_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_amd64.s b/src/pkg/go/build/pkgtest/sqrt_amd64.s
deleted file mode 100644
index f5b329e70a..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_amd64.s
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2009 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.
-
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),7,$0
- SQRTSD x+0(FP), X0
- MOVSD X0, r+8(FP)
- RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_amd64_test.go b/src/pkg/go/build/pkgtest/sqrt_amd64_test.go
deleted file mode 100644
index 26b483fa0b..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_amd64_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_arm.s b/src/pkg/go/build/pkgtest/sqrt_arm.s
deleted file mode 100644
index befbb8a898..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_arm.s
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2011 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.
-
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),7,$0
- MOVD x+0(FP),F0
- SQRTD F0,F0
- MOVD F0,r+8(FP)
- RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_arm_test.go b/src/pkg/go/build/pkgtest/sqrt_arm_test.go
deleted file mode 100644
index 26b483fa0b..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_arm_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package pkgtest
diff --git a/src/pkg/go/build/pkgtest/sqrt_test.go b/src/pkg/go/build/pkgtest/sqrt_test.go
deleted file mode 100644
index ee9fd5de68..0000000000
--- a/src/pkg/go/build/pkgtest/sqrt_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2011 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.
-
-package pkgtest
-
-import "fmt"
-
-var _ = fmt.Printf
diff --git a/src/pkg/go/build/pkgtest/xsqrt_test.go b/src/pkg/go/build/pkgtest/xsqrt_test.go
deleted file mode 100644
index 3898d1dda5..0000000000
--- a/src/pkg/go/build/pkgtest/xsqrt_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2011 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.
-
-package pkgtest_test
-
-import "pkgtest"
-
-var _ = pkgtest.Foo
diff --git a/src/pkg/go/build/syslist_test.go b/src/pkg/go/build/syslist_test.go
index d27630d758..9157faf8cb 100644
--- a/src/pkg/go/build/syslist_test.go
+++ b/src/pkg/go/build/syslist_test.go
@@ -55,7 +55,7 @@ var tests = []GoodFileTest{
func TestGoodOSArch(t *testing.T) {
for _, test := range tests {
- if DefaultContext.goodOSArchFile(test.name) != test.result {
+ if Default.goodOSArchFile(test.name) != test.result {
t.Fatalf("goodOSArchFile(%q) != %v", test.name, test.result)
}
}
diff --git a/src/pkg/go/build/testdata/other/file/file.go b/src/pkg/go/build/testdata/other/file/file.go
new file mode 100644
index 0000000000..bbfd3e9e59
--- /dev/null
+++ b/src/pkg/go/build/testdata/other/file/file.go
@@ -0,0 +1,5 @@
+// Test data - not compiled.
+
+package file
+
+func F() {}
diff --git a/src/pkg/go/build/testdata/other/main.go b/src/pkg/go/build/testdata/other/main.go
new file mode 100644
index 0000000000..e0904357c9
--- /dev/null
+++ b/src/pkg/go/build/testdata/other/main.go
@@ -0,0 +1,11 @@
+// Test data - not compiled.
+
+package main
+
+import (
+ "./file"
+)
+
+func main() {
+ file.F()
+}