|
1 | 1 | package checker
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "fmt" |
4 | 5 | "strings"
|
5 | 6 |
|
6 | 7 | "github.com/microsoft/typescript-go/internal/ast"
|
@@ -79,6 +80,107 @@ func (c *Checker) typeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags
|
79 | 80 | return p.string()
|
80 | 81 | }
|
81 | 82 |
|
| 83 | +func (c *Checker) GetQuickInfoAtLocation(node *ast.Node) string { |
| 84 | + symbol := c.GetSymbolAtLocation(node) |
| 85 | + isAlias := symbol != nil && symbol.Flags&ast.SymbolFlagsAlias != 0 |
| 86 | + if isAlias { |
| 87 | + symbol = c.resolveAlias(symbol) |
| 88 | + } |
| 89 | + if symbol == nil || symbol == c.unknownSymbol { |
| 90 | + return "" |
| 91 | + } |
| 92 | + flags := symbol.Flags |
| 93 | + if flags&ast.SymbolFlagsType != 0 && !ast.IsInExpressionContext(node) { |
| 94 | + // If the symbol has a type meaning and we're not in an expression context, remove any value meanings |
| 95 | + flags &^= ast.SymbolFlagsValue |
| 96 | + } |
| 97 | + p := c.newPrinter(TypeFormatFlagsNone) |
| 98 | + if isAlias { |
| 99 | + p.print("(alias) ") |
| 100 | + } |
| 101 | + switch { |
| 102 | + case flags&(ast.SymbolFlagsVariable|ast.SymbolFlagsProperty|ast.SymbolFlagsAccessor) != 0: |
| 103 | + switch { |
| 104 | + case flags&ast.SymbolFlagsProperty != 0: |
| 105 | + p.print("(property) ") |
| 106 | + case flags&ast.SymbolFlagsAccessor != 0: |
| 107 | + p.print("(accessor) ") |
| 108 | + default: |
| 109 | + decl := symbol.ValueDeclaration |
| 110 | + if decl != nil { |
| 111 | + switch { |
| 112 | + case ast.IsParameter(decl): |
| 113 | + p.print("(parameter) ") |
| 114 | + case ast.IsVarLet(decl): |
| 115 | + p.print("let ") |
| 116 | + case ast.IsVarConst(decl): |
| 117 | + p.print("const ") |
| 118 | + case ast.IsVarUsing(decl): |
| 119 | + p.print("using ") |
| 120 | + case ast.IsVarAwaitUsing(decl): |
| 121 | + p.print("await using ") |
| 122 | + default: |
| 123 | + p.print("var ") |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + p.printName(symbol) |
| 128 | + p.print(": ") |
| 129 | + p.printType(c.getTypeOfSymbol(symbol)) |
| 130 | + case flags&ast.SymbolFlagsEnumMember != 0: |
| 131 | + p.print("(enum member) ") |
| 132 | + t := c.getTypeOfSymbol(symbol) |
| 133 | + p.printType(t) |
| 134 | + if t.flags&TypeFlagsLiteral != 0 { |
| 135 | + p.print(" = ") |
| 136 | + p.printValue(t.AsLiteralType().value) |
| 137 | + } |
| 138 | + case flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0: |
| 139 | + t := c.getTypeOfSymbol(symbol) |
| 140 | + signatures := c.getSignaturesOfType(t, SignatureKindCall) |
| 141 | + prefix := core.IfElse(symbol.Flags&ast.SymbolFlagsMethod != 0, "(method) ", "function ") |
| 142 | + for i, sig := range signatures { |
| 143 | + if i != 0 { |
| 144 | + p.print("\n") |
| 145 | + } |
| 146 | + if i == 3 && len(signatures) >= 5 { |
| 147 | + p.print(fmt.Sprintf("// +%v more overloads", len(signatures)-3)) |
| 148 | + break |
| 149 | + } |
| 150 | + p.print(prefix) |
| 151 | + p.printName(symbol) |
| 152 | + p.printSignature(sig, ": ") |
| 153 | + } |
| 154 | + case flags&(ast.SymbolFlagsClass|ast.SymbolFlagsInterface) != 0: |
| 155 | + p.print(core.IfElse(symbol.Flags&ast.SymbolFlagsClass != 0, "class ", "interface ")) |
| 156 | + p.printName(symbol) |
| 157 | + p.printTypeParameters(c.getDeclaredTypeOfSymbol(symbol).AsInterfaceType().LocalTypeParameters()) |
| 158 | + case flags&ast.SymbolFlagsEnum != 0: |
| 159 | + p.print("enum ") |
| 160 | + p.printName(symbol) |
| 161 | + case flags&ast.SymbolFlagsModule != 0: |
| 162 | + p.print(core.IfElse(symbol.ValueDeclaration != nil && ast.IsSourceFile(symbol.ValueDeclaration), "module ", "namespace ")) |
| 163 | + p.printName(symbol) |
| 164 | + case flags&ast.SymbolFlagsTypeParameter != 0: |
| 165 | + p.print("(type parameter) ") |
| 166 | + p.printTypeParameterAndConstraint(c.getDeclaredTypeOfSymbol(symbol)) |
| 167 | + case flags&ast.SymbolFlagsTypeAlias != 0: |
| 168 | + p.print("type ") |
| 169 | + p.printName(symbol) |
| 170 | + p.printTypeParameters(c.typeAliasLinks.Get(symbol).typeParameters) |
| 171 | + if len(symbol.Declarations) != 0 { |
| 172 | + p.print(" = ") |
| 173 | + p.printTypeNoAlias(c.getDeclaredTypeOfSymbol(symbol)) |
| 174 | + } |
| 175 | + case flags&ast.SymbolFlagsAlias != 0: |
| 176 | + p.print("import ") |
| 177 | + p.printName(symbol) |
| 178 | + default: |
| 179 | + p.printType(c.getTypeOfSymbol(symbol)) |
| 180 | + } |
| 181 | + return p.string() |
| 182 | +} |
| 183 | + |
82 | 184 | func (c *Checker) signatureToString(s *Signature) string {
|
83 | 185 | p := c.newPrinter(TypeFormatFlagsNone)
|
84 | 186 | if s.flags&SignatureFlagsConstruct != 0 {
|
@@ -333,6 +435,21 @@ func (p *Printer) printTypeArguments(typeArguments []*Type) {
|
333 | 435 | }
|
334 | 436 | }
|
335 | 437 |
|
| 438 | +func (p *Printer) printTypeParameters(typeParameters []*Type) { |
| 439 | + if len(typeParameters) != 0 { |
| 440 | + p.print("<") |
| 441 | + var tail bool |
| 442 | + for _, tp := range typeParameters { |
| 443 | + if tail { |
| 444 | + p.print(", ") |
| 445 | + } |
| 446 | + p.printTypeParameterAndConstraint(tp) |
| 447 | + tail = true |
| 448 | + } |
| 449 | + p.print(">") |
| 450 | + } |
| 451 | +} |
| 452 | + |
336 | 453 | func (p *Printer) printArrayType(t *Type) {
|
337 | 454 | d := t.AsTypeReference()
|
338 | 455 | if d.target != p.c.globalArrayType {
|
@@ -460,18 +577,7 @@ func (p *Printer) printAnonymousType(t *Type) {
|
460 | 577 | }
|
461 | 578 |
|
462 | 579 | func (p *Printer) printSignature(sig *Signature, returnSeparator string) {
|
463 |
| - if len(sig.typeParameters) != 0 { |
464 |
| - p.print("<") |
465 |
| - var tail bool |
466 |
| - for _, tp := range sig.typeParameters { |
467 |
| - if tail { |
468 |
| - p.print(", ") |
469 |
| - } |
470 |
| - p.printTypeParameterAndConstraint(tp) |
471 |
| - tail = true |
472 |
| - } |
473 |
| - p.print(">") |
474 |
| - } |
| 580 | + p.printTypeParameters(sig.typeParameters) |
475 | 581 | p.print("(")
|
476 | 582 | var tail bool
|
477 | 583 | if sig.thisParameter != nil {
|
|
0 commit comments