|  | // Copyright 2015 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // +build go1.8,!go1.9 // TODO(adonovan) determine which versions we need to test here | 
|  | // +build !windows | 
|  |  | 
|  | package loader_test | 
|  |  | 
|  | import ( | 
|  | "fmt" | 
|  | "go/token" | 
|  | "log" | 
|  | "path/filepath" | 
|  | "runtime" | 
|  | "sort" | 
|  | "strings" | 
|  |  | 
|  | "golang.org/x/tools/go/loader" | 
|  | ) | 
|  |  | 
|  | func printProgram(prog *loader.Program) { | 
|  | // Created packages are the initial packages specified by a call | 
|  | // to CreateFromFilenames or CreateFromFiles. | 
|  | var names []string | 
|  | for _, info := range prog.Created { | 
|  | names = append(names, info.Pkg.Path()) | 
|  | } | 
|  | fmt.Printf("created: %s\n", names) | 
|  |  | 
|  | // Imported packages are the initial packages specified by a | 
|  | // call to Import or ImportWithTests. | 
|  | names = nil | 
|  | for _, info := range prog.Imported { | 
|  | if strings.Contains(info.Pkg.Path(), "internal") { | 
|  | continue // skip, to reduce fragility | 
|  | } | 
|  | names = append(names, info.Pkg.Path()) | 
|  | } | 
|  | sort.Strings(names) | 
|  | fmt.Printf("imported: %s\n", names) | 
|  |  | 
|  | // InitialPackages contains the union of created and imported. | 
|  | names = nil | 
|  | for _, info := range prog.InitialPackages() { | 
|  | names = append(names, info.Pkg.Path()) | 
|  | } | 
|  | sort.Strings(names) | 
|  | fmt.Printf("initial: %s\n", names) | 
|  |  | 
|  | // AllPackages contains all initial packages and their dependencies. | 
|  | names = nil | 
|  | for pkg := range prog.AllPackages { | 
|  | names = append(names, pkg.Path()) | 
|  | } | 
|  | sort.Strings(names) | 
|  | fmt.Printf("all: %s\n", names) | 
|  | } | 
|  |  | 
|  | func printFilenames(fset *token.FileSet, info *loader.PackageInfo) { | 
|  | var names []string | 
|  | for _, f := range info.Files { | 
|  | names = append(names, filepath.Base(fset.File(f.Pos()).Name())) | 
|  | } | 
|  | fmt.Printf("%s.Files: %s\n", info.Pkg.Path(), names) | 
|  | } | 
|  |  | 
|  | // This example loads a set of packages and all of their dependencies | 
|  | // from a typical command-line.  FromArgs parses a command line and | 
|  | // makes calls to the other methods of Config shown in the examples that | 
|  | // follow. | 
|  | func ExampleConfig_FromArgs() { | 
|  | args := []string{"mytool", "unicode/utf8", "errors", "runtime", "--", "foo", "bar"} | 
|  | const wantTests = false | 
|  |  | 
|  | var conf loader.Config | 
|  | rest, err := conf.FromArgs(args[1:], wantTests) | 
|  | prog, err := conf.Load() | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  |  | 
|  | fmt.Printf("rest: %s\n", rest) | 
|  | printProgram(prog) | 
|  | // Output: | 
|  | // rest: [foo bar] | 
|  | // created: [] | 
|  | // imported: [errors runtime unicode/utf8] | 
|  | // initial: [errors runtime unicode/utf8] | 
|  | // all: [errors runtime runtime/internal/atomic runtime/internal/sys unicode/utf8 unsafe] | 
|  | } | 
|  |  | 
|  | // This example creates and type-checks a single package (without tests) | 
|  | // from a list of filenames, and loads all of its dependencies. | 
|  | // (The input files are actually only a small part of the math/cmplx package.) | 
|  | func ExampleConfig_CreateFromFilenames() { | 
|  | var conf loader.Config | 
|  | conf.CreateFromFilenames("math/cmplx", | 
|  | filepath.Join(runtime.GOROOT(), "src/math/cmplx/abs.go"), | 
|  | filepath.Join(runtime.GOROOT(), "src/math/cmplx/sin.go")) | 
|  | prog, err := conf.Load() | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  |  | 
|  | printProgram(prog) | 
|  | // Output: | 
|  | // created: [math/cmplx] | 
|  | // imported: [] | 
|  | // initial: [math/cmplx] | 
|  | // all: [math math/cmplx unsafe] | 
|  | } | 
|  |  | 
|  | // In the examples below, for stability, the chosen packages are | 
|  | // relatively small, platform-independent, and low-level (and thus | 
|  | // infrequently changing). | 
|  | // The strconv package has internal and external tests. | 
|  |  | 
|  | const hello = `package main | 
|  |  | 
|  | import "fmt" | 
|  |  | 
|  | func main() { | 
|  | fmt.Println("Hello, world.") | 
|  | } | 
|  | ` | 
|  |  | 
|  | // This example creates and type-checks a package from a list of | 
|  | // already-parsed files, and loads all its dependencies. | 
|  | func ExampleConfig_CreateFromFiles() { | 
|  | var conf loader.Config | 
|  | f, err := conf.ParseFile("hello.go", hello) | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | conf.CreateFromFiles("hello", f) | 
|  | prog, err := conf.Load() | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  |  | 
|  | printProgram(prog) | 
|  | printFilenames(prog.Fset, prog.Package("strconv")) | 
|  | // Output: | 
|  | // created: [hello] | 
|  | // imported: [] | 
|  | // initial: [hello] | 
|  | // all: [errors fmt hello internal/race io math os reflect runtime runtime/internal/atomic runtime/internal/sys strconv sync sync/atomic syscall time unicode/utf8 unsafe] | 
|  | // strconv.Files: [atob.go atof.go atoi.go decimal.go doc.go extfloat.go ftoa.go isprint.go itoa.go quote.go] | 
|  | } | 
|  |  | 
|  | // This example imports three packages, including the tests for one of | 
|  | // them, and loads all their dependencies. | 
|  | func ExampleConfig_Import() { | 
|  | // ImportWithTest("strconv") causes strconv to include | 
|  | // internal_test.go, and creates an external test package, | 
|  | // strconv_test. | 
|  | // (Compare with the example of CreateFromFiles.) | 
|  |  | 
|  | var conf loader.Config | 
|  | conf.Import("unicode/utf8") | 
|  | conf.Import("errors") | 
|  | conf.ImportWithTests("strconv") | 
|  | prog, err := conf.Load() | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  |  | 
|  | printProgram(prog) | 
|  | printFilenames(prog.Fset, prog.Package("strconv")) | 
|  | printFilenames(prog.Fset, prog.Package("strconv_test")) | 
|  | // Output: | 
|  | // created: [strconv_test] | 
|  | // imported: [errors strconv unicode/utf8] | 
|  | // initial: [errors strconv strconv_test unicode/utf8] | 
|  | // all: [bufio bytes errors flag fmt internal/race io log math math/rand os reflect runtime runtime/debug runtime/internal/atomic runtime/internal/sys runtime/trace sort strconv strconv_test strings sync sync/atomic syscall testing time unicode unicode/utf8 unsafe] | 
|  | // strconv.Files: [atob.go atof.go atoi.go decimal.go doc.go extfloat.go ftoa.go isprint.go itoa.go quote.go internal_test.go] | 
|  | // strconv_test.Files: [atob_test.go atof_test.go atoi_test.go decimal_test.go example_test.go fp_test.go ftoa_test.go itoa_test.go quote_test.go strconv_test.go] | 
|  | } |