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