Skip to content

Commit dd1c468

Browse files
committed
gopls/internal/lsp/source: simplify extracting object hover doc
Add a new helper HoverDocForObject, which finds the relevant object documentation without needing to type-check. This eliminates the last use of FindPackageFromPos. For golang/go#57987 Change-Id: Ic9deec78d68156e9ead3831a8247f8c30259a3c6 Reviewed-on: https://go-review.googlesource.com/c/tools/+/464455 Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
1 parent 66f8f71 commit dd1c468

File tree

4 files changed

+54
-37
lines changed

4 files changed

+54
-37
lines changed

Diff for: gopls/internal/lsp/source/completion/format.go

+7-14
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"golang.org/x/tools/gopls/internal/lsp/source"
2020
"golang.org/x/tools/gopls/internal/span"
2121
"golang.org/x/tools/internal/event"
22-
"golang.org/x/tools/internal/event/tag"
2322
"golang.org/x/tools/internal/imports"
2423
"golang.org/x/tools/internal/typeparams"
2524
)
@@ -242,27 +241,21 @@ Suffixes:
242241
if !pos.IsValid() {
243242
return item, nil
244243
}
245-
uri := span.URIFromPath(pos.Filename)
246244

247-
// Find the source file of the candidate.
248-
pkg, err := source.FindPackageFromPos(ctx, c.snapshot, c.pkg, obj.Pos())
245+
comment, err := source.HoverDocForObject(ctx, c.snapshot, c.pkg, obj)
249246
if err != nil {
250-
return item, nil
251-
}
252-
253-
decl, _, _ := source.FindDeclInfo(pkg.GetSyntax(), obj.Pos()) // may be nil
254-
hover, err := source.FindHoverContext(ctx, c.snapshot, pkg, obj, decl, nil)
255-
if err != nil {
256-
event.Error(ctx, "failed to find Hover", err, tag.URI.Of(uri))
247+
event.Error(ctx, fmt.Sprintf("failed to find Hover for %q", obj.Name()), err)
257248
return item, nil
258249
}
259250
if c.opts.fullDocumentation {
260-
item.Documentation = hover.Comment.Text()
251+
item.Documentation = comment.Text()
261252
} else {
262-
item.Documentation = doc.Synopsis(hover.Comment.Text())
253+
item.Documentation = doc.Synopsis(comment.Text())
263254
}
264255
// The desired pattern is `^// Deprecated`, but the prefix has been removed
265-
if strings.HasPrefix(hover.Comment.Text(), "Deprecated") {
256+
// TODO(rfindley): It doesn't look like this does the right thing for
257+
// multi-line comments.
258+
if strings.HasPrefix(comment.Text(), "Deprecated") {
266259
if c.snapshot.View().Options().CompletionTags {
267260
item.Tags = []protocol.CompletionItemTag{protocol.ComplDeprecated}
268261
} else if c.snapshot.View().Options().CompletionDeprecated {

Diff for: gopls/internal/lsp/source/hover.go

+45
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,51 @@ func objectString(obj types.Object, qf types.Qualifier, inferred *types.Signatur
499499
return str
500500
}
501501

502+
// HoverDocForObject returns the best doc comment for obj, referenced by srcpkg.
503+
//
504+
// TODO(rfindley): there appears to be zero(!) tests for this functionality.
505+
func HoverDocForObject(ctx context.Context, snapshot Snapshot, srcpkg Package, obj types.Object) (*ast.CommentGroup, error) {
506+
if _, isTypeName := obj.(*types.TypeName); isTypeName {
507+
if _, isTypeParam := obj.Type().(*typeparams.TypeParam); isTypeParam {
508+
return nil, nil
509+
}
510+
}
511+
512+
pgf, pos, err := parseFull(ctx, snapshot, srcpkg, obj.Pos())
513+
if err != nil {
514+
return nil, fmt.Errorf("re-parsing: %v", err)
515+
}
516+
517+
decl, spec, field := FindDeclInfo([]*ast.File{pgf.File}, pos)
518+
if field != nil && field.Doc != nil {
519+
return field.Doc, nil
520+
}
521+
switch decl := decl.(type) {
522+
case *ast.FuncDecl:
523+
return decl.Doc, nil
524+
case *ast.GenDecl:
525+
switch spec := spec.(type) {
526+
case *ast.ValueSpec:
527+
if spec.Doc != nil {
528+
return spec.Doc, nil
529+
}
530+
if decl.Doc != nil {
531+
return decl.Doc, nil
532+
}
533+
return spec.Comment, nil
534+
case *ast.TypeSpec:
535+
if spec.Doc != nil {
536+
return spec.Doc, nil
537+
}
538+
if decl.Doc != nil {
539+
return decl.Doc, nil
540+
}
541+
return spec.Comment, nil
542+
}
543+
}
544+
return nil, nil
545+
}
546+
502547
// parseFull fully parses the file corresponding to position pos, referenced
503548
// from the given srcpkg.
504549
//

Diff for: gopls/internal/lsp/source/signature_help.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,12 @@ FindCall:
9797
comment *ast.CommentGroup
9898
)
9999
if obj != nil {
100-
declPkg, err := FindPackageFromPos(ctx, snapshot, pkg, obj.Pos())
101-
if err != nil {
102-
return nil, 0, err
103-
}
104-
node, _, _ := FindDeclInfo(declPkg.GetSyntax(), obj.Pos()) // may be nil
105-
d, err := FindHoverContext(ctx, snapshot, pkg, obj, node, nil)
100+
d, err := HoverDocForObject(ctx, snapshot, pkg, obj)
106101
if err != nil {
107102
return nil, 0, err
108103
}
109104
name = obj.Name()
110-
comment = d.Comment
105+
comment = d
111106
} else {
112107
name = "func"
113108
}

Diff for: gopls/internal/lsp/source/util.go

-16
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,6 @@ func posToMappedRange(ctx context.Context, snapshot Snapshot, pkg Package, pos,
100100
return pgf.PosMappedRange(pos, end)
101101
}
102102

103-
// FindPackageFromPos returns the Package for the given position, which must be
104-
// among the transitive dependencies of pkg.
105-
//
106-
// TODO(rfindley): is this the best factoring of this API? This function is
107-
// really a trivial wrapper around findFileInDeps, which may be a more useful
108-
// function to expose.
109-
func FindPackageFromPos(ctx context.Context, snapshot Snapshot, pkg Package, pos token.Pos) (Package, error) {
110-
if !pos.IsValid() {
111-
return nil, fmt.Errorf("invalid position")
112-
}
113-
fileName := pkg.FileSet().File(pos).Name()
114-
uri := span.URIFromPath(fileName)
115-
_, pkg, err := findFileInDeps(ctx, snapshot, pkg, uri)
116-
return pkg, err
117-
}
118-
119103
// Matches cgo generated comment as well as the proposed standard:
120104
//
121105
// https://golang.org/s/generatedcode

0 commit comments

Comments
 (0)