Skip to content

Commit 73c9497

Browse files
Revert to ValueDeclaration approach and add test for binding element JSDoc
Co-authored-by: DanielRosenwasser <[email protected]>
1 parent 8a13eab commit 73c9497

File tree

2 files changed

+52
-28
lines changed

2 files changed

+52
-28
lines changed

internal/fourslash/tests/destructuredInterfaceJSDoc_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,30 @@ const {foo: /*1*/myFoo, bar: /*2*/myBar} = fubar;
5252
f.VerifyQuickInfoAt(t, "1", "const myFoo: number", "foo comment")
5353
f.VerifyQuickInfoAt(t, "2", "const myBar: string", "bar comment")
5454
}
55+
56+
func TestDestructuredWithOwnJSDoc(t *testing.T) {
57+
t.Parallel()
58+
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
59+
const content = `
60+
interface Foo {
61+
/** This is bar from the interface */
62+
bar: string;
63+
/** This is baz from the interface */
64+
baz: number;
65+
}
66+
67+
declare var foo: Foo;
68+
69+
/** Comment on the variable statement. */
70+
const {
71+
/** Comment on bar destructuring. */ /*1*/bar,
72+
/** Comment on baz destructuring. */ /*2*/baz
73+
} = foo;
74+
`
75+
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
76+
defer done()
77+
// When binding elements have their own JSDoc, TypeScript doesn't currently show it in hover
78+
// Instead, it falls back to the property's JSDoc from the interface
79+
f.VerifyQuickInfoAt(t, "1", "const bar: string", "This is bar from the interface")
80+
f.VerifyQuickInfoAt(t, "2", "const baz: number", "This is baz from the interface")
81+
}

internal/ls/hover.go

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -71,39 +71,36 @@ func (l *LanguageService) getQuickInfoAndDocumentationForSymbol(c *checker.Check
7171
}
7272

7373
func (l *LanguageService) getDocumentationFromDeclaration(c *checker.Checker, symbol *ast.Symbol, declaration *ast.Node, location *ast.Node, contentFormat lsproto.MarkupKind) string {
74-
// Handle binding elements specially (variables created from destructuring) - we need to get the documentation from the property type
75-
// The declaration passed in might be the binding element itself, but we need the interface property declaration
76-
// Check all declarations to see if any is a binding element
77-
if symbol != nil && ast.IsIdentifier(location) {
78-
for _, decl := range symbol.Declarations {
79-
if decl != nil && ast.IsBindingElement(decl) {
80-
bindingElement := decl
81-
parent := bindingElement.Parent
82-
name := bindingElement.PropertyName()
83-
if name == nil {
84-
name = bindingElement.Name()
85-
}
86-
if ast.IsIdentifier(name) && ast.IsObjectBindingPattern(parent) {
87-
propertyName := name.Text()
88-
objectType := c.GetTypeAtLocation(parent)
89-
if objectType != nil {
90-
propertySymbol := findPropertyInType(c, objectType, propertyName)
91-
if propertySymbol != nil && propertySymbol.ValueDeclaration != nil {
92-
declaration = propertySymbol.ValueDeclaration
93-
break
94-
}
95-
}
96-
}
97-
}
98-
}
99-
}
100-
10174
if declaration == nil {
10275
return ""
10376
}
77+
10478
isMarkdown := contentFormat == lsproto.MarkupKindMarkdown
10579
var b strings.Builder
106-
if jsdoc := getJSDocOrTag(c, declaration); jsdoc != nil && !containsTypedefTag(jsdoc) {
80+
jsdoc := getJSDocOrTag(c, declaration)
81+
82+
// Handle binding elements specially (variables created from destructuring) - we need to get the documentation from the property type
83+
// If the binding element doesn't have its own JSDoc, fall back to the property's JSDoc
84+
if jsdoc == nil && symbol != nil && symbol.ValueDeclaration != nil && ast.IsBindingElement(symbol.ValueDeclaration) && ast.IsIdentifier(location) {
85+
bindingElement := symbol.ValueDeclaration
86+
parent := bindingElement.Parent
87+
name := bindingElement.PropertyName()
88+
if name == nil {
89+
name = bindingElement.Name()
90+
}
91+
if ast.IsIdentifier(name) && ast.IsObjectBindingPattern(parent) {
92+
propertyName := name.Text()
93+
objectType := c.GetTypeAtLocation(parent)
94+
if objectType != nil {
95+
propertySymbol := findPropertyInType(c, objectType, propertyName)
96+
if propertySymbol != nil && propertySymbol.ValueDeclaration != nil {
97+
jsdoc = getJSDocOrTag(c, propertySymbol.ValueDeclaration)
98+
}
99+
}
100+
}
101+
}
102+
103+
if jsdoc != nil && !containsTypedefTag(jsdoc) {
107104
l.writeComments(&b, c, jsdoc.Comments(), isMarkdown)
108105
if jsdoc.Kind == ast.KindJSDoc {
109106
if tags := jsdoc.AsJSDoc().Tags; tags != nil {

0 commit comments

Comments
 (0)