@@ -72,7 +72,7 @@ func (l *LanguageService) getDocumentationFromDeclaration(c *checker.Checker, de
7272 }
7373 isMarkdown := contentFormat == lsproto .MarkupKindMarkdown
7474 var b strings.Builder
75- if jsdoc := getJSDocOrTag (declaration ); jsdoc != nil && ! containsTypedefTag (jsdoc ) {
75+ if jsdoc := getJSDocOrTag (c , declaration ); jsdoc != nil && ! containsTypedefTag (jsdoc ) {
7676 l .writeComments (& b , c , jsdoc .Comments (), isMarkdown )
7777 if jsdoc .Kind == ast .KindJSDoc {
7878 if tags := jsdoc .AsJSDoc ().Tags ; tags != nil {
@@ -143,14 +143,6 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
143143 return "" , nil
144144 }
145145 declaration := symbol .ValueDeclaration
146- if symbol .Flags & ast .SymbolFlagsClass != 0 && inConstructorContext (node ) {
147- if s := symbol .Members [ast .InternalSymbolNameConstructor ]; s != nil {
148- symbol = s
149- declaration = core .Find (symbol .Declarations , func (d * ast.Node ) bool {
150- return ast .IsConstructorDeclaration (d ) || ast .IsConstructSignatureDeclaration (d )
151- })
152- }
153- }
154146 flags := symbol .Flags
155147 if flags & ast .SymbolFlagsProperty != 0 && declaration != nil && ast .IsMethodDeclaration (declaration ) {
156148 flags = ast .SymbolFlagsMethod
@@ -209,30 +201,43 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
209201 b .WriteString (t .AsLiteralType ().String ())
210202 }
211203 case flags & (ast .SymbolFlagsFunction | ast .SymbolFlagsMethod ) != 0 :
212- signatures := getSignaturesAtLocation (c , symbol , checker .SignatureKindCall , node )
213- if len (signatures ) == 1 {
214- if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
215- declaration = d
216- }
217- }
218204 prefix := core .IfElse (flags & ast .SymbolFlagsMethod != 0 , "(method) " , "function " )
219- writeSignatures (& b , c , signatures , container , prefix , symbol )
220- case flags & ast .SymbolFlagsConstructor != 0 :
221- signatures := getSignaturesAtLocation (c , symbol .Parent , checker .SignatureKindConstruct , node )
222- if len (signatures ) == 1 {
223- if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
224- declaration = d
205+ if ast .IsIdentifier (node ) && ast .IsFunctionLikeDeclaration (node .Parent ) && node .Parent .Name () == node {
206+ declaration = node .Parent
207+ signatures := []* checker.Signature {c .GetSignatureFromDeclaration (declaration )}
208+ writeSignatures (& b , c , signatures , container , prefix , symbol )
209+ } else {
210+ signatures := getSignaturesAtLocation (c , symbol , checker .SignatureKindCall , node )
211+ if len (signatures ) == 1 {
212+ if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
213+ declaration = d
214+ }
225215 }
216+ writeSignatures (& b , c , signatures , container , prefix , symbol )
226217 }
227- writeSignatures (& b , c , signatures , container , "constructor " , symbol .Parent )
228218 case flags & (ast .SymbolFlagsClass | ast .SymbolFlagsInterface ) != 0 :
229219 if node .Kind == ast .KindThisKeyword || ast .IsThisInTypeQuery (node ) {
230220 b .WriteString ("this" )
221+ } else if node .Kind == ast .KindConstructorKeyword && (ast .IsConstructorDeclaration (node .Parent ) || ast .IsConstructSignatureDeclaration (node .Parent )) {
222+ declaration = node .Parent
223+ signatures := []* checker.Signature {c .GetSignatureFromDeclaration (declaration )}
224+ writeSignatures (& b , c , signatures , container , "constructor " , symbol )
231225 } else {
232- b .WriteString (core .IfElse (flags & ast .SymbolFlagsClass != 0 , "class " , "interface " ))
233- b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
234- params := c .GetDeclaredTypeOfSymbol (symbol ).AsInterfaceType ().LocalTypeParameters ()
235- writeTypeParams (& b , c , params )
226+ var signatures []* checker.Signature
227+ if flags & ast .SymbolFlagsClass != 0 && getCallOrNewExpression (node ) != nil {
228+ signatures = getSignaturesAtLocation (c , symbol , checker .SignatureKindConstruct , node )
229+ }
230+ if len (signatures ) == 1 {
231+ if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
232+ declaration = d
233+ }
234+ writeSignatures (& b , c , signatures , container , "constructor " , symbol )
235+ } else {
236+ b .WriteString (core .IfElse (flags & ast .SymbolFlagsClass != 0 , "class " , "interface " ))
237+ b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
238+ params := c .GetDeclaredTypeOfSymbol (symbol ).AsInterfaceType ().LocalTypeParameters ()
239+ writeTypeParams (& b , c , params )
240+ }
236241 }
237242 if flags & ast .SymbolFlagsInterface != 0 {
238243 declaration = core .Find (symbol .Declarations , ast .IsInterfaceDeclaration )
@@ -381,7 +386,7 @@ func containsTypedefTag(jsdoc *ast.Node) bool {
381386 if jsdoc .Kind == ast .KindJSDoc {
382387 if tags := jsdoc .AsJSDoc ().Tags ; tags != nil {
383388 for _ , tag := range tags .Nodes {
384- if tag .Kind == ast .KindJSDocTypedefTag {
389+ if tag .Kind == ast .KindJSDocTypedefTag || tag . Kind == ast . KindJSDocCallbackTag {
385390 return true
386391 }
387392 }
@@ -398,26 +403,40 @@ func getJSDoc(node *ast.Node) *ast.Node {
398403 return core .LastOrNil (node .JSDoc (nil ))
399404}
400405
401- func getJSDocOrTag (node * ast.Node ) * ast.Node {
406+ func getJSDocOrTag (c * checker. Checker , node * ast.Node ) * ast.Node {
402407 if jsdoc := getJSDoc (node ); jsdoc != nil {
403408 return jsdoc
404409 }
405410 switch {
406411 case ast .IsParameter (node ):
407- return getMatchingJSDocTag (node .Parent , node .Name ().Text (), isMatchingParameterTag )
412+ return getMatchingJSDocTag (c , node .Parent , node .Name ().Text (), isMatchingParameterTag )
408413 case ast .IsTypeParameterDeclaration (node ):
409- return getMatchingJSDocTag (node .Parent , node .Name ().Text (), isMatchingTemplateTag )
414+ return getMatchingJSDocTag (c , node .Parent , node .Name ().Text (), isMatchingTemplateTag )
410415 case ast .IsVariableDeclaration (node ) && ast .IsVariableDeclarationList (node .Parent ) && core .FirstOrNil (node .Parent .AsVariableDeclarationList ().Declarations .Nodes ) == node :
411- return getJSDocOrTag (node .Parent .Parent )
416+ return getJSDocOrTag (c , node .Parent .Parent )
412417 case (ast .IsFunctionExpressionOrArrowFunction (node ) || ast .IsClassExpression (node )) &&
413418 (ast .IsVariableDeclaration (node .Parent ) || ast .IsPropertyDeclaration (node .Parent ) || ast .IsPropertyAssignment (node .Parent )) && node .Parent .Initializer () == node :
414- return getJSDocOrTag (node .Parent )
419+ return getJSDocOrTag (c , node .Parent )
420+ }
421+ if symbol := node .Symbol (); symbol != nil && node .Parent != nil && ast .IsClassOrInterfaceLike (node .Parent ) {
422+ isStatic := ast .HasStaticModifier (node )
423+ for _ , baseType := range c .GetBaseTypes (c .GetDeclaredTypeOfSymbol (node .Parent .Symbol ())) {
424+ t := baseType
425+ if isStatic {
426+ t = c .GetTypeOfSymbol (baseType .Symbol ())
427+ }
428+ if prop := c .GetPropertyOfType (t , symbol .Name ); prop != nil && prop .ValueDeclaration != nil {
429+ if jsDoc := getJSDocOrTag (c , prop .ValueDeclaration ); jsDoc != nil {
430+ return jsDoc
431+ }
432+ }
433+ }
415434 }
416435 return nil
417436}
418437
419- func getMatchingJSDocTag (node * ast.Node , name string , match func (* ast.Node , string ) bool ) * ast.Node {
420- if jsdoc := getJSDocOrTag (node ); jsdoc != nil && jsdoc .Kind == ast .KindJSDoc {
438+ func getMatchingJSDocTag (c * checker. Checker , node * ast.Node , name string , match func (* ast.Node , string ) bool ) * ast.Node {
439+ if jsdoc := getJSDocOrTag (c , node ); jsdoc != nil && jsdoc .Kind == ast .KindJSDoc {
421440 if tags := jsdoc .AsJSDoc ().Tags ; tags != nil {
422441 for _ , tag := range tags .Nodes {
423442 if match (tag , name ) {
0 commit comments