1// Copyright 2018 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Package completion provides core functionality for code completion in Go 6// editors and tools. 7package completion 8 9import ( 10 "context" 11 "fmt" 12 "go/ast" 13 "go/constant" 14 "go/scanner" 15 "go/token" 16 "go/types" 17 "math" 18 "sort" 19 "strconv" 20 "strings" 21 "sync" 22 "time" 23 "unicode" 24 25 "golang.org/x/tools/go/ast/astutil" 26 "golang.org/x/tools/internal/event" 27 "golang.org/x/tools/internal/imports" 28 "golang.org/x/tools/internal/lsp/fuzzy" 29 "golang.org/x/tools/internal/lsp/protocol" 30 "golang.org/x/tools/internal/lsp/snippet" 31 "golang.org/x/tools/internal/lsp/source" 32 errors "golang.org/x/xerrors" 33) 34 35type CompletionItem struct { 36 // Label is the primary text the user sees for this completion item. 37 Label string 38 39 // Detail is supplemental information to present to the user. 40 // This often contains the type or return type of the completion item. 41 Detail string 42 43 // InsertText is the text to insert if this item is selected. 44 // Any of the prefix that has already been typed is not trimmed. 45 // The insert text does not contain snippets. 46 InsertText string 47 48 Kind protocol.CompletionItemKind 49 Tags []protocol.CompletionItemTag 50 Deprecated bool // Deprecated, prefer Tags if available 51 52 // An optional array of additional TextEdits that are applied when 53 // selecting this completion. 54 // 55 // Additional text edits should be used to change text unrelated to the current cursor position 56 // (for example adding an import statement at the top of the file if the completion item will 57 // insert an unqualified type). 58 AdditionalTextEdits []protocol.TextEdit 59 60 // Depth is how many levels were searched to find this completion. 61 // For example when completing "foo<>", "fooBar" is depth 0, and 62 // "fooBar.Baz" is depth 1. 63 Depth int 64 65 // Score is the internal relevance score. 66 // A higher score indicates that this completion item is more relevant. 67 Score float64 68 69 // snippet is the LSP snippet for the completion item. The LSP 70 // specification contains details about LSP snippets. For example, a 71 // snippet for a function with the following signature: 72 // 73 // func foo(a, b, c int) 74 // 75 // would be: 76 // 77 // foo(${1:a int}, ${2: b int}, ${3: c int}) 78 // 79 // If Placeholders is false in the CompletionOptions, the above 80 // snippet would instead be: 81 // 82 // foo(${1:}) 83 snippet *snippet.Builder 84 85 // Documentation is the documentation for the completion item. 86 Documentation string 87 88 // obj is the object from which this candidate was derived, if any. 89 // obj is for internal use only. 90 obj types.Object 91} 92 93// completionOptions holds completion specific configuration. 94type completionOptions struct { 95 unimported bool 96 documentation bool 97 fullDocumentation bool 98 placeholders bool 99 literal bool 100 snippets bool 101 postfix bool 102 matcher source.Matcher 103 budget time.Duration 104} 105 106// Snippet is a convenience returns the snippet if available, otherwise 107// the InsertText. 108// used for an item, depending on if the callee wants placeholders or not. 109func (i *CompletionItem) Snippet() string { 110 if i.snippet != nil { 111 return i.snippet.String() 112 } 113 return i.InsertText 114} 115 116// Scoring constants are used for weighting the relevance of different candidates. 117const ( 118 // stdScore is the base score for all completion items. 119 stdScore float64 = 1.0 120 121 // highScore indicates a very relevant completion item. 122 highScore float64 = 10.0 123 124 // lowScore indicates an irrelevant or not useful completion item. 125 lowScore float64 = 0.01 126) 127 128// matcher matches a candidate's label against the user input. The 129// returned score reflects the quality of the match. A score of zero 130// indicates no match, and a score of one means a perfect match. 131type matcher interface { 132 Score(candidateLabel string) (score float32) 133} 134 135// prefixMatcher implements case sensitive prefix matching. 136type prefixMatcher string 137 138func (pm prefixMatcher) Score(candidateLabel string) float32 { 139 if strings.HasPrefix(candidateLabel, string(pm)) { 140 return 1 141 } 142 return -1 143} 144 145// insensitivePrefixMatcher implements case insensitive prefix matching. 146type insensitivePrefixMatcher string 147 148func (ipm insensitivePrefixMatcher) Score(candidateLabel string) float32 { 149 if strings.HasPrefix(strings.ToLower(candidateLabel), string(ipm)) { 150 return 1 151 } 152 return -1 153} 154 155// completer contains the necessary information for a single completion request. 156type completer struct { 157 snapshot source.Snapshot 158 pkg source.Package 159 qf types.Qualifier 160 opts *completionOptions 161 162 // completionContext contains information about the trigger for this 163 // completion request. 164 completionContext completionContext 165 166 // fh is a handle to the file associated with this completion request. 167 fh source.FileHandle 168 169 // filename is the name of the file associated with this completion request. 170 filename string 171 172 // file is the AST of the file associated with this completion request. 173 file *ast.File 174 175 // pos is the position at which the request was triggered. 176 pos token.Pos 177 178 // path is the path of AST nodes enclosing the position. 179 path []ast.Node 180 181 // seen is the map that ensures we do not return duplicate results. 182 seen map[types.Object]bool 183 184 // items is the list of completion items returned. 185 items []CompletionItem 186 187 // completionCallbacks is a list of callbacks to collect completions that 188 // require expensive operations. This includes operations where we search 189 // through the entire module cache. 190 completionCallbacks []func(opts *imports.Options) error 191 192 // surrounding describes the identifier surrounding the position. 193 surrounding *Selection 194 195 // inference contains information we've inferred about ideal 196 // candidates such as the candidate's type. 197 inference candidateInference 198 199 // enclosingFunc contains information about the function enclosing 200 // the position. 201 enclosingFunc *funcInfo 202 203 // enclosingCompositeLiteral contains information about the composite literal 204 // enclosing the position. 205 enclosingCompositeLiteral *compLitInfo 206 207 // deepState contains the current state of our deep completion search. 208 deepState deepCompletionState 209 210 // matcher matches the candidates against the surrounding prefix. 211 matcher matcher 212 213 // methodSetCache caches the types.NewMethodSet call, which is relatively 214 // expensive and can be called many times for the same type while searching 215 // for deep completions. 216 methodSetCache map[methodSetKey]*types.MethodSet 217 218 // mapper converts the positions in the file from which the completion originated. 219 mapper *protocol.ColumnMapper 220 221 // startTime is when we started processing this completion request. It does 222 // not include any time the request spent in the queue. 223 startTime time.Time 224} 225 226// funcInfo holds info about a function object. 227type funcInfo struct { 228 // sig is the function declaration enclosing the position. 229 sig *types.Signature 230 231 // body is the function's body. 232 body *ast.BlockStmt 233} 234 235type compLitInfo struct { 236 // cl is the *ast.CompositeLit enclosing the position. 237 cl *ast.CompositeLit 238 239 // clType is the type of cl. 240 clType types.Type 241 242 // kv is the *ast.KeyValueExpr enclosing the position, if any. 243 kv *ast.KeyValueExpr 244 245 // inKey is true if we are certain the position is in the key side 246 // of a key-value pair. 247 inKey bool 248 249 // maybeInFieldName is true if inKey is false and it is possible 250 // we are completing a struct field name. For example, 251 // "SomeStruct{<>}" will be inKey=false, but maybeInFieldName=true 252 // because we _could_ be completing a field name. 253 maybeInFieldName bool 254} 255 256type importInfo struct { 257 importPath string 258 name string 259 pkg source.Package 260} 261 262type methodSetKey struct { 263 typ types.Type 264 addressable bool 265} 266 267type completionContext struct { 268 // triggerCharacter is the character used to trigger completion at current 269 // position, if any. 270 triggerCharacter string 271 272 // triggerKind is information about how a completion was triggered. 273 triggerKind protocol.CompletionTriggerKind 274 275 // commentCompletion is true if we are completing a comment. 276 commentCompletion bool 277 278 // packageCompletion is true if we are completing a package name. 279 packageCompletion bool 280} 281 282// A Selection represents the cursor position and surrounding identifier. 283type Selection struct { 284 content string 285 cursor token.Pos 286 source.MappedRange 287} 288 289func (p Selection) Content() string { 290 return p.content 291} 292 293func (p Selection) Start() token.Pos { 294 return p.MappedRange.SpanRange().Start 295} 296 297func (p Selection) End() token.Pos { 298 return p.MappedRange.SpanRange().End 299} 300 301func (p Selection) Prefix() string { 302 return p.content[:p.cursor-p.SpanRange().Start] 303} 304 305func (p Selection) Suffix() string { 306 return p.content[p.cursor-p.SpanRange().Start:] 307} 308 309func (c *completer) setSurrounding(ident *ast.Ident) { 310 if c.surrounding != nil { 311 return 312 } 313 if !(ident.Pos() <= c.pos && c.pos <= ident.End()) { 314 return 315 } 316 317 c.surrounding = &Selection{ 318 content: ident.Name, 319 cursor: c.pos, 320 // Overwrite the prefix only. 321 MappedRange: source.NewMappedRange(c.snapshot.FileSet(), c.mapper, ident.Pos(), ident.End()), 322 } 323 324 c.setMatcherFromPrefix(c.surrounding.Prefix()) 325} 326 327func (c *completer) setMatcherFromPrefix(prefix string) { 328 switch c.opts.matcher { 329 case source.Fuzzy: 330 c.matcher = fuzzy.NewMatcher(prefix) 331 case source.CaseSensitive: 332 c.matcher = prefixMatcher(prefix) 333 default: 334 c.matcher = insensitivePrefixMatcher(strings.ToLower(prefix)) 335 } 336} 337 338func (c *completer) getSurrounding() *Selection { 339 if c.surrounding == nil { 340 c.surrounding = &Selection{ 341 content: "", 342 cursor: c.pos, 343 MappedRange: source.NewMappedRange(c.snapshot.FileSet(), c.mapper, c.pos, c.pos), 344 } 345 } 346 return c.surrounding 347} 348 349// candidate represents a completion candidate. 350type candidate struct { 351 // obj is the types.Object to complete to. 352 obj types.Object 353 354 // score is used to rank candidates. 355 score float64 356 357 // name is the deep object name path, e.g. "foo.bar" 358 name string 359 360 // detail is additional information about this item. If not specified, 361 // defaults to type string for the object. 362 detail string 363 364 // path holds the path from the search root (excluding the candidate 365 // itself) for a deep candidate. 366 path []types.Object 367 368 // names tracks the names of objects from search root (excluding the 369 // candidate itself) for a deep candidate. This also includes 370 // expanded calls for function invocations. 371 names []string 372 373 // expandFuncCall is true if obj should be invoked in the completion. 374 // For example, expandFuncCall=true yields "foo()", expandFuncCall=false yields "foo". 375 expandFuncCall bool 376 377 // takeAddress is true if the completion should take a pointer to obj. 378 // For example, takeAddress=true yields "&foo", takeAddress=false yields "foo". 379 takeAddress bool 380 381 // addressable is true if a pointer can be taken to the candidate. 382 addressable bool 383 384 // makePointer is true if the candidate type name T should be made into *T. 385 makePointer bool 386 387 // dereference is a count of how many times to dereference the candidate obj. 388 // For example, dereference=2 turns "foo" into "**foo" when formatting. 389 dereference int 390 391 // takeSlice is true if obj is an array that should be converted to a slice. 392 takeSlice bool 393 394 // variadic is true if this candidate fills a variadic param and 395 // needs "..." appended. 396 variadic bool 397 398 // convertTo is a type that this candidate should be cast to. For 399 // example, if convertTo is float64, "foo" should be formatted as 400 // "float64(foo)". 401 convertTo types.Type 402 403 // imp is the import that needs to be added to this package in order 404 // for this candidate to be valid. nil if no import needed. 405 imp *importInfo 406} 407 408// ErrIsDefinition is an error that informs the user they got no 409// completions because they tried to complete the name of a new object 410// being defined. 411type ErrIsDefinition struct { 412 objStr string 413} 414 415func (e ErrIsDefinition) Error() string { 416 msg := "this is a definition" 417 if e.objStr != "" { 418 msg += " of " + e.objStr 419 } 420 return msg 421} 422 423// Completion returns a list of possible candidates for completion, given a 424// a file and a position. 425// 426// The selection is computed based on the preceding identifier and can be used by 427// the client to score the quality of the completion. For instance, some clients 428// may tolerate imperfect matches as valid completion results, since users may make typos. 429func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, protoPos protocol.Position, protoContext protocol.CompletionContext) ([]CompletionItem, *Selection, error) { 430 ctx, done := event.Start(ctx, "completion.Completion") 431 defer done() 432 433 startTime := time.Now() 434 435 pkg, pgf, err := source.GetParsedFile(ctx, snapshot, fh, source.NarrowestPackage) 436 if err != nil || pgf.File.Package == token.NoPos { 437 // If we can't parse this file or find position for the package 438 // keyword, it may be missing a package declaration. Try offering 439 // suggestions for the package declaration. 440 // Note that this would be the case even if the keyword 'package' is 441 // present but no package name exists. 442 items, surrounding, innerErr := packageClauseCompletions(ctx, snapshot, fh, protoPos) 443 if innerErr != nil { 444 // return the error for GetParsedFile since it's more relevant in this situation. 445 return nil, nil, errors.Errorf("getting file for Completion: %w (package completions: %v)", err, innerErr) 446 } 447 return items, surrounding, nil 448 } 449 spn, err := pgf.Mapper.PointSpan(protoPos) 450 if err != nil { 451 return nil, nil, err 452 } 453 rng, err := spn.Range(pgf.Mapper.Converter) 454 if err != nil { 455 return nil, nil, err 456 } 457 // Completion is based on what precedes the cursor. 458 // Find the path to the position before pos. 459 path, _ := astutil.PathEnclosingInterval(pgf.File, rng.Start-1, rng.Start-1) 460 if path == nil { 461 return nil, nil, errors.Errorf("cannot find node enclosing position") 462 } 463 464 pos := rng.Start 465 466 // Check if completion at this position is valid. If not, return early. 467 switch n := path[0].(type) { 468 case *ast.BasicLit: 469 // Skip completion inside literals except for ImportSpec 470 if len(path) > 1 { 471 if _, ok := path[1].(*ast.ImportSpec); ok { 472 break 473 } 474 } 475 return nil, nil, nil 476 case *ast.CallExpr: 477 if n.Ellipsis.IsValid() && pos > n.Ellipsis && pos <= n.Ellipsis+token.Pos(len("...")) { 478 // Don't offer completions inside or directly after "...". For 479 // example, don't offer completions at "<>" in "foo(bar...<>"). 480 return nil, nil, nil 481 } 482 case *ast.Ident: 483 // reject defining identifiers 484 if obj, ok := pkg.GetTypesInfo().Defs[n]; ok { 485 if v, ok := obj.(*types.Var); ok && v.IsField() && v.Embedded() { 486 // An anonymous field is also a reference to a type. 487 } else if pgf.File.Name == n { 488 // Don't skip completions if Ident is for package name. 489 break 490 } else { 491 objStr := "" 492 if obj != nil { 493 qual := types.RelativeTo(pkg.GetTypes()) 494 objStr = types.ObjectString(obj, qual) 495 } 496 return nil, nil, ErrIsDefinition{objStr: objStr} 497 } 498 } 499 } 500 501 opts := snapshot.View().Options() 502 c := &completer{ 503 pkg: pkg, 504 snapshot: snapshot, 505 qf: source.Qualifier(pgf.File, pkg.GetTypes(), pkg.GetTypesInfo()), 506 completionContext: completionContext{ 507 triggerCharacter: protoContext.TriggerCharacter, 508 triggerKind: protoContext.TriggerKind, 509 }, 510 fh: fh, 511 filename: fh.URI().Filename(), 512 file: pgf.File, 513 path: path, 514 pos: pos, 515 seen: make(map[types.Object]bool), 516 enclosingFunc: enclosingFunction(path, pkg.GetTypesInfo()), 517 enclosingCompositeLiteral: enclosingCompositeLiteral(path, rng.Start, pkg.GetTypesInfo()), 518 deepState: deepCompletionState{ 519 enabled: opts.DeepCompletion, 520 }, 521 opts: &completionOptions{ 522 matcher: opts.Matcher, 523 unimported: opts.CompleteUnimported, 524 documentation: opts.CompletionDocumentation && opts.HoverKind != source.NoDocumentation, 525 fullDocumentation: opts.HoverKind == source.FullDocumentation, 526 placeholders: opts.UsePlaceholders, 527 literal: opts.LiteralCompletions && opts.InsertTextFormat == protocol.SnippetTextFormat, 528 budget: opts.CompletionBudget, 529 snippets: opts.InsertTextFormat == protocol.SnippetTextFormat, 530 postfix: opts.ExperimentalPostfixCompletions, 531 }, 532 // default to a matcher that always matches 533 matcher: prefixMatcher(""), 534 methodSetCache: make(map[methodSetKey]*types.MethodSet), 535 mapper: pgf.Mapper, 536 startTime: startTime, 537 } 538 539 var cancel context.CancelFunc 540 if c.opts.budget == 0 { 541 ctx, cancel = context.WithCancel(ctx) 542 } else { 543 // timeoutDuration is the completion budget remaining. If less than 544 // 10ms, set to 10ms 545 timeoutDuration := time.Until(c.startTime.Add(c.opts.budget)) 546 if timeoutDuration < 10*time.Millisecond { 547 timeoutDuration = 10 * time.Millisecond 548 } 549 ctx, cancel = context.WithTimeout(ctx, timeoutDuration) 550 } 551 defer cancel() 552 553 if surrounding := c.containingIdent(pgf.Src); surrounding != nil { 554 c.setSurrounding(surrounding) 555 } 556 557 c.inference = expectedCandidate(ctx, c) 558 559 err = c.collectCompletions(ctx) 560 if err != nil { 561 return nil, nil, err 562 } 563 564 // Deep search collected candidates and their members for more candidates. 565 c.deepSearch(ctx) 566 c.deepState.searchQueue = nil 567 568 for _, callback := range c.completionCallbacks { 569 if err := c.snapshot.RunProcessEnvFunc(ctx, callback); err != nil { 570 return nil, nil, err 571 } 572 } 573 574 // Search candidates populated by expensive operations like 575 // unimportedMembers etc. for more completion items. 576 c.deepSearch(ctx) 577 578 // Statement candidates offer an entire statement in certain contexts, as 579 // opposed to a single object. Add statement candidates last because they 580 // depend on other candidates having already been collected. 581 c.addStatementCandidates() 582 583 c.sortItems() 584 return c.items, c.getSurrounding(), nil 585} 586 587// collectCompletions adds possible completion candidates to either the deep 588// search queue or completion items directly for different completion contexts. 589func (c *completer) collectCompletions(ctx context.Context) error { 590 // Inside import blocks, return completions for unimported packages. 591 for _, importSpec := range c.file.Imports { 592 if !(importSpec.Path.Pos() <= c.pos && c.pos <= importSpec.Path.End()) { 593 continue 594 } 595 return c.populateImportCompletions(ctx, importSpec) 596 } 597 598 // Inside comments, offer completions for the name of the relevant symbol. 599 for _, comment := range c.file.Comments { 600 if comment.Pos() < c.pos && c.pos <= comment.End() { 601 c.populateCommentCompletions(ctx, comment) 602 return nil 603 } 604 } 605 606 // Struct literals are handled entirely separately. 607 if c.wantStructFieldCompletions() { 608 // If we are definitely completing a struct field name, deep completions 609 // don't make sense. 610 if c.enclosingCompositeLiteral.inKey { 611 c.deepState.enabled = false 612 } 613 return c.structLiteralFieldName(ctx) 614 } 615 616 if lt := c.wantLabelCompletion(); lt != labelNone { 617 c.labels(lt) 618 return nil 619 } 620 621 if c.emptySwitchStmt() { 622 // Empty switch statements only admit "default" and "case" keywords. 623 c.addKeywordItems(map[string]bool{}, highScore, CASE, DEFAULT) 624 return nil 625 } 626 627 switch n := c.path[0].(type) { 628 case *ast.Ident: 629 if c.file.Name == n { 630 return c.packageNameCompletions(ctx, c.fh.URI(), n) 631 } else if sel, ok := c.path[1].(*ast.SelectorExpr); ok && sel.Sel == n { 632 // Is this the Sel part of a selector? 633 return c.selector(ctx, sel) 634 } 635 return c.lexical(ctx) 636 // The function name hasn't been typed yet, but the parens are there: 637 // recv.‸(arg) 638 case *ast.TypeAssertExpr: 639 // Create a fake selector expression. 640 return c.selector(ctx, &ast.SelectorExpr{X: n.X}) 641 case *ast.SelectorExpr: 642 return c.selector(ctx, n) 643 // At the file scope, only keywords are allowed. 644 case *ast.BadDecl, *ast.File: 645 c.addKeywordCompletions() 646 default: 647 // fallback to lexical completions 648 return c.lexical(ctx) 649 } 650 651 return nil 652} 653 654// containingIdent returns the *ast.Ident containing pos, if any. It 655// synthesizes an *ast.Ident to allow completion in the face of 656// certain syntax errors. 657func (c *completer) containingIdent(src []byte) *ast.Ident { 658 // In the normal case, our leaf AST node is the identifer being completed. 659 if ident, ok := c.path[0].(*ast.Ident); ok { 660 return ident 661 } 662 663 pos, tkn, lit := c.scanToken(src) 664 if !pos.IsValid() { 665 return nil 666 } 667 668 fakeIdent := &ast.Ident{Name: lit, NamePos: pos} 669 670 if _, isBadDecl := c.path[0].(*ast.BadDecl); isBadDecl { 671 // You don't get *ast.Idents at the file level, so look for bad 672 // decls and use the manually extracted token. 673 return fakeIdent 674 } else if c.emptySwitchStmt() { 675 // Only keywords are allowed in empty switch statements. 676 // *ast.Idents are not parsed, so we must use the manually 677 // extracted token. 678 return fakeIdent 679 } else if tkn.IsKeyword() { 680 // Otherwise, manually extract the prefix if our containing token 681 // is a keyword. This improves completion after an "accidental 682 // keyword", e.g. completing to "variance" in "someFunc(var<>)". 683 return fakeIdent 684 } 685 686 return nil 687} 688 689// scanToken scans pgh's contents for the token containing pos. 690func (c *completer) scanToken(contents []byte) (token.Pos, token.Token, string) { 691 tok := c.snapshot.FileSet().File(c.pos) 692 693 var s scanner.Scanner 694 s.Init(tok, contents, nil, 0) 695 for { 696 tknPos, tkn, lit := s.Scan() 697 if tkn == token.EOF || tknPos >= c.pos { 698 return token.NoPos, token.ILLEGAL, "" 699 } 700 701 if len(lit) > 0 && tknPos <= c.pos && c.pos <= tknPos+token.Pos(len(lit)) { 702 return tknPos, tkn, lit 703 } 704 } 705} 706 707func (c *completer) sortItems() { 708 sort.SliceStable(c.items, func(i, j int) bool { 709 // Sort by score first. 710 if c.items[i].Score != c.items[j].Score { 711 return c.items[i].Score > c.items[j].Score 712 } 713 714 // Then sort by label so order stays consistent. This also has the 715 // effect of preferring shorter candidates. 716 return c.items[i].Label < c.items[j].Label 717 }) 718} 719 720// emptySwitchStmt reports whether pos is in an empty switch or select 721// statement. 722func (c *completer) emptySwitchStmt() bool { 723 block, ok := c.path[0].(*ast.BlockStmt) 724 if !ok || len(block.List) > 0 || len(c.path) == 1 { 725 return false 726 } 727 728 switch c.path[1].(type) { 729 case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt: 730 return true 731 default: 732 return false 733 } 734} 735 736// populateImportCompletions yields completions for an import path around the cursor. 737// 738// Completions are suggested at the directory depth of the given import path so 739// that we don't overwhelm the user with a large list of possibilities. As an 740// example, a completion for the prefix "golang" results in "golang.org/". 741// Completions for "golang.org/" yield its subdirectories 742// (i.e. "golang.org/x/"). The user is meant to accept completion suggestions 743// until they reach a complete import path. 744func (c *completer) populateImportCompletions(ctx context.Context, searchImport *ast.ImportSpec) error { 745 if !strings.HasPrefix(searchImport.Path.Value, `"`) { 746 return nil 747 } 748 749 // deepSearch is not valuable for import completions. 750 c.deepState.enabled = false 751 752 importPath := searchImport.Path.Value 753 754 // Extract the text between the quotes (if any) in an import spec. 755 // prefix is the part of import path before the cursor. 756 prefixEnd := c.pos - searchImport.Path.Pos() 757 prefix := strings.Trim(importPath[:prefixEnd], `"`) 758 759 // The number of directories in the import path gives us the depth at 760 // which to search. 761 depth := len(strings.Split(prefix, "/")) - 1 762 763 content := importPath 764 start, end := searchImport.Path.Pos(), searchImport.Path.End() 765 namePrefix, nameSuffix := `"`, `"` 766 // If a starting quote is present, adjust surrounding to either after the 767 // cursor or after the first slash (/), except if cursor is at the starting 768 // quote. Otherwise we provide a completion including the starting quote. 769 if strings.HasPrefix(importPath, `"`) && c.pos > searchImport.Path.Pos() { 770 content = content[1:] 771 start++ 772 if depth > 0 { 773 // Adjust textEdit start to replacement range. For ex: if current 774 // path was "golang.or/x/to<>ols/internal/", where <> is the cursor 775 // position, start of the replacement range would be after 776 // "golang.org/x/". 777 path := strings.SplitAfter(prefix, "/") 778 numChars := len(strings.Join(path[:len(path)-1], "")) 779 content = content[numChars:] 780 start += token.Pos(numChars) 781 } 782 namePrefix = "" 783 } 784 785 // We won't provide an ending quote if one is already present, except if 786 // cursor is after the ending quote but still in import spec. This is 787 // because cursor has to be in our textEdit range. 788 if strings.HasSuffix(importPath, `"`) && c.pos < searchImport.Path.End() { 789 end-- 790 content = content[:len(content)-1] 791 nameSuffix = "" 792 } 793 794 c.surrounding = &Selection{ 795 content: content, 796 cursor: c.pos, 797 MappedRange: source.NewMappedRange(c.snapshot.FileSet(), c.mapper, start, end), 798 } 799 800 seenImports := make(map[string]struct{}) 801 for _, importSpec := range c.file.Imports { 802 if importSpec.Path.Value == importPath { 803 continue 804 } 805 seenImportPath, err := strconv.Unquote(importSpec.Path.Value) 806 if err != nil { 807 return err 808 } 809 seenImports[seenImportPath] = struct{}{} 810 } 811 812 var mu sync.Mutex // guard c.items locally, since searchImports is called in parallel 813 seen := make(map[string]struct{}) 814 searchImports := func(pkg imports.ImportFix) { 815 path := pkg.StmtInfo.ImportPath 816 if _, ok := seenImports[path]; ok { 817 return 818 } 819 820 // Any package path containing fewer directories than the search 821 // prefix is not a match. 822 pkgDirList := strings.Split(path, "/") 823 if len(pkgDirList) < depth+1 { 824 return 825 } 826 pkgToConsider := strings.Join(pkgDirList[:depth+1], "/") 827 828 name := pkgDirList[depth] 829 // if we're adding an opening quote to completion too, set name to full 830 // package path since we'll need to overwrite that range. 831 if namePrefix == `"` { 832 name = pkgToConsider 833 } 834 835 score := pkg.Relevance 836 if len(pkgDirList)-1 == depth { 837 score *= highScore 838 } else { 839 // For incomplete package paths, add a terminal slash to indicate that the 840 // user should keep triggering completions. 841 name += "/" 842 pkgToConsider += "/" 843 } 844 845 if _, ok := seen[pkgToConsider]; ok { 846 return 847 } 848 seen[pkgToConsider] = struct{}{} 849 850 mu.Lock() 851 defer mu.Unlock() 852 853 name = namePrefix + name + nameSuffix 854 obj := types.NewPkgName(0, nil, name, types.NewPackage(pkgToConsider, name)) 855 c.deepState.enqueue(candidate{ 856 obj: obj, 857 detail: fmt.Sprintf("%q", pkgToConsider), 858 score: score, 859 }) 860 } 861 862 c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { 863 return imports.GetImportPaths(ctx, searchImports, prefix, c.filename, c.pkg.GetTypes().Name(), opts.Env) 864 }) 865 return nil 866} 867 868// populateCommentCompletions yields completions for comments preceding or in declarations. 869func (c *completer) populateCommentCompletions(ctx context.Context, comment *ast.CommentGroup) { 870 // If the completion was triggered by a period, ignore it. These types of 871 // completions will not be useful in comments. 872 if c.completionContext.triggerCharacter == "." { 873 return 874 } 875 876 // Using the comment position find the line after 877 file := c.snapshot.FileSet().File(comment.End()) 878 if file == nil { 879 return 880 } 881 882 // Deep completion doesn't work properly in comments since we don't 883 // have a type object to complete further. 884 c.deepState.enabled = false 885 c.completionContext.commentCompletion = true 886 887 // Documentation isn't useful in comments, since it might end up being the 888 // comment itself. 889 c.opts.documentation = false 890 891 commentLine := file.Line(comment.End()) 892 893 // comment is valid, set surrounding as word boundaries around cursor 894 c.setSurroundingForComment(comment) 895 896 // Using the next line pos, grab and parse the exported symbol on that line 897 for _, n := range c.file.Decls { 898 declLine := file.Line(n.Pos()) 899 // if the comment is not in, directly above or on the same line as a declaration 900 if declLine != commentLine && declLine != commentLine+1 && 901 !(n.Pos() <= comment.Pos() && comment.End() <= n.End()) { 902 continue 903 } 904 switch node := n.(type) { 905 // handle const, vars, and types 906 case *ast.GenDecl: 907 for _, spec := range node.Specs { 908 switch spec := spec.(type) { 909 case *ast.ValueSpec: 910 for _, name := range spec.Names { 911 if name.String() == "_" { 912 continue 913 } 914 obj := c.pkg.GetTypesInfo().ObjectOf(name) 915 c.deepState.enqueue(candidate{obj: obj, score: stdScore}) 916 } 917 case *ast.TypeSpec: 918 // add TypeSpec fields to completion 919 switch typeNode := spec.Type.(type) { 920 case *ast.StructType: 921 c.addFieldItems(ctx, typeNode.Fields) 922 case *ast.FuncType: 923 c.addFieldItems(ctx, typeNode.Params) 924 c.addFieldItems(ctx, typeNode.Results) 925 case *ast.InterfaceType: 926 c.addFieldItems(ctx, typeNode.Methods) 927 } 928 929 if spec.Name.String() == "_" { 930 continue 931 } 932 933 obj := c.pkg.GetTypesInfo().ObjectOf(spec.Name) 934 // Type name should get a higher score than fields but not highScore by default 935 // since field near a comment cursor gets a highScore 936 score := stdScore * 1.1 937 // If type declaration is on the line after comment, give it a highScore. 938 if declLine == commentLine+1 { 939 score = highScore 940 } 941 942 c.deepState.enqueue(candidate{obj: obj, score: score}) 943 } 944 } 945 // handle functions 946 case *ast.FuncDecl: 947 c.addFieldItems(ctx, node.Recv) 948 c.addFieldItems(ctx, node.Type.Params) 949 c.addFieldItems(ctx, node.Type.Results) 950 951 // collect receiver struct fields 952 if node.Recv != nil { 953 for _, fields := range node.Recv.List { 954 for _, name := range fields.Names { 955 obj := c.pkg.GetTypesInfo().ObjectOf(name) 956 if obj == nil { 957 continue 958 } 959 960 recvType := obj.Type().Underlying() 961 if ptr, ok := recvType.(*types.Pointer); ok { 962 recvType = ptr.Elem() 963 } 964 recvStruct, ok := recvType.Underlying().(*types.Struct) 965 if !ok { 966 continue 967 } 968 for i := 0; i < recvStruct.NumFields(); i++ { 969 field := recvStruct.Field(i) 970 c.deepState.enqueue(candidate{obj: field, score: lowScore}) 971 } 972 } 973 } 974 } 975 976 if node.Name.String() == "_" { 977 continue 978 } 979 980 obj := c.pkg.GetTypesInfo().ObjectOf(node.Name) 981 if obj == nil || obj.Pkg() != nil && obj.Pkg() != c.pkg.GetTypes() { 982 continue 983 } 984 985 c.deepState.enqueue(candidate{obj: obj, score: highScore}) 986 } 987 } 988} 989 990// sets word boundaries surrounding a cursor for a comment 991func (c *completer) setSurroundingForComment(comments *ast.CommentGroup) { 992 var cursorComment *ast.Comment 993 for _, comment := range comments.List { 994 if c.pos >= comment.Pos() && c.pos <= comment.End() { 995 cursorComment = comment 996 break 997 } 998 } 999 // if cursor isn't in the comment 1000 if cursorComment == nil { 1001 return 1002 } 1003 1004 // index of cursor in comment text 1005 cursorOffset := int(c.pos - cursorComment.Pos()) 1006 start, end := cursorOffset, cursorOffset 1007 for start > 0 && isValidIdentifierChar(cursorComment.Text[start-1]) { 1008 start-- 1009 } 1010 for end < len(cursorComment.Text) && isValidIdentifierChar(cursorComment.Text[end]) { 1011 end++ 1012 } 1013 1014 c.surrounding = &Selection{ 1015 content: cursorComment.Text[start:end], 1016 cursor: c.pos, 1017 MappedRange: source.NewMappedRange(c.snapshot.FileSet(), c.mapper, 1018 token.Pos(int(cursorComment.Slash)+start), token.Pos(int(cursorComment.Slash)+end)), 1019 } 1020 c.setMatcherFromPrefix(c.surrounding.Prefix()) 1021} 1022 1023// isValidIdentifierChar returns true if a byte is a valid go identifier 1024// character, i.e. unicode letter or digit or underscore. 1025func isValidIdentifierChar(char byte) bool { 1026 charRune := rune(char) 1027 return unicode.In(charRune, unicode.Letter, unicode.Digit) || char == '_' 1028} 1029 1030// adds struct fields, interface methods, function declaration fields to completion 1031func (c *completer) addFieldItems(ctx context.Context, fields *ast.FieldList) { 1032 if fields == nil { 1033 return 1034 } 1035 1036 cursor := c.surrounding.cursor 1037 for _, field := range fields.List { 1038 for _, name := range field.Names { 1039 if name.String() == "_" { 1040 continue 1041 } 1042 obj := c.pkg.GetTypesInfo().ObjectOf(name) 1043 if obj == nil { 1044 continue 1045 } 1046 1047 // if we're in a field comment/doc, score that field as more relevant 1048 score := stdScore 1049 if field.Comment != nil && field.Comment.Pos() <= cursor && cursor <= field.Comment.End() { 1050 score = highScore 1051 } else if field.Doc != nil && field.Doc.Pos() <= cursor && cursor <= field.Doc.End() { 1052 score = highScore 1053 } 1054 1055 c.deepState.enqueue(candidate{obj: obj, score: score}) 1056 } 1057 } 1058} 1059 1060func (c *completer) wantStructFieldCompletions() bool { 1061 clInfo := c.enclosingCompositeLiteral 1062 if clInfo == nil { 1063 return false 1064 } 1065 1066 return clInfo.isStruct() && (clInfo.inKey || clInfo.maybeInFieldName) 1067} 1068 1069func (c *completer) wantTypeName() bool { 1070 return !c.completionContext.commentCompletion && c.inference.typeName.wantTypeName 1071} 1072 1073// See https://golang.org/issue/36001. Unimported completions are expensive. 1074const ( 1075 maxUnimportedPackageNames = 5 1076 unimportedMemberTarget = 100 1077) 1078 1079// selector finds completions for the specified selector expression. 1080func (c *completer) selector(ctx context.Context, sel *ast.SelectorExpr) error { 1081 c.inference.objChain = objChain(c.pkg.GetTypesInfo(), sel.X) 1082 1083 // Is sel a qualified identifier? 1084 if id, ok := sel.X.(*ast.Ident); ok { 1085 if pkgName, ok := c.pkg.GetTypesInfo().Uses[id].(*types.PkgName); ok { 1086 var pkg source.Package 1087 for _, imp := range c.pkg.Imports() { 1088 if imp.PkgPath() == pkgName.Imported().Path() { 1089 pkg = imp 1090 } 1091 } 1092 // If the package is not imported, try searching for unimported 1093 // completions. 1094 if pkg == nil && c.opts.unimported { 1095 if err := c.unimportedMembers(ctx, id); err != nil { 1096 return err 1097 } 1098 } 1099 candidates := c.packageMembers(pkgName.Imported(), stdScore, nil) 1100 for _, cand := range candidates { 1101 c.deepState.enqueue(cand) 1102 } 1103 return nil 1104 } 1105 } 1106 1107 // Invariant: sel is a true selector. 1108 tv, ok := c.pkg.GetTypesInfo().Types[sel.X] 1109 if ok { 1110 candidates := c.methodsAndFields(tv.Type, tv.Addressable(), nil) 1111 for _, cand := range candidates { 1112 c.deepState.enqueue(cand) 1113 } 1114 1115 c.addPostfixSnippetCandidates(ctx, sel) 1116 1117 return nil 1118 } 1119 1120 // Try unimported packages. 1121 if id, ok := sel.X.(*ast.Ident); ok && c.opts.unimported { 1122 if err := c.unimportedMembers(ctx, id); err != nil { 1123 return err 1124 } 1125 } 1126 return nil 1127} 1128 1129func (c *completer) unimportedMembers(ctx context.Context, id *ast.Ident) error { 1130 // Try loaded packages first. They're relevant, fast, and fully typed. 1131 known, err := c.snapshot.CachedImportPaths(ctx) 1132 if err != nil { 1133 return err 1134 } 1135 1136 var paths []string 1137 for path, pkg := range known { 1138 if pkg.GetTypes().Name() != id.Name { 1139 continue 1140 } 1141 paths = append(paths, path) 1142 } 1143 1144 var relevances map[string]float64 1145 if len(paths) != 0 { 1146 if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error { 1147 var err error 1148 relevances, err = imports.ScoreImportPaths(ctx, opts.Env, paths) 1149 return err 1150 }); err != nil { 1151 return err 1152 } 1153 } 1154 sort.Slice(paths, func(i, j int) bool { 1155 return relevances[paths[i]] > relevances[paths[j]] 1156 }) 1157 1158 for _, path := range paths { 1159 pkg := known[path] 1160 if pkg.GetTypes().Name() != id.Name { 1161 continue 1162 } 1163 imp := &importInfo{ 1164 importPath: path, 1165 pkg: pkg, 1166 } 1167 if imports.ImportPathToAssumedName(path) != pkg.GetTypes().Name() { 1168 imp.name = pkg.GetTypes().Name() 1169 } 1170 candidates := c.packageMembers(pkg.GetTypes(), unimportedScore(relevances[path]), imp) 1171 for _, cand := range candidates { 1172 c.deepState.enqueue(cand) 1173 } 1174 if len(c.items) >= unimportedMemberTarget { 1175 return nil 1176 } 1177 } 1178 1179 ctx, cancel := context.WithCancel(ctx) 1180 1181 var mu sync.Mutex 1182 add := func(pkgExport imports.PackageExport) { 1183 mu.Lock() 1184 defer mu.Unlock() 1185 if _, ok := known[pkgExport.Fix.StmtInfo.ImportPath]; ok { 1186 return // We got this one above. 1187 } 1188 1189 // Continue with untyped proposals. 1190 pkg := types.NewPackage(pkgExport.Fix.StmtInfo.ImportPath, pkgExport.Fix.IdentName) 1191 for _, export := range pkgExport.Exports { 1192 score := unimportedScore(pkgExport.Fix.Relevance) 1193 c.deepState.enqueue(candidate{ 1194 obj: types.NewVar(0, pkg, export, nil), 1195 score: score, 1196 imp: &importInfo{ 1197 importPath: pkgExport.Fix.StmtInfo.ImportPath, 1198 name: pkgExport.Fix.StmtInfo.Name, 1199 }, 1200 }) 1201 } 1202 if len(c.items) >= unimportedMemberTarget { 1203 cancel() 1204 } 1205 } 1206 1207 c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { 1208 defer cancel() 1209 return imports.GetPackageExports(ctx, add, id.Name, c.filename, c.pkg.GetTypes().Name(), opts.Env) 1210 }) 1211 return nil 1212} 1213 1214// unimportedScore returns a score for an unimported package that is generally 1215// lower than other candidates. 1216func unimportedScore(relevance float64) float64 { 1217 return (stdScore + .1*relevance) / 2 1218} 1219 1220func (c *completer) packageMembers(pkg *types.Package, score float64, imp *importInfo) []candidate { 1221 var candidates []candidate 1222 scope := pkg.Scope() 1223 for _, name := range scope.Names() { 1224 obj := scope.Lookup(name) 1225 candidates = append(candidates, candidate{ 1226 obj: obj, 1227 score: score, 1228 imp: imp, 1229 addressable: isVar(obj), 1230 }) 1231 } 1232 return candidates 1233} 1234 1235func (c *completer) methodsAndFields(typ types.Type, addressable bool, imp *importInfo) []candidate { 1236 mset := c.methodSetCache[methodSetKey{typ, addressable}] 1237 if mset == nil { 1238 if addressable && !types.IsInterface(typ) && !isPointer(typ) { 1239 // Add methods of *T, which includes methods with receiver T. 1240 mset = types.NewMethodSet(types.NewPointer(typ)) 1241 } else { 1242 // Add methods of T. 1243 mset = types.NewMethodSet(typ) 1244 } 1245 c.methodSetCache[methodSetKey{typ, addressable}] = mset 1246 } 1247 1248 var candidates []candidate 1249 for i := 0; i < mset.Len(); i++ { 1250 candidates = append(candidates, candidate{ 1251 obj: mset.At(i).Obj(), 1252 score: stdScore, 1253 imp: imp, 1254 addressable: addressable || isPointer(typ), 1255 }) 1256 } 1257 1258 // Add fields of T. 1259 eachField(typ, func(v *types.Var) { 1260 candidates = append(candidates, candidate{ 1261 obj: v, 1262 score: stdScore - 0.01, 1263 imp: imp, 1264 addressable: addressable || isPointer(typ), 1265 }) 1266 }) 1267 1268 return candidates 1269} 1270 1271// lexical finds completions in the lexical environment. 1272func (c *completer) lexical(ctx context.Context) error { 1273 scopes := source.CollectScopes(c.pkg.GetTypesInfo(), c.path, c.pos) 1274 scopes = append(scopes, c.pkg.GetTypes().Scope(), types.Universe) 1275 1276 var ( 1277 builtinIota = types.Universe.Lookup("iota") 1278 builtinNil = types.Universe.Lookup("nil") 1279 // comparable is an interface that exists on the dev.typeparams Go branch. 1280 // Filter it out from completion results to stabilize tests. 1281 // TODO(rFindley) update (or remove) our handling for comparable once the 1282 // type parameter API has stabilized. 1283 builtinComparable = types.Universe.Lookup("comparable") 1284 ) 1285 1286 // Track seen variables to avoid showing completions for shadowed variables. 1287 // This works since we look at scopes from innermost to outermost. 1288 seen := make(map[string]struct{}) 1289 1290 // Process scopes innermost first. 1291 for i, scope := range scopes { 1292 if scope == nil { 1293 continue 1294 } 1295 1296 Names: 1297 for _, name := range scope.Names() { 1298 declScope, obj := scope.LookupParent(name, c.pos) 1299 if declScope != scope { 1300 continue // Name was declared in some enclosing scope, or not at all. 1301 } 1302 if obj == builtinComparable { 1303 continue 1304 } 1305 1306 // If obj's type is invalid, find the AST node that defines the lexical block 1307 // containing the declaration of obj. Don't resolve types for packages. 1308 if !isPkgName(obj) && !typeIsValid(obj.Type()) { 1309 // Match the scope to its ast.Node. If the scope is the package scope, 1310 // use the *ast.File as the starting node. 1311 var node ast.Node 1312 if i < len(c.path) { 1313 node = c.path[i] 1314 } else if i == len(c.path) { // use the *ast.File for package scope 1315 node = c.path[i-1] 1316 } 1317 if node != nil { 1318 if resolved := resolveInvalid(c.snapshot.FileSet(), obj, node, c.pkg.GetTypesInfo()); resolved != nil { 1319 obj = resolved 1320 } 1321 } 1322 } 1323 1324 // Don't use LHS of decl in RHS. 1325 for _, ident := range enclosingDeclLHS(c.path) { 1326 if obj.Pos() == ident.Pos() { 1327 continue Names 1328 } 1329 } 1330 1331 // Don't suggest "iota" outside of const decls. 1332 if obj == builtinIota && !c.inConstDecl() { 1333 continue 1334 } 1335 1336 // Rank outer scopes lower than inner. 1337 score := stdScore * math.Pow(.99, float64(i)) 1338 1339 // Dowrank "nil" a bit so it is ranked below more interesting candidates. 1340 if obj == builtinNil { 1341 score /= 2 1342 } 1343 1344 // If we haven't already added a candidate for an object with this name. 1345 if _, ok := seen[obj.Name()]; !ok { 1346 seen[obj.Name()] = struct{}{} 1347 c.deepState.enqueue(candidate{ 1348 obj: obj, 1349 score: score, 1350 addressable: isVar(obj), 1351 }) 1352 } 1353 } 1354 } 1355 1356 if c.inference.objType != nil { 1357 if named, _ := source.Deref(c.inference.objType).(*types.Named); named != nil { 1358 // If we expected a named type, check the type's package for 1359 // completion items. This is useful when the current file hasn't 1360 // imported the type's package yet. 1361 1362 if named.Obj() != nil && named.Obj().Pkg() != nil { 1363 pkg := named.Obj().Pkg() 1364 1365 // Make sure the package name isn't already in use by another 1366 // object, and that this file doesn't import the package yet. 1367 if _, ok := seen[pkg.Name()]; !ok && pkg != c.pkg.GetTypes() && !alreadyImports(c.file, pkg.Path()) { 1368 seen[pkg.Name()] = struct{}{} 1369 obj := types.NewPkgName(0, nil, pkg.Name(), pkg) 1370 imp := &importInfo{ 1371 importPath: pkg.Path(), 1372 } 1373 if imports.ImportPathToAssumedName(pkg.Path()) != pkg.Name() { 1374 imp.name = pkg.Name() 1375 } 1376 c.deepState.enqueue(candidate{ 1377 obj: obj, 1378 score: stdScore, 1379 imp: imp, 1380 }) 1381 } 1382 } 1383 } 1384 } 1385 1386 if c.opts.unimported { 1387 if err := c.unimportedPackages(ctx, seen); err != nil { 1388 return err 1389 } 1390 } 1391 1392 if t := c.inference.objType; t != nil { 1393 t = source.Deref(t) 1394 1395 // If we have an expected type and it is _not_ a named type, 1396 // handle it specially. Non-named types like "[]int" will never be 1397 // considered via a lexical search, so we need to directly inject 1398 // them. 1399 if _, named := t.(*types.Named); !named { 1400 // If our expected type is "[]int", this will add a literal 1401 // candidate of "[]int{}". 1402 c.literal(ctx, t, nil) 1403 1404 if _, isBasic := t.(*types.Basic); !isBasic { 1405 // If we expect a non-basic type name (e.g. "[]int"), hack up 1406 // a named type whose name is literally "[]int". This allows 1407 // us to reuse our object based completion machinery. 1408 fakeNamedType := candidate{ 1409 obj: types.NewTypeName(token.NoPos, nil, types.TypeString(t, c.qf), t), 1410 score: stdScore, 1411 } 1412 // Make sure the type name matches before considering 1413 // candidate. This cuts down on useless candidates. 1414 if c.matchingTypeName(&fakeNamedType) { 1415 c.deepState.enqueue(fakeNamedType) 1416 } 1417 } 1418 } 1419 } 1420 1421 // Add keyword completion items appropriate in the current context. 1422 c.addKeywordCompletions() 1423 1424 return nil 1425} 1426 1427func (c *completer) unimportedPackages(ctx context.Context, seen map[string]struct{}) error { 1428 var prefix string 1429 if c.surrounding != nil { 1430 prefix = c.surrounding.Prefix() 1431 } 1432 1433 // Don't suggest unimported packages if we have absolutely nothing 1434 // to go on. 1435 if prefix == "" { 1436 return nil 1437 } 1438 1439 count := 0 1440 1441 known, err := c.snapshot.CachedImportPaths(ctx) 1442 if err != nil { 1443 return err 1444 } 1445 var paths []string 1446 for path, pkg := range known { 1447 if !strings.HasPrefix(pkg.GetTypes().Name(), prefix) { 1448 continue 1449 } 1450 paths = append(paths, path) 1451 } 1452 1453 var relevances map[string]float64 1454 if len(paths) != 0 { 1455 if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error { 1456 var err error 1457 relevances, err = imports.ScoreImportPaths(ctx, opts.Env, paths) 1458 return err 1459 }); err != nil { 1460 return err 1461 } 1462 } 1463 1464 sort.Slice(paths, func(i, j int) bool { 1465 if relevances[paths[i]] != relevances[paths[j]] { 1466 return relevances[paths[i]] > relevances[paths[j]] 1467 } 1468 1469 // Fall back to lexical sort to keep truncated set of candidates 1470 // in a consistent order. 1471 return paths[i] < paths[j] 1472 }) 1473 1474 for _, path := range paths { 1475 pkg := known[path] 1476 if _, ok := seen[pkg.GetTypes().Name()]; ok { 1477 continue 1478 } 1479 imp := &importInfo{ 1480 importPath: path, 1481 pkg: pkg, 1482 } 1483 if imports.ImportPathToAssumedName(path) != pkg.GetTypes().Name() { 1484 imp.name = pkg.GetTypes().Name() 1485 } 1486 if count >= maxUnimportedPackageNames { 1487 return nil 1488 } 1489 c.deepState.enqueue(candidate{ 1490 // Pass an empty *types.Package to disable deep completions. 1491 obj: types.NewPkgName(0, nil, pkg.GetTypes().Name(), types.NewPackage(path, pkg.Name())), 1492 score: unimportedScore(relevances[path]), 1493 imp: imp, 1494 }) 1495 count++ 1496 } 1497 1498 ctx, cancel := context.WithCancel(ctx) 1499 1500 var mu sync.Mutex 1501 add := func(pkg imports.ImportFix) { 1502 mu.Lock() 1503 defer mu.Unlock() 1504 if _, ok := seen[pkg.IdentName]; ok { 1505 return 1506 } 1507 if _, ok := relevances[pkg.StmtInfo.ImportPath]; ok { 1508 return 1509 } 1510 1511 if count >= maxUnimportedPackageNames { 1512 cancel() 1513 return 1514 } 1515 1516 // Do not add the unimported packages to seen, since we can have 1517 // multiple packages of the same name as completion suggestions, since 1518 // only one will be chosen. 1519 obj := types.NewPkgName(0, nil, pkg.IdentName, types.NewPackage(pkg.StmtInfo.ImportPath, pkg.IdentName)) 1520 c.deepState.enqueue(candidate{ 1521 obj: obj, 1522 score: unimportedScore(pkg.Relevance), 1523 imp: &importInfo{ 1524 importPath: pkg.StmtInfo.ImportPath, 1525 name: pkg.StmtInfo.Name, 1526 }, 1527 }) 1528 count++ 1529 } 1530 c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { 1531 defer cancel() 1532 return imports.GetAllCandidates(ctx, add, prefix, c.filename, c.pkg.GetTypes().Name(), opts.Env) 1533 }) 1534 return nil 1535} 1536 1537// alreadyImports reports whether f has an import with the specified path. 1538func alreadyImports(f *ast.File, path string) bool { 1539 for _, s := range f.Imports { 1540 if source.ImportPath(s) == path { 1541 return true 1542 } 1543 } 1544 return false 1545} 1546 1547func (c *completer) inConstDecl() bool { 1548 for _, n := range c.path { 1549 if decl, ok := n.(*ast.GenDecl); ok && decl.Tok == token.CONST { 1550 return true 1551 } 1552 } 1553 return false 1554} 1555 1556// structLiteralFieldName finds completions for struct field names inside a struct literal. 1557func (c *completer) structLiteralFieldName(ctx context.Context) error { 1558 clInfo := c.enclosingCompositeLiteral 1559 1560 // Mark fields of the composite literal that have already been set, 1561 // except for the current field. 1562 addedFields := make(map[*types.Var]bool) 1563 for _, el := range clInfo.cl.Elts { 1564 if kvExpr, ok := el.(*ast.KeyValueExpr); ok { 1565 if clInfo.kv == kvExpr { 1566 continue 1567 } 1568 1569 if key, ok := kvExpr.Key.(*ast.Ident); ok { 1570 if used, ok := c.pkg.GetTypesInfo().Uses[key]; ok { 1571 if usedVar, ok := used.(*types.Var); ok { 1572 addedFields[usedVar] = true 1573 } 1574 } 1575 } 1576 } 1577 } 1578 1579 deltaScore := 0.0001 1580 switch t := clInfo.clType.(type) { 1581 case *types.Struct: 1582 for i := 0; i < t.NumFields(); i++ { 1583 field := t.Field(i) 1584 if !addedFields[field] { 1585 c.deepState.enqueue(candidate{ 1586 obj: field, 1587 score: highScore - float64(i)*deltaScore, 1588 }) 1589 } 1590 } 1591 1592 // Add lexical completions if we aren't certain we are in the key part of a 1593 // key-value pair. 1594 if clInfo.maybeInFieldName { 1595 return c.lexical(ctx) 1596 } 1597 default: 1598 return c.lexical(ctx) 1599 } 1600 1601 return nil 1602} 1603 1604func (cl *compLitInfo) isStruct() bool { 1605 _, ok := cl.clType.(*types.Struct) 1606 return ok 1607} 1608 1609// enclosingCompositeLiteral returns information about the composite literal enclosing the 1610// position. 1611func enclosingCompositeLiteral(path []ast.Node, pos token.Pos, info *types.Info) *compLitInfo { 1612 for _, n := range path { 1613 switch n := n.(type) { 1614 case *ast.CompositeLit: 1615 // The enclosing node will be a composite literal if the user has just 1616 // opened the curly brace (e.g. &x{<>) or the completion request is triggered 1617 // from an already completed composite literal expression (e.g. &x{foo: 1, <>}) 1618 // 1619 // The position is not part of the composite literal unless it falls within the 1620 // curly braces (e.g. "foo.Foo<>Struct{}"). 1621 if !(n.Lbrace < pos && pos <= n.Rbrace) { 1622 // Keep searching since we may yet be inside a composite literal. 1623 // For example "Foo{B: Ba<>{}}". 1624 break 1625 } 1626 1627 tv, ok := info.Types[n] 1628 if !ok { 1629 return nil 1630 } 1631 1632 clInfo := compLitInfo{ 1633 cl: n, 1634 clType: source.Deref(tv.Type).Underlying(), 1635 } 1636 1637 var ( 1638 expr ast.Expr 1639 hasKeys bool 1640 ) 1641 for _, el := range n.Elts { 1642 // Remember the expression that the position falls in, if any. 1643 if el.Pos() <= pos && pos <= el.End() { 1644 expr = el 1645 } 1646 1647 if kv, ok := el.(*ast.KeyValueExpr); ok { 1648 hasKeys = true 1649 // If expr == el then we know the position falls in this expression, 1650 // so also record kv as the enclosing *ast.KeyValueExpr. 1651 if expr == el { 1652 clInfo.kv = kv 1653 break 1654 } 1655 } 1656 } 1657 1658 if clInfo.kv != nil { 1659 // If in a *ast.KeyValueExpr, we know we are in the key if the position 1660 // is to the left of the colon (e.g. "Foo{F<>: V}". 1661 clInfo.inKey = pos <= clInfo.kv.Colon 1662 } else if hasKeys { 1663 // If we aren't in a *ast.KeyValueExpr but the composite literal has 1664 // other *ast.KeyValueExprs, we must be on the key side of a new 1665 // *ast.KeyValueExpr (e.g. "Foo{F: V, <>}"). 1666 clInfo.inKey = true 1667 } else { 1668 switch clInfo.clType.(type) { 1669 case *types.Struct: 1670 if len(n.Elts) == 0 { 1671 // If the struct literal is empty, next could be a struct field 1672 // name or an expression (e.g. "Foo{<>}" could become "Foo{F:}" 1673 // or "Foo{someVar}"). 1674 clInfo.maybeInFieldName = true 1675 } else if len(n.Elts) == 1 { 1676 // If there is one expression and the position is in that expression 1677 // and the expression is an identifier, we may be writing a field 1678 // name or an expression (e.g. "Foo{F<>}"). 1679 _, clInfo.maybeInFieldName = expr.(*ast.Ident) 1680 } 1681 case *types.Map: 1682 // If we aren't in a *ast.KeyValueExpr we must be adding a new key 1683 // to the map. 1684 clInfo.inKey = true 1685 } 1686 } 1687 1688 return &clInfo 1689 default: 1690 if breaksExpectedTypeInference(n, pos) { 1691 return nil 1692 } 1693 } 1694 } 1695 1696 return nil 1697} 1698 1699// enclosingFunction returns the signature and body of the function 1700// enclosing the given position. 1701func enclosingFunction(path []ast.Node, info *types.Info) *funcInfo { 1702 for _, node := range path { 1703 switch t := node.(type) { 1704 case *ast.FuncDecl: 1705 if obj, ok := info.Defs[t.Name]; ok { 1706 return &funcInfo{ 1707 sig: obj.Type().(*types.Signature), 1708 body: t.Body, 1709 } 1710 } 1711 case *ast.FuncLit: 1712 if typ, ok := info.Types[t]; ok { 1713 return &funcInfo{ 1714 sig: typ.Type.(*types.Signature), 1715 body: t.Body, 1716 } 1717 } 1718 } 1719 } 1720 return nil 1721} 1722 1723func (c *completer) expectedCompositeLiteralType() types.Type { 1724 clInfo := c.enclosingCompositeLiteral 1725 switch t := clInfo.clType.(type) { 1726 case *types.Slice: 1727 if clInfo.inKey { 1728 return types.Typ[types.UntypedInt] 1729 } 1730 return t.Elem() 1731 case *types.Array: 1732 if clInfo.inKey { 1733 return types.Typ[types.UntypedInt] 1734 } 1735 return t.Elem() 1736 case *types.Map: 1737 if clInfo.inKey { 1738 return t.Key() 1739 } 1740 return t.Elem() 1741 case *types.Struct: 1742 // If we are completing a key (i.e. field name), there is no expected type. 1743 if clInfo.inKey { 1744 return nil 1745 } 1746 1747 // If we are in a key-value pair, but not in the key, then we must be on the 1748 // value side. The expected type of the value will be determined from the key. 1749 if clInfo.kv != nil { 1750 if key, ok := clInfo.kv.Key.(*ast.Ident); ok { 1751 for i := 0; i < t.NumFields(); i++ { 1752 if field := t.Field(i); field.Name() == key.Name { 1753 return field.Type() 1754 } 1755 } 1756 } 1757 } else { 1758 // If we aren't in a key-value pair and aren't in the key, we must be using 1759 // implicit field names. 1760 1761 // The order of the literal fields must match the order in the struct definition. 1762 // Find the element that the position belongs to and suggest that field's type. 1763 if i := exprAtPos(c.pos, clInfo.cl.Elts); i < t.NumFields() { 1764 return t.Field(i).Type() 1765 } 1766 } 1767 } 1768 return nil 1769} 1770 1771// typeModifier represents an operator that changes the expected type. 1772type typeModifier struct { 1773 mod typeMod 1774 arrayLen int64 1775} 1776 1777type typeMod int 1778 1779const ( 1780 dereference typeMod = iota // pointer indirection: "*" 1781 reference // adds level of pointer: "&" for values, "*" for type names 1782 chanRead // channel read operator ("<-") 1783 slice // make a slice type ("[]" in "[]int") 1784 array // make an array type ("[2]" in "[2]int") 1785) 1786 1787type objKind int 1788 1789const ( 1790 kindAny objKind = 0 1791 kindArray objKind = 1 << iota 1792 kindSlice 1793 kindChan 1794 kindMap 1795 kindStruct 1796 kindString 1797 kindInt 1798 kindBool 1799 kindBytes 1800 kindPtr 1801 kindFloat 1802 kindComplex 1803 kindError 1804 kindStringer 1805 kindFunc 1806) 1807 1808// penalizedObj represents an object that should be disfavored as a 1809// completion candidate. 1810type penalizedObj struct { 1811 // objChain is the full "chain", e.g. "foo.bar().baz" becomes 1812 // []types.Object{foo, bar, baz}. 1813 objChain []types.Object 1814 // penalty is score penalty in the range (0, 1). 1815 penalty float64 1816} 1817 1818// candidateInference holds information we have inferred about a type that can be 1819// used at the current position. 1820type candidateInference struct { 1821 // objType is the desired type of an object used at the query position. 1822 objType types.Type 1823 1824 // objKind is a mask of expected kinds of types such as "map", "slice", etc. 1825 objKind objKind 1826 1827 // variadic is true if we are completing the initial variadic 1828 // parameter. For example: 1829 // append([]T{}, <>) // objType=T variadic=true 1830 // append([]T{}, T{}, <>) // objType=T variadic=false 1831 variadic bool 1832 1833 // modifiers are prefixes such as "*", "&" or "<-" that influence how 1834 // a candidate type relates to the expected type. 1835 modifiers []typeModifier 1836 1837 // convertibleTo is a type our candidate type must be convertible to. 1838 convertibleTo types.Type 1839 1840 // typeName holds information about the expected type name at 1841 // position, if any. 1842 typeName typeNameInference 1843 1844 // assignees are the types that would receive a function call's 1845 // results at the position. For example: 1846 // 1847 // foo := 123 1848 // foo, bar := <> 1849 // 1850 // at "<>", the assignees are [int, <invalid>]. 1851 assignees []types.Type 1852 1853 // variadicAssignees is true if we could be completing an inner 1854 // function call that fills out an outer function call's variadic 1855 // params. For example: 1856 // 1857 // func foo(int, ...string) {} 1858 // 1859 // foo(<>) // variadicAssignees=true 1860 // foo(bar<>) // variadicAssignees=true 1861 // foo(bar, baz<>) // variadicAssignees=false 1862 variadicAssignees bool 1863 1864 // penalized holds expressions that should be disfavored as 1865 // candidates. For example, it tracks expressions already used in a 1866 // switch statement's other cases. Each expression is tracked using 1867 // its entire object "chain" allowing differentiation between 1868 // "a.foo" and "b.foo" when "a" and "b" are the same type. 1869 penalized []penalizedObj 1870 1871 // objChain contains the chain of objects representing the 1872 // surrounding *ast.SelectorExpr. For example, if we are completing 1873 // "foo.bar.ba<>", objChain will contain []types.Object{foo, bar}. 1874 objChain []types.Object 1875} 1876 1877// typeNameInference holds information about the expected type name at 1878// position. 1879type typeNameInference struct { 1880 // wantTypeName is true if we expect the name of a type. 1881 wantTypeName bool 1882 1883 // modifiers are prefixes such as "*", "&" or "<-" that influence how 1884 // a candidate type relates to the expected type. 1885 modifiers []typeModifier 1886 1887 // assertableFrom is a type that must be assertable to our candidate type. 1888 assertableFrom types.Type 1889 1890 // wantComparable is true if we want a comparable type. 1891 wantComparable bool 1892 1893 // seenTypeSwitchCases tracks types that have already been used by 1894 // the containing type switch. 1895 seenTypeSwitchCases []types.Type 1896 1897 // compLitType is true if we are completing a composite literal type 1898 // name, e.g "foo<>{}". 1899 compLitType bool 1900} 1901 1902// expectedCandidate returns information about the expected candidate 1903// for an expression at the query position. 1904func expectedCandidate(ctx context.Context, c *completer) (inf candidateInference) { 1905 inf.typeName = expectTypeName(c) 1906 1907 if c.enclosingCompositeLiteral != nil { 1908 inf.objType = c.expectedCompositeLiteralType() 1909 } 1910 1911Nodes: 1912 for i, node := range c.path { 1913 switch node := node.(type) { 1914 case *ast.BinaryExpr: 1915 // Determine if query position comes from left or right of op. 1916 e := node.X 1917 if c.pos < node.OpPos { 1918 e = node.Y 1919 } 1920 if tv, ok := c.pkg.GetTypesInfo().Types[e]; ok { 1921 switch node.Op { 1922 case token.LAND, token.LOR: 1923 // Don't infer "bool" type for "&&" or "||". Often you want 1924 // to compose a boolean expression from non-boolean 1925 // candidates. 1926 default: 1927 inf.objType = tv.Type 1928 } 1929 break Nodes 1930 } 1931 case *ast.AssignStmt: 1932 // Only rank completions if you are on the right side of the token. 1933 if c.pos > node.TokPos { 1934 i := exprAtPos(c.pos, node.Rhs) 1935 if i >= len(node.Lhs) { 1936 i = len(node.Lhs) - 1 1937 } 1938 if tv, ok := c.pkg.GetTypesInfo().Types[node.Lhs[i]]; ok { 1939 inf.objType = tv.Type 1940 } 1941 1942 // If we have a single expression on the RHS, record the LHS 1943 // assignees so we can favor multi-return function calls with 1944 // matching result values. 1945 if len(node.Rhs) <= 1 { 1946 for _, lhs := range node.Lhs { 1947 inf.assignees = append(inf.assignees, c.pkg.GetTypesInfo().TypeOf(lhs)) 1948 } 1949 } else { 1950 // Otherwse, record our single assignee, even if its type is 1951 // not available. We use this info to downrank functions 1952 // with the wrong number of result values. 1953 inf.assignees = append(inf.assignees, c.pkg.GetTypesInfo().TypeOf(node.Lhs[i])) 1954 } 1955 } 1956 return inf 1957 case *ast.ValueSpec: 1958 if node.Type != nil && c.pos > node.Type.End() { 1959 inf.objType = c.pkg.GetTypesInfo().TypeOf(node.Type) 1960 } 1961 return inf 1962 case *ast.CallExpr: 1963 // Only consider CallExpr args if position falls between parens. 1964 if node.Lparen < c.pos && c.pos <= node.Rparen { 1965 // For type conversions like "int64(foo)" we can only infer our 1966 // desired type is convertible to int64. 1967 if typ := typeConversion(node, c.pkg.GetTypesInfo()); typ != nil { 1968 inf.convertibleTo = typ 1969 break Nodes 1970 } 1971 1972 if tv, ok := c.pkg.GetTypesInfo().Types[node.Fun]; ok { 1973 if sig, ok := tv.Type.(*types.Signature); ok { 1974 numParams := sig.Params().Len() 1975 if numParams == 0 { 1976 return inf 1977 } 1978 1979 exprIdx := exprAtPos(c.pos, node.Args) 1980 1981 // If we have one or zero arg expressions, we may be 1982 // completing to a function call that returns multiple 1983 // values, in turn getting passed in to the surrounding 1984 // call. Record the assignees so we can favor function 1985 // calls that return matching values. 1986 if len(node.Args) <= 1 && exprIdx == 0 { 1987 for i := 0; i < sig.Params().Len(); i++ { 1988 inf.assignees = append(inf.assignees, sig.Params().At(i).Type()) 1989 } 1990 1991 // Record that we may be completing into variadic parameters. 1992 inf.variadicAssignees = sig.Variadic() 1993 } 1994 1995 // Make sure not to run past the end of expected parameters. 1996 if exprIdx >= numParams { 1997 inf.objType = sig.Params().At(numParams - 1).Type() 1998 } else { 1999 inf.objType = sig.Params().At(exprIdx).Type() 2000 } 2001 2002 if sig.Variadic() && exprIdx >= (numParams-1) { 2003 // If we are completing a variadic param, deslice the variadic type. 2004 inf.objType = deslice(inf.objType) 2005 // Record whether we are completing the initial variadic param. 2006 inf.variadic = exprIdx == numParams-1 && len(node.Args) <= numParams 2007 2008 // Check if we can infer object kind from printf verb. 2009 inf.objKind |= printfArgKind(c.pkg.GetTypesInfo(), node, exprIdx) 2010 } 2011 } 2012 } 2013 2014 if funIdent, ok := node.Fun.(*ast.Ident); ok { 2015 obj := c.pkg.GetTypesInfo().ObjectOf(funIdent) 2016 2017 if obj != nil && obj.Parent() == types.Universe { 2018 // Defer call to builtinArgType so we can provide it the 2019 // inferred type from its parent node. 2020 defer func() { 2021 inf = c.builtinArgType(obj, node, inf) 2022 inf.objKind = c.builtinArgKind(ctx, obj, node) 2023 }() 2024 2025 // The expected type of builtin arguments like append() is 2026 // the expected type of the builtin call itself. For 2027 // example: 2028 // 2029 // var foo []int = append(<>) 2030 // 2031 // To find the expected type at <> we "skip" the append() 2032 // node and get the expected type one level up, which is 2033 // []int. 2034 continue Nodes 2035 } 2036 } 2037 2038 return inf 2039 } 2040 case *ast.ReturnStmt: 2041 if c.enclosingFunc != nil { 2042 sig := c.enclosingFunc.sig 2043 // Find signature result that corresponds to our return statement. 2044 if resultIdx := exprAtPos(c.pos, node.Results); resultIdx < len(node.Results) { 2045 if resultIdx < sig.Results().Len() { 2046 inf.objType = sig.Results().At(resultIdx).Type() 2047 } 2048 } 2049 } 2050 return inf 2051 case *ast.CaseClause: 2052 if swtch, ok := findSwitchStmt(c.path[i+1:], c.pos, node).(*ast.SwitchStmt); ok { 2053 if tv, ok := c.pkg.GetTypesInfo().Types[swtch.Tag]; ok { 2054 inf.objType = tv.Type 2055 2056 // Record which objects have already been used in the case 2057 // statements so we don't suggest them again. 2058 for _, cc := range swtch.Body.List { 2059 for _, caseExpr := range cc.(*ast.CaseClause).List { 2060 // Don't record the expression we are currently completing. 2061 if caseExpr.Pos() < c.pos && c.pos <= caseExpr.End() { 2062 continue 2063 } 2064 2065 if objs := objChain(c.pkg.GetTypesInfo(), caseExpr); len(objs) > 0 { 2066 inf.penalized = append(inf.penalized, penalizedObj{objChain: objs, penalty: 0.1}) 2067 } 2068 } 2069 } 2070 } 2071 } 2072 return inf 2073 case *ast.SliceExpr: 2074 // Make sure position falls within the brackets (e.g. "foo[a:<>]"). 2075 if node.Lbrack < c.pos && c.pos <= node.Rbrack { 2076 inf.objType = types.Typ[types.UntypedInt] 2077 } 2078 return inf 2079 case *ast.IndexExpr: 2080 // Make sure position falls within the brackets (e.g. "foo[<>]"). 2081 if node.Lbrack < c.pos && c.pos <= node.Rbrack { 2082 if tv, ok := c.pkg.GetTypesInfo().Types[node.X]; ok { 2083 switch t := tv.Type.Underlying().(type) { 2084 case *types.Map: 2085 inf.objType = t.Key() 2086 case *types.Slice, *types.Array: 2087 inf.objType = types.Typ[types.UntypedInt] 2088 } 2089 } 2090 } 2091 return inf 2092 case *ast.SendStmt: 2093 // Make sure we are on right side of arrow (e.g. "foo <- <>"). 2094 if c.pos > node.Arrow+1 { 2095 if tv, ok := c.pkg.GetTypesInfo().Types[node.Chan]; ok { 2096 if ch, ok := tv.Type.Underlying().(*types.Chan); ok { 2097 inf.objType = ch.Elem() 2098 } 2099 } 2100 } 2101 return inf 2102 case *ast.RangeStmt: 2103 if source.NodeContains(node.X, c.pos) { 2104 inf.objKind |= kindSlice | kindArray | kindMap | kindString 2105 if node.Value == nil { 2106 inf.objKind |= kindChan 2107 } 2108 } 2109 return inf 2110 case *ast.StarExpr: 2111 inf.modifiers = append(inf.modifiers, typeModifier{mod: dereference}) 2112 case *ast.UnaryExpr: 2113 switch node.Op { 2114 case token.AND: 2115 inf.modifiers = append(inf.modifiers, typeModifier{mod: reference}) 2116 case token.ARROW: 2117 inf.modifiers = append(inf.modifiers, typeModifier{mod: chanRead}) 2118 } 2119 case *ast.DeferStmt, *ast.GoStmt: 2120 inf.objKind |= kindFunc 2121 return inf 2122 default: 2123 if breaksExpectedTypeInference(node, c.pos) { 2124 return inf 2125 } 2126 } 2127 } 2128 2129 return inf 2130} 2131 2132// objChain decomposes e into a chain of objects if possible. For 2133// example, "foo.bar().baz" will yield []types.Object{foo, bar, baz}. 2134// If any part can't be turned into an object, return nil. 2135func objChain(info *types.Info, e ast.Expr) []types.Object { 2136 var objs []types.Object 2137 2138 for e != nil { 2139 switch n := e.(type) { 2140 case *ast.Ident: 2141 obj := info.ObjectOf(n) 2142 if obj == nil { 2143 return nil 2144 } 2145 objs = append(objs, obj) 2146 e = nil 2147 case *ast.SelectorExpr: 2148 obj := info.ObjectOf(n.Sel) 2149 if obj == nil { 2150 return nil 2151 } 2152 objs = append(objs, obj) 2153 e = n.X 2154 case *ast.CallExpr: 2155 if len(n.Args) > 0 { 2156 return nil 2157 } 2158 e = n.Fun 2159 default: 2160 return nil 2161 } 2162 } 2163 2164 // Reverse order so the layout matches the syntactic order. 2165 for i := 0; i < len(objs)/2; i++ { 2166 objs[i], objs[len(objs)-1-i] = objs[len(objs)-1-i], objs[i] 2167 } 2168 2169 return objs 2170} 2171 2172// applyTypeModifiers applies the list of type modifiers to a type. 2173// It returns nil if the modifiers could not be applied. 2174func (ci candidateInference) applyTypeModifiers(typ types.Type, addressable bool) types.Type { 2175 for _, mod := range ci.modifiers { 2176 switch mod.mod { 2177 case dereference: 2178 // For every "*" indirection operator, remove a pointer layer 2179 // from candidate type. 2180 if ptr, ok := typ.Underlying().(*types.Pointer); ok { 2181 typ = ptr.Elem() 2182 } else { 2183 return nil 2184 } 2185 case reference: 2186 // For every "&" address operator, add another pointer layer to 2187 // candidate type, if the candidate is addressable. 2188 if addressable { 2189 typ = types.NewPointer(typ) 2190 } else { 2191 return nil 2192 } 2193 case chanRead: 2194 // For every "<-" operator, remove a layer of channelness. 2195 if ch, ok := typ.(*types.Chan); ok { 2196 typ = ch.Elem() 2197 } else { 2198 return nil 2199 } 2200 } 2201 } 2202 2203 return typ 2204} 2205 2206// applyTypeNameModifiers applies the list of type modifiers to a type name. 2207func (ci candidateInference) applyTypeNameModifiers(typ types.Type) types.Type { 2208 for _, mod := range ci.typeName.modifiers { 2209 switch mod.mod { 2210 case reference: 2211 typ = types.NewPointer(typ) 2212 case array: 2213 typ = types.NewArray(typ, mod.arrayLen) 2214 case slice: 2215 typ = types.NewSlice(typ) 2216 } 2217 } 2218 return typ 2219} 2220 2221// matchesVariadic returns true if we are completing a variadic 2222// parameter and candType is a compatible slice type. 2223func (ci candidateInference) matchesVariadic(candType types.Type) bool { 2224 return ci.variadic && ci.objType != nil && types.AssignableTo(candType, types.NewSlice(ci.objType)) 2225} 2226 2227// findSwitchStmt returns an *ast.CaseClause's corresponding *ast.SwitchStmt or 2228// *ast.TypeSwitchStmt. path should start from the case clause's first ancestor. 2229func findSwitchStmt(path []ast.Node, pos token.Pos, c *ast.CaseClause) ast.Stmt { 2230 // Make sure position falls within a "case <>:" clause. 2231 if exprAtPos(pos, c.List) >= len(c.List) { 2232 return nil 2233 } 2234 // A case clause is always nested within a block statement in a switch statement. 2235 if len(path) < 2 { 2236 return nil 2237 } 2238 if _, ok := path[0].(*ast.BlockStmt); !ok { 2239 return nil 2240 } 2241 switch s := path[1].(type) { 2242 case *ast.SwitchStmt: 2243 return s 2244 case *ast.TypeSwitchStmt: 2245 return s 2246 default: 2247 return nil 2248 } 2249} 2250 2251// breaksExpectedTypeInference reports if an expression node's type is unrelated 2252// to its child expression node types. For example, "Foo{Bar: x.Baz(<>)}" should 2253// expect a function argument, not a composite literal value. 2254func breaksExpectedTypeInference(n ast.Node, pos token.Pos) bool { 2255 switch n := n.(type) { 2256 case *ast.CompositeLit: 2257 // Doesn't break inference if pos is in type name. 2258 // For example: "Foo<>{Bar: 123}" 2259 return !source.NodeContains(n.Type, pos) 2260 case *ast.CallExpr: 2261 // Doesn't break inference if pos is in func name. 2262 // For example: "Foo<>(123)" 2263 return !source.NodeContains(n.Fun, pos) 2264 case *ast.FuncLit, *ast.IndexExpr, *ast.SliceExpr: 2265 return true 2266 default: 2267 return false 2268 } 2269} 2270 2271// expectTypeName returns information about the expected type name at position. 2272func expectTypeName(c *completer) typeNameInference { 2273 var inf typeNameInference 2274 2275Nodes: 2276 for i, p := range c.path { 2277 switch n := p.(type) { 2278 case *ast.FieldList: 2279 // Expect a type name if pos is in a FieldList. This applies to 2280 // FuncType params/results, FuncDecl receiver, StructType, and 2281 // InterfaceType. We don't need to worry about the field name 2282 // because completion bails out early if pos is in an *ast.Ident 2283 // that defines an object. 2284 inf.wantTypeName = true 2285 break Nodes 2286 case *ast.CaseClause: 2287 // Expect type names in type switch case clauses. 2288 if swtch, ok := findSwitchStmt(c.path[i+1:], c.pos, n).(*ast.TypeSwitchStmt); ok { 2289 // The case clause types must be assertable from the type switch parameter. 2290 ast.Inspect(swtch.Assign, func(n ast.Node) bool { 2291 if ta, ok := n.(*ast.TypeAssertExpr); ok { 2292 inf.assertableFrom = c.pkg.GetTypesInfo().TypeOf(ta.X) 2293 return false 2294 } 2295 return true 2296 }) 2297 inf.wantTypeName = true 2298 2299 // Track the types that have already been used in this 2300 // switch's case statements so we don't recommend them. 2301 for _, e := range swtch.Body.List { 2302 for _, typeExpr := range e.(*ast.CaseClause).List { 2303 // Skip if type expression contains pos. We don't want to 2304 // count it as already used if the user is completing it. 2305 if typeExpr.Pos() < c.pos && c.pos <= typeExpr.End() { 2306 continue 2307 } 2308 2309 if t := c.pkg.GetTypesInfo().TypeOf(typeExpr); t != nil { 2310 inf.seenTypeSwitchCases = append(inf.seenTypeSwitchCases, t) 2311 } 2312 } 2313 } 2314 2315 break Nodes 2316 } 2317 return typeNameInference{} 2318 case *ast.TypeAssertExpr: 2319 // Expect type names in type assert expressions. 2320 if n.Lparen < c.pos && c.pos <= n.Rparen { 2321 // The type in parens must be assertable from the expression type. 2322 inf.assertableFrom = c.pkg.GetTypesInfo().TypeOf(n.X) 2323 inf.wantTypeName = true 2324 break Nodes 2325 } 2326 return typeNameInference{} 2327 case *ast.StarExpr: 2328 inf.modifiers = append(inf.modifiers, typeModifier{mod: reference}) 2329 case *ast.CompositeLit: 2330 // We want a type name if position is in the "Type" part of a 2331 // composite literal (e.g. "Foo<>{}"). 2332 if n.Type != nil && n.Type.Pos() <= c.pos && c.pos <= n.Type.End() { 2333 inf.wantTypeName = true 2334 inf.compLitType = true 2335 2336 if i < len(c.path)-1 { 2337 // Track preceding "&" operator. Technically it applies to 2338 // the composite literal and not the type name, but if 2339 // affects our type completion nonetheless. 2340 if u, ok := c.path[i+1].(*ast.UnaryExpr); ok && u.Op == token.AND { 2341 inf.modifiers = append(inf.modifiers, typeModifier{mod: reference}) 2342 } 2343 } 2344 } 2345 break Nodes 2346 case *ast.ArrayType: 2347 // If we are inside the "Elt" part of an array type, we want a type name. 2348 if n.Elt.Pos() <= c.pos && c.pos <= n.Elt.End() { 2349 inf.wantTypeName = true 2350 if n.Len == nil { 2351 // No "Len" expression means a slice type. 2352 inf.modifiers = append(inf.modifiers, typeModifier{mod: slice}) 2353 } else { 2354 // Try to get the array type using the constant value of "Len". 2355 tv, ok := c.pkg.GetTypesInfo().Types[n.Len] 2356 if ok && tv.Value != nil && tv.Value.Kind() == constant.Int { 2357 if arrayLen, ok := constant.Int64Val(tv.Value); ok { 2358 inf.modifiers = append(inf.modifiers, typeModifier{mod: array, arrayLen: arrayLen}) 2359 } 2360 } 2361 } 2362 2363 // ArrayTypes can be nested, so keep going if our parent is an 2364 // ArrayType. 2365 if i < len(c.path)-1 { 2366 if _, ok := c.path[i+1].(*ast.ArrayType); ok { 2367 continue Nodes 2368 } 2369 } 2370 2371 break Nodes 2372 } 2373 case *ast.MapType: 2374 inf.wantTypeName = true 2375 if n.Key != nil { 2376 inf.wantComparable = source.NodeContains(n.Key, c.pos) 2377 } else { 2378 // If the key is empty, assume we are completing the key if 2379 // pos is directly after the "map[". 2380 inf.wantComparable = c.pos == n.Pos()+token.Pos(len("map[")) 2381 } 2382 break Nodes 2383 case *ast.ValueSpec: 2384 inf.wantTypeName = source.NodeContains(n.Type, c.pos) 2385 break Nodes 2386 case *ast.TypeSpec: 2387 inf.wantTypeName = source.NodeContains(n.Type, c.pos) 2388 default: 2389 if breaksExpectedTypeInference(p, c.pos) { 2390 return typeNameInference{} 2391 } 2392 } 2393 } 2394 2395 return inf 2396} 2397 2398func (c *completer) fakeObj(T types.Type) *types.Var { 2399 return types.NewVar(token.NoPos, c.pkg.GetTypes(), "", T) 2400} 2401 2402// anyCandType reports whether f returns true for any candidate type 2403// derivable from c. For example, from "foo" we might derive "&foo", 2404// and "foo()". 2405func (c *candidate) anyCandType(f func(t types.Type, addressable bool) bool) bool { 2406 if c.obj == nil || c.obj.Type() == nil { 2407 return false 2408 } 2409 2410 objType := c.obj.Type() 2411 2412 if f(objType, c.addressable) { 2413 return true 2414 } 2415 2416 // If c is a func type with a single result, offer the result type. 2417 if sig, ok := objType.Underlying().(*types.Signature); ok { 2418 if sig.Results().Len() == 1 && f(sig.Results().At(0).Type(), false) { 2419 // Mark the candidate so we know to append "()" when formatting. 2420 c.expandFuncCall = true 2421 return true 2422 } 2423 } 2424 2425 var ( 2426 seenPtrTypes map[types.Type]bool 2427 ptrType = objType 2428 ptrDepth int 2429 ) 2430 2431 // Check if dereferencing c would match our type inference. We loop 2432 // since c could have arbitrary levels of pointerness. 2433 for { 2434 ptr, ok := ptrType.Underlying().(*types.Pointer) 2435 if !ok { 2436 break 2437 } 2438 2439 ptrDepth++ 2440 2441 // Avoid pointer type cycles. 2442 if seenPtrTypes[ptrType] { 2443 break 2444 } 2445 2446 if _, named := ptrType.(*types.Named); named { 2447 // Lazily allocate "seen" since it isn't used normally. 2448 if seenPtrTypes == nil { 2449 seenPtrTypes = make(map[types.Type]bool) 2450 } 2451 2452 // Track named pointer types we have seen to detect cycles. 2453 seenPtrTypes[ptrType] = true 2454 } 2455 2456 if f(ptr.Elem(), false) { 2457 // Mark the candidate so we know to prepend "*" when formatting. 2458 c.dereference = ptrDepth 2459 return true 2460 } 2461 2462 ptrType = ptr.Elem() 2463 } 2464 2465 // Check if c is addressable and a pointer to c matches our type inference. 2466 if c.addressable && f(types.NewPointer(objType), false) { 2467 // Mark the candidate so we know to prepend "&" when formatting. 2468 c.takeAddress = true 2469 return true 2470 } 2471 2472 if array, ok := objType.Underlying().(*types.Array); ok { 2473 if f(types.NewSlice(array.Elem()), false) { 2474 c.takeSlice = true 2475 return true 2476 } 2477 } 2478 2479 return false 2480} 2481 2482// matchingCandidate reports whether cand matches our type inferences. 2483// It mutates cand's score in certain cases. 2484func (c *completer) matchingCandidate(cand *candidate) bool { 2485 if c.completionContext.commentCompletion { 2486 return false 2487 } 2488 2489 // Bail out early if we are completing a field name in a composite literal. 2490 if v, ok := cand.obj.(*types.Var); ok && v.IsField() && c.wantStructFieldCompletions() { 2491 return true 2492 } 2493 2494 if isTypeName(cand.obj) { 2495 return c.matchingTypeName(cand) 2496 } else if c.wantTypeName() { 2497 // If we want a type, a non-type object never matches. 2498 return false 2499 } 2500 2501 if c.inference.candTypeMatches(cand) { 2502 return true 2503 } 2504 2505 candType := cand.obj.Type() 2506 if candType == nil { 2507 return false 2508 } 2509 2510 if sig, ok := candType.Underlying().(*types.Signature); ok { 2511 if c.inference.assigneesMatch(cand, sig) { 2512 // Invoke the candidate if its results are multi-assignable. 2513 cand.expandFuncCall = true 2514 return true 2515 } 2516 } 2517 2518 // Default to invoking *types.Func candidates. This is so function 2519 // completions in an empty statement (or other cases with no expected type) 2520 // are invoked by default. 2521 cand.expandFuncCall = isFunc(cand.obj) 2522 2523 return false 2524} 2525 2526// candTypeMatches reports whether cand makes a good completion 2527// candidate given the candidate inference. cand's score may be 2528// mutated to downrank the candidate in certain situations. 2529func (ci *candidateInference) candTypeMatches(cand *candidate) bool { 2530 var ( 2531 expTypes = make([]types.Type, 0, 2) 2532 variadicType types.Type 2533 ) 2534 if ci.objType != nil { 2535 expTypes = append(expTypes, ci.objType) 2536 2537 if ci.variadic { 2538 variadicType = types.NewSlice(ci.objType) 2539 expTypes = append(expTypes, variadicType) 2540 } 2541 } 2542 2543 return cand.anyCandType(func(candType types.Type, addressable bool) bool { 2544 // Take into account any type modifiers on the expected type. 2545 candType = ci.applyTypeModifiers(candType, addressable) 2546 if candType == nil { 2547 return false 2548 } 2549 2550 if ci.convertibleTo != nil && types.ConvertibleTo(candType, ci.convertibleTo) { 2551 return true 2552 } 2553 2554 for _, expType := range expTypes { 2555 if isEmptyInterface(expType) { 2556 continue 2557 } 2558 2559 matches := ci.typeMatches(expType, candType) 2560 if !matches { 2561 // If candType doesn't otherwise match, consider if we can 2562 // convert candType directly to expType. 2563 if considerTypeConversion(candType, expType, cand.path) { 2564 cand.convertTo = expType 2565 // Give a major score penalty so we always prefer directly 2566 // assignable candidates, all else equal. 2567 cand.score *= 0.5 2568 return true 2569 } 2570 2571 continue 2572 } 2573 2574 if expType == variadicType { 2575 cand.variadic = true 2576 } 2577 2578 // Lower candidate score for untyped conversions. This avoids 2579 // ranking untyped constants above candidates with an exact type 2580 // match. Don't lower score of builtin constants, e.g. "true". 2581 if isUntyped(candType) && !types.Identical(candType, expType) && cand.obj.Parent() != types.Universe { 2582 // Bigger penalty for deep completions into other packages to 2583 // avoid random constants from other packages popping up all 2584 // the time. 2585 if len(cand.path) > 0 && isPkgName(cand.path[0]) { 2586 cand.score *= 0.5 2587 } else { 2588 cand.score *= 0.75 2589 } 2590 } 2591 2592 return true 2593 } 2594 2595 // If we don't have a specific expected type, fall back to coarser 2596 // object kind checks. 2597 if ci.objType == nil || isEmptyInterface(ci.objType) { 2598 // If we were able to apply type modifiers to our candidate type, 2599 // count that as a match. For example: 2600 // 2601 // var foo chan int 2602 // <-fo<> 2603 // 2604 // We were able to apply the "<-" type modifier to "foo", so "foo" 2605 // matches. 2606 if len(ci.modifiers) > 0 { 2607 return true 2608 } 2609 2610 // If we didn't have an exact type match, check if our object kind 2611 // matches. 2612 if ci.kindMatches(candType) { 2613 if ci.objKind == kindFunc { 2614 cand.expandFuncCall = true 2615 } 2616 return true 2617 } 2618 } 2619 2620 return false 2621 }) 2622} 2623 2624// considerTypeConversion returns true if we should offer a completion 2625// automatically converting "from" to "to". 2626func considerTypeConversion(from, to types.Type, path []types.Object) bool { 2627 // Don't offer to convert deep completions from other packages. 2628 // Otherwise there are many random package level consts/vars that 2629 // pop up as candidates all the time. 2630 if len(path) > 0 && isPkgName(path[0]) { 2631 return false 2632 } 2633 2634 if !types.ConvertibleTo(from, to) { 2635 return false 2636 } 2637 2638 // Don't offer to convert ints to strings since that probably 2639 // doesn't do what the user wants. 2640 if isBasicKind(from, types.IsInteger) && isBasicKind(to, types.IsString) { 2641 return false 2642 } 2643 2644 return true 2645} 2646 2647// typeMatches reports whether an object of candType makes a good 2648// completion candidate given the expected type expType. 2649func (ci *candidateInference) typeMatches(expType, candType types.Type) bool { 2650 // Handle untyped values specially since AssignableTo gives false negatives 2651 // for them (see https://golang.org/issue/32146). 2652 if candBasic, ok := candType.Underlying().(*types.Basic); ok { 2653 if expBasic, ok := expType.Underlying().(*types.Basic); ok { 2654 // Note that the candidate and/or the expected can be untyped. 2655 // In "fo<> == 100" the expected type is untyped, and the 2656 // candidate could also be an untyped constant. 2657 2658 // Sort by is_untyped and then by is_int to simplify below logic. 2659 a, b := candBasic.Info(), expBasic.Info() 2660 if a&types.IsUntyped == 0 || (b&types.IsInteger > 0 && b&types.IsUntyped > 0) { 2661 a, b = b, a 2662 } 2663 2664 // If at least one is untyped... 2665 if a&types.IsUntyped > 0 { 2666 switch { 2667 // Untyped integers are compatible with floats. 2668 case a&types.IsInteger > 0 && b&types.IsFloat > 0: 2669 return true 2670 2671 // Check if their constant kind (bool|int|float|complex|string) matches. 2672 // This doesn't take into account the constant value, so there will be some 2673 // false positives due to integer sign and overflow. 2674 case a&types.IsConstType == b&types.IsConstType: 2675 return true 2676 } 2677 } 2678 } 2679 } 2680 2681 // AssignableTo covers the case where the types are equal, but also handles 2682 // cases like assigning a concrete type to an interface type. 2683 return types.AssignableTo(candType, expType) 2684} 2685 2686// kindMatches reports whether candType's kind matches our expected 2687// kind (e.g. slice, map, etc.). 2688func (ci *candidateInference) kindMatches(candType types.Type) bool { 2689 return ci.objKind > 0 && ci.objKind&candKind(candType) > 0 2690} 2691 2692// assigneesMatch reports whether an invocation of sig matches the 2693// number and type of any assignees. 2694func (ci *candidateInference) assigneesMatch(cand *candidate, sig *types.Signature) bool { 2695 if len(ci.assignees) == 0 { 2696 return false 2697 } 2698 2699 // Uniresult functions are always usable and are handled by the 2700 // normal, non-assignees type matching logic. 2701 if sig.Results().Len() == 1 { 2702 return false 2703 } 2704 2705 var numberOfResultsCouldMatch bool 2706 if ci.variadicAssignees { 2707 numberOfResultsCouldMatch = sig.Results().Len() >= len(ci.assignees)-1 2708 } else { 2709 numberOfResultsCouldMatch = sig.Results().Len() == len(ci.assignees) 2710 } 2711 2712 // If our signature doesn't return the right number of values, it's 2713 // not a match, so downrank it. For example: 2714 // 2715 // var foo func() (int, int) 2716 // a, b, c := <> // downrank "foo()" since it only returns two values 2717 if !numberOfResultsCouldMatch { 2718 cand.score /= 2 2719 return false 2720 } 2721 2722 // If at least one assignee has a valid type, and all valid 2723 // assignees match the corresponding sig result value, the signature 2724 // is a match. 2725 allMatch := false 2726 for i := 0; i < sig.Results().Len(); i++ { 2727 var assignee types.Type 2728 2729 // If we are completing into variadic parameters, deslice the 2730 // expected variadic type. 2731 if ci.variadicAssignees && i >= len(ci.assignees)-1 { 2732 assignee = ci.assignees[len(ci.assignees)-1] 2733 if elem := deslice(assignee); elem != nil { 2734 assignee = elem 2735 } 2736 } else { 2737 assignee = ci.assignees[i] 2738 } 2739 2740 if assignee == nil { 2741 continue 2742 } 2743 2744 allMatch = ci.typeMatches(assignee, sig.Results().At(i).Type()) 2745 if !allMatch { 2746 break 2747 } 2748 } 2749 return allMatch 2750} 2751 2752func (c *completer) matchingTypeName(cand *candidate) bool { 2753 if !c.wantTypeName() { 2754 return false 2755 } 2756 2757 typeMatches := func(candType types.Type) bool { 2758 // Take into account any type name modifier prefixes. 2759 candType = c.inference.applyTypeNameModifiers(candType) 2760 2761 if from := c.inference.typeName.assertableFrom; from != nil { 2762 // Don't suggest the starting type in type assertions. For example, 2763 // if "foo" is an io.Writer, don't suggest "foo.(io.Writer)". 2764 if types.Identical(from, candType) { 2765 return false 2766 } 2767 2768 if intf, ok := from.Underlying().(*types.Interface); ok { 2769 if !types.AssertableTo(intf, candType) { 2770 return false 2771 } 2772 } 2773 } 2774 2775 if c.inference.typeName.wantComparable && !types.Comparable(candType) { 2776 return false 2777 } 2778 2779 // Skip this type if it has already been used in another type 2780 // switch case. 2781 for _, seen := range c.inference.typeName.seenTypeSwitchCases { 2782 if types.Identical(candType, seen) { 2783 return false 2784 } 2785 } 2786 2787 // We can expect a type name and have an expected type in cases like: 2788 // 2789 // var foo []int 2790 // foo = []i<> 2791 // 2792 // Where our expected type is "[]int", and we expect a type name. 2793 if c.inference.objType != nil { 2794 return types.AssignableTo(candType, c.inference.objType) 2795 } 2796 2797 // Default to saying any type name is a match. 2798 return true 2799 } 2800 2801 t := cand.obj.Type() 2802 2803 if typeMatches(t) { 2804 return true 2805 } 2806 2807 if !source.IsInterface(t) && typeMatches(types.NewPointer(t)) { 2808 if c.inference.typeName.compLitType { 2809 // If we are completing a composite literal type as in 2810 // "foo<>{}", to make a pointer we must prepend "&". 2811 cand.takeAddress = true 2812 } else { 2813 // If we are completing a normal type name such as "foo<>", to 2814 // make a pointer we must prepend "*". 2815 cand.makePointer = true 2816 } 2817 return true 2818 } 2819 2820 return false 2821} 2822 2823var ( 2824 // "interface { Error() string }" (i.e. error) 2825 errorIntf = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) 2826 2827 // "interface { String() string }" (i.e. fmt.Stringer) 2828 stringerIntf = types.NewInterfaceType([]*types.Func{ 2829 types.NewFunc(token.NoPos, nil, "String", types.NewSignature( 2830 nil, 2831 nil, 2832 types.NewTuple(types.NewParam(token.NoPos, nil, "", types.Typ[types.String])), 2833 false, 2834 )), 2835 }, nil).Complete() 2836 2837 byteType = types.Universe.Lookup("byte").Type() 2838) 2839 2840// candKind returns the objKind of candType, if any. 2841func candKind(candType types.Type) objKind { 2842 var kind objKind 2843 2844 switch t := candType.Underlying().(type) { 2845 case *types.Array: 2846 kind |= kindArray 2847 if t.Elem() == byteType { 2848 kind |= kindBytes 2849 } 2850 case *types.Slice: 2851 kind |= kindSlice 2852 if t.Elem() == byteType { 2853 kind |= kindBytes 2854 } 2855 case *types.Chan: 2856 kind |= kindChan 2857 case *types.Map: 2858 kind |= kindMap 2859 case *types.Pointer: 2860 kind |= kindPtr 2861 2862 // Some builtins handle array pointers as arrays, so just report a pointer 2863 // to an array as an array. 2864 if _, isArray := t.Elem().Underlying().(*types.Array); isArray { 2865 kind |= kindArray 2866 } 2867 case *types.Basic: 2868 switch info := t.Info(); { 2869 case info&types.IsString > 0: 2870 kind |= kindString 2871 case info&types.IsInteger > 0: 2872 kind |= kindInt 2873 case info&types.IsFloat > 0: 2874 kind |= kindFloat 2875 case info&types.IsComplex > 0: 2876 kind |= kindComplex 2877 case info&types.IsBoolean > 0: 2878 kind |= kindBool 2879 } 2880 case *types.Signature: 2881 return kindFunc 2882 } 2883 2884 if types.Implements(candType, errorIntf) { 2885 kind |= kindError 2886 } 2887 2888 if types.Implements(candType, stringerIntf) { 2889 kind |= kindStringer 2890 } 2891 2892 return kind 2893} 2894