180 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
// 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 // 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 context 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]
 | 
						|
}
 |