зеркало из https://github.com/golang/tools.git
x/tools: deprecate astutil.Unparen
The go1.22 go/ast package now provides it. Updates golang/go#60061 Change-Id: I24e201660e3a8752dd505eefc894c7acae4c99f3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/612038 Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Родитель
c2e057bbd2
Коммит
c055e89c76
|
@ -18,7 +18,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,7 +77,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||||
|
|
||||||
// isMapIndex returns true if e is a map index expression.
|
// isMapIndex returns true if e is a map index expression.
|
||||||
func isMapIndex(info *types.Info, e ast.Expr) bool {
|
func isMapIndex(info *types.Info, e ast.Expr) bool {
|
||||||
if idx, ok := astutil.Unparen(e).(*ast.IndexExpr); ok {
|
if idx, ok := ast.Unparen(e).(*ast.IndexExpr); ok {
|
||||||
if typ := info.Types[idx.X].Type; typ != nil {
|
if typ := info.Types[idx.X].Type; typ != nil {
|
||||||
_, ok := typ.Underlying().(*types.Map)
|
_, ok := typ.Underlying().(*types.Map)
|
||||||
return ok
|
return ok
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -169,7 +168,7 @@ func (op boolOp) checkSuspect(pass *analysis.Pass, exprs []ast.Expr) {
|
||||||
// seen[e] is already true; any newly processed exprs are added to seen.
|
// seen[e] is already true; any newly processed exprs are added to seen.
|
||||||
func (op boolOp) split(e ast.Expr, seen map[*ast.BinaryExpr]bool) (exprs []ast.Expr) {
|
func (op boolOp) split(e ast.Expr, seen map[*ast.BinaryExpr]bool) (exprs []ast.Expr) {
|
||||||
for {
|
for {
|
||||||
e = astutil.Unparen(e)
|
e = ast.Unparen(e)
|
||||||
if b, ok := e.(*ast.BinaryExpr); ok && b.Op == op.tok {
|
if b, ok := e.(*ast.BinaryExpr); ok && b.Op == op.tok {
|
||||||
seen[b] = true
|
seen[b] = true
|
||||||
exprs = append(exprs, op.split(b.Y, seen)...)
|
exprs = append(exprs, op.split(b.Y, seen)...)
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
|
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const debug = false
|
const debug = false
|
||||||
|
@ -65,7 +64,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t
|
||||||
|
|
||||||
// Is this a C.f() call?
|
// Is this a C.f() call?
|
||||||
var name string
|
var name string
|
||||||
if sel, ok := astutil.Unparen(call.Fun).(*ast.SelectorExpr); ok {
|
if sel, ok := ast.Unparen(call.Fun).(*ast.SelectorExpr); ok {
|
||||||
if id, ok := sel.X.(*ast.Ident); ok && id.Name == "C" {
|
if id, ok := sel.X.(*ast.Ident); ok && id.Name == "C" {
|
||||||
name = sel.Sel.Name
|
name = sel.Sel.Name
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
"golang.org/x/tools/internal/aliases"
|
"golang.org/x/tools/internal/aliases"
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
|
@ -253,7 +252,7 @@ func (path typePath) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func lockPathRhs(pass *analysis.Pass, x ast.Expr) typePath {
|
func lockPathRhs(pass *analysis.Pass, x ast.Expr) typePath {
|
||||||
x = astutil.Unparen(x) // ignore parens on rhs
|
x = ast.Unparen(x) // ignore parens on rhs
|
||||||
|
|
||||||
if _, ok := x.(*ast.CompositeLit); ok {
|
if _, ok := x.(*ast.CompositeLit); ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -263,7 +262,7 @@ func lockPathRhs(pass *analysis.Pass, x ast.Expr) typePath {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if star, ok := x.(*ast.StarExpr); ok {
|
if star, ok := x.(*ast.StarExpr); ok {
|
||||||
if _, ok := astutil.Unparen(star.X).(*ast.CallExpr); ok {
|
if _, ok := ast.Unparen(star.X).(*ast.CallExpr); ok {
|
||||||
// A call may return a pointer to a zero value.
|
// A call may return a pointer to a zero value.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/internal/aliases"
|
"golang.org/x/tools/internal/aliases"
|
||||||
|
@ -186,7 +185,7 @@ func withinScope(scope ast.Node, x *types.Var) bool {
|
||||||
func goAsyncCall(info *types.Info, goStmt *ast.GoStmt, toDecl func(*types.Func) *ast.FuncDecl) *asyncCall {
|
func goAsyncCall(info *types.Info, goStmt *ast.GoStmt, toDecl func(*types.Func) *ast.FuncDecl) *asyncCall {
|
||||||
call := goStmt.Call
|
call := goStmt.Call
|
||||||
|
|
||||||
fun := astutil.Unparen(call.Fun)
|
fun := ast.Unparen(call.Fun)
|
||||||
if id := funcIdent(fun); id != nil {
|
if id := funcIdent(fun); id != nil {
|
||||||
if lit := funcLitInScope(id); lit != nil {
|
if lit := funcLitInScope(id); lit != nil {
|
||||||
return &asyncCall{region: lit, async: goStmt, scope: nil, fun: fun}
|
return &asyncCall{region: lit, async: goStmt, scope: nil, fun: fun}
|
||||||
|
@ -213,7 +212,7 @@ func tRunAsyncCall(info *types.Info, call *ast.CallExpr) *asyncCall {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fun := astutil.Unparen(call.Args[1])
|
fun := ast.Unparen(call.Args[1])
|
||||||
if lit, ok := fun.(*ast.FuncLit); ok { // function lit?
|
if lit, ok := fun.(*ast.FuncLit); ok { // function lit?
|
||||||
return &asyncCall{region: lit, async: call, scope: lit, fun: fun}
|
return &asyncCall{region: lit, async: call, scope: lit, fun: fun}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +242,7 @@ var forbidden = []string{
|
||||||
// Returns (nil, nil, nil) if call is not of this form.
|
// Returns (nil, nil, nil) if call is not of this form.
|
||||||
func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.Selection, *types.Func) {
|
func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.Selection, *types.Func) {
|
||||||
// Compare to typeutil.StaticCallee.
|
// Compare to typeutil.StaticCallee.
|
||||||
fun := astutil.Unparen(call.Fun)
|
fun := ast.Unparen(call.Fun)
|
||||||
selExpr, ok := fun.(*ast.SelectorExpr)
|
selExpr, ok := fun.(*ast.SelectorExpr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
|
@ -254,7 +253,7 @@ func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.S
|
||||||
}
|
}
|
||||||
|
|
||||||
var x *types.Var
|
var x *types.Var
|
||||||
if id, ok := astutil.Unparen(selExpr.X).(*ast.Ident); ok {
|
if id, ok := ast.Unparen(selExpr.X).(*ast.Ident); ok {
|
||||||
x, _ = info.Uses[id].(*types.Var)
|
x, _ = info.Uses[id].(*types.Var)
|
||||||
}
|
}
|
||||||
if x == nil {
|
if x == nil {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ func isMethodNamed(f *types.Func, pkgPath string, names ...string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcIdent(fun ast.Expr) *ast.Ident {
|
func funcIdent(fun ast.Expr) *ast.Ident {
|
||||||
switch fun := astutil.Unparen(fun).(type) {
|
switch fun := ast.Unparen(fun).(type) {
|
||||||
case *ast.IndexExpr, *ast.IndexListExpr:
|
case *ast.IndexExpr, *ast.IndexListExpr:
|
||||||
x, _, _, _ := typeparams.UnpackIndexExpr(fun) // necessary?
|
x, _, _, _ := typeparams.UnpackIndexExpr(fun) // necessary?
|
||||||
id, _ := x.(*ast.Ident)
|
id, _ := x.(*ast.Ident)
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
"golang.org/x/tools/internal/aliases"
|
"golang.org/x/tools/internal/aliases"
|
||||||
)
|
)
|
||||||
|
@ -70,7 +69,7 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
|
||||||
// Check unsafe.Pointer safety rules according to
|
// Check unsafe.Pointer safety rules according to
|
||||||
// https://golang.org/pkg/unsafe/#Pointer.
|
// https://golang.org/pkg/unsafe/#Pointer.
|
||||||
|
|
||||||
switch x := astutil.Unparen(x).(type) {
|
switch x := ast.Unparen(x).(type) {
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
// "(6) Conversion of a reflect.SliceHeader or
|
// "(6) Conversion of a reflect.SliceHeader or
|
||||||
// reflect.StringHeader Data field to or from Pointer."
|
// reflect.StringHeader Data field to or from Pointer."
|
||||||
|
@ -119,7 +118,7 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
|
||||||
// isSafeArith reports whether x is a pointer arithmetic expression that is safe
|
// isSafeArith reports whether x is a pointer arithmetic expression that is safe
|
||||||
// to convert to unsafe.Pointer.
|
// to convert to unsafe.Pointer.
|
||||||
func isSafeArith(info *types.Info, x ast.Expr) bool {
|
func isSafeArith(info *types.Info, x ast.Expr) bool {
|
||||||
switch x := astutil.Unparen(x).(type) {
|
switch x := ast.Unparen(x).(type) {
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
// Base case: initial conversion from unsafe.Pointer to uintptr.
|
// Base case: initial conversion from unsafe.Pointer to uintptr.
|
||||||
return len(x.Args) == 1 &&
|
return len(x.Args) == 1 &&
|
||||||
|
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
)
|
)
|
||||||
|
@ -101,7 +100,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||||
(*ast.ExprStmt)(nil),
|
(*ast.ExprStmt)(nil),
|
||||||
}
|
}
|
||||||
inspect.Preorder(nodeFilter, func(n ast.Node) {
|
inspect.Preorder(nodeFilter, func(n ast.Node) {
|
||||||
call, ok := astutil.Unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
|
call, ok := ast.Unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return // not a call statement
|
return // not a call statement
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,5 @@ package astutil
|
||||||
import "go/ast"
|
import "go/ast"
|
||||||
|
|
||||||
// Unparen returns e with any enclosing parentheses stripped.
|
// Unparen returns e with any enclosing parentheses stripped.
|
||||||
// TODO(adonovan): use go1.22's ast.Unparen.
|
// Deprecated: use [ast.Unparen].
|
||||||
func Unparen(e ast.Expr) ast.Expr {
|
func Unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) }
|
||||||
for {
|
|
||||||
p, ok := e.(*ast.ParenExpr)
|
|
||||||
if !ok {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
e = p.X
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/internal/aliases"
|
"golang.org/x/tools/internal/aliases"
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
|
@ -36,7 +35,7 @@ func assert(p bool, msg string) {
|
||||||
|
|
||||||
//// AST utilities
|
//// AST utilities
|
||||||
|
|
||||||
func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
|
func unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) }
|
||||||
|
|
||||||
// isBlankIdent returns true iff e is an Ident with name "_".
|
// isBlankIdent returns true iff e is an Ident with name "_".
|
||||||
// They have no associated types.Object, and thus no type.
|
// They have no associated types.Object, and thus no type.
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ import (
|
||||||
//
|
//
|
||||||
// Functions and methods may potentially have type parameters.
|
// Functions and methods may potentially have type parameters.
|
||||||
func Callee(info *types.Info, call *ast.CallExpr) types.Object {
|
func Callee(info *types.Info, call *ast.CallExpr) types.Object {
|
||||||
fun := astutil.Unparen(call.Fun)
|
fun := ast.Unparen(call.Fun)
|
||||||
|
|
||||||
// Look through type instantiation if necessary.
|
// Look through type instantiation if necessary.
|
||||||
isInstance := false
|
isInstance := false
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"go/types"
|
"go/types"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
)
|
)
|
||||||
|
@ -242,7 +241,7 @@ func AnalyzeCallee(logf func(string, ...any), fset *token.FileSet, pkg *types.Pa
|
||||||
// not just a return statement
|
// not just a return statement
|
||||||
} else if ret, ok := decl.Body.List[0].(*ast.ReturnStmt); ok && len(ret.Results) == 1 {
|
} else if ret, ok := decl.Body.List[0].(*ast.ReturnStmt); ok && len(ret.Results) == 1 {
|
||||||
validForCallStmt = func() bool {
|
validForCallStmt = func() bool {
|
||||||
switch expr := astutil.Unparen(ret.Results[0]).(type) {
|
switch expr := ast.Unparen(ret.Results[0]).(type) {
|
||||||
case *ast.CallExpr: // f(x)
|
case *ast.CallExpr: // f(x)
|
||||||
callee := typeutil.Callee(info, expr)
|
callee := typeutil.Callee(info, expr)
|
||||||
if callee == nil {
|
if callee == nil {
|
||||||
|
|
|
@ -527,7 +527,7 @@ func (st *state) inlineCall() (*inlineCallResult, error) {
|
||||||
// or time.Second.String()) will remain after
|
// or time.Second.String()) will remain after
|
||||||
// inlining, as arguments.
|
// inlining, as arguments.
|
||||||
if pkgName, ok := existing.(*types.PkgName); ok {
|
if pkgName, ok := existing.(*types.PkgName); ok {
|
||||||
if sel, ok := astutil.Unparen(caller.Call.Fun).(*ast.SelectorExpr); ok {
|
if sel, ok := ast.Unparen(caller.Call.Fun).(*ast.SelectorExpr); ok {
|
||||||
if sole := soleUse(caller.Info, pkgName); sole == sel.X {
|
if sole := soleUse(caller.Info, pkgName); sole == sel.X {
|
||||||
for _, spec := range caller.File.Imports {
|
for _, spec := range caller.File.Imports {
|
||||||
pkgName2, ok := importedPkgName(caller.Info, spec)
|
pkgName2, ok := importedPkgName(caller.Info, spec)
|
||||||
|
@ -1263,7 +1263,7 @@ func (st *state) arguments(caller *Caller, calleeDecl *ast.FuncDecl, assign1 fun
|
||||||
|
|
||||||
callArgs := caller.Call.Args
|
callArgs := caller.Call.Args
|
||||||
if calleeDecl.Recv != nil {
|
if calleeDecl.Recv != nil {
|
||||||
sel := astutil.Unparen(caller.Call.Fun).(*ast.SelectorExpr)
|
sel := ast.Unparen(caller.Call.Fun).(*ast.SelectorExpr)
|
||||||
seln := caller.Info.Selections[sel]
|
seln := caller.Info.Selections[sel]
|
||||||
var recvArg ast.Expr
|
var recvArg ast.Expr
|
||||||
switch seln.Kind() {
|
switch seln.Kind() {
|
||||||
|
@ -2227,7 +2227,7 @@ func pure(info *types.Info, assign1 func(*types.Var) bool, e ast.Expr) bool {
|
||||||
// be evaluated at any point--though not necessarily at multiple
|
// be evaluated at any point--though not necessarily at multiple
|
||||||
// points (consider new, make).
|
// points (consider new, make).
|
||||||
func callsPureBuiltin(info *types.Info, call *ast.CallExpr) bool {
|
func callsPureBuiltin(info *types.Info, call *ast.CallExpr) bool {
|
||||||
if id, ok := astutil.Unparen(call.Fun).(*ast.Ident); ok {
|
if id, ok := ast.Unparen(call.Fun).(*ast.Ident); ok {
|
||||||
if b, ok := info.ObjectOf(id).(*types.Builtin); ok {
|
if b, ok := info.ObjectOf(id).(*types.Builtin); ok {
|
||||||
switch b.Name() {
|
switch b.Name() {
|
||||||
case "len", "cap", "complex", "imag", "real", "make", "new", "max", "min":
|
case "len", "cap", "complex", "imag", "real", "make", "new", "max", "min":
|
||||||
|
|
|
@ -43,7 +43,6 @@ import (
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
)
|
)
|
||||||
|
@ -708,7 +707,7 @@ func (f *Finder) stmt(s ast.Stmt) {
|
||||||
|
|
||||||
// -- Plundered from golang.org/x/tools/go/ssa -----------------
|
// -- Plundered from golang.org/x/tools/go/ssa -----------------
|
||||||
|
|
||||||
func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
|
func unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) }
|
||||||
|
|
||||||
func isInterface(T types.Type) bool { return types.IsInterface(T) }
|
func isInterface(T types.Type) bool { return types.IsInterface(T) }
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче