aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-toolsmith
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-toolsmith')
-rw-r--r--vendor/github.com/go-toolsmith/astcast/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/astcast/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/astcast/README.md86
-rw-r--r--vendor/github.com/go-toolsmith/astcast/astcast.go590
-rw-r--r--vendor/github.com/go-toolsmith/astcast/go.mod6
-rw-r--r--vendor/github.com/go-toolsmith/astcast/go.sum4
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/README.md41
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/astcopy.go955
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/go.mod6
-rw-r--r--vendor/github.com/go-toolsmith/astcopy/go.sum4
-rw-r--r--vendor/github.com/go-toolsmith/astequal/.gitignore5
-rw-r--r--vendor/github.com/go-toolsmith/astequal/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/astequal/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/astequal/README.md67
-rw-r--r--vendor/github.com/go-toolsmith/astequal/astequal.go734
-rw-r--r--vendor/github.com/go-toolsmith/astequal/go.mod1
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/README.md39
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/astfmt.go111
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/go.mod6
-rw-r--r--vendor/github.com/go-toolsmith/astfmt/go.sum4
-rw-r--r--vendor/github.com/go-toolsmith/astp/.gitignore4
-rw-r--r--vendor/github.com/go-toolsmith/astp/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/astp/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/astp/README.md39
-rw-r--r--vendor/github.com/go-toolsmith/astp/decl.go39
-rw-r--r--vendor/github.com/go-toolsmith/astp/expr.go141
-rw-r--r--vendor/github.com/go-toolsmith/astp/go.mod6
-rw-r--r--vendor/github.com/go-toolsmith/astp/go.sum4
-rw-r--r--vendor/github.com/go-toolsmith/astp/stmt.go135
-rw-r--r--vendor/github.com/go-toolsmith/strparse/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/strparse/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/strparse/README.md34
-rw-r--r--vendor/github.com/go-toolsmith/strparse/go.mod1
-rw-r--r--vendor/github.com/go-toolsmith/strparse/strparse.go59
-rw-r--r--vendor/github.com/go-toolsmith/typep/.travis.yml9
-rw-r--r--vendor/github.com/go-toolsmith/typep/LICENSE21
-rw-r--r--vendor/github.com/go-toolsmith/typep/README.md37
-rw-r--r--vendor/github.com/go-toolsmith/typep/doc.go2
-rw-r--r--vendor/github.com/go-toolsmith/typep/go.mod1
-rw-r--r--vendor/github.com/go-toolsmith/typep/predicates.go36
-rw-r--r--vendor/github.com/go-toolsmith/typep/safeExpr.go62
-rw-r--r--vendor/github.com/go-toolsmith/typep/simplePredicates.go359
46 files changed, 3828 insertions, 0 deletions
diff --git a/vendor/github.com/go-toolsmith/astcast/.travis.yml b/vendor/github.com/go-toolsmith/astcast/.travis.yml
new file mode 100644
index 000000000..c32ac0062
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./...
diff --git a/vendor/github.com/go-toolsmith/astcast/LICENSE b/vendor/github.com/go-toolsmith/astcast/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/astcast/README.md b/vendor/github.com/go-toolsmith/astcast/README.md
new file mode 100644
index 000000000..b618da461
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/README.md
@@ -0,0 +1,86 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/astcast)](https://goreportcard.com/report/github.com/go-toolsmith/astcast)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/astcast?status.svg)](https://godoc.org/github.com/go-toolsmith/astcast)
+
+# astcast
+
+Package astcast wraps type assertion operations in such way that you don't have
+to worry about nil pointer results anymore.
+
+## Installation
+
+```bash
+go get -v github.com/go-toolsmith/astcast
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/go-toolsmith/astcast"
+ "github.com/go-toolsmith/strparse"
+)
+
+func main() {
+ x := strparse.Expr(`(foo * bar) + 1`)
+
+ // x type is ast.Expr, we want to access bar operand
+ // that is a RHS of the LHS of the addition.
+ // Note that addition LHS (X field) is has parenthesis,
+ // so we have to remove them too.
+
+ add := astcast.ToBinaryExpr(x)
+ mul := astcast.ToBinaryExpr(astcast.ToParenExpr(add.X).X)
+ bar := astcast.ToIdent(mul.Y)
+ fmt.Printf("%T %s\n", bar, bar.Name) // => *ast.Ident bar
+
+ // If argument has different dynamic type,
+ // non-nil sentinel object of requested type is returned.
+ // Those sentinel objects are exported so if you need
+ // to know whether it was a nil interface value of
+ // failed type assertion, you can compare returned
+ // object with such a sentinel.
+
+ y := astcast.ToCallExpr(strparse.Expr(`x`))
+ if y == astcast.NilCallExpr {
+ fmt.Println("it is a sentinel, type assertion failed")
+ }
+}
+```
+
+Without `astcast`, you would have to do a lots of type assertions:
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/go-toolsmith/strparse"
+)
+
+func main() {
+ x := strparse.Expr(`(foo * bar) + 1`)
+
+ add, ok := x.(*ast.BinaryExpr)
+ if !ok || add == nil {
+ return
+ }
+ additionLHS, ok := add.X.(*ast.ParenExpr)
+ if !ok || additionLHS == nil {
+ return
+ }
+ mul, ok := additionLHS.X.(*ast.BinaryExpr)
+ if !ok || mul == nil {
+ return
+ }
+ bar, ok := mul.Y.(*ast.Ident)
+ if !ok || bar == nil {
+ return
+ }
+ fmt.Printf("%T %s\n", bar, bar.Name)
+}
+```
diff --git a/vendor/github.com/go-toolsmith/astcast/astcast.go b/vendor/github.com/go-toolsmith/astcast/astcast.go
new file mode 100644
index 000000000..746d568aa
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/astcast.go
@@ -0,0 +1,590 @@
+// Code generated by astcast_generate.go; DO NOT EDIT
+
+// Package astcast wraps type assertion operations in such way that you don't have
+// to worry about nil pointer results anymore.
+package astcast
+
+import (
+ "go/ast"
+)
+
+// A set of sentinel nil-like values that are returned
+// by all "casting" functions in case of failed type assertion.
+var (
+ NilArrayType = &ast.ArrayType{}
+ NilBadExpr = &ast.BadExpr{}
+ NilBasicLit = &ast.BasicLit{}
+ NilBinaryExpr = &ast.BinaryExpr{}
+ NilCallExpr = &ast.CallExpr{}
+ NilChanType = &ast.ChanType{}
+ NilCompositeLit = &ast.CompositeLit{}
+ NilEllipsis = &ast.Ellipsis{}
+ NilFuncLit = &ast.FuncLit{}
+ NilFuncType = &ast.FuncType{}
+ NilIdent = &ast.Ident{}
+ NilIndexExpr = &ast.IndexExpr{}
+ NilInterfaceType = &ast.InterfaceType{}
+ NilKeyValueExpr = &ast.KeyValueExpr{}
+ NilMapType = &ast.MapType{}
+ NilParenExpr = &ast.ParenExpr{}
+ NilSelectorExpr = &ast.SelectorExpr{}
+ NilSliceExpr = &ast.SliceExpr{}
+ NilStarExpr = &ast.StarExpr{}
+ NilStructType = &ast.StructType{}
+ NilTypeAssertExpr = &ast.TypeAssertExpr{}
+ NilUnaryExpr = &ast.UnaryExpr{}
+ NilAssignStmt = &ast.AssignStmt{}
+ NilBadStmt = &ast.BadStmt{}
+ NilBlockStmt = &ast.BlockStmt{}
+ NilBranchStmt = &ast.BranchStmt{}
+ NilCaseClause = &ast.CaseClause{}
+ NilCommClause = &ast.CommClause{}
+ NilDeclStmt = &ast.DeclStmt{}
+ NilDeferStmt = &ast.DeferStmt{}
+ NilEmptyStmt = &ast.EmptyStmt{}
+ NilExprStmt = &ast.ExprStmt{}
+ NilForStmt = &ast.ForStmt{}
+ NilGoStmt = &ast.GoStmt{}
+ NilIfStmt = &ast.IfStmt{}
+ NilIncDecStmt = &ast.IncDecStmt{}
+ NilLabeledStmt = &ast.LabeledStmt{}
+ NilRangeStmt = &ast.RangeStmt{}
+ NilReturnStmt = &ast.ReturnStmt{}
+ NilSelectStmt = &ast.SelectStmt{}
+ NilSendStmt = &ast.SendStmt{}
+ NilSwitchStmt = &ast.SwitchStmt{}
+ NilTypeSwitchStmt = &ast.TypeSwitchStmt{}
+ NilComment = &ast.Comment{}
+ NilCommentGroup = &ast.CommentGroup{}
+ NilFieldList = &ast.FieldList{}
+ NilFile = &ast.File{}
+ NilPackage = &ast.Package{}
+)
+
+// ToArrayType returns x as a non-nil *ast.ArrayType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilArrayType.
+func ToArrayType(x ast.Node) *ast.ArrayType {
+ if x, ok := x.(*ast.ArrayType); ok {
+ return x
+ }
+ return NilArrayType
+}
+
+// ToBadExpr returns x as a non-nil *ast.BadExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBadExpr.
+func ToBadExpr(x ast.Node) *ast.BadExpr {
+ if x, ok := x.(*ast.BadExpr); ok {
+ return x
+ }
+ return NilBadExpr
+}
+
+// ToBasicLit returns x as a non-nil *ast.BasicLit.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBasicLit.
+func ToBasicLit(x ast.Node) *ast.BasicLit {
+ if x, ok := x.(*ast.BasicLit); ok {
+ return x
+ }
+ return NilBasicLit
+}
+
+// ToBinaryExpr returns x as a non-nil *ast.BinaryExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBinaryExpr.
+func ToBinaryExpr(x ast.Node) *ast.BinaryExpr {
+ if x, ok := x.(*ast.BinaryExpr); ok {
+ return x
+ }
+ return NilBinaryExpr
+}
+
+// ToCallExpr returns x as a non-nil *ast.CallExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilCallExpr.
+func ToCallExpr(x ast.Node) *ast.CallExpr {
+ if x, ok := x.(*ast.CallExpr); ok {
+ return x
+ }
+ return NilCallExpr
+}
+
+// ToChanType returns x as a non-nil *ast.ChanType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilChanType.
+func ToChanType(x ast.Node) *ast.ChanType {
+ if x, ok := x.(*ast.ChanType); ok {
+ return x
+ }
+ return NilChanType
+}
+
+// ToCompositeLit returns x as a non-nil *ast.CompositeLit.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilCompositeLit.
+func ToCompositeLit(x ast.Node) *ast.CompositeLit {
+ if x, ok := x.(*ast.CompositeLit); ok {
+ return x
+ }
+ return NilCompositeLit
+}
+
+// ToEllipsis returns x as a non-nil *ast.Ellipsis.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilEllipsis.
+func ToEllipsis(x ast.Node) *ast.Ellipsis {
+ if x, ok := x.(*ast.Ellipsis); ok {
+ return x
+ }
+ return NilEllipsis
+}
+
+// ToFuncLit returns x as a non-nil *ast.FuncLit.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilFuncLit.
+func ToFuncLit(x ast.Node) *ast.FuncLit {
+ if x, ok := x.(*ast.FuncLit); ok {
+ return x
+ }
+ return NilFuncLit
+}
+
+// ToFuncType returns x as a non-nil *ast.FuncType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilFuncType.
+func ToFuncType(x ast.Node) *ast.FuncType {
+ if x, ok := x.(*ast.FuncType); ok {
+ return x
+ }
+ return NilFuncType
+}
+
+// ToIdent returns x as a non-nil *ast.Ident.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilIdent.
+func ToIdent(x ast.Node) *ast.Ident {
+ if x, ok := x.(*ast.Ident); ok {
+ return x
+ }
+ return NilIdent
+}
+
+// ToIndexExpr returns x as a non-nil *ast.IndexExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilIndexExpr.
+func ToIndexExpr(x ast.Node) *ast.IndexExpr {
+ if x, ok := x.(*ast.IndexExpr); ok {
+ return x
+ }
+ return NilIndexExpr
+}
+
+// ToInterfaceType returns x as a non-nil *ast.InterfaceType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilInterfaceType.
+func ToInterfaceType(x ast.Node) *ast.InterfaceType {
+ if x, ok := x.(*ast.InterfaceType); ok {
+ return x
+ }
+ return NilInterfaceType
+}
+
+// ToKeyValueExpr returns x as a non-nil *ast.KeyValueExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilKeyValueExpr.
+func ToKeyValueExpr(x ast.Node) *ast.KeyValueExpr {
+ if x, ok := x.(*ast.KeyValueExpr); ok {
+ return x
+ }
+ return NilKeyValueExpr
+}
+
+// ToMapType returns x as a non-nil *ast.MapType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilMapType.
+func ToMapType(x ast.Node) *ast.MapType {
+ if x, ok := x.(*ast.MapType); ok {
+ return x
+ }
+ return NilMapType
+}
+
+// ToParenExpr returns x as a non-nil *ast.ParenExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilParenExpr.
+func ToParenExpr(x ast.Node) *ast.ParenExpr {
+ if x, ok := x.(*ast.ParenExpr); ok {
+ return x
+ }
+ return NilParenExpr
+}
+
+// ToSelectorExpr returns x as a non-nil *ast.SelectorExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilSelectorExpr.
+func ToSelectorExpr(x ast.Node) *ast.SelectorExpr {
+ if x, ok := x.(*ast.SelectorExpr); ok {
+ return x
+ }
+ return NilSelectorExpr
+}
+
+// ToSliceExpr returns x as a non-nil *ast.SliceExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilSliceExpr.
+func ToSliceExpr(x ast.Node) *ast.SliceExpr {
+ if x, ok := x.(*ast.SliceExpr); ok {
+ return x
+ }
+ return NilSliceExpr
+}
+
+// ToStarExpr returns x as a non-nil *ast.StarExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilStarExpr.
+func ToStarExpr(x ast.Node) *ast.StarExpr {
+ if x, ok := x.(*ast.StarExpr); ok {
+ return x
+ }
+ return NilStarExpr
+}
+
+// ToStructType returns x as a non-nil *ast.StructType.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilStructType.
+func ToStructType(x ast.Node) *ast.StructType {
+ if x, ok := x.(*ast.StructType); ok {
+ return x
+ }
+ return NilStructType
+}
+
+// ToTypeAssertExpr returns x as a non-nil *ast.TypeAssertExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilTypeAssertExpr.
+func ToTypeAssertExpr(x ast.Node) *ast.TypeAssertExpr {
+ if x, ok := x.(*ast.TypeAssertExpr); ok {
+ return x
+ }
+ return NilTypeAssertExpr
+}
+
+// ToUnaryExpr returns x as a non-nil *ast.UnaryExpr.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilUnaryExpr.
+func ToUnaryExpr(x ast.Node) *ast.UnaryExpr {
+ if x, ok := x.(*ast.UnaryExpr); ok {
+ return x
+ }
+ return NilUnaryExpr
+}
+
+// ToAssignStmt returns x as a non-nil *ast.AssignStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilAssignStmt.
+func ToAssignStmt(x ast.Node) *ast.AssignStmt {
+ if x, ok := x.(*ast.AssignStmt); ok {
+ return x
+ }
+ return NilAssignStmt
+}
+
+// ToBadStmt returns x as a non-nil *ast.BadStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBadStmt.
+func ToBadStmt(x ast.Node) *ast.BadStmt {
+ if x, ok := x.(*ast.BadStmt); ok {
+ return x
+ }
+ return NilBadStmt
+}
+
+// ToBlockStmt returns x as a non-nil *ast.BlockStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBlockStmt.
+func ToBlockStmt(x ast.Node) *ast.BlockStmt {
+ if x, ok := x.(*ast.BlockStmt); ok {
+ return x
+ }
+ return NilBlockStmt
+}
+
+// ToBranchStmt returns x as a non-nil *ast.BranchStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilBranchStmt.
+func ToBranchStmt(x ast.Node) *ast.BranchStmt {
+ if x, ok := x.(*ast.BranchStmt); ok {
+ return x
+ }
+ return NilBranchStmt
+}
+
+// ToCaseClause returns x as a non-nil *ast.CaseClause.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilCaseClause.
+func ToCaseClause(x ast.Node) *ast.CaseClause {
+ if x, ok := x.(*ast.CaseClause); ok {
+ return x
+ }
+ return NilCaseClause
+}
+
+// ToCommClause returns x as a non-nil *ast.CommClause.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilCommClause.
+func ToCommClause(x ast.Node) *ast.CommClause {
+ if x, ok := x.(*ast.CommClause); ok {
+ return x
+ }
+ return NilCommClause
+}
+
+// ToDeclStmt returns x as a non-nil *ast.DeclStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilDeclStmt.
+func ToDeclStmt(x ast.Node) *ast.DeclStmt {
+ if x, ok := x.(*ast.DeclStmt); ok {
+ return x
+ }
+ return NilDeclStmt
+}
+
+// ToDeferStmt returns x as a non-nil *ast.DeferStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilDeferStmt.
+func ToDeferStmt(x ast.Node) *ast.DeferStmt {
+ if x, ok := x.(*ast.DeferStmt); ok {
+ return x
+ }
+ return NilDeferStmt
+}
+
+// ToEmptyStmt returns x as a non-nil *ast.EmptyStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilEmptyStmt.
+func ToEmptyStmt(x ast.Node) *ast.EmptyStmt {
+ if x, ok := x.(*ast.EmptyStmt); ok {
+ return x
+ }
+ return NilEmptyStmt
+}
+
+// ToExprStmt returns x as a non-nil *ast.ExprStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilExprStmt.
+func ToExprStmt(x ast.Node) *ast.ExprStmt {
+ if x, ok := x.(*ast.ExprStmt); ok {
+ return x
+ }
+ return NilExprStmt
+}
+
+// ToForStmt returns x as a non-nil *ast.ForStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilForStmt.
+func ToForStmt(x ast.Node) *ast.ForStmt {
+ if x, ok := x.(*ast.ForStmt); ok {
+ return x
+ }
+ return NilForStmt
+}
+
+// ToGoStmt returns x as a non-nil *ast.GoStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilGoStmt.
+func ToGoStmt(x ast.Node) *ast.GoStmt {
+ if x, ok := x.(*ast.GoStmt); ok {
+ return x
+ }
+ return NilGoStmt
+}
+
+// ToIfStmt returns x as a non-nil *ast.IfStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilIfStmt.
+func ToIfStmt(x ast.Node) *ast.IfStmt {
+ if x, ok := x.(*ast.IfStmt); ok {
+ return x
+ }
+ return NilIfStmt
+}
+
+// ToIncDecStmt returns x as a non-nil *ast.IncDecStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilIncDecStmt.
+func ToIncDecStmt(x ast.Node) *ast.IncDecStmt {
+ if x, ok := x.(*ast.IncDecStmt); ok {
+ return x
+ }
+ return NilIncDecStmt
+}
+
+// ToLabeledStmt returns x as a non-nil *ast.LabeledStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilLabeledStmt.
+func ToLabeledStmt(x ast.Node) *ast.LabeledStmt {
+ if x, ok := x.(*ast.LabeledStmt); ok {
+ return x
+ }
+ return NilLabeledStmt
+}
+
+// ToRangeStmt returns x as a non-nil *ast.RangeStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilRangeStmt.
+func ToRangeStmt(x ast.Node) *ast.RangeStmt {
+ if x, ok := x.(*ast.RangeStmt); ok {
+ return x
+ }
+ return NilRangeStmt
+}
+
+// ToReturnStmt returns x as a non-nil *ast.ReturnStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilReturnStmt.
+func ToReturnStmt(x ast.Node) *ast.ReturnStmt {
+ if x, ok := x.(*ast.ReturnStmt); ok {
+ return x
+ }
+ return NilReturnStmt
+}
+
+// ToSelectStmt returns x as a non-nil *ast.SelectStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilSelectStmt.
+func ToSelectStmt(x ast.Node) *ast.SelectStmt {
+ if x, ok := x.(*ast.SelectStmt); ok {
+ return x
+ }
+ return NilSelectStmt
+}
+
+// ToSendStmt returns x as a non-nil *ast.SendStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilSendStmt.
+func ToSendStmt(x ast.Node) *ast.SendStmt {
+ if x, ok := x.(*ast.SendStmt); ok {
+ return x
+ }
+ return NilSendStmt
+}
+
+// ToSwitchStmt returns x as a non-nil *ast.SwitchStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilSwitchStmt.
+func ToSwitchStmt(x ast.Node) *ast.SwitchStmt {
+ if x, ok := x.(*ast.SwitchStmt); ok {
+ return x
+ }
+ return NilSwitchStmt
+}
+
+// ToTypeSwitchStmt returns x as a non-nil *ast.TypeSwitchStmt.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilTypeSwitchStmt.
+func ToTypeSwitchStmt(x ast.Node) *ast.TypeSwitchStmt {
+ if x, ok := x.(*ast.TypeSwitchStmt); ok {
+ return x
+ }
+ return NilTypeSwitchStmt
+}
+
+// ToComment returns x as a non-nil *ast.Comment.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilComment.
+func ToComment(x ast.Node) *ast.Comment {
+ if x, ok := x.(*ast.Comment); ok {
+ return x
+ }
+ return NilComment
+}
+
+// ToCommentGroup returns x as a non-nil *ast.CommentGroup.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilCommentGroup.
+func ToCommentGroup(x ast.Node) *ast.CommentGroup {
+ if x, ok := x.(*ast.CommentGroup); ok {
+ return x
+ }
+ return NilCommentGroup
+}
+
+// ToFieldList returns x as a non-nil *ast.FieldList.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilFieldList.
+func ToFieldList(x ast.Node) *ast.FieldList {
+ if x, ok := x.(*ast.FieldList); ok {
+ return x
+ }
+ return NilFieldList
+}
+
+// ToFile returns x as a non-nil *ast.File.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilFile.
+func ToFile(x ast.Node) *ast.File {
+ if x, ok := x.(*ast.File); ok {
+ return x
+ }
+ return NilFile
+}
+
+// ToPackage returns x as a non-nil *ast.Package.
+// If ast.Node actually has such dynamic type, the result is
+// identical to normal type assertion. In case if it has
+// different type, the returned value is NilPackage.
+func ToPackage(x ast.Node) *ast.Package {
+ if x, ok := x.(*ast.Package); ok {
+ return x
+ }
+ return NilPackage
+}
diff --git a/vendor/github.com/go-toolsmith/astcast/go.mod b/vendor/github.com/go-toolsmith/astcast/go.mod
new file mode 100644
index 000000000..3e431993e
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/go.mod
@@ -0,0 +1,6 @@
+module github.com/go-toolsmith/astcast
+
+require (
+ github.com/go-toolsmith/astequal v1.0.0 // indirect
+ github.com/go-toolsmith/strparse v1.0.0
+)
diff --git a/vendor/github.com/go-toolsmith/astcast/go.sum b/vendor/github.com/go-toolsmith/astcast/go.sum
new file mode 100644
index 000000000..aa0857030
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcast/go.sum
@@ -0,0 +1,4 @@
+github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
diff --git a/vendor/github.com/go-toolsmith/astcopy/.travis.yml b/vendor/github.com/go-toolsmith/astcopy/.travis.yml
new file mode 100644
index 000000000..8994d395c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./... \ No newline at end of file
diff --git a/vendor/github.com/go-toolsmith/astcopy/LICENSE b/vendor/github.com/go-toolsmith/astcopy/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/astcopy/README.md b/vendor/github.com/go-toolsmith/astcopy/README.md
new file mode 100644
index 000000000..4dae5c41b
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/README.md
@@ -0,0 +1,41 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/astcopy)](https://goreportcard.com/report/github.com/go-toolsmith/astcopy)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/astcopy?status.svg)](https://godoc.org/github.com/go-toolsmith/astcopy)
+[![Build Status](https://travis-ci.org/go-toolsmith/astcopy.svg?branch=master)](https://travis-ci.org/go-toolsmith/astcopy)
+
+# astcopy
+
+Package astcopy implements Go AST reflection-free deep copy operations.
+
+## Installation:
+
+```bash
+go get github.com/go-toolsmith/astcopy
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "github.com/go-toolsmith/astcopy"
+ "github.com/go-toolsmith/astequal"
+ "github.com/go-toolsmith/strparse"
+)
+
+func main() {
+ x := strparse.Expr(`1 + 2`).(*ast.BinaryExpr)
+ y := astcopy.BinaryExpr(x)
+ fmt.Println(astequal.Expr(x, y)) // => true
+
+ // Now modify x and make sure y is not modified.
+ z := astcopy.BinaryExpr(y)
+ x.Op = token.SUB
+ fmt.Println(astequal.Expr(y, z)) // => true
+ fmt.Println(astequal.Expr(x, y)) // => false
+}
+```
diff --git a/vendor/github.com/go-toolsmith/astcopy/astcopy.go b/vendor/github.com/go-toolsmith/astcopy/astcopy.go
new file mode 100644
index 000000000..2feffb199
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/astcopy.go
@@ -0,0 +1,955 @@
+// Package astcopy implements Go AST reflection-free deep copy operations.
+package astcopy
+
+import (
+ "go/ast"
+)
+
+// Node returns x node deep copy.
+// Copy of nil argument is nil.
+func Node(x ast.Node) ast.Node {
+ return copyNode(x)
+}
+
+// NodeList returns xs node slice deep copy.
+// Copy of nil argument is nil.
+func NodeList(xs []ast.Node) []ast.Node {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]ast.Node, len(xs))
+ for i := range xs {
+ cp[i] = copyNode(xs[i])
+ }
+ return cp
+}
+
+// Expr returns x expression deep copy.
+// Copy of nil argument is nil.
+func Expr(x ast.Expr) ast.Expr {
+ return copyExpr(x)
+}
+
+// ExprList returns xs expression slice deep copy.
+// Copy of nil argument is nil.
+func ExprList(xs []ast.Expr) []ast.Expr {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]ast.Expr, len(xs))
+ for i := range xs {
+ cp[i] = copyExpr(xs[i])
+ }
+ return cp
+}
+
+// Stmt returns x statement deep copy.
+// Copy of nil argument is nil.
+func Stmt(x ast.Stmt) ast.Stmt {
+ return copyStmt(x)
+}
+
+// StmtList returns xs statement slice deep copy.
+// Copy of nil argument is nil.
+func StmtList(xs []ast.Stmt) []ast.Stmt {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]ast.Stmt, len(xs))
+ for i := range xs {
+ cp[i] = copyStmt(xs[i])
+ }
+ return cp
+}
+
+// Decl returns x declaration deep copy.
+// Copy of nil argument is nil.
+func Decl(x ast.Decl) ast.Decl {
+ return copyDecl(x)
+}
+
+// DeclList returns xs declaration slice deep copy.
+// Copy of nil argument is nil.
+func DeclList(xs []ast.Decl) []ast.Decl {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]ast.Decl, len(xs))
+ for i := range xs {
+ cp[i] = copyDecl(xs[i])
+ }
+ return cp
+}
+
+// BadExpr returns x deep copy.
+// Copy of nil argument is nil.
+func BadExpr(x *ast.BadExpr) *ast.BadExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// Ident returns x deep copy.
+// Copy of nil argument is nil.
+func Ident(x *ast.Ident) *ast.Ident {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// IdentList returns xs identifier slice deep copy.
+// Copy of nil argument is nil.
+func IdentList(xs []*ast.Ident) []*ast.Ident {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]*ast.Ident, len(xs))
+ for i := range xs {
+ cp[i] = Ident(xs[i])
+ }
+ return cp
+}
+
+// Ellipsis returns x deep copy.
+// Copy of nil argument is nil.
+func Ellipsis(x *ast.Ellipsis) *ast.Ellipsis {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Elt = copyExpr(x.Elt)
+ return &cp
+}
+
+// BasicLit returns x deep copy.
+// Copy of nil argument is nil.
+func BasicLit(x *ast.BasicLit) *ast.BasicLit {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// FuncLit returns x deep copy.
+// Copy of nil argument is nil.
+func FuncLit(x *ast.FuncLit) *ast.FuncLit {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Type = FuncType(x.Type)
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// CompositeLit returns x deep copy.
+// Copy of nil argument is nil.
+func CompositeLit(x *ast.CompositeLit) *ast.CompositeLit {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Type = copyExpr(x.Type)
+ cp.Elts = ExprList(x.Elts)
+ return &cp
+}
+
+// ParenExpr returns x deep copy.
+// Copy of nil argument is nil.
+func ParenExpr(x *ast.ParenExpr) *ast.ParenExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ return &cp
+}
+
+// SelectorExpr returns x deep copy.
+// Copy of nil argument is nil.
+func SelectorExpr(x *ast.SelectorExpr) *ast.SelectorExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ cp.Sel = Ident(x.Sel)
+ return &cp
+}
+
+// IndexExpr returns x deep copy.
+// Copy of nil argument is nil.
+func IndexExpr(x *ast.IndexExpr) *ast.IndexExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ cp.Index = copyExpr(x.Index)
+ return &cp
+}
+
+// SliceExpr returns x deep copy.
+// Copy of nil argument is nil.
+func SliceExpr(x *ast.SliceExpr) *ast.SliceExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ cp.Low = copyExpr(x.Low)
+ cp.High = copyExpr(x.High)
+ cp.Max = copyExpr(x.Max)
+ return &cp
+}
+
+// TypeAssertExpr returns x deep copy.
+// Copy of nil argument is nil.
+func TypeAssertExpr(x *ast.TypeAssertExpr) *ast.TypeAssertExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ cp.Type = copyExpr(x.Type)
+ return &cp
+}
+
+// CallExpr returns x deep copy.
+// Copy of nil argument is nil.
+func CallExpr(x *ast.CallExpr) *ast.CallExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Fun = copyExpr(x.Fun)
+ cp.Args = ExprList(x.Args)
+ return &cp
+}
+
+// StarExpr returns x deep copy.
+// Copy of nil argument is nil.
+func StarExpr(x *ast.StarExpr) *ast.StarExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ return &cp
+}
+
+// UnaryExpr returns x deep copy.
+// Copy of nil argument is nil.
+func UnaryExpr(x *ast.UnaryExpr) *ast.UnaryExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ return &cp
+}
+
+// BinaryExpr returns x deep copy.
+// Copy of nil argument is nil.
+func BinaryExpr(x *ast.BinaryExpr) *ast.BinaryExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ cp.Y = copyExpr(x.Y)
+ return &cp
+}
+
+// KeyValueExpr returns x deep copy.
+// Copy of nil argument is nil.
+func KeyValueExpr(x *ast.KeyValueExpr) *ast.KeyValueExpr {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Key = copyExpr(x.Key)
+ cp.Value = copyExpr(x.Value)
+ return &cp
+}
+
+// ArrayType returns x deep copy.
+// Copy of nil argument is nil.
+func ArrayType(x *ast.ArrayType) *ast.ArrayType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Len = copyExpr(x.Len)
+ cp.Elt = copyExpr(x.Elt)
+ return &cp
+}
+
+// StructType returns x deep copy.
+// Copy of nil argument is nil.
+func StructType(x *ast.StructType) *ast.StructType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Fields = FieldList(x.Fields)
+ return &cp
+}
+
+// Field returns x deep copy.
+// Copy of nil argument is nil.
+func Field(x *ast.Field) *ast.Field {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Names = IdentList(x.Names)
+ cp.Type = copyExpr(x.Type)
+ cp.Tag = BasicLit(x.Tag)
+ cp.Doc = CommentGroup(x.Doc)
+ cp.Comment = CommentGroup(x.Comment)
+ return &cp
+}
+
+// FieldList returns x deep copy.
+// Copy of nil argument is nil.
+func FieldList(x *ast.FieldList) *ast.FieldList {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ if x.List != nil {
+ cp.List = make([]*ast.Field, len(x.List))
+ for i := range x.List {
+ cp.List[i] = Field(x.List[i])
+ }
+ }
+ return &cp
+}
+
+// FuncType returns x deep copy.
+// Copy of nil argument is nil.
+func FuncType(x *ast.FuncType) *ast.FuncType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Params = FieldList(x.Params)
+ cp.Results = FieldList(x.Results)
+ return &cp
+}
+
+// InterfaceType returns x deep copy.
+// Copy of nil argument is nil.
+func InterfaceType(x *ast.InterfaceType) *ast.InterfaceType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Methods = FieldList(x.Methods)
+ return &cp
+}
+
+// MapType returns x deep copy.
+// Copy of nil argument is nil.
+func MapType(x *ast.MapType) *ast.MapType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Key = copyExpr(x.Key)
+ cp.Value = copyExpr(x.Value)
+ return &cp
+}
+
+// ChanType returns x deep copy.
+// Copy of nil argument is nil.
+func ChanType(x *ast.ChanType) *ast.ChanType {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Value = copyExpr(x.Value)
+ return &cp
+}
+
+// BlockStmt returns x deep copy.
+// Copy of nil argument is nil.
+func BlockStmt(x *ast.BlockStmt) *ast.BlockStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.List = StmtList(x.List)
+ return &cp
+}
+
+// ImportSpec returns x deep copy.
+// Copy of nil argument is nil.
+func ImportSpec(x *ast.ImportSpec) *ast.ImportSpec {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Name = Ident(x.Name)
+ cp.Path = BasicLit(x.Path)
+ cp.Doc = CommentGroup(x.Doc)
+ cp.Comment = CommentGroup(x.Comment)
+ return &cp
+}
+
+// ValueSpec returns x deep copy.
+// Copy of nil argument is nil.
+func ValueSpec(x *ast.ValueSpec) *ast.ValueSpec {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Names = IdentList(x.Names)
+ cp.Values = ExprList(x.Values)
+ cp.Type = copyExpr(x.Type)
+ cp.Doc = CommentGroup(x.Doc)
+ cp.Comment = CommentGroup(x.Comment)
+ return &cp
+}
+
+// TypeSpec returns x deep copy.
+// Copy of nil argument is nil.
+func TypeSpec(x *ast.TypeSpec) *ast.TypeSpec {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Name = Ident(x.Name)
+ cp.Type = copyExpr(x.Type)
+ cp.Doc = CommentGroup(x.Doc)
+ cp.Comment = CommentGroup(x.Comment)
+ return &cp
+}
+
+// Spec returns x deep copy.
+// Copy of nil argument is nil.
+func Spec(x ast.Spec) ast.Spec {
+ if x == nil {
+ return nil
+ }
+
+ switch x := x.(type) {
+ case *ast.ImportSpec:
+ return ImportSpec(x)
+ case *ast.ValueSpec:
+ return ValueSpec(x)
+ case *ast.TypeSpec:
+ return TypeSpec(x)
+ default:
+ panic("unhandled spec")
+ }
+}
+
+// SpecList returns xs spec slice deep copy.
+// Copy of nil argument is nil.
+func SpecList(xs []ast.Spec) []ast.Spec {
+ if xs == nil {
+ return nil
+ }
+ cp := make([]ast.Spec, len(xs))
+ for i := range xs {
+ cp[i] = Spec(xs[i])
+ }
+ return cp
+}
+
+// BadStmt returns x deep copy.
+// Copy of nil argument is nil.
+func BadStmt(x *ast.BadStmt) *ast.BadStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// DeclStmt returns x deep copy.
+// Copy of nil argument is nil.
+func DeclStmt(x *ast.DeclStmt) *ast.DeclStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Decl = copyDecl(x.Decl)
+ return &cp
+}
+
+// EmptyStmt returns x deep copy.
+// Copy of nil argument is nil.
+func EmptyStmt(x *ast.EmptyStmt) *ast.EmptyStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// LabeledStmt returns x deep copy.
+// Copy of nil argument is nil.
+func LabeledStmt(x *ast.LabeledStmt) *ast.LabeledStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Label = Ident(x.Label)
+ cp.Stmt = copyStmt(x.Stmt)
+ return &cp
+}
+
+// ExprStmt returns x deep copy.
+// Copy of nil argument is nil.
+func ExprStmt(x *ast.ExprStmt) *ast.ExprStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ return &cp
+}
+
+// SendStmt returns x deep copy.
+// Copy of nil argument is nil.
+func SendStmt(x *ast.SendStmt) *ast.SendStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Chan = copyExpr(x.Chan)
+ cp.Value = copyExpr(x.Value)
+ return &cp
+}
+
+// IncDecStmt returns x deep copy.
+// Copy of nil argument is nil.
+func IncDecStmt(x *ast.IncDecStmt) *ast.IncDecStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.X = copyExpr(x.X)
+ return &cp
+}
+
+// AssignStmt returns x deep copy.
+// Copy of nil argument is nil.
+func AssignStmt(x *ast.AssignStmt) *ast.AssignStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Lhs = ExprList(x.Lhs)
+ cp.Rhs = ExprList(x.Rhs)
+ return &cp
+}
+
+// GoStmt returns x deep copy.
+// Copy of nil argument is nil.
+func GoStmt(x *ast.GoStmt) *ast.GoStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Call = CallExpr(x.Call)
+ return &cp
+}
+
+// DeferStmt returns x deep copy.
+// Copy of nil argument is nil.
+func DeferStmt(x *ast.DeferStmt) *ast.DeferStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Call = CallExpr(x.Call)
+ return &cp
+}
+
+// ReturnStmt returns x deep copy.
+// Copy of nil argument is nil.
+func ReturnStmt(x *ast.ReturnStmt) *ast.ReturnStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Results = ExprList(x.Results)
+ return &cp
+}
+
+// BranchStmt returns x deep copy.
+// Copy of nil argument is nil.
+func BranchStmt(x *ast.BranchStmt) *ast.BranchStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Label = Ident(x.Label)
+ return &cp
+}
+
+// IfStmt returns x deep copy.
+// Copy of nil argument is nil.
+func IfStmt(x *ast.IfStmt) *ast.IfStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Init = copyStmt(x.Init)
+ cp.Cond = copyExpr(x.Cond)
+ cp.Body = BlockStmt(x.Body)
+ cp.Else = copyStmt(x.Else)
+ return &cp
+}
+
+// CaseClause returns x deep copy.
+// Copy of nil argument is nil.
+func CaseClause(x *ast.CaseClause) *ast.CaseClause {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.List = ExprList(x.List)
+ cp.Body = StmtList(x.Body)
+ return &cp
+}
+
+// SwitchStmt returns x deep copy.
+// Copy of nil argument is nil.
+func SwitchStmt(x *ast.SwitchStmt) *ast.SwitchStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Init = copyStmt(x.Init)
+ cp.Tag = copyExpr(x.Tag)
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// TypeSwitchStmt returns x deep copy.
+// Copy of nil argument is nil.
+func TypeSwitchStmt(x *ast.TypeSwitchStmt) *ast.TypeSwitchStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Init = copyStmt(x.Init)
+ cp.Assign = copyStmt(x.Assign)
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// CommClause returns x deep copy.
+// Copy of nil argument is nil.
+func CommClause(x *ast.CommClause) *ast.CommClause {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Comm = copyStmt(x.Comm)
+ cp.Body = StmtList(x.Body)
+ return &cp
+}
+
+// SelectStmt returns x deep copy.
+// Copy of nil argument is nil.
+func SelectStmt(x *ast.SelectStmt) *ast.SelectStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// ForStmt returns x deep copy.
+// Copy of nil argument is nil.
+func ForStmt(x *ast.ForStmt) *ast.ForStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Init = copyStmt(x.Init)
+ cp.Cond = copyExpr(x.Cond)
+ cp.Post = copyStmt(x.Post)
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// RangeStmt returns x deep copy.
+// Copy of nil argument is nil.
+func RangeStmt(x *ast.RangeStmt) *ast.RangeStmt {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Key = copyExpr(x.Key)
+ cp.Value = copyExpr(x.Value)
+ cp.X = copyExpr(x.X)
+ cp.Body = BlockStmt(x.Body)
+ return &cp
+}
+
+// Comment returns x deep copy.
+// Copy of nil argument is nil.
+func Comment(x *ast.Comment) *ast.Comment {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// CommentGroup returns x deep copy.
+// Copy of nil argument is nil.
+func CommentGroup(x *ast.CommentGroup) *ast.CommentGroup {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ if x.List != nil {
+ cp.List = make([]*ast.Comment, len(x.List))
+ for i := range x.List {
+ cp.List[i] = Comment(x.List[i])
+ }
+ }
+ return &cp
+}
+
+// File returns x deep copy.
+// Copy of nil argument is nil.
+func File(x *ast.File) *ast.File {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Doc = CommentGroup(x.Doc)
+ cp.Name = Ident(x.Name)
+ cp.Decls = DeclList(x.Decls)
+ cp.Imports = make([]*ast.ImportSpec, len(x.Imports))
+ for i := range x.Imports {
+ cp.Imports[i] = ImportSpec(x.Imports[i])
+ }
+ cp.Unresolved = IdentList(x.Unresolved)
+ cp.Comments = make([]*ast.CommentGroup, len(x.Comments))
+ for i := range x.Comments {
+ cp.Comments[i] = CommentGroup(x.Comments[i])
+ }
+ return &cp
+}
+
+// Package returns x deep copy.
+// Copy of nil argument is nil.
+func Package(x *ast.Package) *ast.Package {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Files = make(map[string]*ast.File)
+ for filename, f := range x.Files {
+ cp.Files[filename] = f
+ }
+ return &cp
+}
+
+// BadDecl returns x deep copy.
+// Copy of nil argument is nil.
+func BadDecl(x *ast.BadDecl) *ast.BadDecl {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ return &cp
+}
+
+// GenDecl returns x deep copy.
+// Copy of nil argument is nil.
+func GenDecl(x *ast.GenDecl) *ast.GenDecl {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Specs = SpecList(x.Specs)
+ cp.Doc = CommentGroup(x.Doc)
+ return &cp
+}
+
+// FuncDecl returns x deep copy.
+// Copy of nil argument is nil.
+func FuncDecl(x *ast.FuncDecl) *ast.FuncDecl {
+ if x == nil {
+ return nil
+ }
+ cp := *x
+ cp.Recv = FieldList(x.Recv)
+ cp.Name = Ident(x.Name)
+ cp.Type = FuncType(x.Type)
+ cp.Body = BlockStmt(x.Body)
+ cp.Doc = CommentGroup(x.Doc)
+ return &cp
+}
+
+func copyNode(x ast.Node) ast.Node {
+ switch x := x.(type) {
+ case ast.Expr:
+ return copyExpr(x)
+ case ast.Stmt:
+ return copyStmt(x)
+ case ast.Decl:
+ return copyDecl(x)
+
+ case ast.Spec:
+ return Spec(x)
+ case *ast.FieldList:
+ return FieldList(x)
+ case *ast.Comment:
+ return Comment(x)
+ case *ast.CommentGroup:
+ return CommentGroup(x)
+ case *ast.File:
+ return File(x)
+ case *ast.Package:
+ return Package(x)
+
+ default:
+ panic("unhandled node")
+ }
+}
+
+func copyExpr(x ast.Expr) ast.Expr {
+ if x == nil {
+ return nil
+ }
+
+ switch x := x.(type) {
+ case *ast.BadExpr:
+ return BadExpr(x)
+ case *ast.Ident:
+ return Ident(x)
+ case *ast.Ellipsis:
+ return Ellipsis(x)
+ case *ast.BasicLit:
+ return BasicLit(x)
+ case *ast.FuncLit:
+ return FuncLit(x)
+ case *ast.CompositeLit:
+ return CompositeLit(x)
+ case *ast.ParenExpr:
+ return ParenExpr(x)
+ case *ast.SelectorExpr:
+ return SelectorExpr(x)
+ case *ast.IndexExpr:
+ return IndexExpr(x)
+ case *ast.SliceExpr:
+ return SliceExpr(x)
+ case *ast.TypeAssertExpr:
+ return TypeAssertExpr(x)
+ case *ast.CallExpr:
+ return CallExpr(x)
+ case *ast.StarExpr:
+ return StarExpr(x)
+ case *ast.UnaryExpr:
+ return UnaryExpr(x)
+ case *ast.BinaryExpr:
+ return BinaryExpr(x)
+ case *ast.KeyValueExpr:
+ return KeyValueExpr(x)
+ case *ast.ArrayType:
+ return ArrayType(x)
+ case *ast.StructType:
+ return StructType(x)
+ case *ast.FuncType:
+ return FuncType(x)
+ case *ast.InterfaceType:
+ return InterfaceType(x)
+ case *ast.MapType:
+ return MapType(x)
+ case *ast.ChanType:
+ return ChanType(x)
+
+ default:
+ panic("unhandled expr")
+ }
+}
+
+func copyStmt(x ast.Stmt) ast.Stmt {
+ if x == nil {
+ return nil
+ }
+
+ switch x := x.(type) {
+ case *ast.BadStmt:
+ return BadStmt(x)
+ case *ast.DeclStmt:
+ return DeclStmt(x)
+ case *ast.EmptyStmt:
+ return EmptyStmt(x)
+ case *ast.LabeledStmt:
+ return LabeledStmt(x)
+ case *ast.ExprStmt:
+ return ExprStmt(x)
+ case *ast.SendStmt:
+ return SendStmt(x)
+ case *ast.IncDecStmt:
+ return IncDecStmt(x)
+ case *ast.AssignStmt:
+ return AssignStmt(x)
+ case *ast.GoStmt:
+ return GoStmt(x)
+ case *ast.DeferStmt:
+ return DeferStmt(x)
+ case *ast.ReturnStmt:
+ return ReturnStmt(x)
+ case *ast.BranchStmt:
+ return BranchStmt(x)
+ case *ast.BlockStmt:
+ return BlockStmt(x)
+ case *ast.IfStmt:
+ return IfStmt(x)
+ case *ast.CaseClause:
+ return CaseClause(x)
+ case *ast.SwitchStmt:
+ return SwitchStmt(x)
+ case *ast.TypeSwitchStmt:
+ return TypeSwitchStmt(x)
+ case *ast.CommClause:
+ return CommClause(x)
+ case *ast.SelectStmt:
+ return SelectStmt(x)
+ case *ast.ForStmt:
+ return ForStmt(x)
+ case *ast.RangeStmt:
+ return RangeStmt(x)
+
+ default:
+ panic("unhandled stmt")
+ }
+}
+
+func copyDecl(x ast.Decl) ast.Decl {
+ if x == nil {
+ return nil
+ }
+
+ switch x := x.(type) {
+ case *ast.BadDecl:
+ return BadDecl(x)
+ case *ast.GenDecl:
+ return GenDecl(x)
+ case *ast.FuncDecl:
+ return FuncDecl(x)
+
+ default:
+ panic("unhandled decl")
+ }
+}
diff --git a/vendor/github.com/go-toolsmith/astcopy/go.mod b/vendor/github.com/go-toolsmith/astcopy/go.mod
new file mode 100644
index 000000000..6f3b3027a
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/go.mod
@@ -0,0 +1,6 @@
+module github.com/go-toolsmith/astcopy
+
+require (
+ github.com/go-toolsmith/astequal v1.0.0
+ github.com/go-toolsmith/strparse v1.0.0
+)
diff --git a/vendor/github.com/go-toolsmith/astcopy/go.sum b/vendor/github.com/go-toolsmith/astcopy/go.sum
new file mode 100644
index 000000000..aa0857030
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astcopy/go.sum
@@ -0,0 +1,4 @@
+github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
diff --git a/vendor/github.com/go-toolsmith/astequal/.gitignore b/vendor/github.com/go-toolsmith/astequal/.gitignore
new file mode 100644
index 000000000..f38c2b852
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/.gitignore
@@ -0,0 +1,5 @@
+bin
+pkg
+src/main
+tmp
+
diff --git a/vendor/github.com/go-toolsmith/astequal/.travis.yml b/vendor/github.com/go-toolsmith/astequal/.travis.yml
new file mode 100644
index 000000000..8994d395c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./... \ No newline at end of file
diff --git a/vendor/github.com/go-toolsmith/astequal/LICENSE b/vendor/github.com/go-toolsmith/astequal/LICENSE
new file mode 100644
index 000000000..717f894f5
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Iskander Sharipov / Quasilyte
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/astequal/README.md b/vendor/github.com/go-toolsmith/astequal/README.md
new file mode 100644
index 000000000..b14f80f6f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/README.md
@@ -0,0 +1,67 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/astequal)](https://goreportcard.com/report/github.com/go-toolsmith/astequal)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/astequal?status.svg)](https://godoc.org/github.com/go-toolsmith/astequal)
+[![Build Status](https://travis-ci.org/go-toolsmith/astequal.svg?branch=master)](https://travis-ci.org/go-toolsmith/astequal)
+
+
+# astequal
+
+Package astequal provides AST (deep) equallity check operations.
+
+## Installation:
+
+```bash
+go get github.com/go-toolsmith/astequal
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "log"
+ "reflect"
+
+ "github.com/go-toolsmith/astequal"
+)
+
+func main() {
+ const code = `
+ package foo
+
+ func main() {
+ x := []int{1, 2, 3}
+ x := []int{1, 2, 3}
+ }`
+
+ fset := token.NewFileSet()
+ pkg, err := parser.ParseFile(fset, "string", code, 0)
+ if err != nil {
+ log.Fatalf("parse error: %+v", err)
+ }
+
+ fn := pkg.Decls[0].(*ast.FuncDecl)
+ x := fn.Body.List[0]
+ y := fn.Body.List[1]
+
+ // Reflect DeepEqual will fail due to different Pos values.
+ // astequal only checks whether two nodes describe AST.
+ fmt.Println(reflect.DeepEqual(x, y)) // => false
+ fmt.Println(astequal.Node(x, y)) // => true
+ fmt.Println(astequal.Stmt(x, y)) // => true
+}
+```
+
+## Performance
+
+`astequal` outperforms reflection-based comparison by a big margin:
+
+```
+BenchmarkEqualExpr/astequal.Expr-8 5000000 298 ns/op 0 B/op 0 allocs/op
+BenchmarkEqualExpr/astequal.Node-8 3000000 409 ns/op 0 B/op 0 allocs/op
+BenchmarkEqualExpr/reflect.DeepEqual-8 50000 38898 ns/op 10185 B/op 156 allocs/op
+```
diff --git a/vendor/github.com/go-toolsmith/astequal/astequal.go b/vendor/github.com/go-toolsmith/astequal/astequal.go
new file mode 100644
index 000000000..6a32d7218
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/astequal.go
@@ -0,0 +1,734 @@
+// Package astequal provides AST (deep) equallity check operations.
+package astequal
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// Node reports whether two AST nodes are structurally (deep) equal.
+//
+// Nil arguments are permitted: true is returned if x and y are both nils.
+//
+// See also: Expr, Stmt, Decl functions.
+func Node(x, y ast.Node) bool {
+ return astNodeEq(x, y)
+}
+
+// Expr reports whether two AST expressions are structurally (deep) equal.
+//
+// Nil arguments are permitted: true is returned if x and y are both nils.
+// ast.BadExpr comparison always yields false.
+func Expr(x, y ast.Expr) bool {
+ return astExprEq(x, y)
+}
+
+// Stmt reports whether two AST statements are structurally (deep) equal.
+//
+// Nil arguments are permitted: true is returned if x and y are both nils.
+// ast.BadStmt comparison always yields false.
+func Stmt(x, y ast.Stmt) bool {
+ return astStmtEq(x, y)
+}
+
+// Decl reports whether two AST declarations are structurally (deep) equal.
+//
+// Nil arguments are permitted: true is returned if x and y are both nils.
+// ast.BadDecl comparison always yields false.
+func Decl(x, y ast.Decl) bool {
+ return astDeclEq(x, y)
+}
+
+// Functions to perform deep equallity checks between arbitrary AST nodes.
+
+// Compare interface node types.
+//
+// Interfaces, as well as their values, can be nil.
+//
+// Even if AST does expect field X to be mandatory,
+// nil checks are required as nodes can be constructed
+// manually, or be partially invalid/incomplete.
+
+func astNodeEq(x, y ast.Node) bool {
+ switch x := x.(type) {
+ case ast.Expr:
+ y, ok := y.(ast.Expr)
+ return ok && astExprEq(x, y)
+ case ast.Stmt:
+ y, ok := y.(ast.Stmt)
+ return ok && astStmtEq(x, y)
+ case ast.Decl:
+ y, ok := y.(ast.Decl)
+ return ok && astDeclEq(x, y)
+ default:
+ return false
+ }
+}
+
+func astExprEq(x, y ast.Expr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+
+ switch x := x.(type) {
+ case *ast.Ident:
+ y, ok := y.(*ast.Ident)
+ return ok && astIdentEq(x, y)
+
+ case *ast.BasicLit:
+ y, ok := y.(*ast.BasicLit)
+ return ok && astBasicLitEq(x, y)
+
+ case *ast.FuncLit:
+ y, ok := y.(*ast.FuncLit)
+ return ok && astFuncLitEq(x, y)
+
+ case *ast.CompositeLit:
+ y, ok := y.(*ast.CompositeLit)
+ return ok && astCompositeLitEq(x, y)
+
+ case *ast.ParenExpr:
+ y, ok := y.(*ast.ParenExpr)
+ return ok && astParenExprEq(x, y)
+
+ case *ast.SelectorExpr:
+ y, ok := y.(*ast.SelectorExpr)
+ return ok && astSelectorExprEq(x, y)
+
+ case *ast.IndexExpr:
+ y, ok := y.(*ast.IndexExpr)
+ return ok && astIndexExprEq(x, y)
+
+ case *ast.SliceExpr:
+ y, ok := y.(*ast.SliceExpr)
+ return ok && astSliceExprEq(x, y)
+
+ case *ast.TypeAssertExpr:
+ y, ok := y.(*ast.TypeAssertExpr)
+ return ok && astTypeAssertExprEq(x, y)
+
+ case *ast.CallExpr:
+ y, ok := y.(*ast.CallExpr)
+ return ok && astCallExprEq(x, y)
+
+ case *ast.StarExpr:
+ y, ok := y.(*ast.StarExpr)
+ return ok && astStarExprEq(x, y)
+
+ case *ast.UnaryExpr:
+ y, ok := y.(*ast.UnaryExpr)
+ return ok && astUnaryExprEq(x, y)
+
+ case *ast.BinaryExpr:
+ y, ok := y.(*ast.BinaryExpr)
+ return ok && astBinaryExprEq(x, y)
+
+ case *ast.KeyValueExpr:
+ y, ok := y.(*ast.KeyValueExpr)
+ return ok && astKeyValueExprEq(x, y)
+
+ case *ast.ArrayType:
+ y, ok := y.(*ast.ArrayType)
+ return ok && astArrayTypeEq(x, y)
+
+ case *ast.StructType:
+ y, ok := y.(*ast.StructType)
+ return ok && astStructTypeEq(x, y)
+
+ case *ast.FuncType:
+ y, ok := y.(*ast.FuncType)
+ return ok && astFuncTypeEq(x, y)
+
+ case *ast.InterfaceType:
+ y, ok := y.(*ast.InterfaceType)
+ return ok && astInterfaceTypeEq(x, y)
+
+ case *ast.MapType:
+ y, ok := y.(*ast.MapType)
+ return ok && astMapTypeEq(x, y)
+
+ case *ast.ChanType:
+ y, ok := y.(*ast.ChanType)
+ return ok && astChanTypeEq(x, y)
+
+ case *ast.Ellipsis:
+ y, ok := y.(*ast.Ellipsis)
+ return ok && astEllipsisEq(x, y)
+
+ default:
+ return false
+ }
+}
+
+func astStmtEq(x, y ast.Stmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+
+ switch x := x.(type) {
+ case *ast.ExprStmt:
+ y, ok := y.(*ast.ExprStmt)
+ return ok && astExprStmtEq(x, y)
+
+ case *ast.SendStmt:
+ y, ok := y.(*ast.SendStmt)
+ return ok && astSendStmtEq(x, y)
+
+ case *ast.IncDecStmt:
+ y, ok := y.(*ast.IncDecStmt)
+ return ok && astIncDecStmtEq(x, y)
+
+ case *ast.AssignStmt:
+ y, ok := y.(*ast.AssignStmt)
+ return ok && astAssignStmtEq(x, y)
+
+ case *ast.GoStmt:
+ y, ok := y.(*ast.GoStmt)
+ return ok && astGoStmtEq(x, y)
+
+ case *ast.DeferStmt:
+ y, ok := y.(*ast.DeferStmt)
+ return ok && astDeferStmtEq(x, y)
+
+ case *ast.ReturnStmt:
+ y, ok := y.(*ast.ReturnStmt)
+ return ok && astReturnStmtEq(x, y)
+
+ case *ast.BranchStmt:
+ y, ok := y.(*ast.BranchStmt)
+ return ok && astBranchStmtEq(x, y)
+
+ case *ast.BlockStmt:
+ y, ok := y.(*ast.BlockStmt)
+ return ok && astBlockStmtEq(x, y)
+
+ case *ast.IfStmt:
+ y, ok := y.(*ast.IfStmt)
+ return ok && astIfStmtEq(x, y)
+
+ case *ast.CaseClause:
+ y, ok := y.(*ast.CaseClause)
+ return ok && astCaseClauseEq(x, y)
+
+ case *ast.SwitchStmt:
+ y, ok := y.(*ast.SwitchStmt)
+ return ok && astSwitchStmtEq(x, y)
+
+ case *ast.TypeSwitchStmt:
+ y, ok := y.(*ast.TypeSwitchStmt)
+ return ok && astTypeSwitchStmtEq(x, y)
+
+ case *ast.CommClause:
+ y, ok := y.(*ast.CommClause)
+ return ok && astCommClauseEq(x, y)
+
+ case *ast.SelectStmt:
+ y, ok := y.(*ast.SelectStmt)
+ return ok && astSelectStmtEq(x, y)
+
+ case *ast.ForStmt:
+ y, ok := y.(*ast.ForStmt)
+ return ok && astForStmtEq(x, y)
+
+ case *ast.RangeStmt:
+ y, ok := y.(*ast.RangeStmt)
+ return ok && astRangeStmtEq(x, y)
+
+ case *ast.DeclStmt:
+ y, ok := y.(*ast.DeclStmt)
+ return ok && astDeclStmtEq(x, y)
+
+ case *ast.LabeledStmt:
+ y, ok := y.(*ast.LabeledStmt)
+ return ok && astLabeledStmtEq(x, y)
+
+ case *ast.EmptyStmt:
+ y, ok := y.(*ast.EmptyStmt)
+ return ok && astEmptyStmtEq(x, y)
+
+ default:
+ return false
+ }
+}
+
+func astDeclEq(x, y ast.Decl) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+
+ switch x := x.(type) {
+ case *ast.GenDecl:
+ y, ok := y.(*ast.GenDecl)
+ return ok && astGenDeclEq(x, y)
+
+ case *ast.FuncDecl:
+ y, ok := y.(*ast.FuncDecl)
+ return ok && astFuncDeclEq(x, y)
+
+ default:
+ return false
+ }
+}
+
+// Compare concrete nodes for equallity.
+//
+// Any node of pointer type permitted to be nil,
+// hence nil checks are mandatory.
+
+func astIdentEq(x, y *ast.Ident) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Name == y.Name
+}
+
+func astKeyValueExprEq(x, y *ast.KeyValueExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Key, y.Key) && astExprEq(x.Value, y.Value)
+}
+
+func astArrayTypeEq(x, y *ast.ArrayType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Len, y.Len) && astExprEq(x.Elt, y.Elt)
+}
+
+func astStructTypeEq(x, y *ast.StructType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFieldListEq(x.Fields, y.Fields)
+}
+
+func astFuncTypeEq(x, y *ast.FuncType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFieldListEq(x.Params, y.Params) &&
+ astFieldListEq(x.Results, y.Results)
+}
+
+func astBasicLitEq(x, y *ast.BasicLit) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Kind == y.Kind && x.Value == y.Value
+}
+
+func astBlockStmtEq(x, y *ast.BlockStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtSliceEq(x.List, y.List)
+}
+
+func astFieldEq(x, y *ast.Field) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astIdentSliceEq(x.Names, y.Names) &&
+ astExprEq(x.Type, y.Type)
+}
+
+func astFuncLitEq(x, y *ast.FuncLit) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFuncTypeEq(x.Type, y.Type) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astCompositeLitEq(x, y *ast.CompositeLit) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Type, y.Type) &&
+ astExprSliceEq(x.Elts, y.Elts)
+}
+
+func astSelectorExprEq(x, y *ast.SelectorExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X) && astIdentEq(x.Sel, y.Sel)
+}
+
+func astIndexExprEq(x, y *ast.IndexExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X) && astExprEq(x.Index, y.Index)
+}
+
+func astSliceExprEq(x, y *ast.SliceExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X) &&
+ astExprEq(x.Low, y.Low) &&
+ astExprEq(x.High, y.High) &&
+ astExprEq(x.Max, y.Max)
+}
+
+func astTypeAssertExprEq(x, y *ast.TypeAssertExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X) && astExprEq(x.Type, y.Type)
+}
+
+func astInterfaceTypeEq(x, y *ast.InterfaceType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFieldListEq(x.Methods, y.Methods)
+}
+
+func astMapTypeEq(x, y *ast.MapType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Key, y.Key) && astExprEq(x.Value, y.Value)
+}
+
+func astChanTypeEq(x, y *ast.ChanType) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Dir == y.Dir && astExprEq(x.Value, y.Value)
+}
+
+func astCallExprEq(x, y *ast.CallExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Fun, y.Fun) &&
+ astExprSliceEq(x.Args, y.Args) &&
+ (x.Ellipsis == 0) == (y.Ellipsis == 0)
+}
+
+func astEllipsisEq(x, y *ast.Ellipsis) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Elt, y.Elt)
+}
+
+func astUnaryExprEq(x, y *ast.UnaryExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Op == y.Op && astExprEq(x.X, y.X)
+}
+
+func astBinaryExprEq(x, y *ast.BinaryExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Op == y.Op &&
+ astExprEq(x.X, y.X) &&
+ astExprEq(x.Y, y.Y)
+}
+
+func astParenExprEq(x, y *ast.ParenExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X)
+}
+
+func astStarExprEq(x, y *ast.StarExpr) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X)
+}
+
+func astFieldListEq(x, y *ast.FieldList) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFieldSliceEq(x.List, y.List)
+}
+
+func astEmptyStmtEq(x, y *ast.EmptyStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Implicit == y.Implicit
+}
+
+func astLabeledStmtEq(x, y *ast.LabeledStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astIdentEq(x.Label, y.Label) && astStmtEq(x.Stmt, y.Stmt)
+}
+
+func astExprStmtEq(x, y *ast.ExprStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.X, y.X)
+}
+
+func astSendStmtEq(x, y *ast.SendStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprEq(x.Chan, y.Chan) && astExprEq(x.Value, y.Value)
+}
+
+func astDeclStmtEq(x, y *ast.DeclStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astDeclEq(x.Decl, y.Decl)
+}
+
+func astIncDecStmtEq(x, y *ast.IncDecStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Tok == y.Tok && astExprEq(x.X, y.X)
+}
+
+func astAssignStmtEq(x, y *ast.AssignStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Tok == y.Tok &&
+ astExprSliceEq(x.Lhs, y.Lhs) &&
+ astExprSliceEq(x.Rhs, y.Rhs)
+}
+
+func astGoStmtEq(x, y *ast.GoStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astCallExprEq(x.Call, y.Call)
+}
+
+func astDeferStmtEq(x, y *ast.DeferStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astCallExprEq(x.Call, y.Call)
+}
+
+func astReturnStmtEq(x, y *ast.ReturnStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprSliceEq(x.Results, y.Results)
+}
+
+func astBranchStmtEq(x, y *ast.BranchStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Tok == y.Tok && astIdentEq(x.Label, y.Label)
+}
+
+func astIfStmtEq(x, y *ast.IfStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtEq(x.Init, y.Init) &&
+ astExprEq(x.Cond, y.Cond) &&
+ astBlockStmtEq(x.Body, y.Body) &&
+ astStmtEq(x.Else, y.Else)
+}
+
+func astCaseClauseEq(x, y *ast.CaseClause) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astExprSliceEq(x.List, y.List) &&
+ astStmtSliceEq(x.Body, y.Body)
+}
+
+func astSwitchStmtEq(x, y *ast.SwitchStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtEq(x.Init, y.Init) &&
+ astExprEq(x.Tag, y.Tag) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astTypeSwitchStmtEq(x, y *ast.TypeSwitchStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtEq(x.Init, y.Init) &&
+ astStmtEq(x.Assign, y.Assign) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astCommClauseEq(x, y *ast.CommClause) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtEq(x.Comm, y.Comm) && astStmtSliceEq(x.Body, y.Body)
+}
+
+func astSelectStmtEq(x, y *ast.SelectStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astBlockStmtEq(x.Body, y.Body)
+}
+
+func astForStmtEq(x, y *ast.ForStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astStmtEq(x.Init, y.Init) &&
+ astExprEq(x.Cond, y.Cond) &&
+ astStmtEq(x.Post, y.Post) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astRangeStmtEq(x, y *ast.RangeStmt) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return x.Tok == y.Tok &&
+ astExprEq(x.Key, y.Key) &&
+ astExprEq(x.Value, y.Value) &&
+ astExprEq(x.X, y.X) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astFuncDeclEq(x, y *ast.FuncDecl) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astFieldListEq(x.Recv, y.Recv) &&
+ astIdentEq(x.Name, y.Name) &&
+ astFuncTypeEq(x.Type, y.Type) &&
+ astBlockStmtEq(x.Body, y.Body)
+}
+
+func astGenDeclEq(x, y *ast.GenDecl) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+
+ if x.Tok != y.Tok {
+ return false
+ }
+ if len(x.Specs) != len(y.Specs) {
+ return false
+ }
+
+ switch x.Tok {
+ case token.IMPORT:
+ for i := range x.Specs {
+ xspec := x.Specs[i].(*ast.ImportSpec)
+ yspec := y.Specs[i].(*ast.ImportSpec)
+ if !astImportSpecEq(xspec, yspec) {
+ return false
+ }
+ }
+ case token.TYPE:
+ for i := range x.Specs {
+ xspec := x.Specs[i].(*ast.TypeSpec)
+ yspec := y.Specs[i].(*ast.TypeSpec)
+ if !astTypeSpecEq(xspec, yspec) {
+ return false
+ }
+ }
+ default:
+ for i := range x.Specs {
+ xspec := x.Specs[i].(*ast.ValueSpec)
+ yspec := y.Specs[i].(*ast.ValueSpec)
+ if !astValueSpecEq(xspec, yspec) {
+ return false
+ }
+ }
+ }
+
+ return true
+}
+
+func astImportSpecEq(x, y *ast.ImportSpec) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astIdentEq(x.Name, y.Name) && astBasicLitEq(x.Path, y.Path)
+}
+
+func astTypeSpecEq(x, y *ast.TypeSpec) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astIdentEq(x.Name, y.Name) && astExprEq(x.Type, y.Type)
+}
+
+func astValueSpecEq(x, y *ast.ValueSpec) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ return astIdentSliceEq(x.Names, y.Names) &&
+ astExprEq(x.Type, y.Type) &&
+ astExprSliceEq(x.Values, y.Values)
+}
+
+// Compare slices for equallity.
+//
+// Each slice element that has pointer type permitted to be nil,
+// hence instead of using adhoc comparison of values,
+// equallity functions that are defined above are used.
+
+func astIdentSliceEq(xs, ys []*ast.Ident) bool {
+ if len(xs) != len(ys) {
+ return false
+ }
+ for i := range xs {
+ if !astIdentEq(xs[i], ys[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+func astFieldSliceEq(xs, ys []*ast.Field) bool {
+ if len(xs) != len(ys) {
+ return false
+ }
+ for i := range xs {
+ if !astFieldEq(xs[i], ys[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+func astStmtSliceEq(xs, ys []ast.Stmt) bool {
+ if len(xs) != len(ys) {
+ return false
+ }
+ for i := range xs {
+ if !astStmtEq(xs[i], ys[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+func astExprSliceEq(xs, ys []ast.Expr) bool {
+ if len(xs) != len(ys) {
+ return false
+ }
+ for i := range xs {
+ if !astExprEq(xs[i], ys[i]) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/go-toolsmith/astequal/go.mod b/vendor/github.com/go-toolsmith/astequal/go.mod
new file mode 100644
index 000000000..86fa40772
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astequal/go.mod
@@ -0,0 +1 @@
+module github.com/go-toolsmith/astequal
diff --git a/vendor/github.com/go-toolsmith/astfmt/.travis.yml b/vendor/github.com/go-toolsmith/astfmt/.travis.yml
new file mode 100644
index 000000000..c32ac0062
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./...
diff --git a/vendor/github.com/go-toolsmith/astfmt/LICENSE b/vendor/github.com/go-toolsmith/astfmt/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/astfmt/README.md b/vendor/github.com/go-toolsmith/astfmt/README.md
new file mode 100644
index 000000000..954c92bf4
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/README.md
@@ -0,0 +1,39 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/strparse)](https://goreportcard.com/report/github.com/go-toolsmith/strparse)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/strparse?status.svg)](https://godoc.org/github.com/go-toolsmith/strparse)
+
+
+# astfmt
+
+Package astfmt implements ast.Node formatting with fmt-like API.
+
+## Installation
+
+```bash
+go get github.com/go-toolsmith/astfmt
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "go/token"
+ "os"
+
+ "github.com/go-toolsmith/astfmt"
+ "github.com/go-toolsmith/strparse"
+)
+
+func Example() {
+ x := strparse.Expr(`foo(bar(baz(1+2)))`)
+ // astfmt functions add %s support for ast.Node arguments.
+ astfmt.Println(x) // => foo(bar(baz(1 + 2)))
+ astfmt.Fprintf(os.Stdout, "node=%s\n", x) // => node=foo(bar(baz(1 + 2)))
+
+ // Can use specific file set with printer.
+ fset := token.NewFileSet() // Suppose this fset is used when parsing
+ pp := astfmt.NewPrinter(fset)
+ pp.Println(x) // => foo(bar(baz(1 + 2)))
+}
+```
diff --git a/vendor/github.com/go-toolsmith/astfmt/astfmt.go b/vendor/github.com/go-toolsmith/astfmt/astfmt.go
new file mode 100644
index 000000000..ca993e033
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/astfmt.go
@@ -0,0 +1,111 @@
+// Package astfmt implements `ast.Node` formatting with fmt-like API.
+package astfmt
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/printer"
+ "go/token"
+ "io"
+)
+
+// Println calls fmt.Println with additional support of %s format
+// for ast.Node arguments.
+//
+// Uses empty file set for AST printing.
+func Println(args ...interface{}) error {
+ return defaultPrinter.Println(args...)
+}
+
+// Fprintf calls fmt.Fprintf with additional support of %s format
+// for ast.Node arguments.
+//
+// Uses empty file set for AST printing.
+func Fprintf(w io.Writer, format string, args ...interface{}) error {
+ return defaultPrinter.Fprintf(w, format, args...)
+}
+
+// Sprintf calls fmt.Sprintf with additional support of %s format
+// for ast.Node arguments.
+//
+// Uses empty file set for AST printing.
+func Sprintf(format string, args ...interface{}) string {
+ return defaultPrinter.Sprintf(format, args...)
+}
+
+// Sprint calls fmt.Sprint with additional support of %s format
+// for ast.Node arguments.
+//
+// Uses empty file set for AST printing.
+func Sprint(args ...interface{}) string {
+ return defaultPrinter.Sprint(args...)
+}
+
+// NewPrinter returns printer that uses bound file set when printing AST nodes.
+func NewPrinter(fset *token.FileSet) *Printer {
+ return &Printer{fset: fset}
+}
+
+// Printer provides API close to fmt package for printing AST nodes.
+// Unlike freestanding functions from this package, it makes it possible
+// to associate appropriate file set for better output.
+type Printer struct {
+ fset *token.FileSet
+}
+
+// Println printer method is like Println function, but uses bound file set when printing.
+func (p *Printer) Println(args ...interface{}) error {
+ _, err := fmt.Println(wrapArgs(p.fset, args)...)
+ return err
+}
+
+// Fprintf printer method is like Fprintf function, but uses bound file set when printing.
+func (p *Printer) Fprintf(w io.Writer, format string, args ...interface{}) error {
+ _, err := fmt.Fprintf(w, format, wrapArgs(p.fset, args)...)
+ return err
+}
+
+// Sprintf printer method is like Sprintf function, but uses bound file set when printing.
+func (p *Printer) Sprintf(format string, args ...interface{}) string {
+ return fmt.Sprintf(format, wrapArgs(p.fset, args)...)
+}
+
+// Sprint printer method is like Sprint function, but uses bound file set when printing.
+func (p *Printer) Sprint(args ...interface{}) string {
+ return fmt.Sprint(wrapArgs(p.fset, args)...)
+}
+
+// defaultPrinter is used in printing functions like Println.
+// Uses empty file set.
+var defaultPrinter = NewPrinter(token.NewFileSet())
+
+// wrapArgs returns arguments slice with every ast.Node element
+// replaced with fmtNode wrapper that supports additional formatting.
+func wrapArgs(fset *token.FileSet, args []interface{}) []interface{} {
+ for i := range args {
+ if x, ok := args[i].(ast.Node); ok {
+ args[i] = fmtNode{fset: fset, node: x}
+ }
+ }
+ return args
+}
+
+type fmtNode struct {
+ fset *token.FileSet
+ node ast.Node
+}
+
+func (n fmtNode) String() string {
+ var buf bytes.Buffer
+ if err := printer.Fprint(&buf, n.fset, n.node); err != nil {
+ return fmt.Sprintf("%%!s(ast.Node=%s)", err)
+ }
+ return buf.String()
+}
+
+func (n fmtNode) GoString() string {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "%#v", n.node)
+ return buf.String()
+}
diff --git a/vendor/github.com/go-toolsmith/astfmt/go.mod b/vendor/github.com/go-toolsmith/astfmt/go.mod
new file mode 100644
index 000000000..d23db1566
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/go.mod
@@ -0,0 +1,6 @@
+module github.com/go-toolsmith/astfmt
+
+require (
+ github.com/go-toolsmith/astequal v1.0.0 // indirect
+ github.com/go-toolsmith/strparse v1.0.0
+)
diff --git a/vendor/github.com/go-toolsmith/astfmt/go.sum b/vendor/github.com/go-toolsmith/astfmt/go.sum
new file mode 100644
index 000000000..aa0857030
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astfmt/go.sum
@@ -0,0 +1,4 @@
+github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
diff --git a/vendor/github.com/go-toolsmith/astp/.gitignore b/vendor/github.com/go-toolsmith/astp/.gitignore
new file mode 100644
index 000000000..1f6187ecd
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/.gitignore
@@ -0,0 +1,4 @@
+bin
+pkg
+src/main
+tmp \ No newline at end of file
diff --git a/vendor/github.com/go-toolsmith/astp/.travis.yml b/vendor/github.com/go-toolsmith/astp/.travis.yml
new file mode 100644
index 000000000..8994d395c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./... \ No newline at end of file
diff --git a/vendor/github.com/go-toolsmith/astp/LICENSE b/vendor/github.com/go-toolsmith/astp/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/astp/README.md b/vendor/github.com/go-toolsmith/astp/README.md
new file mode 100644
index 000000000..7313c6ab8
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/README.md
@@ -0,0 +1,39 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/astp)](https://goreportcard.com/report/github.com/go-toolsmith/astp)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/astp?status.svg)](https://godoc.org/github.com/go-toolsmith/astp)
+[![Build Status](https://travis-ci.org/go-toolsmith/astp.svg?branch=master)](https://travis-ci.org/go-toolsmith/astp)
+
+
+# astp
+
+Package astp provides AST predicates.
+
+## Installation:
+
+```bash
+go get github.com/go-toolsmith/astp
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/go-toolsmith/astp"
+ "github.com/go-toolsmith/strparse"
+)
+
+func main() {
+ if astp.IsIdent(strparse.Expr(`x`)) {
+ fmt.Println("ident")
+ }
+ if astp.IsBlockStmt(strparse.Stmt(`{f()}`)) {
+ fmt.Println("block stmt")
+ }
+ if astp.IsGenDecl(strparse.Decl(`var x int = 10`)) {
+ fmt.Println("gen decl")
+ }
+}
+```
diff --git a/vendor/github.com/go-toolsmith/astp/decl.go b/vendor/github.com/go-toolsmith/astp/decl.go
new file mode 100644
index 000000000..4654ad95c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/decl.go
@@ -0,0 +1,39 @@
+package astp
+
+import "go/ast"
+
+// IsDecl reports whether a node is a ast.Decl.
+func IsDecl(node ast.Node) bool {
+ _, ok := node.(ast.Decl)
+ return ok
+}
+
+// IsFuncDecl reports whether a given ast.Node is a function declaration (*ast.FuncDecl).
+func IsFuncDecl(node ast.Node) bool {
+ _, ok := node.(*ast.FuncDecl)
+ return ok
+}
+
+// IsGenDecl reports whether a given ast.Node is a generic declaration (*ast.GenDecl).
+func IsGenDecl(node ast.Node) bool {
+ _, ok := node.(*ast.GenDecl)
+ return ok
+}
+
+// IsImportSpec reports whether a given ast.Node is an import declaration (*ast.ImportSpec).
+func IsImportSpec(node ast.Node) bool {
+ _, ok := node.(*ast.ImportSpec)
+ return ok
+}
+
+// IsValueSpec reports whether a given ast.Node is a value declaration (*ast.ValueSpec).
+func IsValueSpec(node ast.Node) bool {
+ _, ok := node.(*ast.ValueSpec)
+ return ok
+}
+
+// IsTypeSpec reports whether a given ast.Node is a type declaration (*ast.TypeSpec).
+func IsTypeSpec(node ast.Node) bool {
+ _, ok := node.(*ast.TypeSpec)
+ return ok
+}
diff --git a/vendor/github.com/go-toolsmith/astp/expr.go b/vendor/github.com/go-toolsmith/astp/expr.go
new file mode 100644
index 000000000..adf9668ce
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/expr.go
@@ -0,0 +1,141 @@
+package astp
+
+import "go/ast"
+
+// IsExpr reports whether a given ast.Node is an expression(ast.Expr).
+func IsExpr(node ast.Node) bool {
+ _, ok := node.(ast.Expr)
+ return ok
+}
+
+// IsBadExpr reports whether a given ast.Node is a bad expression (*ast.IsBadExpr).
+func IsBadExpr(node ast.Node) bool {
+ _, ok := node.(*ast.BadExpr)
+ return ok
+}
+
+// IsIdent reports whether a given ast.Node is an identifier (*ast.IsIdent).
+func IsIdent(node ast.Node) bool {
+ _, ok := node.(*ast.Ident)
+ return ok
+}
+
+// IsEllipsis reports whether a given ast.Node is an `...` (ellipsis) (*ast.IsEllipsis).
+func IsEllipsis(node ast.Node) bool {
+ _, ok := node.(*ast.Ellipsis)
+ return ok
+}
+
+// IsBasicLit reports whether a given ast.Node is a literal of basic type (*ast.IsBasicLit).
+func IsBasicLit(node ast.Node) bool {
+ _, ok := node.(*ast.BasicLit)
+ return ok
+}
+
+// IsFuncLit reports whether a given ast.Node is a function literal (*ast.IsFuncLit).
+func IsFuncLit(node ast.Node) bool {
+ _, ok := node.(*ast.FuncLit)
+ return ok
+}
+
+// IsCompositeLit reports whether a given ast.Node is a composite literal (*ast.IsCompositeLit).
+func IsCompositeLit(node ast.Node) bool {
+ _, ok := node.(*ast.CompositeLit)
+ return ok
+}
+
+// IsParenExpr reports whether a given ast.Node is a parenthesized expression (*ast.IsParenExpr).
+func IsParenExpr(node ast.Node) bool {
+ _, ok := node.(*ast.ParenExpr)
+ return ok
+}
+
+// IsSelectorExpr reports whether a given ast.Node is a selector expression (*ast.IsSelectorExpr).
+func IsSelectorExpr(node ast.Node) bool {
+ _, ok := node.(*ast.SelectorExpr)
+ return ok
+}
+
+// IsIndexExpr reports whether a given ast.Node is an index expression (*ast.IsIndexExpr).
+func IsIndexExpr(node ast.Node) bool {
+ _, ok := node.(*ast.IndexExpr)
+ return ok
+}
+
+// IsSliceExpr reports whether a given ast.Node is a slice expression (*ast.IsSliceExpr).
+func IsSliceExpr(node ast.Node) bool {
+ _, ok := node.(*ast.SliceExpr)
+ return ok
+}
+
+// IsTypeAssertExpr reports whether a given ast.Node is a type assert expression (*ast.IsTypeAssertExpr).
+func IsTypeAssertExpr(node ast.Node) bool {
+ _, ok := node.(*ast.TypeAssertExpr)
+ return ok
+}
+
+// IsCallExpr reports whether a given ast.Node is an expression followed by an argument list (*ast.IsCallExpr).
+func IsCallExpr(node ast.Node) bool {
+ _, ok := node.(*ast.CallExpr)
+ return ok
+}
+
+// IsStarExpr reports whether a given ast.Node is a star expression(unary "*" or apointer) (*ast.IsStarExpr)
+func IsStarExpr(node ast.Node) bool {
+ _, ok := node.(*ast.StarExpr)
+ return ok
+}
+
+// IsUnaryExpr reports whether a given ast.Node is a unary expression (*ast.IsUnaryExpr).
+func IsUnaryExpr(node ast.Node) bool {
+ _, ok := node.(*ast.UnaryExpr)
+ return ok
+}
+
+// IsBinaryExpr reports whether a given ast.Node is a binary expression (*ast.IsBinaryExpr).
+func IsBinaryExpr(node ast.Node) bool {
+ _, ok := node.(*ast.BinaryExpr)
+ return ok
+}
+
+// IsKeyValueExpr reports whether a given ast.Node is a (key:value) pair (*ast.IsKeyValueExpr).
+func IsKeyValueExpr(node ast.Node) bool {
+ _, ok := node.(*ast.KeyValueExpr)
+ return ok
+}
+
+// IsArrayType reports whether a given ast.Node is an array or slice type (*ast.IsArrayType).
+func IsArrayType(node ast.Node) bool {
+ _, ok := node.(*ast.ArrayType)
+ return ok
+}
+
+// IsStructType reports whether a given ast.Node is a struct type (*ast.IsStructType).
+func IsStructType(node ast.Node) bool {
+ _, ok := node.(*ast.StructType)
+ return ok
+}
+
+// IsFuncType reports whether a given ast.Node is a function type (*ast.IsFuncType).
+func IsFuncType(node ast.Node) bool {
+ _, ok := node.(*ast.FuncType)
+ return ok
+}
+
+// IsInterfaceType reports whether a given ast.Node is an interface type (*ast.IsInterfaceType).
+func IsInterfaceType(node ast.Node) bool {
+ _, ok := node.(*ast.InterfaceType)
+ return ok
+}
+
+// IsMapType reports whether a given ast.Node is a map type (*ast.IsMapType).
+func IsMapType(node ast.Node) bool {
+ _, ok := node.(*ast.MapType)
+ return ok
+}
+
+// IsChanType reports whether a given ast.Node is a channel type (*ast.IsChanType).
+func IsChanType(node ast.Node) bool {
+ _, ok := node.(*ast.ChanType)
+ return ok
+}
diff --git a/vendor/github.com/go-toolsmith/astp/go.mod b/vendor/github.com/go-toolsmith/astp/go.mod
new file mode 100644
index 000000000..023a09392
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/go.mod
@@ -0,0 +1,6 @@
+module github.com/go-toolsmith/astp
+
+require (
+ github.com/go-toolsmith/astequal v1.0.0 // indirect
+ github.com/go-toolsmith/strparse v1.0.0
+)
diff --git a/vendor/github.com/go-toolsmith/astp/go.sum b/vendor/github.com/go-toolsmith/astp/go.sum
new file mode 100644
index 000000000..aa0857030
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/go.sum
@@ -0,0 +1,4 @@
+github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
diff --git a/vendor/github.com/go-toolsmith/astp/stmt.go b/vendor/github.com/go-toolsmith/astp/stmt.go
new file mode 100644
index 000000000..19645d212
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/astp/stmt.go
@@ -0,0 +1,135 @@
+package astp
+
+import "go/ast"
+
+// IsStmt reports whether a given ast.Node is a statement(ast.Stmt).
+func IsStmt(node ast.Node) bool {
+ _, ok := node.(ast.Stmt)
+ return ok
+}
+
+// IsBadStmt reports whether a given ast.Node is a bad statement(*ast.BadStmt)
+func IsBadStmt(node ast.Node) bool {
+ _, ok := node.(*ast.BadStmt)
+ return ok
+}
+
+// IsDeclStmt reports whether a given ast.Node is a declaration statement(*ast.DeclStmt)
+func IsDeclStmt(node ast.Node) bool {
+ _, ok := node.(*ast.DeclStmt)
+ return ok
+}
+
+// IsEmptyStmt reports whether a given ast.Node is an empty statement(*ast.EmptyStmt)
+func IsEmptyStmt(node ast.Node) bool {
+ _, ok := node.(*ast.EmptyStmt)
+ return ok
+}
+
+// IsLabeledStmt reports whether a given ast.Node is a label statement(*ast.LabeledStmt)
+func IsLabeledStmt(node ast.Node) bool {
+ _, ok := node.(*ast.LabeledStmt)
+ return ok
+}
+
+// IsExprStmt reports whether a given ast.Node is an expression statement(*ast.ExprStmt)
+func IsExprStmt(node ast.Node) bool {
+ _, ok := node.(*ast.ExprStmt)
+ return ok
+}
+
+// IsSendStmt reports whether a given ast.Node is a send to chan statement(*ast.SendStmt)
+func IsSendStmt(node ast.Node) bool {
+ _, ok := node.(*ast.SendStmt)
+ return ok
+}
+
+// IsIncDecStmt reports whether a given ast.Node is a increment/decrement statement(*ast.IncDecStmt)
+func IsIncDecStmt(node ast.Node) bool {
+ _, ok := node.(*ast.IncDecStmt)
+ return ok
+}
+
+// IsAssignStmt reports whether a given ast.Node is an assignment statement(*ast.AssignStmt)
+func IsAssignStmt(node ast.Node) bool {
+ _, ok := node.(*ast.AssignStmt)
+ return ok
+}
+
+// IsGoStmt reports whether a given ast.Node is a go statement(*ast.GoStmt)
+func IsGoStmt(node ast.Node) bool {
+ _, ok := node.(*ast.GoStmt)
+ return ok
+}
+
+// IsDeferStmt reports whether a given ast.Node is a defer statement(*ast.DeferStmt)
+func IsDeferStmt(node ast.Node) bool {
+ _, ok := node.(*ast.DeferStmt)
+ return ok
+}
+
+// IsReturnStmt reports whether a given ast.Node is a return statement(*ast.ReturnStmt)
+func IsReturnStmt(node ast.Node) bool {
+ _, ok := node.(*ast.ReturnStmt)
+ return ok
+}
+
+// IsBranchStmt reports whether a given ast.Node is a branch(goto/continue/break/fallthrough)statement(*ast.BranchStmt)
+func IsBranchStmt(node ast.Node) bool {
+ _, ok := node.(*ast.BranchStmt)
+ return ok
+}
+
+// IsBlockStmt reports whether a given ast.Node is a block statement(*ast.BlockStmt)
+func IsBlockStmt(node ast.Node) bool {
+ _, ok := node.(*ast.BlockStmt)
+ return ok
+}
+
+// IsIfStmt reports whether a given ast.Node is an if statement(*ast.IfStmt)
+func IsIfStmt(node ast.Node) bool {
+ _, ok := node.(*ast.IfStmt)
+ return ok
+}
+
+// IsCaseClause reports whether a given ast.Node is a case statement(*ast.CaseClause)
+func IsCaseClause(node ast.Node) bool {
+ _, ok := node.(*ast.CaseClause)
+ return ok
+}
+
+// IsSwitchStmt reports whether a given ast.Node is a switch statement(*ast.SwitchStmt)
+func IsSwitchStmt(node ast.Node) bool {
+ _, ok := node.(*ast.SwitchStmt)
+ return ok
+}
+
+// IsTypeSwitchStmt reports whether a given ast.Node is a type switch statement(*ast.TypeSwitchStmt)
+func IsTypeSwitchStmt(node ast.Node) bool {
+ _, ok := node.(*ast.TypeSwitchStmt)
+ return ok
+}
+
+// IsCommClause reports whether a given ast.Node is a select statement(*ast.CommClause)
+func IsCommClause(node ast.Node) bool {
+ _, ok := node.(*ast.CommClause)
+ return ok
+}
+
+// IsSelectStmt reports whether a given ast.Node is a selection statement(*ast.SelectStmt)
+func IsSelectStmt(node ast.Node) bool {
+ _, ok := node.(*ast.SelectStmt)
+ return ok
+}
+
+// IsForStmt reports whether a given ast.Node is a for statement(*ast.ForStmt)
+func IsForStmt(node ast.Node) bool {
+ _, ok := node.(*ast.ForStmt)
+ return ok
+}
+
+// IsRangeStmt reports whether a given ast.Node is a range statement(*ast.RangeStmt)
+func IsRangeStmt(node ast.Node) bool {
+ _, ok := node.(*ast.RangeStmt)
+ return ok
+}
diff --git a/vendor/github.com/go-toolsmith/strparse/.travis.yml b/vendor/github.com/go-toolsmith/strparse/.travis.yml
new file mode 100644
index 000000000..8994d395c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/strparse/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./... \ No newline at end of file
diff --git a/vendor/github.com/go-toolsmith/strparse/LICENSE b/vendor/github.com/go-toolsmith/strparse/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/strparse/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/strparse/README.md b/vendor/github.com/go-toolsmith/strparse/README.md
new file mode 100644
index 000000000..ae80a5398
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/strparse/README.md
@@ -0,0 +1,34 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/strparse)](https://goreportcard.com/report/github.com/go-toolsmith/strparse)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/strparse?status.svg)](https://godoc.org/github.com/go-toolsmith/strparse)
+[![Build Status](https://travis-ci.org/go-toolsmith/strparse.svg?branch=master)](https://travis-ci.org/go-toolsmith/strparse)
+
+
+# strparse
+
+Package strparse provides convenience wrappers around `go/parser` for simple
+expression, statement and declaretion parsing from string.
+
+## Installation
+
+```bash
+go get github.com/go-toolsmith/strparse
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "go-toolsmith/astequal"
+ "go-toolsmith/strparse"
+)
+
+func main() {
+ // Comparing AST strings for equallity (note different spacing):
+ x := strparse.Expr(`1 + f(v[0].X)`)
+ y := strparse.Expr(` 1+f( v[0].X ) `)
+ fmt.Println(astequal.Expr(x, y)) // => true
+}
+
+```
diff --git a/vendor/github.com/go-toolsmith/strparse/go.mod b/vendor/github.com/go-toolsmith/strparse/go.mod
new file mode 100644
index 000000000..ed9d88136
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/strparse/go.mod
@@ -0,0 +1 @@
+module github.com/go-toolsmith/strparse
diff --git a/vendor/github.com/go-toolsmith/strparse/strparse.go b/vendor/github.com/go-toolsmith/strparse/strparse.go
new file mode 100644
index 000000000..894c7ebac
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/strparse/strparse.go
@@ -0,0 +1,59 @@
+// Package strparse provides convenience wrappers around `go/parser` for simple
+// expression, statement and declaration parsing from string.
+//
+// Can be used to construct AST nodes using source syntax.
+package strparse
+
+import (
+ "go/ast"
+ "go/parser"
+ "go/token"
+)
+
+var (
+ // BadExpr is returned as a parse result for malformed expressions.
+ // Should be treated as constant or readonly variable.
+ BadExpr = &ast.BadExpr{}
+
+ // BadStmt is returned as a parse result for malformed statmenents.
+ // Should be treated as constant or readonly variable.
+ BadStmt = &ast.BadStmt{}
+
+ // BadDecl is returned as a parse result for malformed declarations.
+ // Should be treated as constant or readonly variable.
+ BadDecl = &ast.BadDecl{}
+)
+
+// Expr parses single expression node from s.
+// In case of parse error, BadExpr is returned.
+func Expr(s string) ast.Expr {
+ node, err := parser.ParseExpr(s)
+ if err != nil {
+ return BadExpr
+ }
+ return node
+}
+
+// Stmt parses single statement node from s.
+// In case of parse error, BadStmt is returned.
+func Stmt(s string) ast.Stmt {
+ node, err := parser.ParseFile(token.NewFileSet(), "", "package main;func main() {"+s+"}", 0)
+ if err != nil {
+ return BadStmt
+ }
+ fn := node.Decls[0].(*ast.FuncDecl)
+ if len(fn.Body.List) != 1 {
+ return BadStmt
+ }
+ return fn.Body.List[0]
+}
+
+// Decl parses single declaration node from s.
+// In case of parse error, BadDecl is returned.
+func Decl(s string) ast.Decl {
+ node, err := parser.ParseFile(token.NewFileSet(), "", "package main;"+s, 0)
+ if err != nil || len(node.Decls) != 1 {
+ return BadDecl
+ }
+ return node.Decls[0]
+}
diff --git a/vendor/github.com/go-toolsmith/typep/.travis.yml b/vendor/github.com/go-toolsmith/typep/.travis.yml
new file mode 100644
index 000000000..c32ac0062
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/.travis.yml
@@ -0,0 +1,9 @@
+language: go
+go:
+ - 1.x
+install:
+ - # Prevent default install action "go get -t -v ./...".
+script:
+ - go get -t -v ./...
+ - go tool vet .
+ - go test -v -race ./...
diff --git a/vendor/github.com/go-toolsmith/typep/LICENSE b/vendor/github.com/go-toolsmith/typep/LICENSE
new file mode 100644
index 000000000..eef17180f
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 go-toolsmith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/go-toolsmith/typep/README.md b/vendor/github.com/go-toolsmith/typep/README.md
new file mode 100644
index 000000000..736658012
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/README.md
@@ -0,0 +1,37 @@
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-toolsmith/typep)](https://goreportcard.com/report/github.com/go-toolsmith/typep)
+[![GoDoc](https://godoc.org/github.com/go-toolsmith/typep?status.svg)](https://godoc.org/github.com/go-toolsmith/typep)
+
+
+# typep
+
+Package typep provides type predicates.
+
+## Installation:
+
+```bash
+go get -v github.com/go-toolsmith/typep
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/go-toolsmith/typep"
+ "github.com/go-toolsmith/strparse"
+)
+
+func main() {
+ floatTyp := types.Typ[types.Float32]
+ intTyp := types.Typ[types.Int]
+ ptr := types.NewPointer(intTyp)
+ arr := types.NewArray(intTyp, 64)
+ fmt.Println(typep.HasFloatProp(floatTyp)) // => true
+ fmt.Println(typep.HasFloatProp(intTyp)) // => false
+ fmt.Println(typep.IsPointer(ptr)) // => true
+ fmt.Println(typep.IsArray(arr)) // => true
+}
+```
diff --git a/vendor/github.com/go-toolsmith/typep/doc.go b/vendor/github.com/go-toolsmith/typep/doc.go
new file mode 100644
index 000000000..990bc402c
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/doc.go
@@ -0,0 +1,2 @@
+// Package typep provides type predicates.
+package typep
diff --git a/vendor/github.com/go-toolsmith/typep/go.mod b/vendor/github.com/go-toolsmith/typep/go.mod
new file mode 100644
index 000000000..197a57d30
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/go.mod
@@ -0,0 +1 @@
+module github.com/go-toolsmith/typep
diff --git a/vendor/github.com/go-toolsmith/typep/predicates.go b/vendor/github.com/go-toolsmith/typep/predicates.go
new file mode 100644
index 000000000..70e5b55cd
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/predicates.go
@@ -0,0 +1,36 @@
+package typep
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// IsTypeExpr reports whether x represents a type expression.
+//
+// Type expression does not evaluate to any run time value,
+// but rather describes a type that is used inside Go expression.
+//
+// For example, (*T)(v) is a CallExpr that "calls" (*T).
+// (*T) is a type expression that tells Go compiler type v should be converted to.
+func IsTypeExpr(info *types.Info, x ast.Expr) bool {
+ switch x := x.(type) {
+ case *ast.StarExpr:
+ return IsTypeExpr(info, x.X)
+ case *ast.ParenExpr:
+ return IsTypeExpr(info, x.X)
+ case *ast.SelectorExpr:
+ return IsTypeExpr(info, x.Sel)
+
+ case *ast.Ident:
+ // Identifier may be a type expression if object
+ // it reffers to is a type name.
+ _, ok := info.ObjectOf(x).(*types.TypeName)
+ return ok
+
+ case *ast.FuncType, *ast.StructType, *ast.InterfaceType, *ast.ArrayType, *ast.MapType:
+ return true
+
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/go-toolsmith/typep/safeExpr.go b/vendor/github.com/go-toolsmith/typep/safeExpr.go
new file mode 100644
index 000000000..7236e6e03
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/safeExpr.go
@@ -0,0 +1,62 @@
+package typep
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+)
+
+// SideEffectFree reports whether expr is softly safe expression and contains
+// no significant side-effects. As opposed to strictly safe expressions,
+// soft safe expressions permit some forms of side-effects, like
+// panic possibility during indexing or nil pointer dereference.
+//
+// Uses types info to determine type conversion expressions that
+// are the only permitted kinds of call expressions.
+// Note that is does not check whether called function really
+// has any side effects. The analysis is very conservative.
+func SideEffectFree(info *types.Info, expr ast.Expr) bool {
+ // This list switch is not comprehensive and uses
+ // whitelist to be on the conservative side.
+ // Can be extended as needed.
+
+ switch expr := expr.(type) {
+ case *ast.StarExpr:
+ return SideEffectFree(info, expr.X)
+ case *ast.BinaryExpr:
+ return SideEffectFree(info, expr.X) &&
+ SideEffectFree(info, expr.Y)
+ case *ast.UnaryExpr:
+ return expr.Op != token.ARROW &&
+ SideEffectFree(info, expr.X)
+ case *ast.BasicLit, *ast.Ident:
+ return true
+ case *ast.IndexExpr:
+ return SideEffectFree(info, expr.X) &&
+ SideEffectFree(info, expr.Index)
+ case *ast.SelectorExpr:
+ return SideEffectFree(info, expr.X)
+ case *ast.ParenExpr:
+ return SideEffectFree(info, expr.X)
+ case *ast.CompositeLit:
+ return SideEffectFreeList(info, expr.Elts)
+ case *ast.CallExpr:
+ return IsTypeExpr(info, expr.Fun) &&
+ SideEffectFreeList(info, expr.Args)
+
+ default:
+ return false
+ }
+}
+
+// SideEffectFreeList reports whether every expr in list is safe.
+//
+// See SideEffectFree.
+func SideEffectFreeList(info *types.Info, list []ast.Expr) bool {
+ for _, expr := range list {
+ if !SideEffectFree(info, expr) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/go-toolsmith/typep/simplePredicates.go b/vendor/github.com/go-toolsmith/typep/simplePredicates.go
new file mode 100644
index 000000000..3bc9c29c8
--- /dev/null
+++ b/vendor/github.com/go-toolsmith/typep/simplePredicates.go
@@ -0,0 +1,359 @@
+// Code generated by simplePredicates_generate.go; DO NOT EDIT
+
+package typep
+
+import (
+ "go/types"
+)
+
+// Simple 1-to-1 type predicates via type assertion.
+
+// IsBasic reports whether a given type has *types.Basic type.
+func IsBasic(typ types.Type) bool {
+ _, ok := typ.(*types.Basic)
+ return ok
+}
+
+// IsArray reports whether a given type has *types.Array type.
+func IsArray(typ types.Type) bool {
+ _, ok := typ.(*types.Array)
+ return ok
+}
+
+// IsSlice reports whether a given type has *types.Slice type.
+func IsSlice(typ types.Type) bool {
+ _, ok := typ.(*types.Slice)
+ return ok
+}
+
+// IsStruct reports whether a given type has *types.Struct type.
+func IsStruct(typ types.Type) bool {
+ _, ok := typ.(*types.Struct)
+ return ok
+}
+
+// IsPointer reports whether a given type has *types.Pointer type.
+func IsPointer(typ types.Type) bool {
+ _, ok := typ.(*types.Pointer)
+ return ok
+}
+
+// IsTuple reports whether a given type has *types.Tuple type.
+func IsTuple(typ types.Type) bool {
+ _, ok := typ.(*types.Tuple)
+ return ok
+}
+
+// IsSignature reports whether a given type has *types.Signature type.
+func IsSignature(typ types.Type) bool {
+ _, ok := typ.(*types.Signature)
+ return ok
+}
+
+// IsInterface reports whether a given type has *types.Interface type.
+func IsInterface(typ types.Type) bool {
+ _, ok := typ.(*types.Interface)
+ return ok
+}
+
+// IsMap reports whether a given type has *types.Map type.
+func IsMap(typ types.Type) bool {
+ _, ok := typ.(*types.Map)
+ return ok
+}
+
+// IsChan reports whether a given type has *types.Chan type.
+func IsChan(typ types.Type) bool {
+ _, ok := typ.(*types.Chan)
+ return ok
+}
+
+// IsNamed reports whether a given type has *types.Named type.
+func IsNamed(typ types.Type) bool {
+ _, ok := typ.(*types.Named)
+ return ok
+}
+
+// *types.Basic predicates for the info field.
+
+// HasBooleanProp reports whether typ is a *types.Basic has IsBoolean property.
+func HasBooleanProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsBoolean != 0
+ }
+ return false
+}
+
+// HasIntegerProp reports whether typ is a *types.Basic has IsInteger property.
+func HasIntegerProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsInteger != 0
+ }
+ return false
+}
+
+// HasUnsignedProp reports whether typ is a *types.Basic has IsUnsigned property.
+func HasUnsignedProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsUnsigned != 0
+ }
+ return false
+}
+
+// HasFloatProp reports whether typ is a *types.Basic has IsFloat property.
+func HasFloatProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsFloat != 0
+ }
+ return false
+}
+
+// HasComplexProp reports whether typ is a *types.Basic has IsComplex property.
+func HasComplexProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsComplex != 0
+ }
+ return false
+}
+
+// HasStringProp reports whether typ is a *types.Basic has IsString property.
+func HasStringProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsString != 0
+ }
+ return false
+}
+
+// HasUntypedProp reports whether typ is a *types.Basic has IsUntyped property.
+func HasUntypedProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsUntyped != 0
+ }
+ return false
+}
+
+// HasOrderedProp reports whether typ is a *types.Basic has IsOrdered property.
+func HasOrderedProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsOrdered != 0
+ }
+ return false
+}
+
+// HasNumericProp reports whether typ is a *types.Basic has IsNumeric property.
+func HasNumericProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsNumeric != 0
+ }
+ return false
+}
+
+// HasConstTypeProp reports whether typ is a *types.Basic has IsConstType property.
+func HasConstTypeProp(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Info()&types.IsConstType != 0
+ }
+ return false
+}
+
+// *types.Basic predicates for the kind field.
+
+// HasBoolKind reports whether typ is a *types.Basic with its kind set to types.Bool.
+func HasBoolKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Bool
+ }
+ return false
+}
+
+// HasIntKind reports whether typ is a *types.Basic with its kind set to types.Int.
+func HasIntKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Int
+ }
+ return false
+}
+
+// HasInt8Kind reports whether typ is a *types.Basic with its kind set to types.Int8.
+func HasInt8Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Int8
+ }
+ return false
+}
+
+// HasInt16Kind reports whether typ is a *types.Basic with its kind set to types.Int16.
+func HasInt16Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Int16
+ }
+ return false
+}
+
+// HasInt32Kind reports whether typ is a *types.Basic with its kind set to types.Int32.
+func HasInt32Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Int32
+ }
+ return false
+}
+
+// HasInt64Kind reports whether typ is a *types.Basic with its kind set to types.Int64.
+func HasInt64Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Int64
+ }
+ return false
+}
+
+// HasUintKind reports whether typ is a *types.Basic with its kind set to types.Uint.
+func HasUintKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uint
+ }
+ return false
+}
+
+// HasUint8Kind reports whether typ is a *types.Basic with its kind set to types.Uint8.
+func HasUint8Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uint8
+ }
+ return false
+}
+
+// HasUint16Kind reports whether typ is a *types.Basic with its kind set to types.Uint16.
+func HasUint16Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uint16
+ }
+ return false
+}
+
+// HasUint32Kind reports whether typ is a *types.Basic with its kind set to types.Uint32.
+func HasUint32Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uint32
+ }
+ return false
+}
+
+// HasUint64Kind reports whether typ is a *types.Basic with its kind set to types.Uint64.
+func HasUint64Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uint64
+ }
+ return false
+}
+
+// HasUintptrKind reports whether typ is a *types.Basic with its kind set to types.Uintptr.
+func HasUintptrKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Uintptr
+ }
+ return false
+}
+
+// HasFloat32Kind reports whether typ is a *types.Basic with its kind set to types.Float32.
+func HasFloat32Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Float32
+ }
+ return false
+}
+
+// HasFloat64Kind reports whether typ is a *types.Basic with its kind set to types.Float64.
+func HasFloat64Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Float64
+ }
+ return false
+}
+
+// HasComplex64Kind reports whether typ is a *types.Basic with its kind set to types.Complex64.
+func HasComplex64Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Complex64
+ }
+ return false
+}
+
+// HasComplex128Kind reports whether typ is a *types.Basic with its kind set to types.Complex128.
+func HasComplex128Kind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.Complex128
+ }
+ return false
+}
+
+// HasStringKind reports whether typ is a *types.Basic with its kind set to types.String.
+func HasStringKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.String
+ }
+ return false
+}
+
+// HasUnsafePointerKind reports whether typ is a *types.Basic with its kind set to types.UnsafePointer.
+func HasUnsafePointerKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UnsafePointer
+ }
+ return false
+}
+
+// HasUntypedBoolKind reports whether typ is a *types.Basic with its kind set to types.UntypedBool.
+func HasUntypedBoolKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedBool
+ }
+ return false
+}
+
+// HasUntypedIntKind reports whether typ is a *types.Basic with its kind set to types.UntypedInt.
+func HasUntypedIntKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedInt
+ }
+ return false
+}
+
+// HasUntypedRuneKind reports whether typ is a *types.Basic with its kind set to types.UntypedRune.
+func HasUntypedRuneKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedRune
+ }
+ return false
+}
+
+// HasUntypedFloatKind reports whether typ is a *types.Basic with its kind set to types.UntypedFloat.
+func HasUntypedFloatKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedFloat
+ }
+ return false
+}
+
+// HasUntypedComplexKind reports whether typ is a *types.Basic with its kind set to types.UntypedComplex.
+func HasUntypedComplexKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedComplex
+ }
+ return false
+}
+
+// HasUntypedStringKind reports whether typ is a *types.Basic with its kind set to types.UntypedString.
+func HasUntypedStringKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedString
+ }
+ return false
+}
+
+// HasUntypedNilKind reports whether typ is a *types.Basic with its kind set to types.UntypedNil.
+func HasUntypedNilKind(typ types.Type) bool {
+ if typ, ok := typ.(*types.Basic); ok {
+ return typ.Kind() == types.UntypedNil
+ }
+ return false
+}