mirror of https://github.com/golang/go.git
internal/lsp/completion: indicate completion candidates that are deprecated
In LSP, CompletionItems can say if they are for deprecated names. This
CL implements that for items where the doc comments contain a line
starting // Deprecated.
Semantic tokens now similarly mark deprecated tokens, but in vscode
the default theme doesn't change the display, and the customization
options seem limited to:
"editor.semanticTokenColorCustomizations": {
"rules": {
// only foreground, bold, underline, italic
"*.deprecated": {"italic": true}
}
},
Change-Id: I93ccc227bf4e1e30a4f23b40da4d2cbafe1cd925
Reviewed-on: https://go-review.googlesource.com/c/tools/+/313509
Run-TryBot: Peter Weinberger <pjw@google.com>
Trust: Peter Weinberger <pjw@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
9b9633e07a
commit
edbe9bef04
|
|
@ -456,3 +456,50 @@ func _() {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompletionDeprecation(t *testing.T) {
|
||||
const files = `
|
||||
-- go.mod --
|
||||
module test.com
|
||||
|
||||
go 1.16
|
||||
-- prog.go --
|
||||
package waste
|
||||
// Deprecated, use newFoof
|
||||
func fooFunc() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
const badPi = 3.14
|
||||
|
||||
func doit() {
|
||||
if fooF
|
||||
panic()
|
||||
x := badP
|
||||
}
|
||||
`
|
||||
Run(t, files, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("prog.go")
|
||||
pos := env.RegexpSearch("prog.go", "if fooF")
|
||||
pos.Column += len("if fooF")
|
||||
completions := env.Completion("prog.go", pos)
|
||||
diff := compareCompletionResults([]string{"fooFunc"}, completions.Items)
|
||||
if diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
if completions.Items[0].Tags == nil {
|
||||
t.Errorf("expected Tags to show deprecation %#v", diff[0])
|
||||
}
|
||||
pos = env.RegexpSearch("prog.go", "= badP")
|
||||
pos.Column += len("= badP")
|
||||
completions = env.Completion("prog.go", pos)
|
||||
diff = compareCompletionResults([]string{"badPi"}, completions.Items)
|
||||
if diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
if completions.Items[0].Tags == nil {
|
||||
t.Errorf("expected Tags to show deprecation %#v", diff[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ func toProtocolCompletionItems(candidates []completion.CompletionItem, rng proto
|
|||
|
||||
Preselect: i == 0,
|
||||
Documentation: candidate.Documentation,
|
||||
Tags: candidate.Tags,
|
||||
Deprecated: candidate.Deprecated,
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ func (e *Editor) initialize(ctx context.Context, workspaceFolders []string) erro
|
|||
params.Capabilities.Workspace.Configuration = true
|
||||
params.Capabilities.Window.WorkDoneProgress = true
|
||||
// TODO: set client capabilities
|
||||
params.Capabilities.TextDocument.Completion.CompletionItem.TagSupport.ValueSet = []protocol.CompletionItemTag{protocol.ComplDeprecated}
|
||||
params.InitializationOptions = e.configuration()
|
||||
if e.Config.SendPID {
|
||||
params.ProcessID = int32(os.Getpid())
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ import (
|
|||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const maxFullFileSize int = 100000 // reject full semantic token requests for large files
|
||||
// reject full semantic token requests for large files
|
||||
const maxFullFileSize int = 100000
|
||||
|
||||
func (s *Server) semanticTokensFull(ctx context.Context, p *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) {
|
||||
ret, err := s.computeSemanticTokens(ctx, p.TextDocument, nil)
|
||||
|
|
@ -426,6 +427,18 @@ func (e *encoded) ident(x *ast.Ident) {
|
|||
}
|
||||
}
|
||||
|
||||
func isDeprecated(n *ast.CommentGroup) bool {
|
||||
if n == nil {
|
||||
return false
|
||||
}
|
||||
for _, c := range n.List {
|
||||
if strings.HasPrefix(c.Text, "// Deprecated") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {
|
||||
mods := []string{"definition"}
|
||||
for i := len(e.stack) - 1; i >= 0; i-- {
|
||||
|
|
@ -437,6 +450,9 @@ func (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {
|
|||
}
|
||||
return "variable", mods
|
||||
case *ast.GenDecl:
|
||||
if isDeprecated(y.Doc) {
|
||||
mods = append(mods, "deprecated")
|
||||
}
|
||||
if y.Tok == token.CONST {
|
||||
mods = append(mods, "readonly")
|
||||
}
|
||||
|
|
@ -444,6 +460,9 @@ func (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {
|
|||
case *ast.FuncDecl:
|
||||
// If x is immediately under a FuncDecl, it is a function or method
|
||||
if i == len(e.stack)-2 {
|
||||
if isDeprecated(y.Doc) {
|
||||
mods = append(mods, "deprecated")
|
||||
}
|
||||
if y.Recv != nil {
|
||||
return tokMember, mods
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ type CompletionItem struct {
|
|||
// The insert text does not contain snippets.
|
||||
InsertText string
|
||||
|
||||
Kind protocol.CompletionItemKind
|
||||
Kind protocol.CompletionItemKind
|
||||
Tags []protocol.CompletionItemTag
|
||||
Deprecated bool // Deprecated, prefer Tags if available
|
||||
|
||||
// An optional array of additional TextEdits that are applied when
|
||||
// selecting this completion.
|
||||
|
|
|
|||
|
|
@ -243,6 +243,14 @@ func (c *completer) item(ctx context.Context, cand candidate) (CompletionItem, e
|
|||
if c.opts.fullDocumentation {
|
||||
item.Documentation = hover.FullDocumentation
|
||||
}
|
||||
// The desired pattern is `^// Deprecated`, but the prefix has been removed
|
||||
if strings.HasPrefix(hover.FullDocumentation, "Deprecated") {
|
||||
if c.snapshot.View().Options().CompletionTags {
|
||||
item.Tags = []protocol.CompletionItemTag{protocol.ComplDeprecated}
|
||||
} else if c.snapshot.View().Options().CompletionDeprecated {
|
||||
item.Deprecated = true
|
||||
}
|
||||
}
|
||||
|
||||
return item, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ type ClientOptions struct {
|
|||
SemanticTypes []string
|
||||
SemanticMods []string
|
||||
RelatedInformationSupported bool
|
||||
CompletionTags bool
|
||||
CompletionDeprecated bool
|
||||
}
|
||||
|
||||
// ServerOptions holds LSP-specific configuration that is provided by the
|
||||
|
|
@ -647,6 +649,12 @@ func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) {
|
|||
|
||||
// Check if the client supports diagnostic related information.
|
||||
o.RelatedInformationSupported = caps.TextDocument.PublishDiagnostics.RelatedInformation
|
||||
// Check if the client completion support incliudes tags (preferred) or deprecation
|
||||
if caps.TextDocument.Completion.CompletionItem.TagSupport.ValueSet != nil {
|
||||
o.CompletionTags = true
|
||||
} else if caps.TextDocument.Completion.CompletionItem.DeprecatedSupport {
|
||||
o.CompletionDeprecated = true
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Options) Clone() *Options {
|
||||
|
|
|
|||
Loading…
Reference in New Issue