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:
Alan Donovan 2024-09-09 14:03:46 -04:00 коммит произвёл Gopher Robot
Родитель c2e057bbd2
Коммит c055e89c76
14 изменённых файлов: 22 добавлений и 42 удалений

Просмотреть файл

@ -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) }