Skip to content

Commit 429d093

Browse files
authored
Add this/satisfies tag (#1157)
1 parent 3a7e5c1 commit 429d093

File tree

90 files changed

+205
-974
lines changed

Some content is hidden

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

90 files changed

+205
-974
lines changed

internal/parser/reparser.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
224224
}
225225
case ast.KindReturnStatement:
226226
ret := parent.AsReturnStatement()
227-
ret.Expression = p.makeNewTypeAssertion(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), ret.Expression)
227+
ret.Expression = p.makeNewCast(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), ret.Expression, true /*isAssertion*/)
228228
case ast.KindParenthesizedExpression:
229229
paren := parent.AsParenthesizedExpression()
230-
paren.Expression = p.makeNewTypeAssertion(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), paren.Expression)
230+
paren.Expression = p.makeNewCast(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), paren.Expression, true /*isAssertion*/)
231231
case ast.KindExpressionStatement:
232232
if parent.AsExpressionStatement().Expression.Kind == ast.KindBinaryExpression {
233233
bin := parent.AsExpressionStatement().Expression.AsBinaryExpression()
@@ -236,6 +236,11 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
236236
}
237237
}
238238
}
239+
case ast.KindJSDocSatisfiesTag:
240+
if parent.Kind == ast.KindParenthesizedExpression {
241+
paren := parent.AsParenthesizedExpression()
242+
paren.Expression = p.makeNewCast(p.makeNewType(tag.AsJSDocSatisfiesTag().TypeExpression, nil), paren.Expression, false /*isAssertion*/)
243+
}
239244
case ast.KindJSDocTemplateTag:
240245
if fun, ok := getFunctionLikeHost(parent); ok {
241246
if fun.TypeParameters() == nil {
@@ -266,6 +271,31 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
266271
}
267272
}
268273
}
274+
case ast.KindJSDocThisTag:
275+
if fun, ok := getFunctionLikeHost(parent); ok {
276+
params := fun.Parameters()
277+
if len(params) == 0 || params[0].Name().Kind != ast.KindThisKeyword {
278+
thisParam := p.factory.NewParameterDeclaration(
279+
nil, /* decorators */
280+
nil, /* modifiers */
281+
p.factory.NewIdentifier("this"),
282+
nil, /* questionToken */
283+
nil, /* type */
284+
nil, /* initializer */
285+
)
286+
thisParam.AsParameterDeclaration().Type = p.makeNewType(tag.AsJSDocThisTag().TypeExpression, thisParam)
287+
thisParam.Loc = tag.AsJSDocThisTag().TagName.Loc
288+
thisParam.Flags = p.contextFlags | ast.NodeFlagsReparsed
289+
290+
newParams := p.nodeSlicePool.NewSlice(len(params) + 1)
291+
newParams[0] = thisParam
292+
for i, param := range params {
293+
newParams[i+1] = param
294+
}
295+
296+
fun.FunctionLikeData().Parameters = p.newNodeList(thisParam.Loc, newParams)
297+
}
298+
}
269299
case ast.KindJSDocReturnTag:
270300
if fun, ok := getFunctionLikeHost(parent); ok {
271301
if fun.Type() == nil {
@@ -351,7 +381,6 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
351381
}
352382
}
353383
}
354-
// !!! other attached tags (@this, @satisfies) support goes here
355384
}
356385

357386
func (p *Parser) makeQuestionIfOptional(parameter *ast.JSDocParameterTag) *ast.Node {
@@ -398,8 +427,13 @@ func getFunctionLikeHost(host *ast.Node) (*ast.Node, bool) {
398427
return nil, false
399428
}
400429

401-
func (p *Parser) makeNewTypeAssertion(t *ast.TypeNode, e *ast.Node) *ast.Node {
402-
assert := p.factory.NewTypeAssertion(t, e)
430+
func (p *Parser) makeNewCast(t *ast.TypeNode, e *ast.Node, isAssertion bool) *ast.Node {
431+
var assert *ast.Node
432+
if isAssertion {
433+
assert = p.factory.NewAsExpression(e, t)
434+
} else {
435+
assert = p.factory.NewSatisfiesExpression(e, t)
436+
}
403437
assert.Flags = p.contextFlags | ast.NodeFlagsReparsed
404438
assert.Loc = core.NewTextRange(e.Pos(), e.End())
405439
return assert

internal/testutil/tsbaseline/type_symbol_baseline.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,15 @@ func forEachASTNode(node *ast.Node) []*ast.Node {
327327
for len(work) > 0 {
328328
elem := work[len(work)-1]
329329
work = work[:len(work)-1]
330-
if elem.Flags&ast.NodeFlagsReparsed != 0 && elem.Kind != ast.KindTypeAssertionExpression {
331-
continue
330+
if elem.Flags&ast.NodeFlagsReparsed == 0 || elem.Kind == ast.KindAsExpression || elem.Kind == ast.KindSatisfiesExpression {
331+
if elem.Flags&ast.NodeFlagsReparsed == 0 {
332+
result = append(result, elem)
333+
}
334+
elem.ForEachChild(addChild)
335+
slices.Reverse(resChildren)
336+
work = append(work, resChildren...)
337+
resChildren = resChildren[:0]
332338
}
333-
result = append(result, elem)
334-
elem.ForEachChild(addChild)
335-
slices.Reverse(resChildren)
336-
work = append(work, resChildren...)
337-
resChildren = resChildren[:0]
338339
}
339340
return result
340341
}

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const foo1 = value => /** @type {string} */({ ...value });
1111
>value => /** @type {string} */({ ...value }) : <T>(value: T | undefined) => T
1212
>value : T | undefined
1313
>({ ...value }) : string
14-
>{ ...value } : string
1514
>{ ...value } : {}
1615
>value : T | undefined
1716

@@ -25,9 +24,7 @@ const foo2 = value => /** @type {string} */(/** @type {T} */({ ...value }));
2524
>value => /** @type {string} */(/** @type {T} */({ ...value })) : <T>(value: T | undefined) => T
2625
>value : T | undefined
2726
>(/** @type {T} */({ ...value })) : string
28-
>({ ...value }) : string
2927
>({ ...value }) : T
30-
>{ ...value } : T
3128
>{ ...value } : {}
3229
>value : T | undefined
3330

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const cloneObjectGood = value => /** @type {T} */({ ...value });
1111
>value => /** @type {T} */({ ...value }) : <T>(value: T | undefined) => T
1212
>value : T | undefined
1313
>({ ...value }) : T
14-
>{ ...value } : T
1514
>{ ...value } : {}
1615
>value : T | undefined
1716

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ module.exports = /** @type {FooFun} */(void 0);
2929
>module : { "export=": (foo: typeof import("./file")) => string; }
3030
>exports : (foo: typeof import("./file")) => string
3131
>(void 0) : (foo: typeof import("./file")) => string
32-
>void 0 : (foo: typeof import("./file")) => string
3332
>void 0 : undefined
3433
>0 : 0
3534

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ function foo(fns) {
1919

2020
return /** @type {any} */ (null);
2121
>(null) : any
22-
>null : any
2322
}
2423

2524
const result = foo({

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ function filter(predicate) {
1212

1313
return /** @type {any} */ (null);
1414
>(null) : any
15-
>null : any
1615
}
1716

1817
const a = filter(

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
export default /** @type {NumberLike[]} */([ ]);
1010
>([ ]) : (string | number)[]
11-
>[ ] : (string | number)[]
1211
>[ ] : undefined[]
1312

1413
=== b.ts ===

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ function flatMap(array, iterable = identity) {
8989
>push : (...items: unknown[]) => number
9090
>.../** @type {unknown[]} */(iterable(array[i])) : unknown
9191
>(iterable(array[i])) : unknown[]
92-
>iterable(array[i]) : unknown[]
9392
>iterable(array[i]) : unknown
9493
>iterable : (x: unknown) => unknown
9594
>array[i] : unknown

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ function flatMap(array, iterable = identity) {
8484
>push : (...items: unknown[]) => number
8585
>.../** @type {unknown[]} */(iterable(array[i])) : unknown
8686
>(iterable(array[i])) : unknown[]
87-
>iterable(array[i]) : unknown[]
8887
>iterable(array[i]) : unknown
8988
>iterable : (x: unknown) => unknown
9089
>array[i] : unknown

0 commit comments

Comments
 (0)