Skip to content

Commit 62a1b26

Browse files
committed
internal/analysisinternal: IsChildOf(Cursor, edge.Kind) bool
This CL promotes a helper function and uses it in place of Cursor.ParentEdge in all appropriate places. It is very convenient when checking a node's parentage in an expression context. Change-Id: I3151cdb3687957905c7d59e57e823926fce847a0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/708957 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent d32fb50 commit 62a1b26

File tree

11 files changed

+71
-80
lines changed

11 files changed

+71
-80
lines changed

go/analysis/passes/inline/gofix.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ func (a *analyzer) inlineAlias(tn *types.TypeName, curId inspector.Cursor) {
300300
// pkg.Id[T]
301301
// pkg.Id[K, V]
302302
var expr ast.Expr = id
303-
if ek, _ := curId.ParentEdge(); ek == edge.SelectorExpr_Sel {
303+
if analysisinternal.IsChildOf(curId, edge.SelectorExpr_Sel) {
304304
curId = curId.Parent()
305305
expr = curId.Node().(ast.Expr)
306306
}
@@ -462,7 +462,7 @@ func (a *analyzer) inlineConst(con *types.Const, cur inspector.Cursor) {
462462
}
463463
// If n is qualified by a package identifier, we'll need the full selector expression.
464464
var expr ast.Expr = n
465-
if ek, _ := cur.ParentEdge(); ek == edge.SelectorExpr_Sel {
465+
if analysisinternal.IsChildOf(cur, edge.SelectorExpr_Sel) {
466466
expr = cur.Parent().Node().(ast.Expr)
467467
}
468468
a.reportInline("constant", "Constant", expr, edits, importPrefix+incon.RHSName)

go/analysis/passes/modernize/errorsastype.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func errorsastype(pass *analysis.Pass) (any, error) {
187187
// declaration of the typed error var. The var must not be
188188
// used outside the if statement.
189189
func canUseErrorsAsType(info *types.Info, index *typeindex.Index, curCall inspector.Cursor) (_ *types.Var, _ inspector.Cursor) {
190-
if ek, _ := curCall.ParentEdge(); ek != edge.IfStmt_Cond {
190+
if !analysisinternal.IsChildOf(curCall, edge.IfStmt_Cond) {
191191
return // not beneath if statement
192192
}
193193
var (
@@ -219,7 +219,7 @@ func canUseErrorsAsType(info *types.Info, index *typeindex.Index, curCall inspec
219219
return // v used before/after if statement
220220
}
221221
}
222-
if ek, _ := curDef.ParentEdge(); ek != edge.ValueSpec_Names {
222+
if !analysisinternal.IsChildOf(curDef, edge.ValueSpec_Names) {
223223
return // v not declared by "var v T"
224224
}
225225
var (

go/analysis/passes/modernize/minmax.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func minmax(pass *analysis.Pass) (any, error) {
213213
// (This case would require introducing another block
214214
// if cond { ... } else { if a < b { lhs = rhs } }
215215
// and checking that there is no following "else".)
216-
if ek, _ := curIfStmt.ParentEdge(); ek == edge.IfStmt_Else {
216+
if analysisinternal.IsChildOf(curIfStmt, edge.IfStmt_Else) {
217217
continue
218218
}
219219

go/analysis/passes/modernize/modernize.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,13 @@ func within(pass *analysis.Pass, pkgs ...string) bool {
126126
moreiters.Contains(stdlib.Dependencies(pkgs...), path)
127127
}
128128

129-
// childOf reports whether cur.ParentEdge is ek.
130-
func childOf(cur inspector.Cursor, ek edge.Kind) bool {
131-
got, _ := cur.ParentEdge()
132-
return got == ek
133-
}
134-
135129
// unparenEnclosing removes enclosing parens from cur in
136130
// preparation for a call to [Cursor.ParentEdge].
137131
func unparenEnclosing(cur inspector.Cursor) inspector.Cursor {
138-
for {
139-
ek, _ := cur.ParentEdge()
140-
if ek != edge.ParenExpr_X {
141-
return cur
142-
}
132+
for analysisinternal.IsChildOf(cur, edge.ParenExpr_X) {
143133
cur = cur.Parent()
144134
}
135+
return cur
145136
}
146137

147138
var (

go/analysis/passes/modernize/reflect.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ func reflecttypefor(pass *analysis.Pass) (any, error) {
5858

5959
// Special case for TypeOf((*T)(nil)).Elem(),
6060
// needed when T is an interface type.
61-
if childOf(curCall, edge.SelectorExpr_X) {
61+
if analysisinternal.IsChildOf(curCall, edge.SelectorExpr_X) {
6262
curSel := unparenEnclosing(curCall).Parent()
63-
if childOf(curSel, edge.CallExpr_Fun) {
63+
if analysisinternal.IsChildOf(curSel, edge.CallExpr_Fun) {
6464
call2 := unparenEnclosing(curSel).Parent().Node().(*ast.CallExpr)
6565
obj := typeutil.Callee(info, call2)
6666
if analysisinternal.IsMethodNamed(obj, "reflect", "Type", "Elem") {

go/analysis/passes/modernize/stditerators.go

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -174,52 +174,50 @@ func stditerators(pass *analysis.Pass) (any, error) {
174174
curCmp = curLenCall.Parent()
175175
cmp = curCmp.Node().(*ast.BinaryExpr)
176176
)
177-
if cmp.Op != token.LSS {
177+
if cmp.Op != token.LSS ||
178+
!analysisinternal.IsChildOf(curCmp, edge.ForStmt_Cond) {
178179
continue
179180
}
180-
if ek, _ := curCmp.ParentEdge(); ek == edge.ForStmt_Cond {
181-
if id, ok := cmp.X.(*ast.Ident); ok {
182-
// Have: for _; i < x.Len(); _ { ... }
183-
var (
184-
v = info.Uses[id].(*types.Var)
185-
curFor = curCmp.Parent()
186-
loop = curFor.Node().(*ast.ForStmt)
187-
)
188-
if v != isIncrementLoop(info, loop) {
189-
continue
190-
}
191-
// Have: for i := 0; i < x.Len(); i++ { ... }.
192-
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193-
194-
rng = analysisinternal.Range(loop.For, loop.Post.End())
195-
indexVar = v
196-
curBody = curFor.ChildAt(edge.ForStmt_Body, -1)
197-
elem, elemVar = chooseName(curBody, lenSel.X, indexVar)
181+
if id, ok := cmp.X.(*ast.Ident); ok {
182+
// Have: for _; i < x.Len(); _ { ... }
183+
var (
184+
v = info.Uses[id].(*types.Var)
185+
curFor = curCmp.Parent()
186+
loop = curFor.Node().(*ast.ForStmt)
187+
)
188+
if v != isIncrementLoop(info, loop) {
189+
continue
190+
}
191+
// Have: for i := 0; i < x.Len(); i++ { ... }.
192+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193+
rng = analysisinternal.Range(loop.For, loop.Post.End())
194+
indexVar = v
195+
curBody = curFor.ChildAt(edge.ForStmt_Body, -1)
196+
elem, elemVar = chooseName(curBody, lenSel.X, indexVar)
198197

199-
// for i := 0; i < x.Len(); i++ {
200-
// ---- ------- --- -----
201-
// for elem := range x.All() {
202-
edits = []analysis.TextEdit{
203-
{
204-
Pos: v.Pos(),
205-
End: v.Pos() + token.Pos(len(v.Name())),
206-
NewText: []byte(elem),
207-
},
208-
{
209-
Pos: loop.Init.(*ast.AssignStmt).Rhs[0].Pos(),
210-
End: cmp.Y.Pos(),
211-
NewText: []byte("range "),
212-
},
213-
{
214-
Pos: lenSel.Sel.Pos(),
215-
End: lenSel.Sel.End(),
216-
NewText: []byte(row.itermethod),
217-
},
218-
{
219-
Pos: curLenCall.Node().End(),
220-
End: loop.Post.End(),
221-
},
222-
}
198+
// for i := 0; i < x.Len(); i++ {
199+
// ---- ------- --- -----
200+
// for elem := range x.All() {
201+
edits = []analysis.TextEdit{
202+
{
203+
Pos: v.Pos(),
204+
End: v.Pos() + token.Pos(len(v.Name())),
205+
NewText: []byte(elem),
206+
},
207+
{
208+
Pos: loop.Init.(*ast.AssignStmt).Rhs[0].Pos(),
209+
End: cmp.Y.Pos(),
210+
NewText: []byte("range "),
211+
},
212+
{
213+
Pos: lenSel.Sel.Pos(),
214+
End: lenSel.Sel.End(),
215+
NewText: []byte(row.itermethod),
216+
},
217+
{
218+
Pos: curLenCall.Node().End(),
219+
End: loop.Post.End(),
220+
},
223221
}
224222
}
225223

gopls/internal/analysis/maprange/maprange.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ func run(pass *analysis.Pass) (any, error) {
4949
)
5050
for _, callee := range []types.Object{mapsKeys, mapsValues, xmapsKeys, xmapsValues} {
5151
for curCall := range index.Calls(callee) {
52-
if ek, _ := curCall.ParentEdge(); ek != edge.RangeStmt_X {
53-
continue
52+
if analysisinternal.IsChildOf(curCall, edge.RangeStmt_X) {
53+
analyzeRangeStmt(pass, callee, curCall)
5454
}
55-
analyzeRangeStmt(pass, callee, curCall)
5655
}
5756
}
5857
return nil, nil

gopls/internal/golang/codeaction.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"golang.org/x/tools/gopls/internal/protocol"
2929
"golang.org/x/tools/gopls/internal/protocol/command"
3030
"golang.org/x/tools/gopls/internal/settings"
31+
"golang.org/x/tools/internal/analysisinternal"
3132
"golang.org/x/tools/internal/event"
3233
"golang.org/x/tools/internal/imports"
3334
"golang.org/x/tools/internal/typesinternal"
@@ -753,7 +754,7 @@ func refactorRewriteEliminateDotImport(ctx context.Context, req *codeActionsRequ
753754
// that reference package-level symbols.
754755
// All other references to a symbol imported from another package
755756
// are nested within a select expression (pkg.Foo, v.Method, v.Field).
756-
if ek, _ := curId.ParentEdge(); ek == edge.SelectorExpr_Sel {
757+
if analysisinternal.IsChildOf(curId, edge.SelectorExpr_Sel) {
757758
continue // qualified identifier (pkg.X) or selector (T.X or e.X)
758759
}
759760
if !typesinternal.IsPackageLevel(use) {

gopls/internal/golang/inline.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"golang.org/x/tools/gopls/internal/cache/parsego"
2323
"golang.org/x/tools/gopls/internal/protocol"
2424
"golang.org/x/tools/gopls/internal/util/safetoken"
25+
"golang.org/x/tools/internal/analysisinternal"
2526
internalastutil "golang.org/x/tools/internal/astutil"
2627
"golang.org/x/tools/internal/diff"
2728
"golang.org/x/tools/internal/event"
@@ -207,13 +208,10 @@ func isLvalueUse(cur inspector.Cursor, info *types.Info) bool {
207208
// unparenEnclosing removes enclosing parens from cur in
208209
// preparation for a call to [Cursor.ParentEdge].
209210
func unparenEnclosing(cur inspector.Cursor) inspector.Cursor {
210-
for {
211-
ek, _ := cur.ParentEdge()
212-
if ek != edge.ParenExpr_X {
213-
return cur
214-
}
211+
for analysisinternal.IsChildOf(cur, edge.ParenExpr_X) {
215212
cur = cur.Parent()
216213
}
214+
return cur
217215
}
218216

219217
// inlineVariableOne computes a fix to replace the selected variable by
@@ -233,7 +231,7 @@ func inlineVariableOne(pkg *cache.Package, pgf *parsego.File, start, end token.P
233231
scope = info.Scopes[pgf.File].Innermost(pos)
234232
)
235233
for curIdent := range curRHS.Preorder((*ast.Ident)(nil)) {
236-
if ek, _ := curIdent.ParentEdge(); ek == edge.SelectorExpr_Sel {
234+
if analysisinternal.IsChildOf(curIdent, edge.SelectorExpr_Sel) {
237235
continue // ignore f in x.f
238236
}
239237
id := curIdent.Node().(*ast.Ident)

gopls/internal/golang/undeclared.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"golang.org/x/tools/gopls/internal/cache/parsego"
2323
"golang.org/x/tools/gopls/internal/util/cursorutil"
2424
"golang.org/x/tools/gopls/internal/util/typesutil"
25+
"golang.org/x/tools/internal/analysisinternal"
2526
"golang.org/x/tools/internal/moreiters"
2627
"golang.org/x/tools/internal/typesinternal"
2728
)
@@ -56,11 +57,7 @@ func undeclaredFixTitle(curId inspector.Cursor, errMsg string) string {
5657
}
5758

5859
// Offer a fix.
59-
noun := "variable"
60-
ek, _ := curId.ParentEdge()
61-
if ek == edge.CallExpr_Fun {
62-
noun = "function"
63-
}
60+
noun := cond(analysisinternal.IsChildOf(curId, edge.CallExpr_Fun), "function", "variable")
6461
return fmt.Sprintf("Create %s %s", noun, name)
6562
}
6663

@@ -80,8 +77,7 @@ func createUndeclared(pkg *cache.Package, pgf *parsego.File, start, end token.Po
8077

8178
// Check for a possible call expression, in which case we should add a
8279
// new function declaration.
83-
ek, _ := curId.ParentEdge()
84-
if ek == edge.CallExpr_Fun {
80+
if analysisinternal.IsChildOf(curId, edge.CallExpr_Fun) {
8581
return newFunctionDeclaration(curId, file, pkg.Types(), info, fset)
8682
}
8783
var (
@@ -101,8 +97,7 @@ func createUndeclared(pkg *cache.Package, pgf *parsego.File, start, end token.Po
10197
n := curRef.Node().(*ast.Ident)
10298
if n.Name == ident.Name && info.ObjectOf(n) == nil {
10399
firstRef = n
104-
ek, _ := curRef.ParentEdge()
105-
if ek == edge.AssignStmt_Lhs {
100+
if analysisinternal.IsChildOf(curRef, edge.AssignStmt_Lhs) {
106101
assign := curRef.Parent().Node().(*ast.AssignStmt)
107102
if assign.Tok == token.ASSIGN && !referencesIdent(info, assign, ident) {
108103
assignTokPos = assign.TokPos

0 commit comments

Comments
 (0)