@@ -406,23 +406,38 @@ func unwrapTestingFunctionBuilding(pass *analysis.Pass, expr ast.Expr, testFuncT
406
406
return nil
407
407
}
408
408
409
- funIdent , ok := callExpr .Fun .(* ast.Ident )
410
- if ! ok {
411
- return nil
412
- }
409
+ var funcDecl funcDecl
410
+ switch f := callExpr .Fun .(type ) {
411
+ case * ast.FuncLit :
412
+ funcDecl .Body = f .Body
413
+ funcDecl .Type = f .Type
414
+ case * ast.Ident :
415
+ funObjDecl , ok := f .Obj .Decl .(* ast.FuncDecl )
416
+ if ! ok {
417
+ return nil
418
+ }
413
419
414
- funDecl , ok := funIdent .Obj .Decl .(* ast.FuncDecl )
415
- if ! ok {
420
+ funcDecl .Body = funObjDecl .Body
421
+ funcDecl .Type = funObjDecl .Type
422
+ case * ast.SelectorExpr :
423
+ fd := findSelectroDeclaration (pass , f )
424
+ if fd == nil {
425
+ return nil
426
+ }
427
+
428
+ funcDecl .Body = fd .Body
429
+ funcDecl .Type = fd .Type
430
+ default :
416
431
return nil
417
432
}
418
433
419
- results := funDecl .Type .Results .List
434
+ results := funcDecl .Type .Results .List
420
435
if len (results ) != 1 || ! isExprHasType (pass , results [0 ].Type , testFuncType ) {
421
436
return nil
422
437
}
423
438
424
439
var funcs []ast.Expr
425
- ast .Inspect (funDecl .Body , func (n ast.Node ) bool {
440
+ ast .Inspect (funcDecl .Body , func (n ast.Node ) bool {
426
441
if n == nil {
427
442
return false
428
443
}
@@ -483,3 +498,38 @@ func isExprHasType(pass *analysis.Pass, expr ast.Expr, expType types.Type) bool
483
498
484
499
return types .Identical (typeInfo .Type , expType )
485
500
}
501
+
502
+ // findSelectroDeclaration returns function declaration called by selectro expression.
503
+ func findSelectroDeclaration (pass * analysis.Pass , expr * ast.SelectorExpr ) * ast.FuncDecl {
504
+ xsel , ok := pass .TypesInfo .Selections [expr ]
505
+ if ! ok {
506
+ return nil
507
+ }
508
+
509
+ for _ , file := range pass .Files {
510
+ for _ , decl := range file .Decls {
511
+ fd , ok := decl .(* ast.FuncDecl )
512
+ if ok && fd .Recv != nil && len (fd .Recv .List ) == 1 {
513
+ recvType , ok := fd .Recv .List [0 ].Type .(* ast.Ident )
514
+ if ! ok {
515
+ continue
516
+ }
517
+
518
+ recvObj , ok := pass .TypesInfo .Uses [recvType ]
519
+ if ! ok {
520
+ continue
521
+ }
522
+
523
+ if ! (types .Identical (recvObj .Type (), xsel .Recv ())) {
524
+ continue
525
+ }
526
+
527
+ if fd .Name .Name == expr .Sel .Name {
528
+ return fd
529
+ }
530
+ }
531
+ }
532
+ }
533
+
534
+ return nil
535
+ }
0 commit comments