summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/tools/go/ast
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/tools/go/ast')
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/enclosing.go627
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/enclosing_test.go195
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/imports.go470
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/imports_test.go1818
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/rewrite.go477
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/rewrite_test.go248
-rw-r--r--vendor/golang.org/x/tools/go/ast/astutil/util.go14
7 files changed, 0 insertions, 3849 deletions
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
deleted file mode 100644
index 6b7052b..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
+++ /dev/null
@@ -1,627 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package astutil
-
-// This file defines utilities for working with source positions.
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "sort"
-)
-
-// PathEnclosingInterval returns the node that encloses the source
-// interval [start, end), and all its ancestors up to the AST root.
-//
-// The definition of "enclosing" used by this function considers
-// additional whitespace abutting a node to be enclosed by it.
-// In this example:
-//
-// 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.
-// This behaviour makes user interfaces more tolerant of imperfect
-// input.
-//
-// This function treats tokens as nodes, though they are not included
-// in the result. e.g. PathEnclosingInterval("+") returns the
-// enclosing ast.BinaryExpr("x + y").
-//
-// If start==end, the 1-char interval following start is used instead.
-//
-// The 'exact' result is true if the interval contains only path[0]
-// and perhaps some adjacent whitespace. It is false if the interval
-// overlaps multiple children of path[0], or if it contains only
-// interior whitespace of path[0].
-// In this example:
-//
-// 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 (:=,
-// x, +). So too is the 1-char interval D, because it contains only
-// interior whitespace of the assignment. E is considered interior
-// whitespace of the BlockStmt containing the assignment.
-//
-// Precondition: [start, end) both lie within the same file as root.
-// TODO(adonovan): return (nil, false) in this case and remove precond.
-// 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
-
- // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
- var visit func(node ast.Node) bool
- visit = func(node ast.Node) bool {
- path = append(path, node)
-
- nodePos := node.Pos()
- nodeEnd := node.End()
-
- // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
-
- // Intersect [start, end) with interval of node.
- if start < nodePos {
- start = nodePos
- }
- if end > nodeEnd {
- end = nodeEnd
- }
-
- // Find sole child that contains [start, end).
- children := childrenOf(node)
- l := len(children)
- for i, child := range children {
- // [childPos, childEnd) is unaugmented interval of child.
- childPos := child.Pos()
- childEnd := child.End()
-
- // [augPos, augEnd) is whitespace-augmented interval of child.
- augPos := childPos
- augEnd := childEnd
- if i > 0 {
- augPos = children[i-1].End() // start of preceding whitespace
- }
- if i < l-1 {
- nextChildPos := children[i+1].Pos()
- // Does [start, end) lie between child and next child?
- if start >= augEnd && end <= nextChildPos {
- return false // inexact match
- }
- augEnd = nextChildPos // end of following whitespace
- }
-
- // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
- // i, augPos, augEnd, start, end) // debugging
-
- // Does augmented child strictly contain [start, end)?
- if augPos <= start && end <= augEnd {
- _, isToken := child.(tokenNode)
- return isToken || visit(child)
- }
-
- // Does [start, end) overlap multiple children?
- // i.e. left-augmented child contains start
- // but LR-augmented child does not contain end.
- if start < childEnd && end > augEnd {
- break
- }
- }
-
- // No single child contained [start, end),
- // so node is the result. Is it exact?
-
- // (It's tempting to put this condition before the
- // child loop, but it gives the wrong result in the
- // case where a node (e.g. ExprStmt) and its sole
- // child have equal intervals.)
- if start == nodePos && end == nodeEnd {
- return true // exact match
- }
-
- return false // inexact: overlaps multiple children
- }
-
- if start > end {
- start, end = end, start
- }
-
- if start < root.End() && end > root.Pos() {
- if start == end {
- end = start + 1 // empty interval => interval of size 1
- }
- exact = visit(root)
-
- // Reverse the path:
- for i, l := 0, len(path); i < l/2; i++ {
- path[i], path[l-1-i] = path[l-1-i], path[i]
- }
- } else {
- // Selection lies within whitespace preceding the
- // first (or following the last) declaration in the file.
- // The result nonetheless always includes the ast.File.
- path = append(path, root)
- }
-
- return
-}
-
-// 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
-}
-
-func (n tokenNode) Pos() token.Pos {
- return n.pos
-}
-
-func (n tokenNode) End() token.Pos {
- return n.end
-}
-
-func tok(pos token.Pos, len int) ast.Node {
- return tokenNode{pos, pos + token.Pos(len)}
-}
-
-// 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
-
- // First add nodes for all true subtrees.
- ast.Inspect(n, func(node ast.Node) bool {
- if node == n { // push n
- return true // recur
- }
- if node != nil { // push child
- children = append(children, node)
- }
- return false // no recursion
- })
-
- // Then add fake Nodes for bare tokens.
- switch n := n.(type) {
- case *ast.ArrayType:
- children = append(children,
- tok(n.Lbrack, len("[")),
- tok(n.Elt.End(), len("]")))
-
- case *ast.AssignStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.BasicLit:
- children = append(children,
- tok(n.ValuePos, len(n.Value)))
-
- case *ast.BinaryExpr:
- children = append(children, tok(n.OpPos, len(n.Op.String())))
-
- case *ast.BlockStmt:
- children = append(children,
- tok(n.Lbrace, len("{")),
- tok(n.Rbrace, len("}")))
-
- case *ast.BranchStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.CallExpr:
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
- if n.Ellipsis != 0 {
- children = append(children, tok(n.Ellipsis, len("...")))
- }
-
- case *ast.CaseClause:
- if n.List == nil {
- children = append(children,
- tok(n.Case, len("default")))
- } else {
- children = append(children,
- tok(n.Case, len("case")))
- }
- children = append(children, tok(n.Colon, len(":")))
-
- case *ast.ChanType:
- switch n.Dir {
- case ast.RECV:
- children = append(children, tok(n.Begin, len("<-chan")))
- case ast.SEND:
- children = append(children, tok(n.Begin, len("chan<-")))
- case ast.RECV | ast.SEND:
- children = append(children, tok(n.Begin, len("chan")))
- }
-
- case *ast.CommClause:
- if n.Comm == nil {
- children = append(children,
- tok(n.Case, len("default")))
- } else {
- children = append(children,
- tok(n.Case, len("case")))
- }
- children = append(children, tok(n.Colon, len(":")))
-
- case *ast.Comment:
- // nop
-
- case *ast.CommentGroup:
- // nop
-
- case *ast.CompositeLit:
- children = append(children,
- tok(n.Lbrace, len("{")),
- tok(n.Rbrace, len("{")))
-
- case *ast.DeclStmt:
- // nop
-
- case *ast.DeferStmt:
- children = append(children,
- tok(n.Defer, len("defer")))
-
- case *ast.Ellipsis:
- children = append(children,
- tok(n.Ellipsis, len("...")))
-
- case *ast.EmptyStmt:
- // nop
-
- case *ast.ExprStmt:
- // nop
-
- case *ast.Field:
- // TODO(adonovan): Field.{Doc,Comment,Tag}?
-
- case *ast.FieldList:
- children = append(children,
- tok(n.Opening, len("(")),
- tok(n.Closing, len(")")))
-
- case *ast.File:
- // TODO test: Doc
- children = append(children,
- tok(n.Package, len("package")))
-
- case *ast.ForStmt:
- children = append(children,
- tok(n.For, len("for")))
-
- case *ast.FuncDecl:
- // TODO(adonovan): FuncDecl.Comment?
-
- // Uniquely, FuncDecl breaks the invariant that
- // preorder traversal yields tokens in lexical order:
- // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
- //
- // As a workaround, we inline the case for FuncType
- // here and order things correctly.
- //
- children = nil // discard ast.Walk(FuncDecl) info subtrees
- children = append(children, tok(n.Type.Func, len("func")))
- if n.Recv != nil {
- children = append(children, n.Recv)
- }
- children = append(children, n.Name)
- if n.Type.Params != nil {
- children = append(children, n.Type.Params)
- }
- if n.Type.Results != nil {
- children = append(children, n.Type.Results)
- }
- if n.Body != nil {
- children = append(children, n.Body)
- }
-
- case *ast.FuncLit:
- // nop
-
- case *ast.FuncType:
- if n.Func != 0 {
- children = append(children,
- tok(n.Func, len("func")))
- }
-
- case *ast.GenDecl:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
- if n.Lparen != 0 {
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
- }
-
- case *ast.GoStmt:
- children = append(children,
- tok(n.Go, len("go")))
-
- case *ast.Ident:
- children = append(children,
- tok(n.NamePos, len(n.Name)))
-
- case *ast.IfStmt:
- children = append(children,
- tok(n.If, len("if")))
-
- case *ast.ImportSpec:
- // TODO(adonovan): ImportSpec.{Doc,EndPos}?
-
- case *ast.IncDecStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.IndexExpr:
- children = append(children,
- tok(n.Lbrack, len("{")),
- tok(n.Rbrack, len("}")))
-
- case *ast.InterfaceType:
- children = append(children,
- tok(n.Interface, len("interface")))
-
- case *ast.KeyValueExpr:
- children = append(children,
- tok(n.Colon, len(":")))
-
- case *ast.LabeledStmt:
- children = append(children,
- tok(n.Colon, len(":")))
-
- case *ast.MapType:
- children = append(children,
- tok(n.Map, len("map")))
-
- case *ast.ParenExpr:
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
-
- case *ast.RangeStmt:
- children = append(children,
- tok(n.For, len("for")),
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.ReturnStmt:
- children = append(children,
- tok(n.Return, len("return")))
-
- case *ast.SelectStmt:
- children = append(children,
- tok(n.Select, len("select")))
-
- case *ast.SelectorExpr:
- // nop
-
- case *ast.SendStmt:
- children = append(children,
- tok(n.Arrow, len("<-")))
-
- case *ast.SliceExpr:
- children = append(children,
- tok(n.Lbrack, len("[")),
- tok(n.Rbrack, len("]")))
-
- case *ast.StarExpr:
- children = append(children, tok(n.Star, len("*")))
-
- case *ast.StructType:
- children = append(children, tok(n.Struct, len("struct")))
-
- case *ast.SwitchStmt:
- children = append(children, tok(n.Switch, len("switch")))
-
- case *ast.TypeAssertExpr:
- children = append(children,
- tok(n.Lparen-1, len(".")),
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
-
- case *ast.TypeSpec:
- // TODO(adonovan): TypeSpec.{Doc,Comment}?
-
- case *ast.TypeSwitchStmt:
- children = append(children, tok(n.Switch, len("switch")))
-
- case *ast.UnaryExpr:
- children = append(children, tok(n.OpPos, len(n.Op.String())))
-
- case *ast.ValueSpec:
- // TODO(adonovan): ValueSpec.{Doc,Comment}?
-
- case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:
- // nop
- }
-
- // TODO(adonovan): opt: merge the logic of ast.Inspect() into
- // the switch above so we can make interleaved callbacks for
- // both Nodes and Tokens in the right order and avoid the need
- // to sort.
- sort.Sort(byPos(children))
-
- return children
-}
-
-type byPos []ast.Node
-
-func (sl byPos) Len() int {
- return len(sl)
-}
-func (sl byPos) Less(i, j int) bool {
- return sl[i].Pos() < sl[j].Pos()
-}
-func (sl byPos) Swap(i, j int) {
- sl[i], sl[j] = sl[j], sl[i]
-}
-
-// NodeDescription returns a description of the concrete type of n suitable
-// for a user interface.
-//
-// 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:
- return "array type"
- case *ast.AssignStmt:
- return "assignment"
- case *ast.BadDecl:
- return "bad declaration"
- case *ast.BadExpr:
- return "bad expression"
- case *ast.BadStmt:
- return "bad statement"
- case *ast.BasicLit:
- return "basic literal"
- case *ast.BinaryExpr:
- return fmt.Sprintf("binary %s operation", n.Op)
- case *ast.BlockStmt:
- return "block"
- case *ast.BranchStmt:
- switch n.Tok {
- case token.BREAK:
- return "break statement"
- case token.CONTINUE:
- return "continue statement"
- case token.GOTO:
- return "goto statement"
- case token.FALLTHROUGH:
- return "fall-through statement"
- }
- case *ast.CallExpr:
- if len(n.Args) == 1 && !n.Ellipsis.IsValid() {
- return "function call (or conversion)"
- }
- return "function call"
- case *ast.CaseClause:
- return "case clause"
- case *ast.ChanType:
- return "channel type"
- case *ast.CommClause:
- return "communication clause"
- case *ast.Comment:
- return "comment"
- case *ast.CommentGroup:
- return "comment group"
- case *ast.CompositeLit:
- return "composite literal"
- case *ast.DeclStmt:
- return NodeDescription(n.Decl) + " statement"
- case *ast.DeferStmt:
- return "defer statement"
- case *ast.Ellipsis:
- return "ellipsis"
- case *ast.EmptyStmt:
- return "empty statement"
- case *ast.ExprStmt:
- return "expression statement"
- case *ast.Field:
- // Can be any of these:
- // struct {x, y int} -- struct field(s)
- // struct {T} -- anon struct field
- // interface {I} -- interface embedding
- // interface {f()} -- interface method
- // func (A) func(B) C -- receiver, param(s), result(s)
- return "field/method/parameter"
- case *ast.FieldList:
- return "field/method/parameter list"
- case *ast.File:
- return "source file"
- case *ast.ForStmt:
- return "for loop"
- case *ast.FuncDecl:
- return "function declaration"
- case *ast.FuncLit:
- return "function literal"
- case *ast.FuncType:
- return "function type"
- case *ast.GenDecl:
- switch n.Tok {
- case token.IMPORT:
- return "import declaration"
- case token.CONST:
- return "constant declaration"
- case token.TYPE:
- return "type declaration"
- case token.VAR:
- return "variable declaration"
- }
- case *ast.GoStmt:
- return "go statement"
- case *ast.Ident:
- return "identifier"
- case *ast.IfStmt:
- return "if statement"
- case *ast.ImportSpec:
- return "import specification"
- case *ast.IncDecStmt:
- if n.Tok == token.INC {
- return "increment statement"
- }
- return "decrement statement"
- case *ast.IndexExpr:
- return "index expression"
- case *ast.InterfaceType:
- return "interface type"
- case *ast.KeyValueExpr:
- return "key/value association"
- case *ast.LabeledStmt:
- return "statement label"
- case *ast.MapType:
- return "map type"
- case *ast.Package:
- return "package"
- case *ast.ParenExpr:
- return "parenthesized " + NodeDescription(n.X)
- case *ast.RangeStmt:
- return "range loop"
- case *ast.ReturnStmt:
- return "return statement"
- case *ast.SelectStmt:
- return "select statement"
- case *ast.SelectorExpr:
- return "selector"
- case *ast.SendStmt:
- return "channel send"
- case *ast.SliceExpr:
- return "slice expression"
- case *ast.StarExpr:
- return "*-operation" // load/store expr or pointer type
- case *ast.StructType:
- return "struct type"
- case *ast.SwitchStmt:
- return "switch statement"
- case *ast.TypeAssertExpr:
- return "type assertion"
- case *ast.TypeSpec:
- return "type specification"
- case *ast.TypeSwitchStmt:
- return "type switch"
- case *ast.UnaryExpr:
- return fmt.Sprintf("unary %s operation", n.Op)
- case *ast.ValueSpec:
- return "value specification"
-
- }
- panic(fmt.Sprintf("unexpected node type: %T", n))
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing_test.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing_test.go
deleted file mode 100644
index 107f87c..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing_test.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package astutil_test
-
-// This file defines tests of PathEnclosingInterval.
-
-// TODO(adonovan): exhaustive tests that run over the whole input
-// tree, not just handcrafted examples.
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "strings"
- "testing"
-
- "golang.org/x/tools/go/ast/astutil"
-)
-
-// pathToString returns a string containing the concrete types of the
-// nodes in path.
-func pathToString(path []ast.Node) string {
- var buf bytes.Buffer
- fmt.Fprint(&buf, "[")
- for i, n := range path {
- if i > 0 {
- fmt.Fprint(&buf, " ")
- }
- fmt.Fprint(&buf, strings.TrimPrefix(fmt.Sprintf("%T", n), "*ast."))
- }
- fmt.Fprint(&buf, "]")
- return buf.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 {
- t.Errorf("parse error: %s", err)
- return
- }
-
- i := strings.Index(input, substr)
- if i < 0 {
- t.Errorf("%q is not a substring of input", substr)
- f = nil
- return
- }
-
- filePos := fset.File(f.Package)
- return f, filePos.Pos(i), filePos.Pos(i + len(substr))
-}
-
-// Common input for following tests.
-const input = `
-// Hello.
-package main
-import "fmt"
-func f() {}
-func main() {
- z := (x + y) // add them
- f() // NB: ExprStmt and its CallExpr have same Pos/End
-}
-`
-
-func TestPathEnclosingInterval_Exact(t *testing.T) {
- // For the exact tests, we check that a substring is mapped to
- // the canonical string for the node it denotes.
- tests := []struct {
- substr string // first occurrence of this string indicates interval
- node string // complete text of expected containing node
- }{
- {"package",
- input[11 : len(input)-1]},
- {"\npack",
- input[11 : len(input)-1]},
- {"main",
- "main"},
- {"import",
- "import \"fmt\""},
- {"\"fmt\"",
- "\"fmt\""},
- {"\nfunc f() {}\n",
- "func f() {}"},
- {"x ",
- "x"},
- {" y",
- "y"},
- {"z",
- "z"},
- {" + ",
- "x + y"},
- {" :=",
- "z := (x + y)"},
- {"x + y",
- "x + y"},
- {"(x + y)",
- "(x + y)"},
- {" (x + y) ",
- "(x + y)"},
- {" (x + y) // add",
- "(x + y)"},
- {"func",
- "func f() {}"},
- {"func f() {}",
- "func f() {}"},
- {"\nfun",
- "func f() {}"},
- {" f",
- "f"},
- }
- for _, test := range tests {
- f, start, end := findInterval(t, new(token.FileSet), input, test.substr)
- if f == nil {
- continue
- }
-
- path, exact := astutil.PathEnclosingInterval(f, start, end)
- if !exact {
- t.Errorf("PathEnclosingInterval(%q) not exact", test.substr)
- continue
- }
-
- if len(path) == 0 {
- if test.node != "" {
- t.Errorf("PathEnclosingInterval(%q).path: got [], want %q",
- test.substr, test.node)
- }
- continue
- }
-
- if got := input[path[0].Pos():path[0].End()]; got != test.node {
- t.Errorf("PathEnclosingInterval(%q): got %q, want %q (path was %s)",
- test.substr, got, test.node, pathToString(path))
- continue
- }
- }
-}
-
-func TestPathEnclosingInterval_Paths(t *testing.T) {
- // For these tests, we check only the path of the enclosing
- // node, but not its complete text because it's often quite
- // large when !exact.
- tests := []struct {
- substr string // first occurrence of this string indicates interval
- path string // the pathToString(),exact of the expected path
- }{
- {"// add",
- "[BlockStmt FuncDecl File],false"},
- {"(x + y",
- "[ParenExpr AssignStmt BlockStmt FuncDecl File],false"},
- {"x +",
- "[BinaryExpr ParenExpr AssignStmt BlockStmt FuncDecl File],false"},
- {"z := (x",
- "[AssignStmt BlockStmt FuncDecl File],false"},
- {"func f",
- "[FuncDecl File],false"},
- {"func f()",
- "[FuncDecl File],false"},
- {" f()",
- "[FuncDecl File],false"},
- {"() {}",
- "[FuncDecl File],false"},
- {"// Hello",
- "[File],false"},
- {" f",
- "[Ident FuncDecl File],true"},
- {"func ",
- "[FuncDecl File],true"},
- {"mai",
- "[Ident File],true"},
- {"f() // NB",
- "[CallExpr ExprStmt BlockStmt FuncDecl File],true"},
- }
- for _, test := range tests {
- f, start, end := findInterval(t, new(token.FileSet), input, test.substr)
- if f == nil {
- continue
- }
-
- path, exact := astutil.PathEnclosingInterval(f, start, end)
- if got := fmt.Sprintf("%s,%v", pathToString(path), exact); got != test.path {
- t.Errorf("PathEnclosingInterval(%q): got %q, want %q",
- test.substr, got, test.path)
- continue
- }
- }
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
deleted file mode 100644
index 83f196c..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package astutil contains common utilities for working with the Go AST.
-package astutil // import "golang.org/x/tools/go/ast/astutil"
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "strconv"
- "strings"
-)
-
-// AddImport adds the import path to the file f, if absent.
-func AddImport(fset *token.FileSet, f *ast.File, ipath string) (added bool) {
- return AddNamedImport(fset, f, "", ipath)
-}
-
-// AddNamedImport adds the import path to the file f, if absent.
-// 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, ipath string) (added bool) {
- if imports(f, ipath) {
- return false
- }
-
- newImport := &ast.ImportSpec{
- Path: &ast.BasicLit{
- Kind: token.STRING,
- Value: strconv.Quote(ipath),
- },
- }
- if name != "" {
- newImport.Name = &ast.Ident{Name: name}
- }
-
- // Find an import decl to add to.
- // The goal is to find an existing import
- // whose import path has the longest shared
- // prefix with ipath.
- var (
- bestMatch = -1 // length of longest shared prefix
- lastImport = -1 // index in f.Decls of the file's final import decl
- impDecl *ast.GenDecl // import decl containing the best match
- impIndex = -1 // spec index in impDecl containing the best match
-
- isThirdPartyPath = isThirdParty(ipath)
- )
- for i, decl := range f.Decls {
- gen, ok := decl.(*ast.GenDecl)
- if ok && gen.Tok == token.IMPORT {
- lastImport = i
- // Do not add to import "C", to avoid disrupting the
- // association with its doc comment, breaking cgo.
- if declImports(gen, "C") {
- continue
- }
-
- // Match an empty import decl if that's all that is available.
- if len(gen.Specs) == 0 && bestMatch == -1 {
- impDecl = gen
- }
-
- // Compute longest shared prefix with imports in this group and find best
- // matched import spec.
- // 1. Always prefer import spec with longest shared prefix.
- // 2. While match length is 0,
- // - for stdlib package: prefer first import spec.
- // - for third party package: prefer first third party import spec.
- // We cannot use last import spec as best match for third party package
- // because grouped imports are usually placed last by goimports -local
- // flag.
- // See issue #19190.
- seenAnyThirdParty := false
- for j, spec := range gen.Specs {
- impspec := spec.(*ast.ImportSpec)
- p := importPath(impspec)
- n := matchLen(p, ipath)
- if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) {
- bestMatch = n
- impDecl = gen
- impIndex = j
- }
- seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p)
- }
- }
- }
-
- // If no import decl found, add one after the last import.
- if impDecl == nil {
- impDecl = &ast.GenDecl{
- Tok: token.IMPORT,
- }
- if lastImport >= 0 {
- impDecl.TokPos = f.Decls[lastImport].End()
- } else {
- // There are no existing imports.
- // Our new import goes after the package declaration and after
- // the comment, if any, that starts on the same line as the
- // package declaration.
- impDecl.TokPos = f.Package
-
- file := fset.File(f.Package)
- pkgLine := file.Line(f.Package)
- for _, c := range f.Comments {
- if file.Line(c.Pos()) > pkgLine {
- break
- }
- impDecl.TokPos = c.End()
- }
- }
- f.Decls = append(f.Decls, nil)
- copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
- f.Decls[lastImport+1] = impDecl
- }
-
- // Insert new import at insertAt.
- insertAt := 0
- if impIndex >= 0 {
- // insert after the found import
- insertAt = impIndex + 1
- }
- impDecl.Specs = append(impDecl.Specs, nil)
- copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
- impDecl.Specs[insertAt] = newImport
- pos := impDecl.Pos()
- if insertAt > 0 {
- // If there is a comment after an existing import, preserve the comment
- // position by adding the new import after the comment.
- if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil {
- pos = spec.Comment.End()
- } else {
- // Assign same position as the previous import,
- // so that the sorter sees it as being in the same block.
- pos = impDecl.Specs[insertAt-1].Pos()
- }
- }
- if newImport.Name != nil {
- newImport.Name.NamePos = pos
- }
- newImport.Path.ValuePos = pos
- newImport.EndPos = pos
-
- // Clean up parens. impDecl contains at least one spec.
- if len(impDecl.Specs) == 1 {
- // Remove unneeded parens.
- impDecl.Lparen = token.NoPos
- } else if !impDecl.Lparen.IsValid() {
- // impDecl needs parens added.
- impDecl.Lparen = impDecl.Specs[0].Pos()
- }
-
- f.Imports = append(f.Imports, newImport)
-
- if len(f.Decls) <= 1 {
- return true
- }
-
- // Merge all the import declarations into the first one.
- var first *ast.GenDecl
- for i := 0; i < len(f.Decls); i++ {
- decl := f.Decls[i]
- gen, ok := decl.(*ast.GenDecl)
- if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
- continue
- }
- if first == nil {
- first = gen
- continue // Don't touch the first one.
- }
- // We now know there is more than one package in this import
- // declaration. Ensure that it ends up parenthesized.
- first.Lparen = first.Pos()
- // Move the imports of the other import declaration to the first one.
- for _, spec := range gen.Specs {
- spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
- first.Specs = append(first.Specs, spec)
- }
- f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
- i--
- }
-
- return true
-}
-
-func isThirdParty(importPath string) bool {
- // Third party package import path usually contains "." (".com", ".org", ...)
- // This logic is taken from golang.org/x/tools/imports package.
- return strings.Contains(importPath, ".")
-}
-
-// DeleteImport deletes the import path from the file f, if present.
-func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
- return DeleteNamedImport(fset, f, "", path)
-}
-
-// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
-func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
- var delspecs []*ast.ImportSpec
- var delcomments []*ast.CommentGroup
-
- // Find the import nodes that import path, if any.
- for i := 0; i < len(f.Decls); i++ {
- decl := f.Decls[i]
- gen, ok := decl.(*ast.GenDecl)
- if !ok || gen.Tok != token.IMPORT {
- continue
- }
- for j := 0; j < len(gen.Specs); j++ {
- spec := gen.Specs[j]
- impspec := spec.(*ast.ImportSpec)
- if impspec.Name == nil && name != "" {
- continue
- }
- if impspec.Name != nil && impspec.Name.Name != name {
- continue
- }
- if importPath(impspec) != path {
- continue
- }
-
- // We found an import spec that imports path.
- // Delete it.
- delspecs = append(delspecs, impspec)
- deleted = true
- copy(gen.Specs[j:], gen.Specs[j+1:])
- gen.Specs = gen.Specs[:len(gen.Specs)-1]
-
- // If this was the last import spec in this decl,
- // delete the decl, too.
- if len(gen.Specs) == 0 {
- copy(f.Decls[i:], f.Decls[i+1:])
- f.Decls = f.Decls[:len(f.Decls)-1]
- i--
- break
- } else if len(gen.Specs) == 1 {
- if impspec.Doc != nil {
- delcomments = append(delcomments, impspec.Doc)
- }
- if impspec.Comment != nil {
- delcomments = append(delcomments, impspec.Comment)
- }
- for _, cg := range f.Comments {
- // Found comment on the same line as the import spec.
- if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
- delcomments = append(delcomments, cg)
- break
- }
- }
-
- spec := gen.Specs[0].(*ast.ImportSpec)
-
- // Move the documentation right after the import decl.
- if spec.Doc != nil {
- for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line {
- fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
- }
- }
- for _, cg := range f.Comments {
- if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line {
- for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line {
- fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
- }
- break
- }
- }
- }
- if j > 0 {
- lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
- lastLine := fset.Position(lastImpspec.Path.ValuePos).Line
- line := fset.Position(impspec.Path.ValuePos).Line
-
- // We deleted an entry but now there may be
- // a blank line-sized hole where the import was.
- if line-lastLine > 1 {
- // There was a blank line immediately preceding the deleted import,
- // so there's no need to close the hole.
- // Do nothing.
- } else if line != fset.File(gen.Rparen).LineCount() {
- // There was no blank line. Close the hole.
- fset.File(gen.Rparen).MergeLine(line)
- }
- }
- j--
- }
- }
-
- // Delete imports from f.Imports.
- for i := 0; i < len(f.Imports); i++ {
- imp := f.Imports[i]
- for j, del := range delspecs {
- if imp == del {
- copy(f.Imports[i:], f.Imports[i+1:])
- f.Imports = f.Imports[:len(f.Imports)-1]
- copy(delspecs[j:], delspecs[j+1:])
- delspecs = delspecs[:len(delspecs)-1]
- i--
- break
- }
- }
- }
-
- // Delete comments from f.Comments.
- for i := 0; i < len(f.Comments); i++ {
- cg := f.Comments[i]
- for j, del := range delcomments {
- if cg == del {
- copy(f.Comments[i:], f.Comments[i+1:])
- f.Comments = f.Comments[:len(f.Comments)-1]
- copy(delcomments[j:], delcomments[j+1:])
- delcomments = delcomments[:len(delcomments)-1]
- i--
- break
- }
- }
- }
-
- if len(delspecs) > 0 {
- panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
- }
-
- return
-}
-
-// RewriteImport rewrites any import of path oldPath to path newPath.
-func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) {
- for _, imp := range f.Imports {
- if importPath(imp) == oldPath {
- rewrote = true
- // record old End, because the default is to compute
- // it using the length of imp.Path.Value.
- imp.EndPos = imp.End()
- imp.Path.Value = strconv.Quote(newPath)
- }
- }
- return
-}
-
-// UsesImport reports whether a given import is used.
-func UsesImport(f *ast.File, path string) (used bool) {
- spec := importSpec(f, path)
- if spec == nil {
- return
- }
-
- name := spec.Name.String()
- switch name {
- case "<nil>":
- // If the package name is not explicitly specified,
- // make an educated guess. This is not guaranteed to be correct.
- lastSlash := strings.LastIndex(path, "/")
- if lastSlash == -1 {
- name = path
- } else {
- name = path[lastSlash+1:]
- }
- case "_", ".":
- // Not sure if this import is used - err on the side of caution.
- return true
- }
-
- ast.Walk(visitFn(func(n ast.Node) {
- sel, ok := n.(*ast.SelectorExpr)
- if ok && isTopName(sel.X, name) {
- used = true
- }
- }), f)
-
- return
-}
-
-type visitFn func(node ast.Node)
-
-func (fn visitFn) Visit(node ast.Node) ast.Visitor {
- fn(node)
- return fn
-}
-
-// imports returns true if f imports path.
-func imports(f *ast.File, path string) bool {
- return importSpec(f, path) != nil
-}
-
-// importSpec returns the import spec if f imports path,
-// or nil otherwise.
-func importSpec(f *ast.File, path string) *ast.ImportSpec {
- for _, s := range f.Imports {
- if importPath(s) == path {
- return s
- }
- }
- return nil
-}
-
-// importPath returns the unquoted import path of s,
-// or "" if the path is not properly quoted.
-func importPath(s *ast.ImportSpec) string {
- t, err := strconv.Unquote(s.Path.Value)
- if err == nil {
- return t
- }
- return ""
-}
-
-// declImports reports whether gen contains an import of path.
-func declImports(gen *ast.GenDecl, path string) bool {
- if gen.Tok != token.IMPORT {
- return false
- }
- for _, spec := range gen.Specs {
- impspec := spec.(*ast.ImportSpec)
- if importPath(impspec) == path {
- return true
- }
- }
- return false
-}
-
-// matchLen returns the length of the longest path segment prefix shared by x and y.
-func matchLen(x, y string) int {
- n := 0
- for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ {
- if x[i] == '/' {
- n++
- }
- }
- return n
-}
-
-// isTopName returns true if n is a top-level unresolved identifier with the given name.
-func isTopName(n ast.Expr, name string) bool {
- id, ok := n.(*ast.Ident)
- return ok && id.Name == name && id.Obj == nil
-}
-
-// Imports returns the file imports grouped by paragraph.
-func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
- var groups [][]*ast.ImportSpec
-
- for _, decl := range f.Decls {
- genDecl, ok := decl.(*ast.GenDecl)
- if !ok || genDecl.Tok != token.IMPORT {
- break
- }
-
- group := []*ast.ImportSpec{}
-
- var lastLine int
- for _, spec := range genDecl.Specs {
- importSpec := spec.(*ast.ImportSpec)
- pos := importSpec.Path.ValuePos
- line := fset.Position(pos).Line
- if lastLine > 0 && pos > 0 && line-lastLine > 1 {
- groups = append(groups, group)
- group = []*ast.ImportSpec{}
- }
- group = append(group, importSpec)
- lastLine = line
- }
- groups = append(groups, group)
- }
-
- return groups
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports_test.go b/vendor/golang.org/x/tools/go/ast/astutil/imports_test.go
deleted file mode 100644
index 8bc3480..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/imports_test.go
+++ /dev/null
@@ -1,1818 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package astutil
-
-import (
- "bytes"
- "go/ast"
- "go/format"
- "go/parser"
- "go/token"
- "reflect"
- "strconv"
- "testing"
-)
-
-var fset = token.NewFileSet()
-
-func parse(t *testing.T, name, in string) *ast.File {
- file, err := parser.ParseFile(fset, name, in, parser.ParseComments)
- if err != nil {
- t.Fatalf("%s parse: %v", name, err)
- }
- return file
-}
-
-func print(t *testing.T, name string, f *ast.File) string {
- var buf bytes.Buffer
- if err := format.Node(&buf, fset, f); err != nil {
- t.Fatalf("%s gofmt: %v", name, err)
- }
- return string(buf.Bytes())
-}
-
-type test struct {
- name string
- renamedPkg string
- pkg string
- in string
- out string
- broken bool // known broken
-}
-
-var addTests = []test{
- {
- name: "leave os alone",
- pkg: "os",
- in: `package main
-
-import (
- "os"
-)
-`,
- out: `package main
-
-import (
- "os"
-)
-`,
- },
- {
- name: "import.1",
- pkg: "os",
- in: `package main
-`,
- out: `package main
-
-import "os"
-`,
- },
- {
- name: "import.2",
- pkg: "os",
- in: `package main
-
-// Comment
-import "C"
-`,
- out: `package main
-
-// Comment
-import "C"
-import "os"
-`,
- },
- {
- name: "import.3",
- pkg: "os",
- in: `package main
-
-// Comment
-import "C"
-
-import (
- "io"
- "utf8"
-)
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "io"
- "os"
- "utf8"
-)
-`,
- },
- {
- name: "import.17",
- pkg: "x/y/z",
- in: `package main
-
-// Comment
-import "C"
-
-import (
- "a"
- "b"
-
- "x/w"
-
- "d/f"
-)
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "a"
- "b"
-
- "x/w"
- "x/y/z"
-
- "d/f"
-)
-`,
- },
- {
- name: "issue #19190",
- pkg: "x.org/y/z",
- in: `package main
-
-// Comment
-import "C"
-
-import (
- "bytes"
- "os"
-
- "d.com/f"
-)
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "bytes"
- "os"
-
- "d.com/f"
- "x.org/y/z"
-)
-`,
- },
- {
- name: "issue #19190 with existing grouped import packages",
- pkg: "x.org/y/z",
- in: `package main
-
-// Comment
-import "C"
-
-import (
- "bytes"
- "os"
-
- "c.com/f"
- "d.com/f"
-
- "y.com/a"
- "y.com/b"
- "y.com/c"
-)
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "bytes"
- "os"
-
- "c.com/f"
- "d.com/f"
- "x.org/y/z"
-
- "y.com/a"
- "y.com/b"
- "y.com/c"
-)
-`,
- },
- {
- name: "issue #19190 - match score is still respected",
- pkg: "y.org/c",
- in: `package main
-
-import (
- "x.org/a"
-
- "y.org/b"
-)
-`,
- out: `package main
-
-import (
- "x.org/a"
-
- "y.org/b"
- "y.org/c"
-)
-`,
- },
- {
- name: "import into singular group",
- pkg: "bytes",
- in: `package main
-
-import "os"
-
-`,
- out: `package main
-
-import (
- "bytes"
- "os"
-)
-`,
- },
- {
- name: "import into singular group with comment",
- pkg: "bytes",
- in: `package main
-
-import /* why */ /* comment here? */ "os"
-
-`,
- out: `package main
-
-import /* why */ /* comment here? */ (
- "bytes"
- "os"
-)
-`,
- },
- {
- name: "import into group with leading comment",
- pkg: "strings",
- in: `package main
-
-import (
- // comment before bytes
- "bytes"
- "os"
-)
-
-`,
- out: `package main
-
-import (
- // comment before bytes
- "bytes"
- "os"
- "strings"
-)
-`,
- },
- {
- name: "",
- renamedPkg: "fmtpkg",
- pkg: "fmt",
- in: `package main
-
-import "os"
-
-`,
- out: `package main
-
-import (
- fmtpkg "fmt"
- "os"
-)
-`,
- },
- {
- name: "struct comment",
- pkg: "time",
- in: `package main
-
-// This is a comment before a struct.
-type T struct {
- t time.Time
-}
-`,
- out: `package main
-
-import "time"
-
-// This is a comment before a struct.
-type T struct {
- t time.Time
-}
-`,
- },
- {
- name: "issue 8729 import C",
- pkg: "time",
- in: `package main
-
-import "C"
-
-// comment
-type T time.Time
-`,
- out: `package main
-
-import "C"
-import "time"
-
-// comment
-type T time.Time
-`,
- },
- {
- name: "issue 8729 empty import",
- pkg: "time",
- in: `package main
-
-import ()
-
-// comment
-type T time.Time
-`,
- out: `package main
-
-import "time"
-
-// comment
-type T time.Time
-`,
- },
- {
- name: "issue 8729 comment on package line",
- pkg: "time",
- in: `package main // comment
-
-type T time.Time
-`,
- out: `package main // comment
-import "time"
-
-type T time.Time
-`,
- },
- {
- name: "issue 8729 comment after package",
- pkg: "time",
- in: `package main
-// comment
-
-type T time.Time
-`,
- out: `package main
-
-import "time"
-
-// comment
-
-type T time.Time
-`,
- },
- {
- name: "issue 8729 comment before and on package line",
- pkg: "time",
- in: `// comment before
-package main // comment on
-
-type T time.Time
-`,
- out: `// comment before
-package main // comment on
-import "time"
-
-type T time.Time
-`,
- },
-
- // Issue 9961: Match prefixes using path segments rather than bytes
- {
- name: "issue 9961",
- pkg: "regexp",
- in: `package main
-
-import (
- "flag"
- "testing"
-
- "rsc.io/p"
-)
-`,
- out: `package main
-
-import (
- "flag"
- "regexp"
- "testing"
-
- "rsc.io/p"
-)
-`,
- },
- // Issue 10337: Preserve comment position
- {
- name: "issue 10337",
- pkg: "fmt",
- in: `package main
-
-import (
- "bytes" // a
- "log" // c
-)
-`,
- out: `package main
-
-import (
- "bytes" // a
- "fmt"
- "log" // c
-)
-`,
- },
- {
- name: "issue 10337 new import at the start",
- pkg: "bytes",
- in: `package main
-
-import (
- "fmt" // b
- "log" // c
-)
-`,
- out: `package main
-
-import (
- "bytes"
- "fmt" // b
- "log" // c
-)
-`,
- },
- {
- name: "issue 10337 new import at the end",
- pkg: "log",
- in: `package main
-
-import (
- "bytes" // a
- "fmt" // b
-)
-`,
- out: `package main
-
-import (
- "bytes" // a
- "fmt" // b
- "log"
-)
-`,
- },
- // Issue 14075: Merge import declarations
- {
- name: "issue 14075",
- pkg: "bufio",
- in: `package main
-
-import "bytes"
-import "fmt"
-`,
- out: `package main
-
-import (
- "bufio"
- "bytes"
- "fmt"
-)
-`,
- },
- {
- name: "issue 14075 update position",
- pkg: "bufio",
- in: `package main
-
-import "bytes"
-import (
- "fmt"
-)
-`,
- out: `package main
-
-import (
- "bufio"
- "bytes"
- "fmt"
-)
-`,
- },
- {
- name: `issue 14075 ignore import "C"`,
- pkg: "bufio",
- in: `package main
-
-// Comment
-import "C"
-
-import "bytes"
-import "fmt"
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "bufio"
- "bytes"
- "fmt"
-)
-`,
- },
- {
- name: `issue 14075 ignore adjacent import "C"`,
- pkg: "bufio",
- in: `package main
-
-// Comment
-import "C"
-import "fmt"
-`,
- out: `package main
-
-// Comment
-import "C"
-import (
- "bufio"
- "fmt"
-)
-`,
- },
- {
- name: `issue 14075 ignore adjacent import "C" (without factored import)`,
- pkg: "bufio",
- in: `package main
-
-// Comment
-import "C"
-import "fmt"
-`,
- out: `package main
-
-// Comment
-import "C"
-import (
- "bufio"
- "fmt"
-)
-`,
- },
- {
- name: `issue 14075 ignore single import "C"`,
- pkg: "bufio",
- in: `package main
-
-// Comment
-import "C"
-`,
- out: `package main
-
-// Comment
-import "C"
-import "bufio"
-`,
- },
- {
- name: `issue 17212 several single-import lines with shared prefix ending in a slash`,
- pkg: "net/http",
- in: `package main
-
-import "bufio"
-import "net/url"
-`,
- out: `package main
-
-import (
- "bufio"
- "net/http"
- "net/url"
-)
-`,
- },
- {
- name: `issue 17212 block imports lines with shared prefix ending in a slash`,
- pkg: "net/http",
- in: `package main
-
-import (
- "bufio"
- "net/url"
-)
-`,
- out: `package main
-
-import (
- "bufio"
- "net/http"
- "net/url"
-)
-`,
- },
- {
- name: `issue 17213 many single-import lines`,
- pkg: "fmt",
- in: `package main
-
-import "bufio"
-import "bytes"
-import "errors"
-`,
- out: `package main
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
-)
-`,
- },
-}
-
-func TestAddImport(t *testing.T) {
- for _, test := range addTests {
- file := parse(t, test.name, test.in)
- var before bytes.Buffer
- ast.Fprint(&before, fset, file, nil)
- AddNamedImport(fset, file, test.renamedPkg, test.pkg)
- if got := print(t, test.name, file); got != test.out {
- if test.broken {
- t.Logf("%s is known broken:\ngot: %s\nwant: %s", test.name, got, test.out)
- } else {
- t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
- }
- var after bytes.Buffer
- ast.Fprint(&after, fset, file, nil)
-
- t.Logf("AST before:\n%s\nAST after:\n%s\n", before.String(), after.String())
- }
- }
-}
-
-func TestDoubleAddImport(t *testing.T) {
- file := parse(t, "doubleimport", "package main\n")
- AddImport(fset, file, "os")
- AddImport(fset, file, "bytes")
- want := `package main
-
-import (
- "bytes"
- "os"
-)
-`
- if got := print(t, "doubleimport", file); got != want {
- t.Errorf("got: %s\nwant: %s", got, want)
- }
-}
-
-func TestDoubleAddNamedImport(t *testing.T) {
- file := parse(t, "doublenamedimport", "package main\n")
- AddNamedImport(fset, file, "o", "os")
- AddNamedImport(fset, file, "i", "io")
- want := `package main
-
-import (
- i "io"
- o "os"
-)
-`
- if got := print(t, "doublenamedimport", file); got != want {
- t.Errorf("got: %s\nwant: %s", got, want)
- }
-}
-
-// Part of issue 8729.
-func TestDoubleAddImportWithDeclComment(t *testing.T) {
- file := parse(t, "doubleimport", `package main
-
-import (
-)
-
-// comment
-type I int
-`)
- // The AddImport order here matters.
- AddImport(fset, file, "golang.org/x/tools/go/ast/astutil")
- AddImport(fset, file, "os")
- want := `package main
-
-import (
- "golang.org/x/tools/go/ast/astutil"
- "os"
-)
-
-// comment
-type I int
-`
- if got := print(t, "doubleimport_with_decl_comment", file); got != want {
- t.Errorf("got: %s\nwant: %s", got, want)
- }
-}
-
-var deleteTests = []test{
- {
- name: "import.4",
- pkg: "os",
- in: `package main
-
-import (
- "os"
-)
-`,
- out: `package main
-`,
- },
- {
- name: "import.5",
- pkg: "os",
- in: `package main
-
-// Comment
-import "C"
-import "os"
-`,
- out: `package main
-
-// Comment
-import "C"
-`,
- },
- {
- name: "import.6",
- pkg: "os",
- in: `package main
-
-// Comment
-import "C"
-
-import (
- "io"
- "os"
- "utf8"
-)
-`,
- out: `package main
-
-// Comment
-import "C"
-
-import (
- "io"
- "utf8"
-)
-`,
- },
- {
- name: "import.7",
- pkg: "io",
- in: `package main
-
-import (
- "io" // a
- "os" // b
- "utf8" // c
-)
-`,
- out: `package main
-
-import (
- // a
- "os" // b
- "utf8" // c
-)
-`,
- },
- {
- name: "import.8",
- pkg: "os",
- in: `package main
-
-import (
- "io" // a
- "os" // b
- "utf8" // c
-)
-`,
- out: `package main
-
-import (
- "io" // a
- // b
- "utf8" // c
-)
-`,
- },
- {
- name: "import.9",
- pkg: "utf8",
- in: `package main
-
-import (
- "io" // a
- "os" // b
- "utf8" // c
-)
-`,
- out: `package main
-
-import (
- "io" // a
- "os" // b
- // c
-)
-`,
- },
- {
- name: "import.10",
- pkg: "io",
- in: `package main
-
-import (
- "io"
- "os"
- "utf8"
-)
-`,
- out: `package main
-
-import (
- "os"
- "utf8"
-)
-`,
- },
- {
- name: "import.11",
- pkg: "os",
- in: `package main
-
-import (
- "io"
- "os"
- "utf8"
-)
-`,
- out: `package main
-
-import (
- "io"
- "utf8"
-)
-`,
- },
- {
- name: "import.12",
- pkg: "utf8",
- in: `package main
-
-import (
- "io"
- "os"
- "utf8"
-)
-`,
- out: `package main
-
-import (
- "io"
- "os"
-)
-`,
- },
- {
- name: "handle.raw.quote.imports",
- pkg: "os",
- in: "package main\n\nimport `os`",
- out: `package main
-`,
- },
- {
- name: "import.13",
- pkg: "io",
- in: `package main
-
-import (
- "fmt"
-
- "io"
- "os"
- "utf8"
-
- "go/format"
-)
-`,
- out: `package main
-
-import (
- "fmt"
-
- "os"
- "utf8"
-
- "go/format"
-)
-`,
- },
- {
- name: "import.14",
- pkg: "io",
- in: `package main
-
-import (
- "fmt" // a
-
- "io" // b
- "os" // c
- "utf8" // d
-
- "go/format" // e
-)
-`,
- out: `package main
-
-import (
- "fmt" // a
-
- // b
- "os" // c
- "utf8" // d
-
- "go/format" // e
-)
-`,
- },
- {
- name: "import.15",
- pkg: "double",
- in: `package main
-
-import (
- "double"
- "double"
-)
-`,
- out: `package main
-`,
- },
- {
- name: "import.16",
- pkg: "bubble",
- in: `package main
-
-import (
- "toil"
- "bubble"
- "bubble"
- "trouble"
-)
-`,
- out: `package main
-
-import (
- "toil"
- "trouble"
-)
-`,
- },
- {
- name: "import.17",
- pkg: "quad",
- in: `package main
-
-import (
- "quad"
- "quad"
-)
-
-import (
- "quad"
- "quad"
-)
-`,
- out: `package main
-`,
- },
- {
- name: "import.18",
- renamedPkg: "x",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
- x "fmt"
-)
-`,
- out: `package main
-
-import (
- "fmt"
-)
-`,
- },
- {
- name: "import.18",
- renamedPkg: "x",
- pkg: "fmt",
- in: `package main
-
-import x "fmt"
-import y "fmt"
-`,
- out: `package main
-
-import y "fmt"
-`,
- },
- // Issue #15432, #18051
- {
- name: "import.19",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
-
- // Some comment.
- "io"
-)`,
- out: `package main
-
-import (
- // Some comment.
- "io"
-)
-`,
- },
- {
- name: "import.20",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
-
- // Some
- // comment.
- "io"
-)`,
- out: `package main
-
-import (
- // Some
- // comment.
- "io"
-)
-`,
- },
- {
- name: "import.21",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
-
- /*
- Some
- comment.
- */
- "io"
-)`,
- out: `package main
-
-import (
- /*
- Some
- comment.
- */
- "io"
-)
-`,
- },
- {
- name: "import.22",
- pkg: "fmt",
- in: `package main
-
-import (
- /* Some */
- // comment.
- "io"
- "fmt"
-)`,
- out: `package main
-
-import (
- /* Some */
- // comment.
- "io"
-)
-`,
- },
- {
- name: "import.23",
- pkg: "fmt",
- in: `package main
-
-import (
- // comment 1
- "fmt"
- // comment 2
- "io"
-)`,
- out: `package main
-
-import (
- // comment 2
- "io"
-)
-`,
- },
- {
- name: "import.24",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt" // comment 1
- "io" // comment 2
-)`,
- out: `package main
-
-import (
- "io" // comment 2
-)
-`,
- },
- {
- name: "import.25",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
- /* comment */ "io"
-)`,
- out: `package main
-
-import (
- /* comment */ "io"
-)
-`,
- },
- {
- name: "import.26",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt"
- "io" /* comment */
-)`,
- out: `package main
-
-import (
- "io" /* comment */
-)
-`,
- },
- {
- name: "import.27",
- pkg: "fmt",
- in: `package main
-
-import (
- "fmt" /* comment */
- "io"
-)`,
- out: `package main
-
-import (
- "io"
-)
-`,
- },
- {
- name: "import.28",
- pkg: "fmt",
- in: `package main
-
-import (
- /* comment */ "fmt"
- "io"
-)`,
- out: `package main
-
-import (
- "io"
-)
-`,
- },
- {
- name: "import.29",
- pkg: "fmt",
- in: `package main
-
-// comment 1
-import (
- "fmt"
- "io" // comment 2
-)`,
- out: `package main
-
-// comment 1
-import (
- "io" // comment 2
-)
-`,
- },
- {
- name: "import.30",
- pkg: "fmt",
- in: `package main
-
-// comment 1
-import (
- "fmt" // comment 2
- "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- "io"
-)
-`,
- },
- {
- name: "import.31",
- pkg: "fmt",
- in: `package main
-
-// comment 1
-import (
- "fmt"
- /* comment 2 */ "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- /* comment 2 */ "io"
-)
-`,
- },
- {
- name: "import.32",
- pkg: "fmt",
- renamedPkg: "f",
- in: `package main
-
-// comment 1
-import (
- f "fmt"
- /* comment 2 */ i "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- /* comment 2 */ i "io"
-)
-`,
- },
- {
- name: "import.33",
- pkg: "fmt",
- renamedPkg: "f",
- in: `package main
-
-// comment 1
-import (
- /* comment 2 */ f "fmt"
- i "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- i "io"
-)
-`,
- },
- {
- name: "import.34",
- pkg: "fmt",
- renamedPkg: "f",
- in: `package main
-
-// comment 1
-import (
- f "fmt" /* comment 2 */
- i "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- i "io"
-)
-`,
- },
- {
- name: "import.35",
- pkg: "fmt",
- in: `package main
-
-// comment 1
-import (
- "fmt"
- // comment 2
- "io"
-)`,
- out: `package main
-
-// comment 1
-import (
- // comment 2
- "io"
-)
-`,
- },
- {
- name: "import.36",
- pkg: "fmt",
- in: `package main
-
-/* comment 1 */
-import (
- "fmt"
- /* comment 2 */
- "io"
-)`,
- out: `package main
-
-/* comment 1 */
-import (
- /* comment 2 */
- "io"
-)
-`,
- },
-
- // Issue 20229: MergeLine panic on weird input
- {
- name: "import.37",
- pkg: "io",
- in: `package main
-import("_"
-"io")`,
- out: `package main
-
-import (
- "_"
-)
-`,
- },
-}
-
-func TestDeleteImport(t *testing.T) {
- for _, test := range deleteTests {
- file := parse(t, test.name, test.in)
- DeleteNamedImport(fset, file, test.renamedPkg, test.pkg)
- if got := print(t, test.name, file); got != test.out {
- t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
- }
- }
-}
-
-type rewriteTest struct {
- name string
- srcPkg string
- dstPkg string
- in string
- out string
-}
-
-var rewriteTests = []rewriteTest{
- {
- name: "import.13",
- srcPkg: "utf8",
- dstPkg: "encoding/utf8",
- in: `package main
-
-import (
- "io"
- "os"
- "utf8" // thanks ken
-)
-`,
- out: `package main
-
-import (
- "encoding/utf8" // thanks ken
- "io"
- "os"
-)
-`,
- },
- {
- name: "import.14",
- srcPkg: "asn1",
- dstPkg: "encoding/asn1",
- in: `package main
-
-import (
- "asn1"
- "crypto"
- "crypto/rsa"
- _ "crypto/sha1"
- "crypto/x509"
- "crypto/x509/pkix"
- "time"
-)
-
-var x = 1
-`,
- out: `package main
-
-import (
- "crypto"
- "crypto/rsa"
- _ "crypto/sha1"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "time"
-)
-
-var x = 1
-`,
- },
- {
- name: "import.15",
- srcPkg: "url",
- dstPkg: "net/url",
- in: `package main
-
-import (
- "bufio"
- "net"
- "path"
- "url"
-)
-
-var x = 1 // comment on x, not on url
-`,
- out: `package main
-
-import (
- "bufio"
- "net"
- "net/url"
- "path"
-)
-
-var x = 1 // comment on x, not on url
-`,
- },
- {
- name: "import.16",
- srcPkg: "http",
- dstPkg: "net/http",
- in: `package main
-
-import (
- "flag"
- "http"
- "log"
- "text/template"
-)
-
-var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
-`,
- out: `package main
-
-import (
- "flag"
- "log"
- "net/http"
- "text/template"
-)
-
-var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
-`,
- },
-}
-
-func TestRewriteImport(t *testing.T) {
- for _, test := range rewriteTests {
- file := parse(t, test.name, test.in)
- RewriteImport(fset, file, test.srcPkg, test.dstPkg)
- if got := print(t, test.name, file); got != test.out {
- t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out)
- }
- }
-}
-
-var importsTests = []struct {
- name string
- in string
- want [][]string
-}{
- {
- name: "no packages",
- in: `package foo
-`,
- want: nil,
- },
- {
- name: "one group",
- in: `package foo
-
-import (
- "fmt"
- "testing"
-)
-`,
- want: [][]string{{"fmt", "testing"}},
- },
- {
- name: "four groups",
- in: `package foo
-
-import "C"
-import (
- "fmt"
- "testing"
-
- "appengine"
-
- "myproject/mylib1"
- "myproject/mylib2"
-)
-`,
- want: [][]string{
- {"C"},
- {"fmt", "testing"},
- {"appengine"},
- {"myproject/mylib1", "myproject/mylib2"},
- },
- },
- {
- name: "multiple factored groups",
- in: `package foo
-
-import (
- "fmt"
- "testing"
-
- "appengine"
-)
-import (
- "reflect"
-
- "bytes"
-)
-`,
- want: [][]string{
- {"fmt", "testing"},
- {"appengine"},
- {"reflect"},
- {"bytes"},
- },
- },
-}
-
-func unquote(s string) string {
- res, err := strconv.Unquote(s)
- if err != nil {
- return "could_not_unquote"
- }
- return res
-}
-
-func TestImports(t *testing.T) {
- fset := token.NewFileSet()
- for _, test := range importsTests {
- f, err := parser.ParseFile(fset, "test.go", test.in, 0)
- if err != nil {
- t.Errorf("%s: %v", test.name, err)
- continue
- }
- var got [][]string
- for _, group := range Imports(fset, f) {
- var b []string
- for _, spec := range group {
- b = append(b, unquote(spec.Path.Value))
- }
- got = append(got, b)
- }
- if !reflect.DeepEqual(got, test.want) {
- t.Errorf("Imports(%s)=%v, want %v", test.name, got, test.want)
- }
- }
-}
-
-var usesImportTests = []struct {
- name string
- path string
- in string
- want bool
-}{
- {
- name: "no packages",
- path: "io",
- in: `package foo
-`,
- want: false,
- },
- {
- name: "import.1",
- path: "io",
- in: `package foo
-
-import "io"
-
-var _ io.Writer
-`,
- want: true,
- },
- {
- name: "import.2",
- path: "io",
- in: `package foo
-
-import "io"
-`,
- want: false,
- },
- {
- name: "import.3",
- path: "io",
- in: `package foo
-
-import "io"
-
-var io = 42
-`,
- want: false,
- },
- {
- name: "import.4",
- path: "io",
- in: `package foo
-
-import i "io"
-
-var _ i.Writer
-`,
- want: true,
- },
- {
- name: "import.5",
- path: "io",
- in: `package foo
-
-import i "io"
-`,
- want: false,
- },
- {
- name: "import.6",
- path: "io",
- in: `package foo
-
-import i "io"
-
-var i = 42
-var io = 42
-`,
- want: false,
- },
- {
- name: "import.7",
- path: "encoding/json",
- in: `package foo
-
-import "encoding/json"
-
-var _ json.Encoder
-`,
- want: true,
- },
- {
- name: "import.8",
- path: "encoding/json",
- in: `package foo
-
-import "encoding/json"
-`,
- want: false,
- },
- {
- name: "import.9",
- path: "encoding/json",
- in: `package foo
-
-import "encoding/json"
-
-var json = 42
-`,
- want: false,
- },
- {
- name: "import.10",
- path: "encoding/json",
- in: `package foo
-
-import j "encoding/json"
-
-var _ j.Encoder
-`,
- want: true,
- },
- {
- name: "import.11",
- path: "encoding/json",
- in: `package foo
-
-import j "encoding/json"
-`,
- want: false,
- },
- {
- name: "import.12",
- path: "encoding/json",
- in: `package foo
-
-import j "encoding/json"
-
-var j = 42
-var json = 42
-`,
- want: false,
- },
- {
- name: "import.13",
- path: "io",
- in: `package foo
-
-import _ "io"
-`,
- want: true,
- },
- {
- name: "import.14",
- path: "io",
- in: `package foo
-
-import . "io"
-`,
- want: true,
- },
-}
-
-func TestUsesImport(t *testing.T) {
- fset := token.NewFileSet()
- for _, test := range usesImportTests {
- f, err := parser.ParseFile(fset, "test.go", test.in, 0)
- if err != nil {
- t.Errorf("%s: %v", test.name, err)
- continue
- }
- got := UsesImport(f, test.path)
- if got != test.want {
- t.Errorf("UsesImport(%s)=%v, want %v", test.name, got, test.want)
- }
- }
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
deleted file mode 100644
index cf72ea9..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package astutil
-
-import (
- "fmt"
- "go/ast"
- "reflect"
- "sort"
-)
-
-// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
-// before and/or after the node's children, using a Cursor describing
-// the current node and providing operations on it.
-//
-// The return value of ApplyFunc controls the syntax tree traversal.
-// See Apply for details.
-type ApplyFunc func(*Cursor) bool
-
-// Apply traverses a syntax tree recursively, starting with root,
-// and calling pre and post for each node as described below.
-// Apply returns the syntax tree, possibly modified.
-//
-// If pre is not nil, it is called for each node before the node's
-// children are traversed (pre-order). If pre returns false, no
-// children are traversed, and post is not called for that node.
-//
-// If post is not nil, and a prior call of pre didn't return false,
-// post is called for each node after its children are traversed
-// (post-order). If post returns false, traversal is terminated and
-// Apply returns immediately.
-//
-// Only fields that refer to AST nodes are considered children;
-// i.e., token.Pos, Scopes, Objects, and fields of basic types
-// (strings, etc.) are ignored.
-//
-// 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() {
- if r := recover(); r != nil && r != abort {
- panic(r)
- }
- result = parent.Node
- }()
- a := &application{pre: pre, post: post}
- a.apply(parent, "Node", nil, root)
- return
-}
-
-var abort = new(int) // singleton, to signal termination of Apply
-
-// A Cursor describes a node encountered during Apply.
-// Information about the node and its parent is available
-// from the Node, Parent, Name, and Index methods.
-//
-// If p is a variable of type and value of the current parent node
-// 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
-//
-// The methods Replace, Delete, InsertBefore, and InsertAfter
-// can be used to change the AST without disrupting Apply.
-type Cursor struct {
- parent ast.Node
- name string
- iter *iterator // valid if non-nil
- node ast.Node
-}
-
-// Node returns the current Node.
-func (c *Cursor) Node() ast.Node { return c.node }
-
-// Parent returns the parent of the current Node.
-func (c *Cursor) Parent() ast.Node { return c.parent }
-
-// Name returns the name of the parent Node field that contains the current Node.
-// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns
-// the filename for the current Node.
-func (c *Cursor) Name() string { return c.name }
-
-// Index reports the index >= 0 of the current Node in the slice of Nodes that
-// contains it, or a value < 0 if the current Node is not part of a slice.
-// The index of the current node changes if InsertBefore is called while
-// processing the current node.
-func (c *Cursor) Index() int {
- if c.iter != nil {
- return c.iter.index
- }
- return -1
-}
-
-// field returns the current node's parent field value.
-func (c *Cursor) field() reflect.Value {
- return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
-}
-
-// Replace replaces the current Node with n.
-// The replacement node is not walked by Apply.
-func (c *Cursor) Replace(n ast.Node) {
- if _, ok := c.node.(*ast.File); ok {
- file, ok := n.(*ast.File)
- if !ok {
- panic("attempt to replace *ast.File with non-*ast.File")
- }
- c.parent.(*ast.Package).Files[c.name] = file
- return
- }
-
- v := c.field()
- if i := c.Index(); i >= 0 {
- v = v.Index(i)
- }
- v.Set(reflect.ValueOf(n))
-}
-
-// Delete deletes the current Node from its containing slice.
-// If the current Node is not part of a slice, Delete panics.
-// As a special case, if the current node is a package file,
-// Delete removes it from the package's Files map.
-func (c *Cursor) Delete() {
- if _, ok := c.node.(*ast.File); ok {
- delete(c.parent.(*ast.Package).Files, c.name)
- return
- }
-
- i := c.Index()
- if i < 0 {
- panic("Delete node not contained in slice")
- }
- v := c.field()
- l := v.Len()
- reflect.Copy(v.Slice(i, l), v.Slice(i+1, l))
- v.Index(l - 1).Set(reflect.Zero(v.Type().Elem()))
- v.SetLen(l - 1)
- c.iter.step--
-}
-
-// InsertAfter inserts n after the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertAfter panics.
-// Apply does not walk n.
-func (c *Cursor) InsertAfter(n ast.Node) {
- i := c.Index()
- if i < 0 {
- panic("InsertAfter node not contained in slice")
- }
- v := c.field()
- v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
- l := v.Len()
- reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l))
- v.Index(i + 1).Set(reflect.ValueOf(n))
- c.iter.step++
-}
-
-// InsertBefore inserts n before the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertBefore panics.
-// Apply will not walk n.
-func (c *Cursor) InsertBefore(n ast.Node) {
- i := c.Index()
- if i < 0 {
- panic("InsertBefore node not contained in slice")
- }
- v := c.field()
- v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
- l := v.Len()
- reflect.Copy(v.Slice(i+1, l), v.Slice(i, l))
- v.Index(i).Set(reflect.ValueOf(n))
- c.iter.index++
-}
-
-// application carries all the shared data so we can pass it around cheaply.
-type application struct {
- pre, post ApplyFunc
- cursor Cursor
- iter iterator
-}
-
-func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
- // convert typed nil into untyped nil
- if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
- n = nil
- }
-
- // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
- saved := a.cursor
- a.cursor.parent = parent
- a.cursor.name = name
- a.cursor.iter = iter
- a.cursor.node = n
-
- if a.pre != nil && !a.pre(&a.cursor) {
- a.cursor = saved
- return
- }
-
- // walk children
- // (the order of the cases matches the order of the corresponding node types in go/ast)
- switch n := n.(type) {
- case nil:
- // nothing to do
-
- // Comments and fields
- case *ast.Comment:
- // nothing to do
-
- case *ast.CommentGroup:
- if n != nil {
- a.applyList(n, "List")
- }
-
- case *ast.Field:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Names")
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Tag", nil, n.Tag)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.FieldList:
- a.applyList(n, "List")
-
- // Expressions
- case *ast.BadExpr, *ast.Ident, *ast.BasicLit:
- // nothing to do
-
- case *ast.Ellipsis:
- a.apply(n, "Elt", nil, n.Elt)
-
- case *ast.FuncLit:
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.CompositeLit:
- a.apply(n, "Type", nil, n.Type)
- a.applyList(n, "Elts")
-
- case *ast.ParenExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.SelectorExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Sel", nil, n.Sel)
-
- case *ast.IndexExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Index", nil, n.Index)
-
- case *ast.SliceExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Low", nil, n.Low)
- a.apply(n, "High", nil, n.High)
- a.apply(n, "Max", nil, n.Max)
-
- case *ast.TypeAssertExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Type", nil, n.Type)
-
- case *ast.CallExpr:
- a.apply(n, "Fun", nil, n.Fun)
- a.applyList(n, "Args")
-
- case *ast.StarExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.UnaryExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.BinaryExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Y", nil, n.Y)
-
- case *ast.KeyValueExpr:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
-
- // Types
- case *ast.ArrayType:
- a.apply(n, "Len", nil, n.Len)
- a.apply(n, "Elt", nil, n.Elt)
-
- case *ast.StructType:
- a.apply(n, "Fields", nil, n.Fields)
-
- case *ast.FuncType:
- a.apply(n, "Params", nil, n.Params)
- a.apply(n, "Results", nil, n.Results)
-
- case *ast.InterfaceType:
- a.apply(n, "Methods", nil, n.Methods)
-
- case *ast.MapType:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
-
- case *ast.ChanType:
- a.apply(n, "Value", nil, n.Value)
-
- // Statements
- case *ast.BadStmt:
- // nothing to do
-
- case *ast.DeclStmt:
- a.apply(n, "Decl", nil, n.Decl)
-
- case *ast.EmptyStmt:
- // nothing to do
-
- case *ast.LabeledStmt:
- a.apply(n, "Label", nil, n.Label)
- a.apply(n, "Stmt", nil, n.Stmt)
-
- case *ast.ExprStmt:
- a.apply(n, "X", nil, n.X)
-
- case *ast.SendStmt:
- a.apply(n, "Chan", nil, n.Chan)
- a.apply(n, "Value", nil, n.Value)
-
- case *ast.IncDecStmt:
- a.apply(n, "X", nil, n.X)
-
- case *ast.AssignStmt:
- a.applyList(n, "Lhs")
- a.applyList(n, "Rhs")
-
- case *ast.GoStmt:
- a.apply(n, "Call", nil, n.Call)
-
- case *ast.DeferStmt:
- a.apply(n, "Call", nil, n.Call)
-
- case *ast.ReturnStmt:
- a.applyList(n, "Results")
-
- case *ast.BranchStmt:
- a.apply(n, "Label", nil, n.Label)
-
- case *ast.BlockStmt:
- a.applyList(n, "List")
-
- case *ast.IfStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Cond", nil, n.Cond)
- a.apply(n, "Body", nil, n.Body)
- a.apply(n, "Else", nil, n.Else)
-
- case *ast.CaseClause:
- a.applyList(n, "List")
- a.applyList(n, "Body")
-
- case *ast.SwitchStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Tag", nil, n.Tag)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.TypeSwitchStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Assign", nil, n.Assign)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.CommClause:
- a.apply(n, "Comm", nil, n.Comm)
- a.applyList(n, "Body")
-
- case *ast.SelectStmt:
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.ForStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Cond", nil, n.Cond)
- a.apply(n, "Post", nil, n.Post)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.RangeStmt:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Body", nil, n.Body)
-
- // Declarations
- case *ast.ImportSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Path", nil, n.Path)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.ValueSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Names")
- a.apply(n, "Type", nil, n.Type)
- a.applyList(n, "Values")
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.TypeSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.BadDecl:
- // nothing to do
-
- case *ast.GenDecl:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Specs")
-
- case *ast.FuncDecl:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Recv", nil, n.Recv)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Body", nil, n.Body)
-
- // Files and packages
- case *ast.File:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.applyList(n, "Decls")
- // Don't walk n.Comments; they have either been walked already if
- // they are Doc comments, or they can be easily walked explicitly.
-
- case *ast.Package:
- // collect and sort names for reproducible behavior
- var names []string
- for name := range n.Files {
- names = append(names, name)
- }
- sort.Strings(names)
- for _, name := range names {
- a.apply(n, name, nil, n.Files[name])
- }
-
- default:
- panic(fmt.Sprintf("Apply: unexpected node type %T", n))
- }
-
- if a.post != nil && !a.post(&a.cursor) {
- panic(abort)
- }
-
- a.cursor = saved
-}
-
-// An iterator controls iteration over a slice of nodes.
-type iterator struct {
- index, step int
-}
-
-func (a *application) applyList(parent ast.Node, name string) {
- // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
- saved := a.iter
- a.iter.index = 0
- for {
- // must reload parent.name each time, since cursor modifications might change it
- v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
- if a.iter.index >= v.Len() {
- break
- }
-
- // element x may be nil in a bad AST - be cautious
- var x ast.Node
- if e := v.Index(a.iter.index); e.IsValid() {
- x = e.Interface().(ast.Node)
- }
-
- a.iter.step = 1
- a.apply(parent, name, &a.iter, x)
- a.iter.index += a.iter.step
- }
- a.iter = saved
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite_test.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite_test.go
deleted file mode 100644
index 1c86970..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite_test.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package astutil_test
-
-import (
- "bytes"
- "go/ast"
- "go/format"
- "go/parser"
- "go/token"
- "testing"
-
- "golang.org/x/tools/go/ast/astutil"
-)
-
-var rewriteTests = [...]struct {
- name string
- orig, want string
- pre, post astutil.ApplyFunc
-}{
- {name: "nop", orig: "package p\n", want: "package p\n"},
-
- {name: "replace",
- orig: `package p
-
-var x int
-`,
- want: `package p
-
-var t T
-`,
- post: func(c *astutil.Cursor) bool {
- if _, ok := c.Node().(*ast.ValueSpec); ok {
- c.Replace(valspec("t", "T"))
- return false
- }
- return true
- },
- },
-
- {name: "set doc strings",
- orig: `package p
-
-const z = 0
-
-type T struct{}
-
-var x int
-`,
- want: `package p
-// a foo is a foo
-const z = 0
-// a foo is a foo
-type T struct{}
-// a foo is a foo
-var x int
-`,
- post: func(c *astutil.Cursor) bool {
- if _, ok := c.Parent().(*ast.GenDecl); ok && c.Name() == "Doc" && c.Node() == nil {
- c.Replace(&ast.CommentGroup{List: []*ast.Comment{{Text: "// a foo is a foo"}}})
- }
- return true
- },
- },
-
- {name: "insert names",
- orig: `package p
-
-const a = 1
-`,
- want: `package p
-
-const a, b, c = 1, 2, 3
-`,
- pre: func(c *astutil.Cursor) bool {
- if _, ok := c.Parent().(*ast.ValueSpec); ok {
- switch c.Name() {
- case "Names":
- c.InsertAfter(ast.NewIdent("c"))
- c.InsertAfter(ast.NewIdent("b"))
- case "Values":
- c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "3"})
- c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "2"})
- }
- }
- return true
- },
- },
-
- {name: "insert",
- orig: `package p
-
-var (
- x int
- y int
-)
-`,
- want: `package p
-
-var before1 int
-var before2 int
-
-var (
- x int
- y int
-)
-var after2 int
-var after1 int
-`,
- pre: func(c *astutil.Cursor) bool {
- if _, ok := c.Node().(*ast.GenDecl); ok {
- c.InsertBefore(vardecl("before1", "int"))
- c.InsertAfter(vardecl("after1", "int"))
- c.InsertAfter(vardecl("after2", "int"))
- c.InsertBefore(vardecl("before2", "int"))
- }
- return true
- },
- },
-
- {name: "delete",
- orig: `package p
-
-var x int
-var y int
-var z int
-`,
- want: `package p
-
-var y int
-var z int
-`,
- pre: func(c *astutil.Cursor) bool {
- n := c.Node()
- if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
- c.Delete()
- }
- return true
- },
- },
-
- {name: "insertafter-delete",
- orig: `package p
-
-var x int
-var y int
-var z int
-`,
- want: `package p
-
-var x1 int
-
-var y int
-var z int
-`,
- pre: func(c *astutil.Cursor) bool {
- n := c.Node()
- if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
- c.InsertAfter(vardecl("x1", "int"))
- c.Delete()
- }
- return true
- },
- },
-
- {name: "delete-insertafter",
- orig: `package p
-
-var x int
-var y int
-var z int
-`,
- want: `package p
-
-var y int
-var x1 int
-var z int
-`,
- pre: func(c *astutil.Cursor) bool {
- n := c.Node()
- if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
- c.Delete()
- // The cursor is now effectively atop the 'var y int' node.
- c.InsertAfter(vardecl("x1", "int"))
- }
- return true
- },
- },
-}
-
-func valspec(name, typ string) *ast.ValueSpec {
- return &ast.ValueSpec{Names: []*ast.Ident{ast.NewIdent(name)},
- Type: ast.NewIdent(typ),
- }
-}
-
-func vardecl(name, typ string) *ast.GenDecl {
- return &ast.GenDecl{
- Tok: token.VAR,
- Specs: []ast.Spec{valspec(name, typ)},
- }
-}
-
-func TestRewrite(t *testing.T) {
- t.Run("*", func(t *testing.T) {
- for _, test := range rewriteTests {
- test := test
- t.Run(test.name, func(t *testing.T) {
- t.Parallel()
- fset := token.NewFileSet()
- f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
- if err != nil {
- t.Fatal(err)
- }
- n := astutil.Apply(f, test.pre, test.post)
- var buf bytes.Buffer
- if err := format.Node(&buf, fset, n); err != nil {
- t.Fatal(err)
- }
- got := buf.String()
- if got != test.want {
- t.Errorf("got:\n\n%s\nwant:\n\n%s\n", got, test.want)
- }
- })
- }
- })
-}
-
-var sink ast.Node
-
-func BenchmarkRewrite(b *testing.B) {
- for _, test := range rewriteTests {
- b.Run(test.name, func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- b.StopTimer()
- fset := token.NewFileSet()
- f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
- if err != nil {
- b.Fatal(err)
- }
- b.StartTimer()
- sink = astutil.Apply(f, test.pre, test.post)
- }
- })
- }
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go
deleted file mode 100644
index 7630629..0000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/util.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package astutil
-
-import "go/ast"
-
-// Unparen returns e with any enclosing parentheses stripped.
-func Unparen(e ast.Expr) ast.Expr {
- for {
- p, ok := e.(*ast.ParenExpr)
- if !ok {
- return e
- }
- e = p.X
- }
-}