Skip to content

Commit 8975084

Browse files
authored
fix(1196): extend parameter matching with index fallback when name matching fails (#1241)
1 parent b6f391a commit 8975084

File tree

68 files changed

+525
-983
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+525
-983
lines changed

internal/parser/reparser.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (p *Parser) reparseUnhosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Nod
7474
case ast.KindJSDocTypeExpression:
7575
t = setHost(typeExpression, typeAlias)
7676
case ast.KindJSDocTypeLiteral:
77-
t = p.reparseJSDocTypeLiteral(typeExpression, typeAlias)
77+
t = p.reparseJSDocTypeLiteral(typeExpression)
7878
default:
7979
panic("typedef tag type expression should be a name reference or a type expression" + typeExpression.Kind.String())
8080
}
@@ -148,9 +148,7 @@ func (p *Parser) reparseJSDocSignature(jsSignature *ast.Node, fun *ast.Node, jsD
148148
jsparam := param.AsJSDocParameterOrPropertyTag()
149149
parameter = p.factory.NewParameterDeclaration(nil, nil, jsparam.Name(), p.makeQuestionIfOptional(jsparam), nil, nil)
150150
if jsparam.TypeExpression != nil {
151-
t := p.reparseJSDocTypeLiteral(jsparam.TypeExpression.Type(), parameter)
152-
setHost(jsparam.TypeExpression, parameter)
153-
parameter.AsParameterDeclaration().Type = t
151+
parameter.AsParameterDeclaration().Type = p.reparseJSDocTypeLiteral(setHost(jsparam.TypeExpression, parameter))
154152
}
155153
}
156154
parameter.Loc = param.Loc
@@ -170,8 +168,12 @@ func (p *Parser) reparseJSDocSignature(jsSignature *ast.Node, fun *ast.Node, jsD
170168
return signature
171169
}
172170

173-
func (p *Parser) reparseJSDocTypeLiteral(t *ast.TypeNode, host *ast.Node) *ast.Node {
174-
if t != nil && t.Kind == ast.KindJSDocTypeLiteral {
171+
func (p *Parser) reparseJSDocTypeLiteral(t *ast.TypeNode) *ast.Node {
172+
if t == nil {
173+
return nil
174+
}
175+
if t.Kind == ast.KindJSDocTypeLiteral {
176+
isArrayType := t.AsJSDocTypeLiteral().IsArrayType
175177
properties := p.nodeSlicePool.NewSlice(0)
176178
for _, prop := range t.AsJSDocTypeLiteral().JSDocPropertyTags {
177179
jsprop := prop.AsJSDocParameterOrPropertyTag()
@@ -180,7 +182,9 @@ func (p *Parser) reparseJSDocTypeLiteral(t *ast.TypeNode, host *ast.Node) *ast.N
180182
name = name.AsQualifiedName().Right
181183
}
182184
property := p.factory.NewPropertySignatureDeclaration(nil, name, p.makeQuestionIfOptional(jsprop), nil, nil)
183-
property.AsPropertySignatureDeclaration().Type = p.reparseJSDocTypeLiteral(jsprop.TypeExpression, property)
185+
if jsprop.TypeExpression != nil {
186+
property.AsPropertySignatureDeclaration().Type = p.reparseJSDocTypeLiteral(jsprop.TypeExpression.Type())
187+
}
184188
property.Loc = prop.Loc
185189
property.Flags = p.contextFlags | ast.NodeFlagsReparsed
186190
properties = append(properties, property)
@@ -189,6 +193,11 @@ func (p *Parser) reparseJSDocTypeLiteral(t *ast.TypeNode, host *ast.Node) *ast.N
189193
t = p.factory.NewTypeLiteralNode(p.newNodeList(loc, properties))
190194
t.Loc = loc
191195
t.Flags = p.contextFlags | ast.NodeFlagsReparsed
196+
if isArrayType {
197+
t = p.factory.NewArrayTypeNode(t)
198+
t.Flags = p.contextFlags | ast.NodeFlagsReparsed
199+
t.Loc = loc
200+
}
192201
}
193202
return t
194203
}
@@ -327,13 +336,13 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
327336
}
328337
case ast.KindJSDocParameterTag:
329338
if fun, ok := getFunctionLikeHost(parent); ok {
330-
jsparam := tag.AsJSDocParameterOrPropertyTag()
331-
if param, ok := findMatchingParameter(fun, jsparam); ok {
339+
parameterTag := tag.AsJSDocParameterOrPropertyTag()
340+
if param, ok := findMatchingParameter(fun, parameterTag, jsDoc); ok {
332341
if param.Type == nil {
333-
param.Type = setHost(jsparam.TypeExpression, param.AsNode())
342+
param.AsParameterDeclaration().Type = p.reparseJSDocTypeLiteral(setHost(p.reparseJSDocTypeLiteral(parameterTag.TypeExpression), param.AsNode()))
334343
}
335344
if param.QuestionToken == nil && param.Initializer == nil {
336-
if question := p.makeQuestionIfOptional(jsparam); question != nil {
345+
if question := p.makeQuestionIfOptional(parameterTag); question != nil {
337346
param.QuestionToken = question
338347
}
339348
}
@@ -461,11 +470,19 @@ func (p *Parser) makeQuestionIfOptional(parameter *ast.JSDocParameterTag) *ast.N
461470
return questionToken
462471
}
463472

464-
func findMatchingParameter(fun *ast.Node, tag *ast.JSDocParameterTag) (*ast.ParameterDeclaration, bool) {
465-
for _, parameter := range fun.Parameters() {
466-
if parameter.Name().Kind == ast.KindIdentifier && tag.Name().Kind == ast.KindIdentifier &&
467-
parameter.Name().Text() == tag.Name().Text() {
468-
return parameter.AsParameterDeclaration(), true
473+
func findMatchingParameter(fun *ast.Node, tag *ast.JSDocParameterTag, jsDoc *ast.Node) (*ast.ParameterDeclaration, bool) {
474+
tagIndex := core.FindIndex(jsDoc.AsJSDoc().Tags.Nodes, func(n *ast.Node) bool {
475+
return n.Kind == ast.KindJSDocParameterTag && n.AsJSDocParameterOrPropertyTag() == tag
476+
})
477+
for parameterIndex, parameter := range fun.Parameters() {
478+
if parameter.Name().Kind == ast.KindIdentifier {
479+
if tag.Name().Kind == ast.KindIdentifier && parameter.Name().Text() == tag.Name().Text() {
480+
return parameter.AsParameterDeclaration(), true
481+
}
482+
} else {
483+
if parameterIndex == tagIndex {
484+
return parameter.AsParameterDeclaration(), true
485+
}
469486
}
470487
}
471488
return nil, false
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/conformance/jsdoc/jsdocDestructuringParameterDeclaration.ts] ////
2+
3+
//// [a.js]
4+
/**
5+
* @param {{ a: number; b: string }} args
6+
*/
7+
function f({ a, b }) {}
8+
9+
10+
11+
12+
//// [a.d.ts]
13+
/**
14+
* @param {{ a: number; b: string }} args
15+
*/
16+
declare function f({ a, b }: {
17+
a: number;
18+
b: string;
19+
}): void;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [tests/cases/conformance/jsdoc/jsdocDestructuringParameterDeclaration.ts] ////
2+
3+
=== /a.js ===
4+
/**
5+
* @param {{ a: number; b: string }} args
6+
*/
7+
function f({ a, b }) {}
8+
>f : Symbol(f, Decl(a.js, 0, 0))
9+
>a : Symbol(a, Decl(a.js, 3, 12))
10+
>b : Symbol(b, Decl(a.js, 3, 15))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [tests/cases/conformance/jsdoc/jsdocDestructuringParameterDeclaration.ts] ////
2+
3+
=== /a.js ===
4+
/**
5+
* @param {{ a: number; b: string }} args
6+
*/
7+
function f({ a, b }) {}
8+
>f : ({ a, b }: { a: number; b: string; }) => void
9+
>a : number
10+
>b : string
11+

testdata/baselines/reference/conformance/jsdocParseAwait.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ const a = 1;
1414
/** @type {T} */
1515
const b = {
1616
>b : T
17-
>{ await: false,} : { await: boolean; }
17+
>{ await: false,} : { await: false; }
1818

1919
await: false,
20-
>await : boolean
20+
>await : false
2121
>false : false
2222

2323
};

testdata/baselines/reference/submodule/compiler/checkJsdocTypeTagOnExportAssignment8.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
/** @type {Foo} */
1313
export default {
14-
>{ a: 'a', b: 'b'} : { a: string; b: string; }
14+
>{ a: 'a', b: 'b'} : { a: string; b: "b"; }
1515

1616
a: 'a',
1717
>a : string
1818
>'a' : "a"
1919

2020
b: 'b'
21-
>b : string
21+
>b : "b"
2222
>'b' : "b"
2323
}
2424

testdata/baselines/reference/submodule/compiler/declarationEmitClassSetAccessorParamNameInJs2.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ export declare class Foo {
2020
*
2121
* @param {{ prop: string }} baz Baz.
2222
*/
23-
set bar({}: {});
23+
set bar({}: {
24+
prop: string;
25+
});
2426
}

testdata/baselines/reference/submodule/compiler/declarationEmitClassSetAccessorParamNameInJs2.js.diff

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,4 @@
88
+export declare class Foo {
99
/**
1010
* Bar.
11-
*
12-
* @param {{ prop: string }} baz Baz.
13-
*/
14-
- set bar({}: {
15-
- prop: string;
16-
- });
17-
+ set bar({}: {});
18-
}
11+
*

testdata/baselines/reference/submodule/compiler/declarationEmitClassSetAccessorParamNameInJs2.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ export class Foo {
1010
* @param {{ prop: string }} baz Baz.
1111
*/
1212
set bar({}) {}
13-
>bar : any
13+
>bar : { prop: string; }
1414
}
1515

testdata/baselines/reference/submodule/compiler/declarationEmitClassSetAccessorParamNameInJs3.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ export declare class Foo {
2121
* @param {{ prop: string | undefined }} baz Baz.
2222
*/
2323
set bar({ prop }: {
24-
prop?: string;
24+
prop: string | undefined;
2525
});
2626
}

0 commit comments

Comments
 (0)