Skip to content

Commit

Permalink
fix(es/parser): Parse yield<T> (v: T)=>v (#9915)
Browse files Browse the repository at this point in the history
**Related issue:**

- Closes #9914
  • Loading branch information
magic-akari authored Jan 24, 2025
1 parent 5c8eaee commit 04333aa
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 24 deletions.
6 changes: 6 additions & 0 deletions .changeset/pink-kids-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
swc_core: patch
swc_ecma_parser: patch
---

fix(es/parser): Parse `yield<T> (v: T)=>v`
47 changes: 23 additions & 24 deletions crates/swc_ecma_parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,32 @@ impl<I: Tokens> Parser<I> {
pub(super) fn parse_assignment_expr(&mut self) -> PResult<Box<Expr>> {
trace_cur!(self, parse_assignment_expr);

if self.input.syntax().typescript() && self.input.syntax().jsx() {
if self.input.syntax().typescript() && is!(self, JSXTagStart) {
// Note: When the JSX plugin is on, type assertions (`<T> x`) aren't valid
// syntax.

if is!(self, JSXTagStart) {
let cur_context = self.input.token_context().current();
debug_assert_eq!(cur_context, Some(TokenContext::JSXOpeningTag));
// Only time j_oTag is pushed is right after j_expr.
let cur_context = self.input.token_context().current();
debug_assert_eq!(cur_context, Some(TokenContext::JSXOpeningTag));
// Only time j_oTag is pushed is right after j_expr.
debug_assert_eq!(
self.input.token_context().0[self.input.token_context().len() - 2],
TokenContext::JSXExpr
);

let res = self.try_parse_ts(|p| p.parse_assignment_expr_base().map(Some));
if let Some(res) = res {
return Ok(res);
} else {
debug_assert_eq!(
self.input.token_context().0[self.input.token_context().len() - 2],
TokenContext::JSXExpr
self.input.token_context().current(),
Some(TokenContext::JSXOpeningTag)
);

let res = self.try_parse_ts(|p| p.parse_assignment_expr_base().map(Some));
if let Some(res) = res {
return Ok(res);
} else {
debug_assert_eq!(
self.input.token_context().current(),
Some(TokenContext::JSXOpeningTag)
);
self.input.token_context_mut().pop();
debug_assert_eq!(
self.input.token_context().current(),
Some(TokenContext::JSXExpr)
);
self.input.token_context_mut().pop();
}
self.input.token_context_mut().pop();
debug_assert_eq!(
self.input.token_context().current(),
Some(TokenContext::JSXExpr)
);
self.input.token_context_mut().pop();
}
}

Expand Down Expand Up @@ -2004,7 +2002,8 @@ impl<I: Tokens> Parser<I> {
}

if is!(self, ';')
|| (!is!(self, '*')
|| (!is!(self, '<')
&& !is!(self, '*')
&& !is!(self, '/')
&& !is!(self, "/=")
&& !cur!(self, false)
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_ecma_parser/tests/typescript/issue-9914/1/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(function* () {
yield <T>(v: T) => v;
});
153 changes: 153 additions & 0 deletions crates/swc_ecma_parser/tests/typescript/issue-9914/1/input.ts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 46
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 46
},
"expression": {
"type": "ParenthesisExpression",
"span": {
"start": 1,
"end": 45
},
"expression": {
"type": "FunctionExpression",
"identifier": null,
"params": [],
"decorators": [],
"span": {
"start": 2,
"end": 44
},
"ctxt": 0,
"body": {
"type": "BlockStatement",
"span": {
"start": 15,
"end": 44
},
"ctxt": 0,
"stmts": [
{
"type": "ExpressionStatement",
"span": {
"start": 21,
"end": 42
},
"expression": {
"type": "YieldExpression",
"span": {
"start": 21,
"end": 41
},
"argument": {
"type": "ArrowFunctionExpression",
"span": {
"start": 27,
"end": 41
},
"ctxt": 0,
"params": [
{
"type": "Identifier",
"span": {
"start": 31,
"end": 35
},
"ctxt": 0,
"value": "v",
"optional": false,
"typeAnnotation": {
"type": "TsTypeAnnotation",
"span": {
"start": 32,
"end": 35
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 34,
"end": 35
},
"typeName": {
"type": "Identifier",
"span": {
"start": 34,
"end": 35
},
"ctxt": 0,
"value": "T",
"optional": false
},
"typeParams": null
}
}
}
],
"body": {
"type": "Identifier",
"span": {
"start": 40,
"end": 41
},
"ctxt": 0,
"value": "v",
"optional": false
},
"async": false,
"generator": false,
"typeParameters": {
"type": "TsTypeParameterDeclaration",
"span": {
"start": 27,
"end": 30
},
"parameters": [
{
"type": "TsTypeParameter",
"span": {
"start": 28,
"end": 29
},
"name": {
"type": "Identifier",
"span": {
"start": 28,
"end": 29
},
"ctxt": 0,
"value": "T",
"optional": false
},
"in": false,
"out": false,
"const": false,
"constraint": null,
"default": null
}
]
},
"returnType": null
},
"delegate": false
}
}
]
},
"generator": true,
"async": false,
"typeParameters": null,
"returnType": null
}
}
}
],
"interpreter": null
}
3 changes: 3 additions & 0 deletions crates/swc_ecma_parser/tests/typescript/issue-9914/2/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(function* () {
yield <T,>(v: T) => v;
});
153 changes: 153 additions & 0 deletions crates/swc_ecma_parser/tests/typescript/issue-9914/2/input.ts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{
"type": "Script",
"span": {
"start": 1,
"end": 47
},
"body": [
{
"type": "ExpressionStatement",
"span": {
"start": 1,
"end": 47
},
"expression": {
"type": "ParenthesisExpression",
"span": {
"start": 1,
"end": 46
},
"expression": {
"type": "FunctionExpression",
"identifier": null,
"params": [],
"decorators": [],
"span": {
"start": 2,
"end": 45
},
"ctxt": 0,
"body": {
"type": "BlockStatement",
"span": {
"start": 15,
"end": 45
},
"ctxt": 0,
"stmts": [
{
"type": "ExpressionStatement",
"span": {
"start": 21,
"end": 43
},
"expression": {
"type": "YieldExpression",
"span": {
"start": 21,
"end": 42
},
"argument": {
"type": "ArrowFunctionExpression",
"span": {
"start": 27,
"end": 42
},
"ctxt": 0,
"params": [
{
"type": "Identifier",
"span": {
"start": 32,
"end": 36
},
"ctxt": 0,
"value": "v",
"optional": false,
"typeAnnotation": {
"type": "TsTypeAnnotation",
"span": {
"start": 33,
"end": 36
},
"typeAnnotation": {
"type": "TsTypeReference",
"span": {
"start": 35,
"end": 36
},
"typeName": {
"type": "Identifier",
"span": {
"start": 35,
"end": 36
},
"ctxt": 0,
"value": "T",
"optional": false
},
"typeParams": null
}
}
}
],
"body": {
"type": "Identifier",
"span": {
"start": 41,
"end": 42
},
"ctxt": 0,
"value": "v",
"optional": false
},
"async": false,
"generator": false,
"typeParameters": {
"type": "TsTypeParameterDeclaration",
"span": {
"start": 27,
"end": 31
},
"parameters": [
{
"type": "TsTypeParameter",
"span": {
"start": 28,
"end": 29
},
"name": {
"type": "Identifier",
"span": {
"start": 28,
"end": 29
},
"ctxt": 0,
"value": "T",
"optional": false
},
"in": false,
"out": false,
"const": false,
"constraint": null,
"default": null
}
]
},
"returnType": null
},
"delegate": false
}
}
]
},
"generator": true,
"async": false,
"typeParameters": null,
"returnType": null
}
}
}
],
"interpreter": null
}

0 comments on commit 04333aa

Please sign in to comment.