@@ -1189,7 +1189,7 @@ func (c *gopCompleter) selector(ctx context.Context, sel *ast.SelectorExpr) erro
11891189 return err
11901190 }
11911191 path := string (m .PkgPath )
1192- gopForEachPackageMember (content , func (tok token.Token , id * ast.Ident , fn * ast.FuncDecl ) {
1192+ gopForEachPackageMember (content , func (tok token.Token , id * ast.Ident , fnType * ast.FuncType , isOverload bool ) {
11931193 if atomic .LoadInt32 (& enough ) != 0 {
11941194 return
11951195 }
@@ -1237,7 +1237,7 @@ func (c *gopCompleter) selector(ctx context.Context, sel *ast.SelectorExpr) erro
12371237 }
12381238
12391239 // For functions, add a parameter snippet.
1240- if fn != nil {
1240+ if fnType != nil {
12411241 var sn snippet.Builder
12421242 sn .WriteText (id .Name )
12431243
@@ -1277,18 +1277,23 @@ func (c *gopCompleter) selector(ctx context.Context, sel *ast.SelectorExpr) erro
12771277 }
12781278 }
12791279
1280- paramList ("[" , "]" , typeparams .ForFuncType (fn . Type ))
1281- paramList ("(" , ")" , fn . Type .Params )
1280+ paramList ("[" , "]" , typeparams .ForFuncType (fnType ))
1281+ paramList ("(" , ")" , fnType .Params )
12821282
12831283 item .snippet = & sn
12841284 }
1285+ if isOverload {
1286+ // ast.OverloadFuncDecl
1287+ item .isOverload = true
1288+ item .Detail = "Go+ overload func\n \n " + item .Detail
1289+ }
12851290
12861291 cMu .Lock ()
12871292 c .items = append (c .items , item )
12881293 // goxls func alias
12891294 if tok == token .FUNC {
12901295 if alias , ok := hasAliasName (id .Name ); ok {
1291- noSnip := len (fn . Type .Params .List ) == 0
1296+ noSnip := ! isOverload && len (fnType .Params .List ) == 0
12921297 c .items = append (c .items , cloneAliasItem (item , id .Name , alias , 0.0001 , noSnip ))
12931298 }
12941299 }
@@ -1333,45 +1338,7 @@ func (c *gopCompleter) selector(ctx context.Context, sel *ast.SelectorExpr) erro
13331338 if err := g .Wait (); err != nil {
13341339 return err
13351340 }
1336- // check gop packages index overload
1337- for pkg , items := range recheck .items {
1338- if recheck .pkgs [pkg ] {
1339- names := make (map [string ]bool )
1340- sort .Slice (items , func (i , j int ) bool {
1341- return items [i ].Label < items [j ].Label
1342- })
1343- for _ , item := range items {
1344- id := item .Label [:len (item .Label )- 3 ]
1345- if ! names [id ] {
1346- names [id ] = true
1347- item .isOverload = true
1348- c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , id , 0 , false ))
1349- if alias , ok := hasAliasName (id ); ok {
1350- c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , alias , 0.0001 , item .noSnip ))
1351- }
1352- }
1353- }
1354- } else {
1355- for _ , item := range items {
1356- c .items = append (c .items , item .CompletionItem )
1357- if alias , ok := hasAliasName (item .Label ); ok {
1358- c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , alias , 0.0001 , item .noSnip ))
1359- }
1360- }
1361- }
1362- }
1363- // check gop packages gopo overload
1364- for pkg , items := range recheck .gopo {
1365- if recheck .pkgs [pkg ] {
1366- for _ , item := range items {
1367- c .items = append (c .items , item )
1368- if alias , ok := hasAliasName (item .Label ); ok {
1369- c .items = append (c .items , cloneAliasItem (item , item .Label , alias , 0.0001 , true ))
1370- }
1371- }
1372- }
1373- }
1374-
1341+ recheck .checkOverload (c )
13751342 // In addition, we search in the module cache using goimports.
13761343 ctx , cancel := context .WithCancel (ctx )
13771344 var mu sync.Mutex
@@ -1413,12 +1380,6 @@ type recheckItem struct {
14131380 noSnip bool
14141381}
14151382
1416- type unimportChecked struct {
1417- pkgs map [source.PackagePath ]bool // gop package
1418- items map [source.PackagePath ][]recheckItem // index overload funcs
1419- gopo map [source.PackagePath ][]CompletionItem // gopo overload funcs
1420- }
1421-
14221383func (c * gopCompleter ) packageMembers (pkg * types.Package , score float64 , imp * importInfo , cb func (candidate )) {
14231384 scope := pkg .Scope ()
14241385 for _ , name := range scope .Names () {
@@ -2478,7 +2439,7 @@ Nodes:
24782439// TYPE/VAR/CONST/FUNC declaration in the Go source file, based on a
24792440// quick partial parse. fn is non-nil only for function declarations.
24802441// The AST position information is garbage.
2481- func gopForEachPackageMember (content []byte , f func (tok token.Token , id * ast.Ident , fn * ast.FuncDecl )) {
2442+ func gopForEachPackageMember (content []byte , f func (tok token.Token , id * ast.Ident , fnType * ast.FuncType , isOverload bool )) {
24822443 purged := goxlsastutil .PurgeFuncBodies (content )
24832444 file , _ := parserutil .ParseFile (token .NewFileSet (), "" , purged , 0 )
24842445 for _ , decl := range file .Decls {
@@ -2488,15 +2449,86 @@ func gopForEachPackageMember(content []byte, f func(tok token.Token, id *ast.Ide
24882449 switch spec := spec .(type ) {
24892450 case * ast.ValueSpec : // var/const
24902451 for _ , id := range spec .Names {
2491- f (decl .Tok , id , nil )
2452+ f (decl .Tok , id , nil , false )
24922453 }
24932454 case * ast.TypeSpec :
2494- f (decl .Tok , spec .Name , nil )
2455+ f (decl .Tok , spec .Name , nil , false )
24952456 }
24962457 }
24972458 case * ast.FuncDecl :
24982459 if decl .Recv == nil {
2499- f (token .FUNC , decl .Name , decl )
2460+ f (token .FUNC , decl .Name , decl .Type , false )
2461+ }
2462+ case * ast.OverloadFuncDecl :
2463+ if decl .Recv == nil && ast .IsExported (decl .Name .Name ) {
2464+ var typ * ast.FuncType
2465+ FindType:
2466+ for _ , expr := range decl .Funcs {
2467+ switch expr := expr .(type ) {
2468+ case * ast.Ident :
2469+ if ! ast .IsExported (expr .Name ) {
2470+ continue
2471+ }
2472+ if obj := file .Scope .Lookup (expr .Name ); obj != nil {
2473+ if d , ok := obj .Decl .(* ast.FuncDecl ); ok {
2474+ typ = d .Type
2475+ break FindType
2476+ }
2477+ }
2478+ case * ast.FuncLit :
2479+ typ = expr .Type
2480+ break FindType
2481+ }
2482+ }
2483+ f (token .FUNC , decl .Name , typ , false )
2484+ }
2485+ }
2486+ }
2487+ }
2488+
2489+ type unimportChecked struct {
2490+ pkgs map [source.PackagePath ]bool // gop package
2491+ items map [source.PackagePath ][]recheckItem // index overload funcs
2492+ gopo map [source.PackagePath ][]CompletionItem // gopo overload funcs
2493+ }
2494+
2495+ func (recheck * unimportChecked ) checkOverload (c * gopCompleter ) {
2496+ // check gop package index overload
2497+ for pkg , items := range recheck .items {
2498+ if recheck .pkgs [pkg ] {
2499+ names := make (map [string ]bool )
2500+ sort .Slice (items , func (i , j int ) bool {
2501+ return items [i ].Label < items [j ].Label
2502+ })
2503+ for _ , item := range items {
2504+ id := item .Label [:len (item .Label )- 3 ]
2505+ if ! names [id ] {
2506+ names [id ] = true
2507+ item .isOverload = true
2508+ item .Detail = "Go+ overload func\n \n " + item .Detail
2509+ c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , id , 0 , false ))
2510+ if alias , ok := hasAliasName (id ); ok {
2511+ c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , alias , 0.0001 , item .noSnip ))
2512+ }
2513+ }
2514+ }
2515+ } else {
2516+ for _ , item := range items {
2517+ c .items = append (c .items , item .CompletionItem )
2518+ if alias , ok := hasAliasName (item .Label ); ok {
2519+ c .items = append (c .items , cloneAliasItem (item .CompletionItem , item .Label , alias , 0.0001 , item .noSnip ))
2520+ }
2521+ }
2522+ }
2523+ }
2524+ // check gop package gopo overload
2525+ for pkg , items := range recheck .gopo {
2526+ if recheck .pkgs [pkg ] {
2527+ for _ , item := range items {
2528+ c .items = append (c .items , item )
2529+ if alias , ok := hasAliasName (item .Label ); ok {
2530+ c .items = append (c .items , cloneAliasItem (item , item .Label , alias , 0.0001 , true ))
2531+ }
25002532 }
25012533 }
25022534 }
0 commit comments