Skip to content

Commit 3e4c31c

Browse files
committed
gopls/internal/lsp/source/completion: gopForEachPackageMember check ast.OverloadFuncDecl
1 parent 12e1bd3 commit 3e4c31c

2 files changed

Lines changed: 87 additions & 55 deletions

File tree

gopls/internal/lsp/source/completion/completion_gox.go

Lines changed: 86 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
14221383
func (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
}

gopls/internal/lsp/source/completion/format_gox.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Suffixes:
142142
if _, objs := gogen.CheckSigFuncExObjects(sig); len(objs) > 0 {
143143
isOverload = true
144144
var buf bytes.Buffer
145-
buf.WriteString("Go+ overload funcs\n")
145+
buf.WriteString("Go+ overload func\n")
146146
for _, o := range objs {
147147
if isIndexOverload(o.Name(), obj.Name()) {
148148
c.seen[o] = true

0 commit comments

Comments
 (0)