@@ -61,9 +61,6 @@ func (l *LanguageService) ProvideHover(ctx context.Context, documentURI lsproto.
6161}
6262
6363func (l * LanguageService ) getQuickInfoAndDocumentationForSymbol (c * checker.Checker , symbol * ast.Symbol , node * ast.Node , contentFormat lsproto.MarkupKind ) (string , string ) {
64- if symbol == nil {
65- return "" , ""
66- }
6764 quickInfo , declaration := getQuickInfoAndDeclarationAtLocation (c , symbol , node )
6865 if quickInfo == "" {
6966 return "" , ""
@@ -175,29 +172,87 @@ func formatQuickInfo(quickInfo string) string {
175172}
176173
177174func getQuickInfoAndDeclarationAtLocation (c * checker.Checker , symbol * ast.Symbol , node * ast.Node ) (string , * ast.Node ) {
178- var b strings.Builder
179- var visitedAliases collections.Set [* ast.Symbol ]
180175 container := getContainerNode (node )
181- if node .Kind == ast .KindThisKeyword && ast .IsInExpressionContext (node ) {
176+ if node .Kind == ast .KindThisKeyword && ast .IsInExpressionContext (node ) || ast . IsThisInTypeQuery ( node ) {
182177 return c .TypeToStringEx (c .GetTypeAtLocation (node ), container , typeFormatFlags ), nil
183178 }
184- writeSymbolMeaning := func (symbol * ast.Symbol , meaning ast.SymbolFlags , isAlias bool ) * ast.Node {
185- flags := symbol .Flags & meaning
186- if flags == 0 {
187- return nil
188- }
189- declaration := symbol .ValueDeclaration
190- if flags & ast .SymbolFlagsProperty != 0 && declaration != nil && ast .IsMethodDeclaration (declaration ) {
191- flags = ast .SymbolFlagsMethod
192- }
179+ if symbol == nil {
180+ return "" , nil
181+ }
182+ var b strings.Builder
183+ var visitedAliases collections.Set [* ast.Symbol ]
184+ var aliasLevel int
185+ writeNewLine := func () {
193186 if b .Len () != 0 {
194187 b .WriteString ("\n " )
195188 }
196- if isAlias {
189+ if aliasLevel != 0 {
197190 b .WriteString ("(alias) " )
198191 }
199- switch {
200- case flags & (ast .SymbolFlagsVariable | ast .SymbolFlagsProperty | ast .SymbolFlagsAccessor ) != 0 :
192+ }
193+ writeSignatures := func (signatures []* checker.Signature , prefix string , symbol * ast.Symbol ) {
194+ for i , sig := range signatures {
195+ writeNewLine ()
196+ if i == 3 && len (signatures ) >= 5 {
197+ b .WriteString (fmt .Sprintf ("// +%v more overloads" , len (signatures )- 3 ))
198+ break
199+ }
200+ b .WriteString (prefix )
201+ b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
202+ b .WriteString (c .SignatureToStringEx (sig , container , typeFormatFlags | checker .TypeFormatFlagsWriteCallStyleSignature | checker .TypeFormatFlagsWriteTypeArgumentsOfSignature ))
203+ }
204+ }
205+ writeTypeParams := func (params []* checker.Type ) {
206+ if len (params ) > 0 {
207+ b .WriteString ("<" )
208+ for i , tp := range params {
209+ if i != 0 {
210+ b .WriteString (", " )
211+ }
212+ b .WriteString (c .SymbolToStringEx (tp .Symbol (), nil , ast .SymbolFlagsNone , symbolFormatFlags ))
213+ cons := c .GetConstraintOfTypeParameter (tp )
214+ if cons != nil {
215+ b .WriteString (" extends " )
216+ b .WriteString (c .TypeToStringEx (cons , nil , typeFormatFlags ))
217+ }
218+ }
219+ b .WriteString (">" )
220+ }
221+ }
222+ var writeSymbol func (* ast.Symbol ) * ast.Node
223+ writeSymbol = func (symbol * ast.Symbol ) * ast.Node {
224+ var declaration * ast.Node
225+ // Recursively write all meanings of alias
226+ if symbol .Flags & ast .SymbolFlagsAlias != 0 && visitedAliases .AddIfAbsent (symbol ) {
227+ if aliasedSymbol := c .GetAliasedSymbol (symbol ); aliasedSymbol != c .GetUnknownSymbol () {
228+ aliasLevel ++
229+ declaration = writeSymbol (aliasedSymbol )
230+ aliasLevel --
231+ }
232+ }
233+ var flags ast.SymbolFlags
234+ switch getMeaningFromLocation (node ) {
235+ case ast .SemanticMeaningValue :
236+ flags = symbol .Flags & (ast .SymbolFlagsValue | ast .SymbolFlagsSignature )
237+ case ast .SemanticMeaningType :
238+ flags = symbol .Flags & ast .SymbolFlagsType
239+ case ast .SemanticMeaningNamespace :
240+ flags = symbol .Flags & ast .SymbolFlagsNamespace
241+ }
242+ if flags == 0 {
243+ flags = symbol .Flags & (ast .SymbolFlagsValue | ast .SymbolFlagsSignature | ast .SymbolFlagsType | ast .SymbolFlagsNamespace )
244+ if flags == 0 {
245+ return nil
246+ }
247+ }
248+ if flags & ast .SymbolFlagsProperty != 0 && symbol .ValueDeclaration != nil && ast .IsMethodDeclaration (symbol .ValueDeclaration ) {
249+ flags = ast .SymbolFlagsMethod
250+ }
251+ if flags & ast .SymbolFlagsValue != 0 {
252+ declaration = symbol .ValueDeclaration
253+ }
254+ if flags & (ast .SymbolFlagsVariable | ast .SymbolFlagsProperty | ast .SymbolFlagsAccessor ) != 0 {
255+ writeNewLine ()
201256 switch {
202257 case flags & ast .SymbolFlagsProperty != 0 :
203258 b .WriteString ("(property) " )
@@ -233,36 +288,44 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
233288 } else {
234289 b .WriteString (c .TypeToStringEx (c .GetTypeOfSymbolAtLocation (symbol , node ), container , typeFormatFlags ))
235290 }
236- case flags & ast .SymbolFlagsEnumMember != 0 :
291+ }
292+ if flags & ast .SymbolFlagsEnumMember != 0 {
293+ writeNewLine ()
237294 b .WriteString ("(enum member) " )
238295 t := c .GetTypeOfSymbol (symbol )
239296 b .WriteString (c .TypeToStringEx (t , container , typeFormatFlags ))
240297 if t .Flags ()& checker .TypeFlagsLiteral != 0 {
241298 b .WriteString (" = " )
242299 b .WriteString (t .AsLiteralType ().String ())
243300 }
244- case flags & (ast .SymbolFlagsFunction | ast .SymbolFlagsMethod ) != 0 :
301+ }
302+ if flags & (ast .SymbolFlagsFunction | ast .SymbolFlagsMethod ) != 0 {
245303 prefix := core .IfElse (flags & ast .SymbolFlagsMethod != 0 , "(method) " , "function " )
246304 if ast .IsIdentifier (node ) && ast .IsFunctionLikeDeclaration (node .Parent ) && node .Parent .Name () == node {
247305 declaration = node .Parent
248306 signatures := []* checker.Signature {c .GetSignatureFromDeclaration (declaration )}
249- writeSignatures (& b , c , signatures , container , isAlias , prefix , symbol )
307+ writeSignatures (signatures , prefix , symbol )
250308 } else {
251309 signatures := getSignaturesAtLocation (c , symbol , checker .SignatureKindCall , node )
252310 if len (signatures ) == 1 {
253311 if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
254312 declaration = d
255313 }
256314 }
257- writeSignatures (& b , c , signatures , container , isAlias , prefix , symbol )
315+ writeSignatures (signatures , prefix , symbol )
316+ }
317+ }
318+ if flags & (ast .SymbolFlagsClass | ast .SymbolFlagsInterface ) != 0 {
319+ if flags & ast .SymbolFlagsInterface != 0 && (declaration == nil || ast .IsIdentifier (node ) && ast .IsInterfaceDeclaration (node .Parent )) {
320+ declaration = core .Find (symbol .Declarations , ast .IsInterfaceDeclaration )
258321 }
259- case flags & (ast .SymbolFlagsClass | ast .SymbolFlagsInterface ) != 0 :
260322 if node .Kind == ast .KindThisKeyword || ast .IsThisInTypeQuery (node ) {
323+ writeNewLine ()
261324 b .WriteString ("this" )
262325 } else if node .Kind == ast .KindConstructorKeyword && (ast .IsConstructorDeclaration (node .Parent ) || ast .IsConstructSignatureDeclaration (node .Parent )) {
263326 declaration = node .Parent
264327 signatures := []* checker.Signature {c .GetSignatureFromDeclaration (declaration )}
265- writeSignatures (& b , c , signatures , container , isAlias , "constructor " , symbol )
328+ writeSignatures (signatures , "constructor " , symbol )
266329 } else {
267330 var signatures []* checker.Signature
268331 if flags & ast .SymbolFlagsClass != 0 && getCallOrNewExpression (node ) != nil {
@@ -272,24 +335,34 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
272335 if d := signatures [0 ].Declaration (); d != nil && d .Flags & ast .NodeFlagsJSDoc == 0 {
273336 declaration = d
274337 }
275- writeSignatures (& b , c , signatures , container , isAlias , "constructor " , symbol )
338+ writeSignatures (signatures , "constructor " , symbol )
276339 } else {
340+ writeNewLine ()
277341 b .WriteString (core .IfElse (flags & ast .SymbolFlagsClass != 0 , "class " , "interface " ))
278342 b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
279343 params := c .GetDeclaredTypeOfSymbol (symbol ).AsInterfaceType ().LocalTypeParameters ()
280- writeTypeParams (& b , c , params )
344+ writeTypeParams (params )
281345 }
282346 }
283- if flags & ast .SymbolFlagsInterface != 0 {
284- declaration = core .Find (symbol .Declarations , ast .IsInterfaceDeclaration )
285- }
286- case flags & ast .SymbolFlagsEnum != 0 :
347+ }
348+ if flags & ast .SymbolFlagsEnum != 0 {
349+ writeNewLine ()
287350 b .WriteString ("enum " )
288351 b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
289- case flags & ast .SymbolFlagsModule != 0 :
352+ if declaration == nil || ast .IsIdentifier (node ) && ast .IsEnumDeclaration (node .Parent ) {
353+ declaration = core .Find (symbol .Declarations , ast .IsEnumDeclaration )
354+ }
355+ }
356+ if flags & ast .SymbolFlagsModule != 0 {
357+ writeNewLine ()
290358 b .WriteString (core .IfElse (symbol .ValueDeclaration != nil && ast .IsSourceFile (symbol .ValueDeclaration ), "module " , "namespace " ))
291359 b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
292- case flags & ast .SymbolFlagsTypeParameter != 0 :
360+ if declaration == nil || ast .IsIdentifier (node ) && ast .IsModuleDeclaration (node .Parent ) {
361+ declaration = core .Find (symbol .Declarations , ast .IsModuleDeclaration )
362+ }
363+ }
364+ if flags & ast .SymbolFlagsTypeParameter != 0 {
365+ writeNewLine ()
293366 b .WriteString ("(type parameter) " )
294367 tp := c .GetDeclaredTypeOfSymbol (symbol )
295368 b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
@@ -298,40 +371,30 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
298371 b .WriteString (" extends " )
299372 b .WriteString (c .TypeToStringEx (cons , container , typeFormatFlags ))
300373 }
301- declaration = core .Find (symbol .Declarations , ast .IsTypeParameterDeclaration )
302- case flags & ast .SymbolFlagsTypeAlias != 0 :
374+ if declaration == nil || ast .IsIdentifier (node ) && ast .IsTypeParameterDeclaration (node .Parent ) {
375+ declaration = core .Find (symbol .Declarations , ast .IsTypeParameterDeclaration )
376+ }
377+ }
378+ if flags & ast .SymbolFlagsTypeAlias != 0 {
379+ writeNewLine ()
303380 b .WriteString ("type " )
304381 b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
305- writeTypeParams (& b , c , c .GetTypeAliasTypeParameters (symbol ))
382+ writeTypeParams (c .GetTypeAliasTypeParameters (symbol ))
306383 if len (symbol .Declarations ) != 0 {
307384 b .WriteString (" = " )
308385 b .WriteString (c .TypeToStringEx (c .GetDeclaredTypeOfSymbol (symbol ), container , typeFormatFlags | checker .TypeFormatFlagsInTypeAlias ))
309386 }
310- declaration = core .Find (symbol .Declarations , ast .IsTypeOrJSTypeAliasDeclaration )
311- default :
312- b .WriteString (c .TypeToStringEx (c .GetTypeOfSymbol (symbol ), container , typeFormatFlags ))
313- }
314- return declaration
315- }
316- var writeSymbol func (* ast.Symbol , bool ) * ast.Node
317- writeSymbol = func (symbol * ast.Symbol , isAlias bool ) * ast.Node {
318- var declaration * ast.Node
319- // Recursively write all meanings of alias
320- if symbol .Flags & ast .SymbolFlagsAlias != 0 && visitedAliases .AddIfAbsent (symbol ) {
321- if aliasedSymbol := c .GetAliasedSymbol (symbol ); aliasedSymbol != c .GetUnknownSymbol () {
322- declaration = writeSymbol (aliasedSymbol , true /*isAlias*/ )
387+ if declaration == nil || ast .IsIdentifier (node ) && ast .IsTypeOrJSTypeAliasDeclaration (node .Parent ) {
388+ declaration = core .Find (symbol .Declarations , ast .IsTypeOrJSTypeAliasDeclaration )
323389 }
324390 }
325- // Write the value meaning, if any
326- declaration = core .OrElse (declaration , writeSymbolMeaning (symbol , ast .SymbolFlagsValue | ast .SymbolFlagsSignature , isAlias ))
327- // Write the type meaning, if any
328- declaration = core .OrElse (declaration , writeSymbolMeaning (symbol , ast .SymbolFlagsType &^ast .SymbolFlagsValue , isAlias ))
329- // Write the namespace meaning, if any
330- declaration = core .OrElse (declaration , writeSymbolMeaning (symbol , ast .SymbolFlagsNamespace &^ast .SymbolFlagsValue , isAlias ))
331- // Return the first declaration
391+ if flags & ast .SymbolFlagsSignature != 0 {
392+ writeNewLine ()
393+ b .WriteString (c .TypeToStringEx (c .GetTypeOfSymbol (symbol ), container , typeFormatFlags ))
394+ }
332395 return declaration
333396 }
334- firstDeclaration := writeSymbol (symbol , false /*isAlias*/ )
397+ firstDeclaration := writeSymbol (symbol )
335398 return b .String (), firstDeclaration
336399}
337400
@@ -392,43 +455,6 @@ func getCallOrNewExpression(node *ast.Node) *ast.Node {
392455 return nil
393456}
394457
395- func writeTypeParams (b * strings.Builder , c * checker.Checker , params []* checker.Type ) {
396- if len (params ) > 0 {
397- b .WriteString ("<" )
398- for i , tp := range params {
399- if i != 0 {
400- b .WriteString (", " )
401- }
402- symbol := tp .Symbol ()
403- b .WriteString (c .SymbolToStringEx (symbol , nil , ast .SymbolFlagsNone , symbolFormatFlags ))
404- cons := c .GetConstraintOfTypeParameter (tp )
405- if cons != nil {
406- b .WriteString (" extends " )
407- b .WriteString (c .TypeToStringEx (cons , nil , typeFormatFlags ))
408- }
409- }
410- b .WriteString (">" )
411- }
412- }
413-
414- func writeSignatures (b * strings.Builder , c * checker.Checker , signatures []* checker.Signature , container * ast.Node , isAlias bool , prefix string , symbol * ast.Symbol ) {
415- for i , sig := range signatures {
416- if i != 0 {
417- b .WriteString ("\n " )
418- if isAlias {
419- b .WriteString ("(alias) " )
420- }
421- }
422- if i == 3 && len (signatures ) >= 5 {
423- b .WriteString (fmt .Sprintf ("// +%v more overloads" , len (signatures )- 3 ))
424- break
425- }
426- b .WriteString (prefix )
427- b .WriteString (c .SymbolToStringEx (symbol , container , ast .SymbolFlagsNone , symbolFormatFlags ))
428- b .WriteString (c .SignatureToStringEx (sig , container , typeFormatFlags | checker .TypeFormatFlagsWriteCallStyleSignature | checker .TypeFormatFlagsWriteTypeArgumentsOfSignature ))
429- }
430- }
431-
432458func containsTypedefTag (jsdoc * ast.Node ) bool {
433459 if jsdoc .Kind == ast .KindJSDoc {
434460 if tags := jsdoc .AsJSDoc ().Tags ; tags != nil {
@@ -466,19 +492,29 @@ func getJSDocOrTag(c *checker.Checker, node *ast.Node) *ast.Node {
466492 (ast .IsVariableDeclaration (node .Parent ) || ast .IsPropertyDeclaration (node .Parent ) || ast .IsPropertyAssignment (node .Parent )) && node .Parent .Initializer () == node :
467493 return getJSDocOrTag (c , node .Parent )
468494 }
469- if symbol := node .Symbol (); symbol != nil && node .Parent != nil && ast .IsClassOrInterfaceLike (node .Parent ) {
470- isStatic := ast .HasStaticModifier (node )
471- for _ , baseType := range c .GetBaseTypes (c .GetDeclaredTypeOfSymbol (node .Parent .Symbol ())) {
472- t := baseType
473- if isStatic {
474- t = c .GetTypeOfSymbol (baseType .Symbol ())
475- }
476- if prop := c .GetPropertyOfType (t , symbol .Name ); prop != nil && prop .ValueDeclaration != nil {
477- if jsDoc := getJSDocOrTag (c , prop .ValueDeclaration ); jsDoc != nil {
495+ if symbol := node .Symbol (); symbol != nil && node .Parent != nil {
496+ if ast .IsFunctionDeclaration (node ) || ast .IsMethodDeclaration (node ) || ast .IsMethodSignatureDeclaration (node ) || ast .IsConstructorDeclaration (node ) || ast .IsConstructSignatureDeclaration (node ) {
497+ firstSignature := core .Find (symbol .Declarations , ast .IsFunctionLike )
498+ if firstSignature != nil && node != firstSignature {
499+ if jsDoc := getJSDocOrTag (c , firstSignature ); jsDoc != nil {
478500 return jsDoc
479501 }
480502 }
481503 }
504+ if ast .IsClassOrInterfaceLike (node .Parent ) {
505+ isStatic := ast .HasStaticModifier (node )
506+ for _ , baseType := range c .GetBaseTypes (c .GetDeclaredTypeOfSymbol (node .Parent .Symbol ())) {
507+ t := baseType
508+ if isStatic {
509+ t = c .GetTypeOfSymbol (baseType .Symbol ())
510+ }
511+ if prop := c .GetPropertyOfType (t , symbol .Name ); prop != nil && prop .ValueDeclaration != nil {
512+ if jsDoc := getJSDocOrTag (c , prop .ValueDeclaration ); jsDoc != nil {
513+ return jsDoc
514+ }
515+ }
516+ }
517+ }
482518 }
483519 return nil
484520}
0 commit comments