]> Cypherpunks repositories - gostls13.git/commitdiff
go/build: replace FindTree, ScanDir, Tree, DirInfo with Import, Package
authorRuss Cox <rsc@golang.org>
Thu, 1 Mar 2012 17:12:09 +0000 (12:12 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 1 Mar 2012 17:12:09 +0000 (12:12 -0500)
This is an API change, but one I have been promising would
happen when it was clear what the go command needed.

This is basically a complete replacement of what used to be here.

build.Tree is gone.

build.DirInfo is expanded and now called build.Package.

build.FindTree is now build.Import(package, srcDir, build.FindOnly).
The returned *Package contains information that FindTree returned,
but applicable only to a single package.

build.ScanDir is now build.ImportDir.

build.FindTree+build.ScanDir is now build.Import.

The new Import API allows specifying the source directory,
in order to resolve local imports (import "./foo") and also allows
scanning of packages outside of $GOPATH.  They will come back
with less information in the Package, but they will still work.

The old go/build API exposed both too much and too little.
This API is much closer to what the go command needs,
and it works well enough in the other places where it is
used.  Path is gone, so it can no longer be misused.  (Fixes issue 2749.)

This CL updates clients of go/build other than the go command.
The go command changes are in a separate CL, to be submitted
at the same time.

R=golang-dev, r, alex.brainman, adg
CC=golang-dev
https://golang.org/cl/5713043

24 files changed:
src/cmd/api/goapi.go
src/cmd/api/goapi_test.go
src/cmd/godoc/godoc.go
src/cmd/godoc/main.go
src/pkg/exp/types/gcimporter.go
src/pkg/go/build/build.go
src/pkg/go/build/build_test.go
src/pkg/go/build/cgotest/cgotest.c [deleted file]
src/pkg/go/build/cgotest/cgotest.go [deleted file]
src/pkg/go/build/cgotest/cgotest.h [deleted file]
src/pkg/go/build/cmdtest/main.go [deleted file]
src/pkg/go/build/path.go [deleted file]
src/pkg/go/build/pkgtest/pkgtest.go [deleted file]
src/pkg/go/build/pkgtest/sqrt_386.s [deleted file]
src/pkg/go/build/pkgtest/sqrt_386_test.go [deleted file]
src/pkg/go/build/pkgtest/sqrt_amd64.s [deleted file]
src/pkg/go/build/pkgtest/sqrt_amd64_test.go [deleted file]
src/pkg/go/build/pkgtest/sqrt_arm.s [deleted file]
src/pkg/go/build/pkgtest/sqrt_arm_test.go [deleted file]
src/pkg/go/build/pkgtest/sqrt_test.go [deleted file]
src/pkg/go/build/pkgtest/xsqrt_test.go [deleted file]
src/pkg/go/build/syslist_test.go
src/pkg/go/build/testdata/other/file/file.go [new file with mode: 0644]
src/pkg/go/build/testdata/other/main.go [new file with mode: 0644]

index ee0f92328e311921280d625fd51c71b44a068491..fe9c862f4f217e5b26db44ce3c65e2c69b3421df 100644 (file)
@@ -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
index dbbec46b0d34d64ddcb874ec0e9d54a409ab863b..c7cc601b1a0af2142136c3b0c67e46b5fc147d3c 100644 (file)
@@ -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())
 
index 1f212a0bcd66dd70852be7737f2e6e5fe8b083c5..e5f7a73d4f451ceedfb370885dcc9a8fd45500f2 100644 (file)
@@ -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...)
                }
index ee905bb7a01af2a4f84847e0ead79fa0336a5ece..5f42105393b2bd5ff6b87f4b055e6fbfb59c9877 100644 (file)
@@ -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 {
index 8b28aede1ecf1b9ce47d8e336245f714bd355de2..cb996f28055531868b516773db13ad70c7329638 100644 (file)
@@ -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() {
index aeb9ad259be3759b83245990e2a661f5182adbae..f893ddd0ba53d956457b7528c2367b171e5c6f5e 100644 (file)
@@ -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
-
-       // 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.
+       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
+
+       // 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)
 }
 
-func (ctxt *Context) readDir(dir string) ([]os.FileInfo, 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
+}
+
+// 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 ioutil.ReadDir(dir)
+       return f, nil
 }
 
-func (ctxt *Context) readFile(dir, file string) (string, []byte, error) {
-       if f := ctxt.ReadFile; f != nil {
-               return f(dir, file)
+// 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
        }
-       p := filepath.Join(dir, file)
-       content, err := ioutil.ReadFile(p)
-       return p, content, err
+       f.Close()
+       return true
 }
 
-// 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()
+// 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 all
+}
+
+// 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)
+               }
+       }
+       for _, p := range ctxt.gopath() {
+               dir := ctxt.joinPath(p, "src")
+               if ctxt.isDir(dir) {
+                       all = append(all, dir)
+               }
+       }
+       return all
+}
+
+// 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)
-               }
-               if pf.Doc != nil {
-                       if di.PackageComment != nil {
-                               di.PackageComment.List = append(di.PackageComment.List, pf.Doc.List...)
-                       } else {
-                               di.PackageComment = pf.Doc
-                       }
+               } 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 && 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.
index 3c706a46edda484793f4e7da866e1c89ff112e2e..06b8b0e94f86365f6553e7f0f462602998383752 100644 (file)
@@ -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 (file)
index b13acb2..0000000
+++ /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 (file)
index 93bbf06..0000000
+++ /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 (file)
index 9c73643..0000000
+++ /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 (file)
index bed4f48..0000000
+++ /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 (file)
index 6115ada..0000000
+++ /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 (file)
index 08eea1e..0000000
+++ /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 (file)
index d0a428d..0000000
+++ /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 (file)
index 26b483f..0000000
+++ /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 (file)
index f5b329e..0000000
+++ /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 (file)
index 26b483f..0000000
+++ /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 (file)
index befbb8a..0000000
+++ /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 (file)
index 26b483f..0000000
+++ /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 (file)
index ee9fd5d..0000000
+++ /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 (file)
index 3898d1d..0000000
+++ /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
index d27630d758d94c09b0200d7a59c61fa03dc1378d..9157faf8cb94ff36308589456939b4ea4394ae41 100644 (file)
@@ -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 (file)
index 0000000..bbfd3e9
--- /dev/null
@@ -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 (file)
index 0000000..e090435
--- /dev/null
@@ -0,0 +1,11 @@
+// Test data - not compiled.
+
+package main
+
+import (
+       "./file"
+)
+
+func main() {
+       file.F()
+}