Skip to content

Commit a9843d9

Browse files
authored
Display JSDoc documentation in Quick Info (#1018)
1 parent e34eca1 commit a9843d9

File tree

11 files changed

+368
-166
lines changed

11 files changed

+368
-166
lines changed

internal/api/encoder/encoder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ func getChildrenPropertyMask(node *ast.Node) uint8 {
635635
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
636636
case ast.KindJSDocTemplateTag:
637637
n := node.AsJSDocTemplateTag()
638-
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Constraint != nil) << 1) | (boolToByte(n.TypeParameters() != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
638+
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Constraint != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
639639
case ast.KindJSDocReturnTag:
640640
n := node.AsJSDocReturnTag()
641641
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)

internal/ast/ast.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ func (n *Node) Text() string {
289289
return n.AsJsxNamespacedName().Namespace.Text() + ":" + n.AsJsxNamespacedName().name.Text()
290290
case KindRegularExpressionLiteral:
291291
return n.AsRegularExpressionLiteral().Text
292+
case KindJSDocText:
293+
return n.AsJSDocText().Text
292294
}
293295
panic(fmt.Sprintf("Unhandled case in Node.Text: %T", n.data))
294296
}
@@ -429,6 +431,8 @@ func (n *Node) TypeParameterList() *NodeList {
429431
return n.AsInterfaceDeclaration().TypeParameters
430432
case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration:
431433
return n.AsTypeAliasDeclaration().TypeParameters
434+
case KindJSDocTemplateTag:
435+
return n.AsJSDocTemplateTag().TypeParameters
432436
default:
433437
funcLike := n.FunctionLikeData()
434438
if funcLike != nil {
@@ -9159,39 +9163,37 @@ func IsJSDocUnknownTag(node *Node) bool {
91599163
type JSDocTemplateTag struct {
91609164
JSDocTagBase
91619165
Constraint *Node
9162-
typeParameters *TypeParameterList
9166+
TypeParameters *TypeParameterList
91639167
}
91649168

91659169
func (f *NodeFactory) NewJSDocTemplateTag(tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node {
91669170
data := &JSDocTemplateTag{}
91679171
data.TagName = tagName
91689172
data.Constraint = constraint
9169-
data.typeParameters = typeParameters
9173+
data.TypeParameters = typeParameters
91709174
data.Comment = comment
91719175
return f.newNode(KindJSDocTemplateTag, data)
91729176
}
91739177

91749178
func (f *NodeFactory) UpdateJSDocTemplateTag(node *JSDocTemplateTag, tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node {
9175-
if tagName != node.TagName || constraint != node.Constraint || typeParameters != node.typeParameters || comment != node.Comment {
9179+
if tagName != node.TagName || constraint != node.Constraint || typeParameters != node.TypeParameters || comment != node.Comment {
91769180
return updateNode(f.NewJSDocTemplateTag(tagName, constraint, typeParameters, comment), node.AsNode(), f.hooks)
91779181
}
91789182
return node.AsNode()
91799183
}
91809184

91819185
func (node *JSDocTemplateTag) ForEachChild(v Visitor) bool {
9182-
return visit(v, node.TagName) || visit(v, node.Constraint) || visitNodeList(v, node.typeParameters) || visitNodeList(v, node.Comment)
9186+
return visit(v, node.TagName) || visit(v, node.Constraint) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Comment)
91839187
}
91849188

91859189
func (node *JSDocTemplateTag) VisitEachChild(v *NodeVisitor) *Node {
9186-
return v.Factory.UpdateJSDocTemplateTag(node, v.visitNode(node.TagName), v.visitNode(node.Constraint), v.visitNodes(node.typeParameters), v.visitNodes(node.Comment))
9190+
return v.Factory.UpdateJSDocTemplateTag(node, v.visitNode(node.TagName), v.visitNode(node.Constraint), v.visitNodes(node.TypeParameters), v.visitNodes(node.Comment))
91879191
}
91889192

91899193
func (node *JSDocTemplateTag) Clone(f NodeFactoryCoercible) *Node {
9190-
return cloneNode(f.AsNodeFactory().NewJSDocTemplateTag(node.TagName, node.Constraint, node.TypeParameters(), node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
9194+
return cloneNode(f.AsNodeFactory().NewJSDocTemplateTag(node.TagName, node.Constraint, node.TypeParameters, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
91919195
}
91929196

9193-
func (node *JSDocTemplateTag) TypeParameters() *TypeParameterList { return node.typeParameters }
9194-
91959197
// JSDocPropertyTag
91969198
type JSDocPropertyTag struct {
91979199
JSDocTagBase

internal/ast/utilities.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3372,3 +3372,16 @@ func IsTypeDeclarationName(name *Node) bool {
33723372
IsTypeDeclaration(name.Parent) &&
33733373
GetNameOfDeclaration(name.Parent) == name
33743374
}
3375+
3376+
func IsRightSideOfQualifiedNameOrPropertyAccess(node *Node) bool {
3377+
parent := node.Parent
3378+
switch parent.Kind {
3379+
case KindQualifiedName:
3380+
return parent.AsQualifiedName().Right == node
3381+
case KindPropertyAccessExpression:
3382+
return parent.AsPropertyAccessExpression().Name() == node
3383+
case KindMetaProperty:
3384+
return parent.AsMetaProperty().Name() == node
3385+
}
3386+
return false
3387+
}

internal/binder/binder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,8 +1562,8 @@ func (b *Binder) bindChildren(node *ast.Node) {
15621562
// and set it before we descend into nodes that could actually be part of an assignment pattern.
15631563
b.inAssignmentPattern = false
15641564
if b.checkUnreachable(node) {
1565-
b.bindEachChild(node)
15661565
b.setJSDocParents(node)
1566+
b.bindEachChild(node)
15671567
b.inAssignmentPattern = saveInAssignmentPattern
15681568
return
15691569
}
@@ -1574,6 +1574,7 @@ func (b *Binder) bindChildren(node *ast.Node) {
15741574
hasFlowNodeData.FlowNode = b.currentFlow
15751575
}
15761576
}
1577+
b.setJSDocParents(node)
15771578
switch node.Kind {
15781579
case ast.KindWhileStatement:
15791580
b.bindWhileStatement(node)
@@ -1653,7 +1654,6 @@ func (b *Binder) bindChildren(node *ast.Node) {
16531654
default:
16541655
b.bindEachChild(node)
16551656
}
1656-
b.setJSDocParents(node)
16571657
b.inAssignmentPattern = saveInAssignmentPattern
16581658
}
16591659

internal/checker/checker.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13691,7 +13691,7 @@ func (c *Checker) getSymbolOfPartOfRightHandSideOfImportEquals(entityName *ast.N
1369113691
// import a = |b|; // Namespace
1369213692
// import a = |b.c|; // Value, type, namespace
1369313693
// import a = |b.c|.d; // Namespace
13694-
if entityName.Kind == ast.KindIdentifier && isRightSideOfQualifiedNameOrPropertyAccess(entityName) {
13694+
if entityName.Kind == ast.KindIdentifier && ast.IsRightSideOfQualifiedNameOrPropertyAccess(entityName) {
1369513695
entityName = entityName.Parent // QualifiedName
1369613696
}
1369713697
// Check for case 1 and 3 in the above example
@@ -15454,7 +15454,7 @@ func (c *Checker) GetTypeOfSymbolAtLocation(symbol *ast.Symbol, location *ast.No
1545415454
// of the expression (which will reflect control flow analysis). If the expression indeed
1545515455
// resolved to the given symbol, return the narrowed type.
1545615456
if ast.IsIdentifier(location) || ast.IsPrivateIdentifier(location) {
15457-
if isRightSideOfQualifiedNameOrPropertyAccess(location) {
15457+
if ast.IsRightSideOfQualifiedNameOrPropertyAccess(location) {
1545815458
location = location.Parent
1545915459
}
1546015460
if ast.IsExpressionNode(location) && (!ast.IsAssignmentTarget(location) || isWriteAccess(location)) {
@@ -21807,7 +21807,7 @@ func (c *Checker) getUnresolvedSymbolForEntityName(name *ast.Node) *ast.Symbol {
2180721807
result = c.newSymbolEx(ast.SymbolFlagsTypeAlias, text, ast.CheckFlagsUnresolved)
2180821808
c.unresolvedSymbols[path] = result
2180921809
result.Parent = parentSymbol
21810-
c.declaredTypeLinks.Get(result).declaredType = c.unresolvedType
21810+
c.typeAliasLinks.Get(result).declaredType = c.unresolvedType
2181121811
}
2181221812
return result
2181321813
}
@@ -29935,7 +29935,7 @@ func (c *Checker) getSymbolOfNameOrPropertyAccessExpression(name *ast.Node) *ast
2993529935
}
2993629936
}
2993729937

29938-
for isRightSideOfQualifiedNameOrPropertyAccess(name) {
29938+
for ast.IsRightSideOfQualifiedNameOrPropertyAccess(name) {
2993929939
name = name.Parent
2994029940
}
2994129941

@@ -30228,7 +30228,7 @@ func (c *Checker) getApplicableIndexSymbol(t *Type, keyType *Type) *ast.Symbol {
3022830228
}
3022930229

3023030230
func (c *Checker) getRegularTypeOfExpression(expr *ast.Node) *Type {
30231-
if isRightSideOfQualifiedNameOrPropertyAccess(expr) {
30231+
if ast.IsRightSideOfQualifiedNameOrPropertyAccess(expr) {
3023230232
expr = expr.Parent
3023330233
}
3023430234
return c.getRegularTypeOfLiteralType(c.getTypeOfExpression(expr))

internal/checker/printer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func (c *Checker) SignatureToStringEx(signature *Signature, enclosingDeclaration
276276
}
277277

278278
func (c *Checker) signatureToStringEx(signature *Signature, enclosingDeclaration *ast.Node, flags TypeFormatFlags) string {
279-
isConstructor := signature.flags&SignatureFlagsConstruct != 0
279+
isConstructor := signature.flags&SignatureFlagsConstruct != 0 && flags&TypeFormatFlagsWriteCallStyleSignature == 0
280280
var sigOutput ast.Kind
281281
if flags&TypeFormatFlagsWriteArrowStyleSignature != 0 {
282282
if isConstructor {

internal/checker/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const (
6363
TypeFormatFlagsUseSingleQuotesForStringLiteralType TypeFormatFlags = 1 << 28 // Use single quotes for string literal type
6464
TypeFormatFlagsNoTypeReduction TypeFormatFlags = 1 << 29 // Don't call getReducedType
6565
TypeFormatFlagsOmitThisParameter TypeFormatFlags = 1 << 25
66+
TypeFormatFlagsWriteCallStyleSignature TypeFormatFlags = 1 << 27 // Write construct signatures as call style signatures
6667
// Error Handling
6768
TypeFormatFlagsAllowUniqueESSymbolType TypeFormatFlags = 1 << 20 // This is bit 20 to align with the same bit in `NodeBuilderFlags`
6869
// TypeFormatFlags exclusive
@@ -776,7 +777,7 @@ func (t *LiteralType) Value() any {
776777
}
777778

778779
func (t *LiteralType) String() string {
779-
return ValueToString(t)
780+
return ValueToString(t.value)
780781
}
781782

782783
// UniqueESSymbolTypeData

internal/checker/utilities.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,6 @@ func getExternalModuleRequireArgument(node *ast.Node) *ast.Node {
347347
return nil
348348
}
349349

350-
func isRightSideOfQualifiedNameOrPropertyAccess(node *ast.Node) bool {
351-
parent := node.Parent
352-
switch parent.Kind {
353-
case ast.KindQualifiedName:
354-
return parent.AsQualifiedName().Right == node
355-
case ast.KindPropertyAccessExpression:
356-
return parent.AsPropertyAccessExpression().Name() == node
357-
case ast.KindMetaProperty:
358-
return parent.AsMetaProperty().Name() == node
359-
}
360-
return false
361-
}
362-
363350
func isRightSideOfAccessExpression(node *ast.Node) bool {
364351
return node.Parent != nil && (ast.IsPropertyAccessExpression(node.Parent) && node.Parent.Name() == node ||
365352
ast.IsElementAccessExpression(node.Parent) && node.Parent.AsElementAccessExpression().ArgumentExpression == node)

0 commit comments

Comments
 (0)