зеркало из https://github.com/golang/tools.git
all: gofmt
Gofmt to update doc comments to the new formatting. (There are so many files in x/tools I am breaking up the gofmt'ing into multiple CLs. This is the leftovers.) For golang/go#51082. Change-Id: Id9d440cde9de7093d2ffe06cbaa7098993823d6b Reviewed-on: https://go-review.googlesource.com/c/tools/+/399363 Run-TryBot: Russ Cox <rsc@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Родитель
d996daab27
Коммит
d5f48fca53
|
@ -10,7 +10,6 @@
|
|||
// space-efficient than equivalent operations on sets based on the Go
|
||||
// map type. The IsEmpty, Min, Max, Clear and TakeMin operations
|
||||
// require constant time.
|
||||
//
|
||||
package intsets // import "golang.org/x/tools/container/intsets"
|
||||
|
||||
// TODO(adonovan):
|
||||
|
@ -37,7 +36,6 @@ import (
|
|||
//
|
||||
// Sparse sets must be copied using the Copy method, not by assigning
|
||||
// a Sparse value.
|
||||
//
|
||||
type Sparse struct {
|
||||
// An uninitialized Sparse represents an empty set.
|
||||
// An empty set may also be represented by
|
||||
|
@ -105,7 +103,6 @@ func ntz(x word) int {
|
|||
// is the Euclidean remainder.
|
||||
//
|
||||
// A block may only be empty transiently.
|
||||
//
|
||||
type block struct {
|
||||
offset int // offset mod bitsPerBlock == 0
|
||||
bits [wordsPerBlock]word // contains at least one set bit
|
||||
|
@ -122,7 +119,6 @@ func wordMask(i uint) (w uint, mask word) {
|
|||
|
||||
// insert sets the block b's ith bit and
|
||||
// returns true if it was not already set.
|
||||
//
|
||||
func (b *block) insert(i uint) bool {
|
||||
w, mask := wordMask(i)
|
||||
if b.bits[w]&mask == 0 {
|
||||
|
@ -135,7 +131,6 @@ func (b *block) insert(i uint) bool {
|
|||
// remove clears the block's ith bit and
|
||||
// returns true if the bit was previously set.
|
||||
// NB: may leave the block empty.
|
||||
//
|
||||
func (b *block) remove(i uint) bool {
|
||||
w, mask := wordMask(i)
|
||||
if b.bits[w]&mask != 0 {
|
||||
|
@ -238,7 +233,6 @@ func (b *block) forEach(f func(int)) {
|
|||
|
||||
// offsetAndBitIndex returns the offset of the block that would
|
||||
// contain x and the bit index of x within that block.
|
||||
//
|
||||
func offsetAndBitIndex(x int) (int, uint) {
|
||||
mod := x % bitsPerBlock
|
||||
if mod < 0 {
|
||||
|
@ -438,9 +432,8 @@ func (s *Sparse) Clear() {
|
|||
//
|
||||
// This method may be used for iteration over a worklist like so:
|
||||
//
|
||||
// var x int
|
||||
// for worklist.TakeMin(&x) { use(x) }
|
||||
//
|
||||
// var x int
|
||||
// for worklist.TakeMin(&x) { use(x) }
|
||||
func (s *Sparse) TakeMin(p *int) bool {
|
||||
if s.IsEmpty() {
|
||||
return false
|
||||
|
@ -466,7 +459,6 @@ func (s *Sparse) Has(x int) bool {
|
|||
// f must not mutate s. Consequently, forEach is not safe to expose
|
||||
// to clients. In any case, using "range s.AppendTo()" allows more
|
||||
// natural control flow with continue/break/return.
|
||||
//
|
||||
func (s *Sparse) forEach(f func(int)) {
|
||||
for b := s.first(); b != &none; b = s.next(b) {
|
||||
b.forEach(f)
|
||||
|
@ -1021,11 +1013,11 @@ func (s *Sparse) String() string {
|
|||
// preceded by a digit, appears if the sum is non-integral.
|
||||
//
|
||||
// Examples:
|
||||
// {}.BitString() = "0"
|
||||
// {4,5}.BitString() = "110000"
|
||||
// {-3}.BitString() = "0.001"
|
||||
// {-3,0,4,5}.BitString() = "110001.001"
|
||||
//
|
||||
// {}.BitString() = "0"
|
||||
// {4,5}.BitString() = "110000"
|
||||
// {-3}.BitString() = "0.001"
|
||||
// {-3,0,4,5}.BitString() = "110001.001"
|
||||
func (s *Sparse) BitString() string {
|
||||
if s.IsEmpty() {
|
||||
return "0"
|
||||
|
@ -1060,7 +1052,6 @@ func (s *Sparse) BitString() string {
|
|||
|
||||
// GoString returns a string showing the internal representation of
|
||||
// the set s.
|
||||
//
|
||||
func (s *Sparse) GoString() string {
|
||||
var buf bytes.Buffer
|
||||
for b := s.first(); b != &none; b = s.next(b) {
|
||||
|
|
|
@ -96,6 +96,7 @@ func checkFile(toolsDir, filename string) (bool, error) {
|
|||
|
||||
// Copied from golang.org/x/tools/internal/lsp/source/util.go.
|
||||
// Matches cgo generated comment as well as the proposed standard:
|
||||
//
|
||||
// https://golang.org/s/generatedcode
|
||||
var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`)
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import (
|
|||
// additional whitespace abutting a node to be enclosed by it.
|
||||
// In this example:
|
||||
//
|
||||
// z := x + y // add them
|
||||
// <-A->
|
||||
// <----B----->
|
||||
// z := x + y // add them
|
||||
// <-A->
|
||||
// <----B----->
|
||||
//
|
||||
// the ast.BinaryExpr(+) node is considered to enclose interval B
|
||||
// even though its [Pos()..End()) is actually only interval A.
|
||||
|
@ -43,10 +43,10 @@ import (
|
|||
// interior whitespace of path[0].
|
||||
// In this example:
|
||||
//
|
||||
// z := x + y // add them
|
||||
// <--C--> <---E-->
|
||||
// ^
|
||||
// D
|
||||
// z := x + y // add them
|
||||
// <--C--> <---E-->
|
||||
// ^
|
||||
// D
|
||||
//
|
||||
// intervals C, D and E are inexact. C is contained by the
|
||||
// z-assignment statement, because it spans three of its children (:=,
|
||||
|
@ -59,7 +59,6 @@ import (
|
|||
// Requires FileSet; see loader.tokenFileContainsPos.
|
||||
//
|
||||
// Postcondition: path is never nil; it always contains at least 'root'.
|
||||
//
|
||||
func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
|
||||
// fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
|
||||
|
||||
|
@ -162,7 +161,6 @@ func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Nod
|
|||
// tokenNode is a dummy implementation of ast.Node for a single token.
|
||||
// They are used transiently by PathEnclosingInterval but never escape
|
||||
// this package.
|
||||
//
|
||||
type tokenNode struct {
|
||||
pos token.Pos
|
||||
end token.Pos
|
||||
|
@ -183,7 +181,6 @@ func tok(pos token.Pos, len int) ast.Node {
|
|||
// childrenOf returns the direct non-nil children of ast.Node n.
|
||||
// It may include fake ast.Node implementations for bare tokens.
|
||||
// it is not safe to call (e.g.) ast.Walk on such nodes.
|
||||
//
|
||||
func childrenOf(n ast.Node) []ast.Node {
|
||||
var children []ast.Node
|
||||
|
||||
|
@ -488,7 +485,6 @@ func (sl byPos) Swap(i, j int) {
|
|||
// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
|
||||
// StarExpr) we could be much more specific given the path to the AST
|
||||
// root. Perhaps we should do that.
|
||||
//
|
||||
func NodeDescription(n ast.Node) string {
|
||||
switch n := n.(type) {
|
||||
case *ast.ArrayType:
|
||||
|
|
|
@ -40,7 +40,6 @@ func pathToString(path []ast.Node) string {
|
|||
// findInterval parses input and returns the [start, end) positions of
|
||||
// the first occurrence of substr in input. f==nil indicates failure;
|
||||
// an error has already been reported in that case.
|
||||
//
|
||||
func findInterval(t *testing.T, fset *token.FileSet, input, substr string) (f *ast.File, start, end token.Pos) {
|
||||
f, err := parser.ParseFile(fset, "<input>", input, 0)
|
||||
if err != nil {
|
||||
|
|
|
@ -22,8 +22,11 @@ func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) {
|
|||
// If name is not empty, it is used to rename the import.
|
||||
//
|
||||
// For example, calling
|
||||
//
|
||||
// AddNamedImport(fset, f, "pathpkg", "path")
|
||||
//
|
||||
// adds
|
||||
//
|
||||
// import pathpkg "path"
|
||||
func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) {
|
||||
if imports(f, name, path) {
|
||||
|
|
|
@ -41,7 +41,6 @@ type ApplyFunc func(*Cursor) bool
|
|||
// Children are traversed in the order in which they appear in the
|
||||
// respective node's struct definition. A package's files are
|
||||
// traversed in the filenames' alphabetical order.
|
||||
//
|
||||
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
|
||||
parent := &struct{ ast.Node }{root}
|
||||
defer func() {
|
||||
|
@ -65,8 +64,8 @@ var abort = new(int) // singleton, to signal termination of Apply
|
|||
// c.Parent(), and f is the field identifier with name c.Name(),
|
||||
// the following invariants hold:
|
||||
//
|
||||
// p.f == c.Node() if c.Index() < 0
|
||||
// p.f[c.Index()] == c.Node() if c.Index() >= 0
|
||||
// p.f == c.Node() if c.Index() < 0
|
||||
// p.f[c.Index()] == c.Node() if c.Index() >= 0
|
||||
//
|
||||
// The methods Replace, Delete, InsertBefore, and InsertAfter
|
||||
// can be used to change the AST without disrupting Apply.
|
||||
|
|
|
@ -77,12 +77,14 @@ const (
|
|||
// typeOf returns a distinct single-bit value that represents the type of n.
|
||||
//
|
||||
// Various implementations were benchmarked with BenchmarkNewInspector:
|
||||
// GOGC=off
|
||||
// - type switch 4.9-5.5ms 2.1ms
|
||||
// - binary search over a sorted list of types 5.5-5.9ms 2.5ms
|
||||
// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms
|
||||
// - linear scan, unordered list 6.4ms 2.7ms
|
||||
// - hash table 6.5ms 3.1ms
|
||||
//
|
||||
// GOGC=off
|
||||
// - type switch 4.9-5.5ms 2.1ms
|
||||
// - binary search over a sorted list of types 5.5-5.9ms 2.5ms
|
||||
// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms
|
||||
// - linear scan, unordered list 6.4ms 2.7ms
|
||||
// - hash table 6.5ms 3.1ms
|
||||
//
|
||||
// A perfect hash seemed like overkill.
|
||||
//
|
||||
// The compiler's switch statement is the clear winner
|
||||
|
@ -90,7 +92,6 @@ const (
|
|||
// with constant conditions and good branch prediction.
|
||||
// (Sadly it is the most verbose in source code.)
|
||||
// Binary search suffered from poor branch prediction.
|
||||
//
|
||||
func typeOf(n ast.Node) uint64 {
|
||||
// Fast path: nearly half of all nodes are identifiers.
|
||||
if _, ok := n.(*ast.Ident); ok {
|
||||
|
|
|
@ -28,7 +28,6 @@ import (
|
|||
//
|
||||
// All I/O is done via the build.Context file system interface,
|
||||
// which must be concurrency-safe.
|
||||
//
|
||||
func AllPackages(ctxt *build.Context) []string {
|
||||
var list []string
|
||||
ForEachPackage(ctxt, func(pkg string, _ error) {
|
||||
|
@ -48,7 +47,6 @@ func AllPackages(ctxt *build.Context) []string {
|
|||
//
|
||||
// All I/O is done via the build.Context file system interface,
|
||||
// which must be concurrency-safe.
|
||||
//
|
||||
func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) {
|
||||
ch := make(chan item)
|
||||
|
||||
|
@ -127,19 +125,18 @@ func allPackages(ctxt *build.Context, root string, ch chan<- item) {
|
|||
// ExpandPatterns returns the set of packages matched by patterns,
|
||||
// which may have the following forms:
|
||||
//
|
||||
// golang.org/x/tools/cmd/guru # a single package
|
||||
// golang.org/x/tools/... # all packages beneath dir
|
||||
// ... # the entire workspace.
|
||||
// golang.org/x/tools/cmd/guru # a single package
|
||||
// golang.org/x/tools/... # all packages beneath dir
|
||||
// ... # the entire workspace.
|
||||
//
|
||||
// Order is significant: a pattern preceded by '-' removes matching
|
||||
// packages from the set. For example, these patterns match all encoding
|
||||
// packages except encoding/xml:
|
||||
//
|
||||
// encoding/... -encoding/xml
|
||||
// encoding/... -encoding/xml
|
||||
//
|
||||
// A trailing slash in a pattern is ignored. (Path components of Go
|
||||
// package names are separated by slash, not the platform's path separator.)
|
||||
//
|
||||
func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool {
|
||||
// TODO(adonovan): support other features of 'go list':
|
||||
// - "std"/"cmd"/"all" meta-packages
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
// /go/src/ including, for instance, "math" and "math/big".
|
||||
// ReadDir("/go/src/math/big") would return all the files in the
|
||||
// "math/big" package.
|
||||
//
|
||||
func FakeContext(pkgs map[string]map[string]string) *build.Context {
|
||||
clean := func(filename string) string {
|
||||
f := path.Clean(filepath.ToSlash(filename))
|
||||
|
|
|
@ -60,8 +60,7 @@ func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Conte
|
|||
// ParseOverlayArchive parses an archive containing Go files and their
|
||||
// contents. The result is intended to be used with OverlayContext.
|
||||
//
|
||||
//
|
||||
// Archive format
|
||||
// # Archive format
|
||||
//
|
||||
// The archive consists of a series of files. Each file consists of a
|
||||
// name, a decimal file size and the file contents, separated by
|
||||
|
|
|
@ -20,7 +20,8 @@ const TagsFlagDoc = "a list of `build tags` to consider satisfied during the bui
|
|||
// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag.
|
||||
//
|
||||
// Example:
|
||||
// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||
//
|
||||
// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||
type TagsFlag []string
|
||||
|
||||
func (v *TagsFlag) Set(s string) error {
|
||||
|
|
|
@ -28,7 +28,6 @@ import (
|
|||
// filename that will be attached to the ASTs.
|
||||
//
|
||||
// TODO(adonovan): call this from go/loader.parseFiles when the tree thaws.
|
||||
//
|
||||
func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) {
|
||||
if !IsAbsPath(ctxt, file) {
|
||||
file = JoinPath(ctxt, dir, file)
|
||||
|
@ -51,7 +50,6 @@ func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string
|
|||
//
|
||||
// The '...Files []string' fields of the resulting build.Package are not
|
||||
// populated (build.FindOnly mode).
|
||||
//
|
||||
func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) {
|
||||
if !IsAbsPath(ctxt, filename) {
|
||||
filename = JoinPath(ctxt, dir, filename)
|
||||
|
@ -196,7 +194,6 @@ func SplitPathList(ctxt *build.Context, s string) []string {
|
|||
|
||||
// sameFile returns true if x and y have the same basename and denote
|
||||
// the same file.
|
||||
//
|
||||
func sameFile(x, y string) bool {
|
||||
if path.Clean(x) == path.Clean(y) {
|
||||
return true
|
||||
|
|
|
@ -443,7 +443,6 @@ func (b *builder) rangeStmt(s *ast.RangeStmt, label *lblock) {
|
|||
// Destinations associated with unlabeled for/switch/select stmts.
|
||||
// We push/pop one of these as we enter/leave each construct and for
|
||||
// each BranchStmt we scan for the innermost target of the right type.
|
||||
//
|
||||
type targets struct {
|
||||
tail *targets // rest of stack
|
||||
_break *Block
|
||||
|
@ -454,7 +453,6 @@ type targets struct {
|
|||
// Destinations associated with a labeled block.
|
||||
// We populate these as labels are encountered in forward gotos or
|
||||
// labeled statements.
|
||||
//
|
||||
type lblock struct {
|
||||
_goto *Block
|
||||
_break *Block
|
||||
|
@ -463,7 +461,6 @@ type lblock struct {
|
|||
|
||||
// labeledBlock returns the branch target associated with the
|
||||
// specified label, creating it if needed.
|
||||
//
|
||||
func (b *builder) labeledBlock(label *ast.Ident) *lblock {
|
||||
lb := b.lblocks[label.Obj]
|
||||
if lb == nil {
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
//
|
||||
// produces this CFG:
|
||||
//
|
||||
// 1: x := f()
|
||||
// x != nil
|
||||
// succs: 2, 3
|
||||
// 2: T()
|
||||
// succs: 4
|
||||
// 3: F()
|
||||
// succs: 4
|
||||
// 4:
|
||||
// 1: x := f()
|
||||
// x != nil
|
||||
// succs: 2, 3
|
||||
// 2: T()
|
||||
// succs: 4
|
||||
// 3: F()
|
||||
// succs: 4
|
||||
// 4:
|
||||
//
|
||||
// The CFG does contain Return statements; even implicit returns are
|
||||
// materialized (at the position of the function's closing brace).
|
||||
|
@ -36,7 +36,6 @@
|
|||
// edges, nor the short-circuit semantics of the && and || operators,
|
||||
// nor abnormal control flow caused by panic. If you need this
|
||||
// information, use golang.org/x/tools/go/ssa instead.
|
||||
//
|
||||
package cfg
|
||||
|
||||
import (
|
||||
|
|
|
@ -16,20 +16,19 @@ The interpretation of the notes depends on the application.
|
|||
For example, the test suite for a static checking tool might
|
||||
use a @diag note to indicate an expected diagnostic:
|
||||
|
||||
fmt.Printf("%s", 1) //@ diag("%s wants a string, got int")
|
||||
fmt.Printf("%s", 1) //@ diag("%s wants a string, got int")
|
||||
|
||||
By contrast, the test suite for a source code navigation tool
|
||||
might use notes to indicate the positions of features of
|
||||
interest, the actions to be performed by the test,
|
||||
and their expected outcomes:
|
||||
|
||||
var x = 1 //@ x_decl
|
||||
...
|
||||
print(x) //@ definition("x", x_decl)
|
||||
print(x) //@ typeof("x", "int")
|
||||
var x = 1 //@ x_decl
|
||||
...
|
||||
print(x) //@ definition("x", x_decl)
|
||||
print(x) //@ typeof("x", "int")
|
||||
|
||||
|
||||
Note comment syntax
|
||||
# Note comment syntax
|
||||
|
||||
Note comments always start with the special marker @, which must be the
|
||||
very first character after the comment opening pair, so //@ or /*@ with no
|
||||
|
|
|
@ -18,12 +18,12 @@ import (
|
|||
//
|
||||
// The testdata/{short,long}.a ELF archive files were produced by:
|
||||
//
|
||||
// $ echo 'package foo; func F()' > foo.go
|
||||
// $ gccgo -c -fgo-pkgpath blah foo.go
|
||||
// $ objcopy -j .go_export foo.o foo.gox
|
||||
// $ ar q short.a foo.gox
|
||||
// $ objcopy -j .go_export foo.o name-longer-than-16-bytes.gox
|
||||
// $ ar q long.a name-longer-than-16-bytes.gox
|
||||
// $ echo 'package foo; func F()' > foo.go
|
||||
// $ gccgo -c -fgo-pkgpath blah foo.go
|
||||
// $ objcopy -j .go_export foo.o foo.gox
|
||||
// $ ar q short.a foo.gox
|
||||
// $ objcopy -j .go_export foo.o name-longer-than-16-bytes.gox
|
||||
// $ ar q long.a name-longer-than-16-bytes.gox
|
||||
//
|
||||
// The file long.a contains an archive string table.
|
||||
//
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
// developer tools, which will then be able to consume both Go 1.7 and
|
||||
// Go 1.8 export data files, so they will work before and after the
|
||||
// Go update. (See discussion at https://golang.org/issue/15651.)
|
||||
//
|
||||
package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
|
||||
|
||||
import (
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
// version-skew problems described in the documentation of this package,
|
||||
// or to control the FileSet or access the imports map populated during
|
||||
// package loading.
|
||||
//
|
||||
func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
|
||||
return importer{fset, imports}
|
||||
}
|
||||
|
|
|
@ -20,36 +20,35 @@
|
|||
// be called any number of times. Finally, these are followed by a
|
||||
// call to Load() to actually load and type-check the program.
|
||||
//
|
||||
// var conf loader.Config
|
||||
// var conf loader.Config
|
||||
//
|
||||
// // Use the command-line arguments to specify
|
||||
// // a set of initial packages to load from source.
|
||||
// // See FromArgsUsage for help.
|
||||
// rest, err := conf.FromArgs(os.Args[1:], wantTests)
|
||||
// // Use the command-line arguments to specify
|
||||
// // a set of initial packages to load from source.
|
||||
// // See FromArgsUsage for help.
|
||||
// rest, err := conf.FromArgs(os.Args[1:], wantTests)
|
||||
//
|
||||
// // Parse the specified files and create an ad hoc package with path "foo".
|
||||
// // All files must have the same 'package' declaration.
|
||||
// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
|
||||
// // Parse the specified files and create an ad hoc package with path "foo".
|
||||
// // All files must have the same 'package' declaration.
|
||||
// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
|
||||
//
|
||||
// // Create an ad hoc package with path "foo" from
|
||||
// // the specified already-parsed files.
|
||||
// // All ASTs must have the same 'package' declaration.
|
||||
// conf.CreateFromFiles("foo", parsedFiles)
|
||||
// // Create an ad hoc package with path "foo" from
|
||||
// // the specified already-parsed files.
|
||||
// // All ASTs must have the same 'package' declaration.
|
||||
// conf.CreateFromFiles("foo", parsedFiles)
|
||||
//
|
||||
// // Add "runtime" to the set of packages to be loaded.
|
||||
// conf.Import("runtime")
|
||||
// // Add "runtime" to the set of packages to be loaded.
|
||||
// conf.Import("runtime")
|
||||
//
|
||||
// // Adds "fmt" and "fmt_test" to the set of packages
|
||||
// // to be loaded. "fmt" will include *_test.go files.
|
||||
// conf.ImportWithTests("fmt")
|
||||
// // Adds "fmt" and "fmt_test" to the set of packages
|
||||
// // to be loaded. "fmt" will include *_test.go files.
|
||||
// conf.ImportWithTests("fmt")
|
||||
//
|
||||
// // Finally, load all the packages specified by the configuration.
|
||||
// prog, err := conf.Load()
|
||||
// // Finally, load all the packages specified by the configuration.
|
||||
// prog, err := conf.Load()
|
||||
//
|
||||
// See examples_test.go for examples of API usage.
|
||||
//
|
||||
//
|
||||
// CONCEPTS AND TERMINOLOGY
|
||||
// # CONCEPTS AND TERMINOLOGY
|
||||
//
|
||||
// The WORKSPACE is the set of packages accessible to the loader. The
|
||||
// workspace is defined by Config.Build, a *build.Context. The
|
||||
|
@ -92,7 +91,6 @@
|
|||
// The INITIAL packages are those specified in the configuration. A
|
||||
// DEPENDENCY is a package loaded to satisfy an import in an initial
|
||||
// package or another dependency.
|
||||
//
|
||||
package loader
|
||||
|
||||
// IMPLEMENTATION NOTES
|
||||
|
|
|
@ -179,7 +179,6 @@ type Program struct {
|
|||
// for a single package.
|
||||
//
|
||||
// Not mutated once exposed via the API.
|
||||
//
|
||||
type PackageInfo struct {
|
||||
Pkg *types.Package
|
||||
Importable bool // true if 'import "Pkg.Path()"' would resolve to this
|
||||
|
@ -217,7 +216,6 @@ func (conf *Config) fset() *token.FileSet {
|
|||
// src specifies the parser input as a string, []byte, or io.Reader, and
|
||||
// filename is its apparent name. If src is nil, the contents of
|
||||
// filename are read from the file system.
|
||||
//
|
||||
func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) {
|
||||
// TODO(adonovan): use conf.build() etc like parseFiles does.
|
||||
return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode)
|
||||
|
@ -262,7 +260,6 @@ A '--' argument terminates the list of packages.
|
|||
//
|
||||
// Only superficial errors are reported at this stage; errors dependent
|
||||
// on I/O are detected during Load.
|
||||
//
|
||||
func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) {
|
||||
var rest []string
|
||||
for i, arg := range args {
|
||||
|
@ -300,14 +297,12 @@ func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) {
|
|||
// CreateFromFilenames is a convenience function that adds
|
||||
// a conf.CreatePkgs entry to create a package of the specified *.go
|
||||
// files.
|
||||
//
|
||||
func (conf *Config) CreateFromFilenames(path string, filenames ...string) {
|
||||
conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames})
|
||||
}
|
||||
|
||||
// CreateFromFiles is a convenience function that adds a conf.CreatePkgs
|
||||
// entry to create package of the specified path and parsed files.
|
||||
//
|
||||
func (conf *Config) CreateFromFiles(path string, files ...*ast.File) {
|
||||
conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files})
|
||||
}
|
||||
|
@ -321,12 +316,10 @@ func (conf *Config) CreateFromFiles(path string, files ...*ast.File) {
|
|||
// In addition, if any *_test.go files contain a "package x_test"
|
||||
// declaration, an additional package comprising just those files will
|
||||
// be added to CreatePkgs.
|
||||
//
|
||||
func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) }
|
||||
|
||||
// Import is a convenience function that adds path to ImportPkgs, the
|
||||
// set of initial packages that will be imported from source.
|
||||
//
|
||||
func (conf *Config) Import(path string) { conf.addImport(path, false) }
|
||||
|
||||
func (conf *Config) addImport(path string, tests bool) {
|
||||
|
@ -345,7 +338,6 @@ func (conf *Config) addImport(path string, tests bool) {
|
|||
// exact is defined as for astutil.PathEnclosingInterval.
|
||||
//
|
||||
// The zero value is returned if not found.
|
||||
//
|
||||
func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) {
|
||||
for _, info := range prog.AllPackages {
|
||||
for _, f := range info.Files {
|
||||
|
@ -368,7 +360,6 @@ func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageIn
|
|||
|
||||
// InitialPackages returns a new slice containing the set of initial
|
||||
// packages (Created + Imported) in unspecified order.
|
||||
//
|
||||
func (prog *Program) InitialPackages() []*PackageInfo {
|
||||
infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported))
|
||||
infos = append(infos, prog.Created...)
|
||||
|
@ -435,7 +426,6 @@ type findpkgValue struct {
|
|||
// Upon completion, exactly one of info and err is non-nil:
|
||||
// info on successful creation of a package, err otherwise.
|
||||
// A successful package may still contain type errors.
|
||||
//
|
||||
type importInfo struct {
|
||||
path string // import path
|
||||
info *PackageInfo // results of typechecking (including errors)
|
||||
|
@ -475,7 +465,6 @@ type importError struct {
|
|||
// false, Load will fail if any package had an error.
|
||||
//
|
||||
// It is an error if no packages were loaded.
|
||||
//
|
||||
func (conf *Config) Load() (*Program, error) {
|
||||
// Create a simple default error handler for parse/type errors.
|
||||
if conf.TypeChecker.Error == nil {
|
||||
|
@ -732,10 +721,10 @@ func (conf *Config) build() *build.Context {
|
|||
// errors that were encountered.
|
||||
//
|
||||
// 'which' indicates which files to include:
|
||||
// 'g': include non-test *.go source files (GoFiles + processed CgoFiles)
|
||||
// 't': include in-package *_test.go source files (TestGoFiles)
|
||||
// 'x': include external *_test.go source files. (XTestGoFiles)
|
||||
//
|
||||
// 'g': include non-test *.go source files (GoFiles + processed CgoFiles)
|
||||
// 't': include in-package *_test.go source files (TestGoFiles)
|
||||
// 'x': include external *_test.go source files. (XTestGoFiles)
|
||||
func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) {
|
||||
if bp.ImportPath == "unsafe" {
|
||||
return nil, nil
|
||||
|
@ -776,7 +765,6 @@ func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.Fil
|
|||
// in the package's PackageInfo).
|
||||
//
|
||||
// Idempotent.
|
||||
//
|
||||
func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) {
|
||||
if to == "C" {
|
||||
// This should be unreachable, but ad hoc packages are
|
||||
|
@ -868,7 +856,6 @@ func (imp *importer) findPackage(importPath, fromDir string, mode build.ImportMo
|
|||
//
|
||||
// fromDir is the directory containing the import declaration that
|
||||
// caused these imports.
|
||||
//
|
||||
func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) {
|
||||
if fromPath != "" {
|
||||
// We're loading a set of imports.
|
||||
|
@ -951,7 +938,6 @@ func (imp *importer) findPath(from, to string) []string {
|
|||
// caller must call awaitCompletion() before accessing its info field.
|
||||
//
|
||||
// startLoad is concurrency-safe and idempotent.
|
||||
//
|
||||
func (imp *importer) startLoad(bp *build.Package) *importInfo {
|
||||
path := bp.ImportPath
|
||||
imp.importedMu.Lock()
|
||||
|
@ -995,7 +981,6 @@ func (imp *importer) load(bp *build.Package) *PackageInfo {
|
|||
//
|
||||
// cycleCheck determines whether the imports within files create
|
||||
// dependency edges that should be checked for potential cycles.
|
||||
//
|
||||
func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) {
|
||||
// Ensure the dependencies are loaded, in parallel.
|
||||
var fromPath string
|
||||
|
|
|
@ -27,7 +27,6 @@ var ioLimit = make(chan bool, 10)
|
|||
//
|
||||
// I/O is done via ctxt, which may specify a virtual file system.
|
||||
// displayPath is used to transform the filenames attached to the ASTs.
|
||||
//
|
||||
func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) {
|
||||
if displayPath == nil {
|
||||
displayPath = func(path string) string { return path }
|
||||
|
|
|
@ -67,7 +67,6 @@ Most tools should pass their command-line arguments (after any flags)
|
|||
uninterpreted to the loader, so that the loader can interpret them
|
||||
according to the conventions of the underlying build system.
|
||||
See the Example function for typical usage.
|
||||
|
||||
*/
|
||||
package packages // import "golang.org/x/tools/go/packages"
|
||||
|
||||
|
|
|
@ -1079,7 +1079,6 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) {
|
|||
//
|
||||
// Because files are scanned in parallel, the token.Pos
|
||||
// positions of the resulting ast.Files are not ordered.
|
||||
//
|
||||
func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
||||
var wg sync.WaitGroup
|
||||
n := len(filenames)
|
||||
|
@ -1123,7 +1122,6 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
|||
|
||||
// sameFile returns true if x and y have the same basename and denote
|
||||
// the same file.
|
||||
//
|
||||
func sameFile(x, y string) bool {
|
||||
if x == y {
|
||||
// It could be the case that y doesn't exist.
|
||||
|
|
|
@ -41,24 +41,27 @@ const (
|
|||
// call the Mark method to add the marker to the global set.
|
||||
// You can register the "mark" method to override these in your own call to
|
||||
// Expect. The bound Mark function is usable directly in your method map, so
|
||||
// exported.Expect(map[string]interface{}{"mark": exported.Mark})
|
||||
//
|
||||
// exported.Expect(map[string]interface{}{"mark": exported.Mark})
|
||||
//
|
||||
// replicates the built in behavior.
|
||||
//
|
||||
// Method invocation
|
||||
// # Method invocation
|
||||
//
|
||||
// When invoking a method the expressions in the parameter list need to be
|
||||
// converted to values to be passed to the method.
|
||||
// There are a very limited set of types the arguments are allowed to be.
|
||||
// expect.Note : passed the Note instance being evaluated.
|
||||
// string : can be supplied either a string literal or an identifier.
|
||||
// int : can only be supplied an integer literal.
|
||||
// *regexp.Regexp : can only be supplied a regular expression literal
|
||||
// token.Pos : has a file position calculated as described below.
|
||||
// token.Position : has a file position calculated as described below.
|
||||
// expect.Range: has a start and end position as described below.
|
||||
// interface{} : will be passed any value
|
||||
//
|
||||
// Position calculation
|
||||
// expect.Note : passed the Note instance being evaluated.
|
||||
// string : can be supplied either a string literal or an identifier.
|
||||
// int : can only be supplied an integer literal.
|
||||
// *regexp.Regexp : can only be supplied a regular expression literal
|
||||
// token.Pos : has a file position calculated as described below.
|
||||
// token.Position : has a file position calculated as described below.
|
||||
// expect.Range: has a start and end position as described below.
|
||||
// interface{} : will be passed any value
|
||||
//
|
||||
// # Position calculation
|
||||
//
|
||||
// There is some extra handling when a parameter is being coerced into a
|
||||
// token.Pos, token.Position or Range type argument.
|
||||
|
|
|
@ -9,7 +9,7 @@ By changing the exporter used, you can create projects for multiple build
|
|||
systems from the same description, and run the same tests on them in many
|
||||
cases.
|
||||
|
||||
Example
|
||||
# Example
|
||||
|
||||
As an example of packagestest use, consider the following test that runs
|
||||
the 'go list' command on the specified modules:
|
||||
|
@ -60,7 +60,6 @@ Running the test with verbose output will print:
|
|||
main_test.go:36: 'go list gopher.example/...' with Modules mode layout:
|
||||
gopher.example/repoa/a
|
||||
gopher.example/repob/b
|
||||
|
||||
*/
|
||||
package packagestest
|
||||
|
||||
|
@ -452,17 +451,19 @@ func copyFile(dest, source string, perm os.FileMode) error {
|
|||
|
||||
// GroupFilesByModules attempts to map directories to the modules within each directory.
|
||||
// This function assumes that the folder is structured in the following way:
|
||||
// - dir
|
||||
// - primarymod
|
||||
// - .go files
|
||||
// - packages
|
||||
// - go.mod (optional)
|
||||
// - modules
|
||||
// - repoa
|
||||
// - mod1
|
||||
// - .go files
|
||||
// - packages
|
||||
// - go.mod (optional)
|
||||
//
|
||||
// dir/
|
||||
// primarymod/
|
||||
// *.go files
|
||||
// packages
|
||||
// go.mod (optional)
|
||||
// modules/
|
||||
// repoa/
|
||||
// mod1/
|
||||
// *.go files
|
||||
// packages
|
||||
// go.mod (optional)
|
||||
//
|
||||
// It scans the directory tree anchored at root and adds a Copy writer to the
|
||||
// map for every file found.
|
||||
// This is to enable the common case in tests where you have a full copy of the
|
||||
|
|
|
@ -12,26 +12,33 @@ import (
|
|||
// GOPATH is the exporter that produces GOPATH layouts.
|
||||
// Each "module" is put in it's own GOPATH entry to help test complex cases.
|
||||
// Given the two files
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
//
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
//
|
||||
// You would get the directory layout
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ └── src
|
||||
// │ └── golang.org
|
||||
// │ └── repoa
|
||||
// │ └── a
|
||||
// │ └── a.go
|
||||
// └── repob
|
||||
// └── src
|
||||
// └── golang.org
|
||||
// └── repob
|
||||
// └── b
|
||||
// └── b.go
|
||||
//
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ └── src
|
||||
// │ └── golang.org
|
||||
// │ └── repoa
|
||||
// │ └── a
|
||||
// │ └── a.go
|
||||
// └── repob
|
||||
// └── src
|
||||
// └── golang.org
|
||||
// └── repob
|
||||
// └── b
|
||||
// └── b.go
|
||||
//
|
||||
// GOPATH would be set to
|
||||
// /sometemporarydirectory/repoa;/sometemporarydirectory/repob
|
||||
//
|
||||
// /sometemporarydirectory/repoa;/sometemporarydirectory/repob
|
||||
//
|
||||
// and the working directory would be
|
||||
// /sometemporarydirectory/repoa/src
|
||||
//
|
||||
// /sometemporarydirectory/repoa/src
|
||||
var GOPATH = gopath{}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -23,20 +23,25 @@ import (
|
|||
// Each "repository" is put in it's own module, and the module file generated
|
||||
// will have replace directives for all other modules.
|
||||
// Given the two files
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
//
|
||||
// golang.org/repoa#a/a.go
|
||||
// golang.org/repob#b/b.go
|
||||
//
|
||||
// You would get the directory layout
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ ├── a
|
||||
// │ │ └── a.go
|
||||
// │ └── go.mod
|
||||
// └── repob
|
||||
// ├── b
|
||||
// │ └── b.go
|
||||
// └── go.mod
|
||||
//
|
||||
// /sometemporarydirectory
|
||||
// ├── repoa
|
||||
// │ ├── a
|
||||
// │ │ └── a.go
|
||||
// │ └── go.mod
|
||||
// └── repob
|
||||
// ├── b
|
||||
// │ └── b.go
|
||||
// └── go.mod
|
||||
//
|
||||
// and the working directory would be
|
||||
// /sometemporarydirectory/repoa
|
||||
//
|
||||
// /sometemporarydirectory/repoa
|
||||
var Modules = modules{}
|
||||
|
||||
type modules struct{}
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
// distinct but logically equivalent.
|
||||
//
|
||||
// A single object may have multiple paths. In this example,
|
||||
// type A struct{ X int }
|
||||
// type B A
|
||||
//
|
||||
// type A struct{ X int }
|
||||
// type B A
|
||||
//
|
||||
// the field X has two paths due to its membership of both A and B.
|
||||
// The For(obj) function always returns one of these paths, arbitrarily
|
||||
// but consistently.
|
||||
|
@ -45,30 +47,30 @@ type Path string
|
|||
// The sequences represent a path through the package/object/type graph.
|
||||
// We classify these operators by their type:
|
||||
//
|
||||
// PO package->object Package.Scope.Lookup
|
||||
// OT object->type Object.Type
|
||||
// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU]
|
||||
// TO type->object Type.{At,Field,Method,Obj} [AFMO]
|
||||
// PO package->object Package.Scope.Lookup
|
||||
// OT object->type Object.Type
|
||||
// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU]
|
||||
// TO type->object Type.{At,Field,Method,Obj} [AFMO]
|
||||
//
|
||||
// All valid paths start with a package and end at an object
|
||||
// and thus may be defined by the regular language:
|
||||
//
|
||||
// objectpath = PO (OT TT* TO)*
|
||||
// objectpath = PO (OT TT* TO)*
|
||||
//
|
||||
// The concrete encoding follows directly:
|
||||
// - The only PO operator is Package.Scope.Lookup, which requires an identifier.
|
||||
// - The only OT operator is Object.Type,
|
||||
// which we encode as '.' because dot cannot appear in an identifier.
|
||||
// - The TT operators are encoded as [EKPRUTC];
|
||||
// one of these (TypeParam) requires an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// - The TO operators are encoded as [AFMO];
|
||||
// three of these (At,Field,Method) require an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// These indices are stable across different representations
|
||||
// of the same package, even source and export data.
|
||||
// The indices used are implementation specific and may not correspond to
|
||||
// the argument to the go/types function.
|
||||
// - The only PO operator is Package.Scope.Lookup, which requires an identifier.
|
||||
// - The only OT operator is Object.Type,
|
||||
// which we encode as '.' because dot cannot appear in an identifier.
|
||||
// - The TT operators are encoded as [EKPRUTC];
|
||||
// one of these (TypeParam) requires an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// - The TO operators are encoded as [AFMO];
|
||||
// three of these (At,Field,Method) require an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// These indices are stable across different representations
|
||||
// of the same package, even source and export data.
|
||||
// The indices used are implementation specific and may not correspond to
|
||||
// the argument to the go/types function.
|
||||
//
|
||||
// In the example below,
|
||||
//
|
||||
|
@ -81,15 +83,14 @@ type Path string
|
|||
// field X has the path "T.UM0.RA1.F0",
|
||||
// representing the following sequence of operations:
|
||||
//
|
||||
// p.Lookup("T") T
|
||||
// .Type().Underlying().Method(0). f
|
||||
// .Type().Results().At(1) b
|
||||
// .Type().Field(0) X
|
||||
// p.Lookup("T") T
|
||||
// .Type().Underlying().Method(0). f
|
||||
// .Type().Results().At(1) b
|
||||
// .Type().Field(0) X
|
||||
//
|
||||
// The encoding is not maximally compact---every R or P is
|
||||
// followed by an A, for example---but this simplifies the
|
||||
// encoder and decoder.
|
||||
//
|
||||
const (
|
||||
// object->type operators
|
||||
opType = '.' // .Type() (Object)
|
||||
|
@ -136,10 +137,10 @@ const (
|
|||
//
|
||||
// For(X) would return a path that denotes the following sequence of operations:
|
||||
//
|
||||
// p.Scope().Lookup("T") (TypeName T)
|
||||
// .Type().Underlying().Method(0). (method Func f)
|
||||
// .Type().Results().At(1) (field Var b)
|
||||
// .Type().Field(0) (field Var X)
|
||||
// p.Scope().Lookup("T") (TypeName T)
|
||||
// .Type().Underlying().Method(0). (method Func f)
|
||||
// .Type().Results().At(1) (field Var b)
|
||||
// .Type().Field(0) (field Var X)
|
||||
//
|
||||
// where p is the package (*types.Package) to which X belongs.
|
||||
func For(obj types.Object) (Path, error) {
|
||||
|
|
|
@ -12,7 +12,6 @@ import "go/types"
|
|||
// package Q, Q appears earlier than P in the result.
|
||||
// The algorithm follows import statements in the order they
|
||||
// appear in the source code, so the result is a total order.
|
||||
//
|
||||
func Dependencies(pkgs ...*types.Package) []*types.Package {
|
||||
var result []*types.Package
|
||||
seen := make(map[*types.Package]bool)
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
// Just as with map[K]V, a nil *Map is a valid empty map.
|
||||
//
|
||||
// Not thread-safe.
|
||||
//
|
||||
type Map struct {
|
||||
hasher Hasher // shared by many Maps
|
||||
table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused
|
||||
|
@ -57,14 +56,12 @@ type entry struct {
|
|||
//
|
||||
// If SetHasher is not called, the Map will create a private hasher at
|
||||
// the first call to Insert.
|
||||
//
|
||||
func (m *Map) SetHasher(hasher Hasher) {
|
||||
m.hasher = hasher
|
||||
}
|
||||
|
||||
// Delete removes the entry with the given key, if any.
|
||||
// It returns true if the entry was found.
|
||||
//
|
||||
func (m *Map) Delete(key types.Type) bool {
|
||||
if m != nil && m.table != nil {
|
||||
hash := m.hasher.Hash(key)
|
||||
|
@ -84,7 +81,6 @@ func (m *Map) Delete(key types.Type) bool {
|
|||
|
||||
// At returns the map entry for the given key.
|
||||
// The result is nil if the entry is not present.
|
||||
//
|
||||
func (m *Map) At(key types.Type) interface{} {
|
||||
if m != nil && m.table != nil {
|
||||
for _, e := range m.table[m.hasher.Hash(key)] {
|
||||
|
@ -145,7 +141,6 @@ func (m *Map) Len() int {
|
|||
// f will not be invoked for it, but if f inserts a map entry that
|
||||
// Iterate has not yet reached, whether or not f will be invoked for
|
||||
// it is unspecified.
|
||||
//
|
||||
func (m *Map) Iterate(f func(key types.Type, value interface{})) {
|
||||
if m != nil {
|
||||
for _, bucket := range m.table {
|
||||
|
@ -190,14 +185,12 @@ func (m *Map) toString(values bool) string {
|
|||
// String returns a string representation of the map's entries.
|
||||
// Values are printed using fmt.Sprintf("%v", v).
|
||||
// Order is unspecified.
|
||||
//
|
||||
func (m *Map) String() string {
|
||||
return m.toString(true)
|
||||
}
|
||||
|
||||
// KeysString returns a string representation of the map's key set.
|
||||
// Order is unspecified.
|
||||
//
|
||||
func (m *Map) KeysString() string {
|
||||
return m.toString(false)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ type MethodSetCache struct {
|
|||
// If cache is nil, this function is equivalent to types.NewMethodSet(T).
|
||||
// Utility functions can thus expose an optional *MethodSetCache
|
||||
// parameter to clients that care about performance.
|
||||
//
|
||||
func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
|
||||
if cache == nil {
|
||||
return types.NewMethodSet(T)
|
||||
|
|
|
@ -22,7 +22,6 @@ import "go/types"
|
|||
// this function is intended only for user interfaces.
|
||||
//
|
||||
// The order of the result is as for types.MethodSet(T).
|
||||
//
|
||||
func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
|
||||
isPointerToConcrete := func(T types.Type) bool {
|
||||
ptr, ok := T.(*types.Pointer)
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
// for developers who want to write tools with similar semantics.
|
||||
// It needs to be manually kept in sync with upstream when changes are
|
||||
// made to cmd/go/internal/get; see https://golang.org/issue/11490.
|
||||
//
|
||||
package vcs // import "golang.org/x/tools/go/vcs"
|
||||
|
||||
import (
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
// ERRORS: for each locus of a frontend (scanner/parser/type) error, the
|
||||
// location is highlighted in red and hover text provides the compiler
|
||||
// error message.
|
||||
//
|
||||
package analysis // import "golang.org/x/tools/godoc/analysis"
|
||||
|
||||
import (
|
||||
|
@ -160,7 +159,6 @@ func (res *Result) Status() string {
|
|||
// HTML link markup for the specified godoc file URL. Thread-safe.
|
||||
// Callers must not mutate the elements.
|
||||
// It returns "zero" if no data is available.
|
||||
//
|
||||
func (res *Result) FileInfo(url string) (fi FileInfo) {
|
||||
return res.fileInfo(url).get()
|
||||
}
|
||||
|
@ -185,7 +183,6 @@ func (res *Result) pkgInfo(importPath string) *pkgInfo {
|
|||
// type info for the specified package. Thread-safe.
|
||||
// Callers must not mutate its fields.
|
||||
// PackageInfo returns "zero" if no data is available.
|
||||
//
|
||||
func (res *Result) PackageInfo(importPath string) PackageInfo {
|
||||
return res.pkgInfo(importPath).get()
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
// Conventional name for directories containing test data.
|
||||
// Excluded from directory trees.
|
||||
//
|
||||
const testdataDirName = "testdata"
|
||||
|
||||
type Directory struct {
|
||||
|
@ -217,7 +216,6 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
|
|||
// provided for maxDepth, nodes at larger depths are pruned as well; they
|
||||
// are assumed to contain package files even if their contents are not known
|
||||
// (i.e., in this case the tree may contain directories w/o any package files).
|
||||
//
|
||||
func (c *Corpus) newDirectory(root string, maxDepth int) *Directory {
|
||||
// The root could be a symbolic link so use Stat not Lstat.
|
||||
d, err := c.fs.Stat(root)
|
||||
|
@ -300,7 +298,6 @@ func (dir *Directory) lookup(path string) *Directory {
|
|||
|
||||
// DirEntry describes a directory entry. The Depth and Height values
|
||||
// are useful for presenting an entry in an indented fashion.
|
||||
//
|
||||
type DirEntry struct {
|
||||
Depth int // >= 0
|
||||
Height int // = DirList.MaxHeight - Depth, > 0
|
||||
|
@ -331,7 +328,6 @@ func hasThirdParty(list []DirEntry) bool {
|
|||
// If skipRoot is set, the root directory itself is excluded from the list.
|
||||
// If filter is set, only the directory entries whose paths match the filter
|
||||
// are included.
|
||||
//
|
||||
func (dir *Directory) listing(skipRoot bool, filter func(string) bool) *DirList {
|
||||
if dir == nil {
|
||||
return nil
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
|
||||
// A Segment describes a text segment [start, end).
|
||||
// The zero value of a Segment is a ready-to-use empty segment.
|
||||
//
|
||||
type Segment struct {
|
||||
start, end int
|
||||
}
|
||||
|
@ -36,12 +35,10 @@ func (seg *Segment) isEmpty() bool { return seg.start >= seg.end }
|
|||
// Repeated calls to a selection return consecutive, non-overlapping,
|
||||
// non-empty segments, followed by an infinite sequence of empty
|
||||
// segments. The first empty segment marks the end of the selection.
|
||||
//
|
||||
type Selection func() Segment
|
||||
|
||||
// A LinkWriter writes some start or end "tag" to w for the text offset offs.
|
||||
// It is called by FormatSelections at the start or end of each link segment.
|
||||
//
|
||||
type LinkWriter func(w io.Writer, offs int, start bool)
|
||||
|
||||
// A SegmentWriter formats a text according to selections and writes it to w.
|
||||
|
@ -49,7 +46,6 @@ type LinkWriter func(w io.Writer, offs int, start bool)
|
|||
// to FormatSelections overlap with the text segment: If the n'th bit is set
|
||||
// in selections, the n'th selection provided to FormatSelections is overlapping
|
||||
// with the text.
|
||||
//
|
||||
type SegmentWriter func(w io.Writer, text []byte, selections int)
|
||||
|
||||
// FormatSelections takes a text and writes it to w using link and segment
|
||||
|
@ -58,7 +54,6 @@ type SegmentWriter func(w io.Writer, text []byte, selections int)
|
|||
// consecutive segments of text overlapped by the same selections as specified
|
||||
// by selections. The link writer lw may be nil, in which case the links
|
||||
// Selection is ignored.
|
||||
//
|
||||
func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection, sw SegmentWriter, selections ...Selection) {
|
||||
// If we have a link writer, make the links
|
||||
// selection the last entry in selections
|
||||
|
@ -144,7 +139,6 @@ func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection,
|
|||
|
||||
// A merger merges a slice of Selections and produces a sequence of
|
||||
// consecutive segment change events through repeated next() calls.
|
||||
//
|
||||
type merger struct {
|
||||
selections []Selection
|
||||
segments []Segment // segments[i] is the next segment of selections[i]
|
||||
|
@ -169,7 +163,6 @@ func newMerger(selections []Selection) *merger {
|
|||
// to which the segment belongs, offs is the segment start or end offset
|
||||
// as determined by the start value. If there are no more segment changes,
|
||||
// next returns an index value < 0.
|
||||
//
|
||||
func (m *merger) next() (index, offs int, start bool) {
|
||||
// find the next smallest offset where a segment starts or ends
|
||||
offs = infinity
|
||||
|
@ -233,7 +226,6 @@ func lineSelection(text []byte) Selection {
|
|||
|
||||
// tokenSelection returns, as a selection, the sequence of
|
||||
// consecutive occurrences of token sel in the Go src text.
|
||||
//
|
||||
func tokenSelection(src []byte, sel token.Token) Selection {
|
||||
var s scanner.Scanner
|
||||
fset := token.NewFileSet()
|
||||
|
@ -257,7 +249,6 @@ func tokenSelection(src []byte, sel token.Token) Selection {
|
|||
|
||||
// makeSelection is a helper function to make a Selection from a slice of pairs.
|
||||
// Pairs describing empty segments are ignored.
|
||||
//
|
||||
func makeSelection(matches [][]int) Selection {
|
||||
i := 0
|
||||
return func() Segment {
|
||||
|
@ -306,7 +297,6 @@ func RangeSelection(str string) Selection {
|
|||
// bit 0: comments
|
||||
// bit 1: highlights
|
||||
// bit 2: selections
|
||||
//
|
||||
var startTags = [][]byte{
|
||||
/* 000 */ []byte(``),
|
||||
/* 001 */ []byte(`<span class="comment">`),
|
||||
|
@ -336,16 +326,15 @@ func selectionTag(w io.Writer, text []byte, selections int) {
|
|||
// Consecutive text segments are wrapped in HTML spans (with tags as
|
||||
// defined by startTags and endTag) as follows:
|
||||
//
|
||||
// - if line >= 0, line number (ln) spans are inserted before each line,
|
||||
// starting with the value of line
|
||||
// - if the text is Go source, comments get the "comment" span class
|
||||
// - each occurrence of the regular expression pattern gets the "highlight"
|
||||
// span class
|
||||
// - text segments covered by selection get the "selection" span class
|
||||
// - if line >= 0, line number (ln) spans are inserted before each line,
|
||||
// starting with the value of line
|
||||
// - if the text is Go source, comments get the "comment" span class
|
||||
// - each occurrence of the regular expression pattern gets the "highlight"
|
||||
// span class
|
||||
// - text segments covered by selection get the "selection" span class
|
||||
//
|
||||
// Comments, highlights, and selections may overlap arbitrarily; the respective
|
||||
// HTML span classes are specified in the startTags variable.
|
||||
//
|
||||
func FormatText(w io.Writer, text []byte, line int, goSource bool, pattern string, selection Selection) {
|
||||
var comments, highlights Selection
|
||||
if goSource {
|
||||
|
|
|
@ -41,8 +41,8 @@ const builtinPkgPath = "builtin"
|
|||
// FuncMap defines template functions used in godoc templates.
|
||||
//
|
||||
// Convention: template function names ending in "_html" or "_url" produce
|
||||
// HTML- or URL-escaped strings; all other function results may
|
||||
// require explicit escaping in the template.
|
||||
// HTML- or URL-escaped strings; all other function results may
|
||||
// require explicit escaping in the template.
|
||||
func (p *Presentation) FuncMap() template.FuncMap {
|
||||
p.initFuncMapOnce.Do(p.initFuncMap)
|
||||
return p.funcMap
|
||||
|
|
|
@ -1359,7 +1359,6 @@ type FileLines struct {
|
|||
// LookupRegexp returns the number of matches and the matches where a regular
|
||||
// expression r is found in the full text index. At most n matches are
|
||||
// returned (thus found <= n).
|
||||
//
|
||||
func (x *Index) LookupRegexp(r *regexp.Regexp, n int) (found int, result []FileLines) {
|
||||
if x.suffixes == nil || n <= 0 {
|
||||
return
|
||||
|
@ -1431,7 +1430,6 @@ func (c *Corpus) invalidateIndex() {
|
|||
|
||||
// feedDirnames feeds the directory names of all directories
|
||||
// under the file system given by root to channel c.
|
||||
//
|
||||
func (c *Corpus) feedDirnames(ch chan<- string) {
|
||||
if dir, _ := c.fsTree.Get(); dir != nil {
|
||||
for d := range dir.(*Directory).iter(false) {
|
||||
|
@ -1442,7 +1440,6 @@ func (c *Corpus) feedDirnames(ch chan<- string) {
|
|||
|
||||
// fsDirnames() returns a channel sending all directory names
|
||||
// of all the file systems under godoc's observation.
|
||||
//
|
||||
func (c *Corpus) fsDirnames() <-chan string {
|
||||
ch := make(chan string, 256) // buffered for fewer context switches
|
||||
go func() {
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
// not being declared), are wrapped with HTML links pointing
|
||||
// to the respective declaration, if possible. Comments are
|
||||
// formatted the same way as with FormatText.
|
||||
//
|
||||
func LinkifyText(w io.Writer, text []byte, n ast.Node) {
|
||||
links := linksFor(n)
|
||||
|
||||
|
@ -75,7 +74,6 @@ func LinkifyText(w io.Writer, text []byte, n ast.Node) {
|
|||
|
||||
// A link describes the (HTML) link information for an identifier.
|
||||
// The zero value of a link represents "no link".
|
||||
//
|
||||
type link struct {
|
||||
path, name string // package path, identifier name
|
||||
isVal bool // identifier is defined in a const or var declaration
|
||||
|
@ -83,7 +81,6 @@ type link struct {
|
|||
|
||||
// linksFor returns the list of links for the identifiers used
|
||||
// by node in the same order as they appear in the source.
|
||||
//
|
||||
func linksFor(node ast.Node) (links []link) {
|
||||
// linkMap tracks link information for each ast.Ident node. Entries may
|
||||
// be created out of source order (for example, when we visit a parent
|
||||
|
|
|
@ -43,7 +43,6 @@ func (m *Metadata) FilePath() string { return m.filePath }
|
|||
// extractMetadata extracts the Metadata from a byte slice.
|
||||
// It returns the Metadata value and the remaining data.
|
||||
// If no metadata is present the original byte slice is returned.
|
||||
//
|
||||
func extractMetadata(b []byte) (meta Metadata, tail []byte, err error) {
|
||||
tail = b
|
||||
if !bytes.HasPrefix(b, jsonStart) {
|
||||
|
@ -121,7 +120,6 @@ func (c *Corpus) updateMetadata() {
|
|||
|
||||
// MetadataFor returns the *Metadata for a given relative path or nil if none
|
||||
// exists.
|
||||
//
|
||||
func (c *Corpus) MetadataFor(relpath string) *Metadata {
|
||||
if m, _ := c.docMetadata.Get(); m != nil {
|
||||
meta := m.(map[string]*Metadata)
|
||||
|
@ -142,7 +140,6 @@ func (c *Corpus) MetadataFor(relpath string) *Metadata {
|
|||
|
||||
// refreshMetadata sends a signal to update DocMetadata. If a refresh is in
|
||||
// progress the metadata will be refreshed again afterward.
|
||||
//
|
||||
func (c *Corpus) refreshMetadata() {
|
||||
select {
|
||||
case c.refreshMetadataSignal <- true:
|
||||
|
|
|
@ -55,7 +55,6 @@ func (s *handlerServer) registerWithMux(mux *http.ServeMux) {
|
|||
// directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub-
|
||||
// directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is
|
||||
// set to the respective error but the error is not logged.
|
||||
//
|
||||
func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode, goos, goarch string) *PageInfo {
|
||||
info := &PageInfo{Dirname: abspath, Mode: mode}
|
||||
|
||||
|
@ -411,7 +410,6 @@ func (p *Presentation) GetPageInfoMode(r *http.Request) PageInfoMode {
|
|||
// (as is the convention for packages). This is sufficient
|
||||
// to resolve package identifiers without doing an actual
|
||||
// import. It never returns an error.
|
||||
//
|
||||
func poorMansImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
|
||||
pkg := imports[path]
|
||||
if pkg == nil {
|
||||
|
@ -498,7 +496,6 @@ func addNames(names map[string]bool, decl ast.Decl) {
|
|||
// which correctly updates each package file's comment list.
|
||||
// (The ast.PackageExports signature is frozen, hence the local
|
||||
// implementation).
|
||||
//
|
||||
func packageExports(fset *token.FileSet, pkg *ast.Package) {
|
||||
for _, src := range pkg.Files {
|
||||
cmap := ast.NewCommentMap(fset, src, src.Comments)
|
||||
|
@ -621,7 +618,6 @@ func (p *Presentation) serveTextFile(w http.ResponseWriter, r *http.Request, abs
|
|||
|
||||
// formatGoSource HTML-escapes Go source text and writes it to w,
|
||||
// decorating it with the specified analysis links.
|
||||
//
|
||||
func formatGoSource(buf *bytes.Buffer, text []byte, links []analysis.Link, pattern string, selection Selection) {
|
||||
// Emit to a temp buffer so that we can add line anchors at the end.
|
||||
saved, buf := buf, new(bytes.Buffer)
|
||||
|
|
|
@ -13,9 +13,8 @@ package godoc
|
|||
//
|
||||
// The following encoding is used:
|
||||
//
|
||||
// bits 32 4 1 0
|
||||
// value [lori|kind|isIndex]
|
||||
//
|
||||
// bits 32 4 1 0
|
||||
// value [lori|kind|isIndex]
|
||||
type SpotInfo uint32
|
||||
|
||||
// SpotKind describes whether an identifier is declared (and what kind of
|
||||
|
|
|
@ -8,7 +8,6 @@ import "time"
|
|||
|
||||
// A Throttle permits throttling of a goroutine by
|
||||
// calling the Throttle method repeatedly.
|
||||
//
|
||||
type Throttle struct {
|
||||
f float64 // f = (1-r)/r for 0 < r < 1
|
||||
dt time.Duration // minimum run time slice; >= 0
|
||||
|
@ -27,7 +26,6 @@ type Throttle struct {
|
|||
// approx. 60% of the time, and sleeps approx. 40% of the time.
|
||||
// Values of r < 0 or r > 1 are clamped down to values between 0 and 1.
|
||||
// Values of dt < 0 are set to 0.
|
||||
//
|
||||
func NewThrottle(r float64, dt time.Duration) *Throttle {
|
||||
var f float64
|
||||
switch {
|
||||
|
@ -49,7 +47,6 @@ func NewThrottle(r float64, dt time.Duration) *Throttle {
|
|||
// accumulated run (tr) and sleep times (ts) approximates the value 1/(1-r)
|
||||
// where r is the throttle value. Throttle returns immediately (w/o sleeping)
|
||||
// if less than tm ns have passed since the last call to Throttle.
|
||||
//
|
||||
func (p *Throttle) Throttle() {
|
||||
if p.f < 0 {
|
||||
select {} // always sleep
|
||||
|
|
|
@ -97,7 +97,6 @@ const debugNS = false
|
|||
// mount table entries always have old == "/src/pkg"). The 'old' field is
|
||||
// useful to callers, because they receive just a []mountedFS and not any
|
||||
// other indication of which mount point was found.
|
||||
//
|
||||
type NameSpace map[string][]mountedFS
|
||||
|
||||
// A mountedFS handles requests for path by replacing
|
||||
|
@ -294,7 +293,6 @@ var startTime = time.Now()
|
|||
// to find that subdirectory, because we've mounted d:\Work1 and d:\Work2
|
||||
// there. So if we don't see "src" in the directory listing for c:\Go, we add an
|
||||
// entry for it before returning.
|
||||
//
|
||||
func (ns NameSpace) ReadDir(path string) ([]os.FileInfo, error) {
|
||||
path = ns.clean(path)
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
//
|
||||
// Assumptions:
|
||||
//
|
||||
// - The file paths stored in the zip file must use a slash ('/') as path
|
||||
// separator; and they must be relative (i.e., they must not start with
|
||||
// a '/' - this is usually the case if the file was created w/o special
|
||||
// options).
|
||||
// - The zip file system treats the file paths found in the zip internally
|
||||
// like absolute paths w/o a leading '/'; i.e., the paths are considered
|
||||
// relative to the root of the file system.
|
||||
// - All path arguments to file system methods must be absolute paths.
|
||||
// - The file paths stored in the zip file must use a slash ('/') as path
|
||||
// separator; and they must be relative (i.e., they must not start with
|
||||
// a '/' - this is usually the case if the file was created w/o special
|
||||
// options).
|
||||
// - The zip file system treats the file paths found in the zip internally
|
||||
// like absolute paths w/o a leading '/'; i.e., the paths are considered
|
||||
// relative to the root of the file system.
|
||||
// - All path arguments to file system methods must be absolute paths.
|
||||
package zipfs // import "golang.org/x/tools/godoc/vfs/zipfs"
|
||||
|
||||
import (
|
||||
|
|
|
@ -40,7 +40,7 @@ var LocalPrefix string
|
|||
//
|
||||
// Note that filename's directory influences which imports can be chosen,
|
||||
// so it is important that filename be accurate.
|
||||
// To process data ``as if'' it were in filename, pass the data as a non-nil src.
|
||||
// To process data “as if” it were in filename, pass the data as a non-nil src.
|
||||
func Process(filename string, src []byte, opt *Options) ([]byte, error) {
|
||||
var err error
|
||||
if src == nil {
|
||||
|
|
|
@ -138,13 +138,13 @@ func unexportedMethod(t *types.Interface) *types.Func {
|
|||
}
|
||||
|
||||
// We need to check three things for structs:
|
||||
// 1. The set of exported fields must be compatible. This ensures that keyed struct
|
||||
// literals continue to compile. (There is no compatibility guarantee for unkeyed
|
||||
// struct literals.)
|
||||
// 2. The set of exported *selectable* fields must be compatible. This includes the exported
|
||||
// fields of all embedded structs. This ensures that selections continue to compile.
|
||||
// 3. If the old struct is comparable, so must the new one be. This ensures that equality
|
||||
// expressions and uses of struct values as map keys continue to compile.
|
||||
// 1. The set of exported fields must be compatible. This ensures that keyed struct
|
||||
// literals continue to compile. (There is no compatibility guarantee for unkeyed
|
||||
// struct literals.)
|
||||
// 2. The set of exported *selectable* fields must be compatible. This includes the exported
|
||||
// fields of all embedded structs. This ensures that selections continue to compile.
|
||||
// 3. If the old struct is comparable, so must the new one be. This ensures that equality
|
||||
// expressions and uses of struct values as map keys continue to compile.
|
||||
//
|
||||
// An unexported embedded struct can't appear in a struct literal outside the
|
||||
// package, so it doesn't have to be present, or have the same name, in the new
|
||||
|
|
|
@ -71,9 +71,12 @@ type PointInt64Value struct {
|
|||
// OpenCensus service can correctly determine the underlying value type.
|
||||
// This custom MarshalJSON exists because,
|
||||
// by default *Point is JSON marshalled as:
|
||||
// {"value": {"int64Value": 1}}
|
||||
//
|
||||
// {"value": {"int64Value": 1}}
|
||||
//
|
||||
// but it should be marshalled as:
|
||||
// {"int64Value": 1}
|
||||
//
|
||||
// {"int64Value": 1}
|
||||
func (p *Point) MarshalJSON() ([]byte, error) {
|
||||
if p == nil {
|
||||
return []byte("null"), nil
|
||||
|
@ -158,9 +161,12 @@ type bucketOptionsExplicitAlias BucketOptionsExplicit
|
|||
// OpenCensus service can correctly determine the underlying value type.
|
||||
// This custom MarshalJSON exists because,
|
||||
// by default BucketOptionsExplicit is JSON marshalled as:
|
||||
// {"bounds":[1,2,3]}
|
||||
//
|
||||
// {"bounds":[1,2,3]}
|
||||
//
|
||||
// but it should be marshalled as:
|
||||
// {"explicit":{"bounds":[1,2,3]}}
|
||||
//
|
||||
// {"explicit":{"bounds":[1,2,3]}}
|
||||
func (be *BucketOptionsExplicit) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&struct {
|
||||
Explicit *bucketOptionsExplicitAlias `json:"explicit,omitempty"`
|
||||
|
|
|
@ -40,12 +40,12 @@ var ErrSkipFiles = errors.New("fastwalk: skip remaining files in directory")
|
|||
// If fastWalk returns filepath.SkipDir, the directory is skipped.
|
||||
//
|
||||
// Unlike filepath.Walk:
|
||||
// * file stat calls must be done by the user.
|
||||
// - file stat calls must be done by the user.
|
||||
// The only provided metadata is the file type, which does not include
|
||||
// any permission bits.
|
||||
// * multiple goroutines stat the filesystem concurrently. The provided
|
||||
// - multiple goroutines stat the filesystem concurrently. The provided
|
||||
// walkFn must be safe for concurrent use.
|
||||
// * fastWalk can follow symlinks if walkFn returns the TraverseLink
|
||||
// - fastWalk can follow symlinks if walkFn returns the TraverseLink
|
||||
// sentinel error. It is the walkFn's responsibility to prevent
|
||||
// fastWalk from going into symlink cycles.
|
||||
func Walk(root string, walkFn func(path string, typ os.FileMode) error) error {
|
||||
|
|
|
@ -276,11 +276,11 @@ func cutSpace(b []byte) (before, middle, after []byte) {
|
|||
}
|
||||
|
||||
// matchSpace reformats src to use the same space context as orig.
|
||||
// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
|
||||
// 2) matchSpace copies the indentation of the first non-blank line in orig
|
||||
// to every non-blank line in src.
|
||||
// 3) matchSpace copies the trailing space from orig and uses it in place
|
||||
// of src's trailing space.
|
||||
// 1. If orig begins with blank lines, matchSpace inserts them at the beginning of src.
|
||||
// 2. matchSpace copies the indentation of the first non-blank line in orig
|
||||
// to every non-blank line in src.
|
||||
// 3. matchSpace copies the trailing space from orig and uses it in place
|
||||
// of src's trailing space.
|
||||
func matchSpace(orig []byte, src []byte) []byte {
|
||||
before, _, after := cutSpace(orig)
|
||||
i := bytes.LastIndex(before, []byte{'\n'})
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//
|
||||
// To use this package, build a store and use it to acquire handles with the
|
||||
// Bind method.
|
||||
//
|
||||
package memoize
|
||||
|
||||
import (
|
||||
|
|
|
@ -96,7 +96,7 @@ func (s *Summary) addGoroutine(gr Goroutine) {
|
|||
s.Calls[index].merge(gr)
|
||||
}
|
||||
|
||||
//TODO: do we want other grouping strategies?
|
||||
// TODO: do we want other grouping strategies?
|
||||
func (c *Call) merge(gr Goroutine) {
|
||||
for i := range c.Groups {
|
||||
canditate := &c.Groups[i]
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"golang.org/x/tools/internal/stack"
|
||||
)
|
||||
|
||||
//this is only needed to support pre 1.14 when testing.TB did not have Cleanup
|
||||
// this is only needed to support pre 1.14 when testing.TB did not have Cleanup
|
||||
type withCleanup interface {
|
||||
Cleanup(func())
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ func NeedsGoPackagesEnv(t Testing, env []string) {
|
|||
NeedsGoPackages(t)
|
||||
}
|
||||
|
||||
// NeedsGoBuild skips t if the current system can't build programs with ``go build''
|
||||
// NeedsGoBuild skips t if the current system can't build programs with “go build”
|
||||
// and then run them with os.StartProcess or exec.Command.
|
||||
// android, and darwin/arm systems don't have the userspace go build needs to run,
|
||||
// and js/wasm doesn't support running subprocesses.
|
||||
|
|
|
@ -121,15 +121,15 @@ func OriginMethod(fn *types.Func) *types.Func {
|
|||
//
|
||||
// For example, consider the following type declarations:
|
||||
//
|
||||
// type Interface[T any] interface {
|
||||
// Accept(T)
|
||||
// }
|
||||
// type Interface[T any] interface {
|
||||
// Accept(T)
|
||||
// }
|
||||
//
|
||||
// type Container[T any] struct {
|
||||
// Element T
|
||||
// }
|
||||
// type Container[T any] struct {
|
||||
// Element T
|
||||
// }
|
||||
//
|
||||
// func (c Container[T]) Accept(t T) { c.Element = t }
|
||||
// func (c Container[T]) Accept(t T) { c.Element = t }
|
||||
//
|
||||
// In this case, GenericAssignableTo reports that instantiations of Container
|
||||
// are assignable to the corresponding instantiation of Interface.
|
||||
|
|
|
@ -36,7 +36,7 @@ func MakePair[L, R Constraint](l L, r R) Pair[L, R] {
|
|||
//!-input
|
||||
`
|
||||
|
||||
//!+print
|
||||
// !+print
|
||||
func PrintTypeParams(fset *token.FileSet, file *ast.File) error {
|
||||
conf := types.Config{Importer: importer.Default()}
|
||||
info := &types.Info{
|
||||
|
|
|
@ -24,20 +24,22 @@ var ErrEmptyTypeSet = errors.New("empty type set")
|
|||
// Structural type restrictions of a type parameter are created via
|
||||
// non-interface types embedded in its constraint interface (directly, or via a
|
||||
// chain of interface embeddings). For example, in the declaration
|
||||
// type T[P interface{~int; m()}] int
|
||||
//
|
||||
// type T[P interface{~int; m()}] int
|
||||
//
|
||||
// the structural restriction of the type parameter P is ~int.
|
||||
//
|
||||
// With interface embedding and unions, the specification of structural type
|
||||
// restrictions may be arbitrarily complex. For example, consider the
|
||||
// following:
|
||||
//
|
||||
// type A interface{ ~string|~[]byte }
|
||||
// type A interface{ ~string|~[]byte }
|
||||
//
|
||||
// type B interface{ int|string }
|
||||
// type B interface{ int|string }
|
||||
//
|
||||
// type C interface { ~string|~int }
|
||||
// type C interface { ~string|~int }
|
||||
//
|
||||
// type T[P interface{ A|B; C }] int
|
||||
// type T[P interface{ A|B; C }] int
|
||||
//
|
||||
// In this example, the structural type restriction of P is ~string|int: A|B
|
||||
// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
|
||||
|
|
|
@ -10,11 +10,10 @@ import "go/types"
|
|||
|
||||
// A term describes elementary type sets:
|
||||
//
|
||||
// ∅: (*term)(nil) == ∅ // set of no types (empty set)
|
||||
// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
|
||||
// T: &term{false, T} == {T} // set of type T
|
||||
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
|
||||
//
|
||||
// ∅: (*term)(nil) == ∅ // set of no types (empty set)
|
||||
// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
|
||||
// T: &term{false, T} == {T} // set of type T
|
||||
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
|
||||
type term struct {
|
||||
tilde bool // valid if typ != nil
|
||||
typ types.Type
|
||||
|
|
|
@ -56,7 +56,9 @@ var (
|
|||
)
|
||||
|
||||
// parseCode parses a code present directive. Its syntax:
|
||||
// .code [-numbers] [-edit] <filename> [address] [highlight]
|
||||
//
|
||||
// .code [-numbers] [-edit] <filename> [address] [highlight]
|
||||
//
|
||||
// The directive may also be ".play" if the snippet is executable.
|
||||
func parseCode(ctx *Context, sourceFile string, sourceLine int, cmd string) (Elem, error) {
|
||||
cmd = strings.TrimSpace(cmd)
|
||||
|
|
|
@ -7,7 +7,7 @@ Package present implements parsing and rendering of present files,
|
|||
which can be slide presentations as in golang.org/x/tools/cmd/present
|
||||
or articles as in golang.org/x/blog (the Go blog).
|
||||
|
||||
File Format
|
||||
# File Format
|
||||
|
||||
Present files begin with a header giving the title of the document
|
||||
and other metadata, which looks like:
|
||||
|
@ -26,7 +26,9 @@ If the "# " prefix is missing, the file uses
|
|||
legacy present markup, described below.
|
||||
|
||||
The date line may be written without a time:
|
||||
|
||||
2 Jan 2006
|
||||
|
||||
In this case, the time will be interpreted as 10am UTC on that date.
|
||||
|
||||
The tags line is a comma-separated list of tags that may be used to categorize
|
||||
|
@ -82,7 +84,7 @@ with a dot, as in:
|
|||
Other than the commands, the text in a section is interpreted
|
||||
either as Markdown or as legacy present markup.
|
||||
|
||||
Markdown Syntax
|
||||
# Markdown Syntax
|
||||
|
||||
Markdown typically means the generic name for a family of similar markup languages.
|
||||
The specific variant used in present is CommonMark.
|
||||
|
@ -138,7 +140,7 @@ Example:
|
|||
|
||||
Visit [the Go home page](https://golang.org/).
|
||||
|
||||
Legacy Present Syntax
|
||||
# Legacy Present Syntax
|
||||
|
||||
Compared to Markdown,
|
||||
in legacy present
|
||||
|
@ -201,7 +203,7 @@ marker quotes the marker character.
|
|||
Links can be included in any text with the form [[url][label]], or
|
||||
[[url]] to use the URL itself as the label.
|
||||
|
||||
Command Invocations
|
||||
# Command Invocations
|
||||
|
||||
A number of special commands are available through invocations
|
||||
in the input text. Each such invocation contains a period as the
|
||||
|
@ -224,38 +226,55 @@ a file name followed by an optional address that specifies what
|
|||
section of the file to display. The address syntax is similar in
|
||||
its simplest form to that of ed, but comes from sam and is more
|
||||
general. See
|
||||
|
||||
https://plan9.io/sys/doc/sam/sam.html Table II
|
||||
|
||||
for full details. The displayed block is always rounded out to a
|
||||
full line at both ends.
|
||||
|
||||
If no pattern is present, the entire file is displayed.
|
||||
|
||||
Any line in the program that ends with the four characters
|
||||
|
||||
OMIT
|
||||
|
||||
is deleted from the source before inclusion, making it easy
|
||||
to write things like
|
||||
|
||||
.code test.go /START OMIT/,/END OMIT/
|
||||
|
||||
to find snippets like this
|
||||
|
||||
tedious_code = boring_function()
|
||||
// START OMIT
|
||||
interesting_code = fascinating_function()
|
||||
// END OMIT
|
||||
|
||||
and see only this:
|
||||
|
||||
interesting_code = fascinating_function()
|
||||
|
||||
Also, inside the displayed text a line that ends
|
||||
|
||||
// HL
|
||||
|
||||
will be highlighted in the display. A highlighting mark may have a
|
||||
suffix word, such as
|
||||
|
||||
// HLxxx
|
||||
|
||||
Such highlights are enabled only if the code invocation ends with
|
||||
"HL" followed by the word:
|
||||
|
||||
.code test.go /^type Foo/,/^}/ HLxxx
|
||||
|
||||
The .code function may take one or more flags immediately preceding
|
||||
the filename. This command shows test.go in an editable text area:
|
||||
|
||||
.code -edit test.go
|
||||
|
||||
This command shows test.go with line numbers:
|
||||
|
||||
.code -numbers test.go
|
||||
|
||||
play:
|
||||
|
@ -333,7 +352,7 @@ It is your responsibility to make sure the included HTML is valid and safe.
|
|||
|
||||
.html file.html
|
||||
|
||||
Presenter Notes
|
||||
# Presenter Notes
|
||||
|
||||
Lines that begin with ": " are treated as presenter notes,
|
||||
in both Markdown and legacy present syntax.
|
||||
|
@ -347,7 +366,7 @@ window, except that presenter notes are only visible in the second window.
|
|||
|
||||
Notes may appear anywhere within the slide text. For example:
|
||||
|
||||
* Title of slide
|
||||
## Title of slide
|
||||
|
||||
Some text.
|
||||
|
||||
|
@ -356,6 +375,5 @@ Notes may appear anywhere within the slide text. For example:
|
|||
Some more text.
|
||||
|
||||
: Presenter notes (subsequent paragraph(s))
|
||||
|
||||
*/
|
||||
package present // import "golang.org/x/tools/present"
|
||||
|
|
|
@ -157,7 +157,6 @@ type Transformer struct {
|
|||
// a single-file package containing "before" and "after" functions as
|
||||
// described in the package documentation.
|
||||
// tmplInfo is the type information for tmplFile.
|
||||
//
|
||||
func NewTransformer(fset *token.FileSet, tmplPkg *types.Package, tmplFile *ast.File, tmplInfo *types.Info, verbose bool) (*Transformer, error) {
|
||||
// Check the template.
|
||||
beforeSig := funcSig(tmplPkg, "before")
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
//
|
||||
// A wildcard appearing more than once in the pattern must
|
||||
// consistently match the same tree.
|
||||
//
|
||||
func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
|
||||
if x == nil && y == nil {
|
||||
return true
|
||||
|
|
|
@ -77,7 +77,6 @@ func (tr *Transformer) transformItem(rv reflect.Value) (reflect.Value, bool, map
|
|||
// available in info.
|
||||
//
|
||||
// Derived from rewriteFile in $GOROOT/src/cmd/gofmt/rewrite.go.
|
||||
//
|
||||
func (tr *Transformer) Transform(info *types.Info, pkg *types.Package, file *ast.File) int {
|
||||
if !tr.seenInfos[info] {
|
||||
tr.seenInfos[info] = true
|
||||
|
|
|
@ -206,7 +206,6 @@ func (r *renamer) checkInLocalScope(from types.Object) {
|
|||
//
|
||||
// Removing the old name (and all references to it) is always safe, and
|
||||
// requires no checks.
|
||||
//
|
||||
func (r *renamer) checkInLexicalScope(from types.Object, info *loader.PackageInfo) {
|
||||
b := from.Parent() // the block defining the 'from' object
|
||||
if b != nil {
|
||||
|
@ -568,13 +567,14 @@ func (r *renamer) selectionConflict(from types.Object, delta int, syntax *ast.Se
|
|||
|
||||
// checkMethod performs safety checks for renaming a method.
|
||||
// There are three hazards:
|
||||
// - declaration conflicts
|
||||
// - selection ambiguity/changes
|
||||
// - entailed renamings of assignable concrete/interface types.
|
||||
// We reject renamings initiated at concrete methods if it would
|
||||
// change the assignability relation. For renamings of abstract
|
||||
// methods, we rename all methods transitively coupled to it via
|
||||
// assignability.
|
||||
// - declaration conflicts
|
||||
// - selection ambiguity/changes
|
||||
// - entailed renamings of assignable concrete/interface types.
|
||||
//
|
||||
// We reject renamings initiated at concrete methods if it would
|
||||
// change the assignability relation. For renamings of abstract
|
||||
// methods, we rename all methods transitively coupled to it via
|
||||
// assignability.
|
||||
func (r *renamer) checkMethod(from *types.Func) {
|
||||
// e.g. error.Error
|
||||
if from.Pkg() == nil {
|
||||
|
|
|
@ -31,7 +31,6 @@ import (
|
|||
//
|
||||
// It is populated from an -offset flag or -from query;
|
||||
// see Usage for the allowed -from query forms.
|
||||
//
|
||||
type spec struct {
|
||||
// pkg is the package containing the position
|
||||
// specified by the -from or -offset flag.
|
||||
|
@ -413,7 +412,6 @@ func typeSwitchVar(info *types.Info, path []ast.Node) types.Object {
|
|||
// spec.fromName matching the spec. On success, the result has exactly
|
||||
// one element unless spec.searchFor!="", in which case it has at least one
|
||||
// element.
|
||||
//
|
||||
func findObjects(info *loader.PackageInfo, spec *spec) ([]types.Object, error) {
|
||||
if spec.pkgMember == "" {
|
||||
if spec.searchFor == "" {
|
||||
|
@ -572,6 +570,7 @@ func ambiguityError(fset *token.FileSet, objects []types.Object) error {
|
|||
}
|
||||
|
||||
// Matches cgo generated comment as well as the proposed standard:
|
||||
//
|
||||
// https://golang.org/s/generatedcode
|
||||
var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`)
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ func isDigit(ch rune) bool {
|
|||
|
||||
// sameFile returns true if x and y have the same basename and denote
|
||||
// the same file.
|
||||
//
|
||||
func sameFile(x, y string) bool {
|
||||
if runtime.GOOS == "windows" {
|
||||
x = filepath.ToSlash(x)
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
// functionality will become part of the type-checker in due course,
|
||||
// since it is computing it anyway, and it is robust for ill-typed
|
||||
// inputs, which this package is not.
|
||||
//
|
||||
package satisfy // import "golang.org/x/tools/refactor/satisfy"
|
||||
|
||||
// NOTES:
|
||||
|
@ -69,7 +68,6 @@ type Constraint struct {
|
|||
// that is checked during compilation of a package. Refactoring tools
|
||||
// will need to preserve at least this part of the relation to ensure
|
||||
// continued compilation.
|
||||
//
|
||||
type Finder struct {
|
||||
Result map[Constraint]bool
|
||||
msetcache typeutil.MethodSetCache
|
||||
|
@ -88,7 +86,6 @@ type Finder struct {
|
|||
// The package must be free of type errors, and
|
||||
// info.{Defs,Uses,Selections,Types} must have been populated by the
|
||||
// type-checker.
|
||||
//
|
||||
func (f *Finder) Find(info *types.Info, files []*ast.File) {
|
||||
if f.Result == nil {
|
||||
f.Result = make(map[Constraint]bool)
|
||||
|
@ -276,7 +273,6 @@ func (f *Finder) valueSpec(spec *ast.ValueSpec) {
|
|||
// explicit conversions and comparisons between two types, unless the
|
||||
// types are uninteresting (e.g. lhs is a concrete type, or the empty
|
||||
// interface; rhs has no methods).
|
||||
//
|
||||
func (f *Finder) assign(lhs, rhs types.Type) {
|
||||
if types.Identical(lhs, rhs) {
|
||||
return
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
//
|
||||
// The goals for the format are:
|
||||
//
|
||||
// - be trivial enough to create and edit by hand.
|
||||
// - be able to store trees of text files describing go command test cases.
|
||||
// - diff nicely in git history and code reviews.
|
||||
// - be trivial enough to create and edit by hand.
|
||||
// - be able to store trees of text files describing go command test cases.
|
||||
// - diff nicely in git history and code reviews.
|
||||
//
|
||||
// Non-goals include being a completely general archive format,
|
||||
// storing binary data, storing file modes, storing special files like
|
||||
// symbolic links, and so on.
|
||||
//
|
||||
// Txtar format
|
||||
// # Txtar format
|
||||
//
|
||||
// A txtar archive is zero or more comment lines and then a sequence of file entries.
|
||||
// Each file entry begins with a file marker line of the form "-- FILENAME --"
|
||||
|
|
Загрузка…
Ссылка в новой задаче