@@ -123,7 +123,7 @@ func (info *Info) newFuncInfoInstances(fd *ast.FuncDecl) []*FuncInfo {
123
123
// IsBlocking returns true if the function may contain blocking calls or operations.
124
124
func (info * Info ) IsBlocking (inst typeparams.Instance ) bool {
125
125
if funInfo := info .FuncInfo (inst ); funInfo != nil {
126
- return funInfo .HasBlocking ()
126
+ return funInfo .IsBlocking ()
127
127
}
128
128
panic (fmt .Errorf (`info did not have function declaration instance for %q` , inst ))
129
129
}
@@ -193,7 +193,7 @@ func AnalyzePkg(files []*ast.File, fileSet *token.FileSet, typesInfo *types.Info
193
193
for _ , caller := range info .allInfos {
194
194
// Check calls to named functions and function-typed variables.
195
195
caller .localInstCallees .Iterate (func (callee typeparams.Instance , callSites []astPath ) {
196
- if info .FuncInfo (callee ).HasBlocking () {
196
+ if info .FuncInfo (callee ).IsBlocking () {
197
197
for _ , callSite := range callSites {
198
198
caller .markBlocking (callSite )
199
199
}
@@ -204,7 +204,7 @@ func AnalyzePkg(files []*ast.File, fileSet *token.FileSet, typesInfo *types.Info
204
204
205
205
// Check direct calls to function literals.
206
206
for callee , callSites := range caller .literalFuncCallees {
207
- if info .FuncLitInfo (callee ).HasBlocking () {
207
+ if info .FuncLitInfo (callee ).IsBlocking () {
208
208
for _ , callSite := range callSites {
209
209
caller .markBlocking (callSite )
210
210
}
@@ -267,11 +267,11 @@ type FuncInfo struct {
267
267
visitorStack astPath
268
268
}
269
269
270
- // HasBlocking indicates if this function may block goroutine execution.
270
+ // IsBlocking indicates if this function may block goroutine execution.
271
271
//
272
272
// For example, a channel operation in a function or a call to another
273
273
// possibly blocking function may block the function.
274
- func (fi * FuncInfo ) HasBlocking () bool {
274
+ func (fi * FuncInfo ) IsBlocking () bool {
275
275
return fi == nil || len (fi .Blocking ) != 0
276
276
}
277
277
@@ -397,19 +397,22 @@ func (fi *FuncInfo) visitCallExpr(n *ast.CallExpr) ast.Visitor {
397
397
switch f := astutil .RemoveParens (n .Fun ).(type ) {
398
398
case * ast.Ident :
399
399
fi .callToNamedFunc (fi .instanceForIdent (f ))
400
+ return fi
400
401
case * ast.SelectorExpr :
401
402
if sel := fi .pkgInfo .Selections [f ]; sel != nil {
402
403
if typesutil .IsJsObject (sel .Recv ()) {
403
404
// js.Object methods are known to be non-blocking, but we still must
404
405
// check its arguments.
405
- } else {
406
- // selection is a method call like `foo.Bar()`, where `foo` might
407
- // be generic and needs to be substituted with the type argument.
408
- fi .callToNamedFunc (fi .instanceFoSelection (sel ))
406
+ return fi
409
407
}
410
- } else {
411
- fi .callToNamedFunc (fi .instanceForIdent (f .Sel ))
408
+ // selection is a method call like `foo.Bar()`, where `foo` might
409
+ // be generic and needs to be substituted with the type argument.
410
+ fi .callToNamedFunc (fi .instanceForSelection (sel ))
411
+ return fi
412
412
}
413
+
414
+ fi .callToNamedFunc (fi .instanceForIdent (f .Sel ))
415
+ return fi
413
416
case * ast.FuncLit :
414
417
// Collect info about the function literal itself.
415
418
ast .Walk (fi , n .Fun )
@@ -427,40 +430,43 @@ func (fi *FuncInfo) visitCallExpr(n *ast.CallExpr) ast.Visitor {
427
430
// This is a type conversion to an instance of a generic type,
428
431
// not a call. Type assertion itself is not blocking, but we will
429
432
// visit the input expression.
430
- } else if astutil .IsTypeExpr (f .Index , fi .pkgInfo .Info ) {
433
+ return fi
434
+ }
435
+ if astutil .IsTypeExpr (f .Index , fi .pkgInfo .Info ) {
431
436
// This is a call of an instantiation of a generic function,
432
437
// e.g. `foo[int]` in `func foo[T any]() { ... }; func main() { foo[int]() }`
433
438
fi .callToNamedFunc (fi .instanceForIdent (f .X .(* ast.Ident )))
434
- } else {
435
- // The called function is gotten with an index or key from a map, array, or slice.
436
- // e.g. `m := map[string]func(){}; m["key"]()`, `s := []func(); s[0]()`.
437
- // Since we can't predict if the returned function will be blocking
438
- // or not, we have to be conservative and assume that function might be blocking.
439
- fi .markBlocking (fi .visitorStack )
439
+ return fi
440
440
}
441
+ // The called function is gotten with an index or key from a map, array, or slice.
442
+ // e.g. `m := map[string]func(){}; m["key"]()`, `s := []func(); s[0]()`.
443
+ // Since we can't predict if the returned function will be blocking
444
+ // or not, we have to be conservative and assume that function might be blocking.
445
+ fi .markBlocking (fi .visitorStack )
446
+ return fi
441
447
case * ast.IndexListExpr :
442
448
// Collect info about the instantiated type or function.
443
449
if astutil .IsTypeExpr (f , fi .pkgInfo .Info ) {
444
450
// This is a type conversion to an instance of a generic type,
445
451
// not a call. Type assertion itself is not blocking, but we will
446
452
// visit the input expression.
447
- } else {
448
- // This is a call of an instantiation of a generic function,
449
- // e.g. `foo[int, bool]` in `func foo[T1, T2 any]() { ... }; func main() { foo[int, bool]() }`
450
- fi .callToNamedFunc (fi .instanceForIdent (f .X .(* ast.Ident )))
453
+ return fi
451
454
}
455
+ // This is a call of an instantiation of a generic function,
456
+ // e.g. `foo[int, bool]` in `func foo[T1, T2 any]() { ... }; func main() { foo[int, bool]() }`
457
+ fi .callToNamedFunc (fi .instanceForIdent (f .X .(* ast.Ident )))
458
+ return fi
452
459
default :
453
460
if astutil .IsTypeExpr (f , fi .pkgInfo .Info ) {
454
461
// This is a type conversion, not a call. Type assertion itself is not
455
462
// blocking, but we will visit the input expression.
456
- } else {
457
- // The function is returned by a non-trivial expression. We have to be
458
- // conservative and assume that function might be blocking.
459
- fi .markBlocking (fi .visitorStack )
463
+ return fi
460
464
}
465
+ // The function is returned by a non-trivial expression. We have to be
466
+ // conservative and assume that function might be blocking.
467
+ fi .markBlocking (fi .visitorStack )
468
+ return fi
461
469
}
462
-
463
- return fi
464
470
}
465
471
466
472
func (fi * FuncInfo ) instanceForIdent (fnId * ast.Ident ) typeparams.Instance {
@@ -471,7 +477,7 @@ func (fi *FuncInfo) instanceForIdent(fnId *ast.Ident) typeparams.Instance {
471
477
}
472
478
}
473
479
474
- func (fi * FuncInfo ) instanceFoSelection (sel * types.Selection ) typeparams.Instance {
480
+ func (fi * FuncInfo ) instanceForSelection (sel * types.Selection ) typeparams.Instance {
475
481
if _ , ok := sel .Obj ().Type ().(* types.Signature ); ok {
476
482
// Substitute the selection to ensure that the receiver has the correct
477
483
// type arguments propagated down from the caller.
0 commit comments