Skip to content

Commit

Permalink
fix(es/parser): Wrap with OptChain across TsNonNull (#8332)
Browse files Browse the repository at this point in the history
**Related issue:**

- Closes #8326.
  • Loading branch information
magic-akari committed Nov 22, 2023
1 parent 7fd59b2 commit 8af6ffb
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 408 deletions.
20 changes: 20 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8326/1/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2019",
"loose": false,
"minify": {
"compress": false,
"mangle": false
},
"externalHelpers": true
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}
3 changes: 3 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8326/1/input/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function someFunc(a) {
const result = a?.b!.toString();
}
3 changes: 3 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8326/1/output/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function someFunc(a) {
const result = a === null || a === void 0 ? void 0 : a.b.toString();
}
36 changes: 24 additions & 12 deletions crates/swc_ecma_parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ impl<I: Tokens> Parser<I> {
}
}
Callee::Expr(obj) => {
let is_opt_chain = obj.is_opt_chain();
let is_opt_chain = unwrap_ts_non_null(&obj).is_opt_chain();
let expr = MemberExpr {
span,
obj,
Expand Down Expand Up @@ -1392,7 +1392,7 @@ impl<I: Tokens> Parser<I> {
let span = span!(self, start);
return if question_dot_token.is_some()
|| match &obj {
Callee::Expr(obj) => obj.is_opt_chain(),
Callee::Expr(obj) => unwrap_ts_non_null(obj).is_opt_chain(),
_ => false,
} {
match obj {
Expand Down Expand Up @@ -1493,7 +1493,9 @@ impl<I: Tokens> Parser<I> {
}
Callee::Expr(obj) => {
let expr = MemberExpr { span, obj, prop };
let expr = if expr.obj.is_opt_chain() || question_dot_token.is_some() {
let expr = if unwrap_ts_non_null(&expr.obj).is_opt_chain()
|| question_dot_token.is_some()
{
Expr::OptChain(OptChainExpr {
span: span!(self, start),
optional: question_dot_token.is_some(),
Expand Down Expand Up @@ -1656,16 +1658,18 @@ impl<I: Tokens> Parser<I> {
let args = self.parse_args(is_import)?;

let call_expr = match callee {
Callee::Expr(e) if e.is_opt_chain() => Box::new(Expr::OptChain(OptChainExpr {
span: span!(self, start),
base: Box::new(OptChainBase::Call(OptCall {
Callee::Expr(e) if unwrap_ts_non_null(&e).is_opt_chain() => {
Box::new(Expr::OptChain(OptChainExpr {
span: span!(self, start),
callee: e,
args,
type_args,
})),
optional: false,
})),
base: Box::new(OptChainBase::Call(OptCall {
span: span!(self, start),
callee: e,
args,
type_args,
})),
optional: false,
}))
}
_ => Box::new(Expr::Call(CallExpr {
span: span!(self, start),

Expand Down Expand Up @@ -2139,3 +2143,11 @@ impl<I: Tokens> Parser<I> {
|| (is!(self, '#') && peeked_is!(self, IdentName)))
}
}

fn unwrap_ts_non_null(mut expr: &Expr) -> &Expr {
while let Expr::TsNonNull(ts_non_null) = expr {
expr = &ts_non_null.expr;
}

expr
}
194 changes: 106 additions & 88 deletions crates/swc_ecma_parser/tests/tsc/callChain.json
Original file line number Diff line number Diff line change
Expand Up @@ -3700,85 +3700,94 @@
"ctxt": 0
},
"expression": {
"type": "MemberExpression",
"type": "OptionalChainingExpression",
"span": {
"start": 898,
"end": 915,
"ctxt": 0
},
"object": {
"type": "TsNonNullExpression",
"optional": false,
"base": {
"type": "MemberExpression",
"span": {
"start": 898,
"end": 906,
"end": 915,
"ctxt": 0
},
"expression": {
"type": "OptionalChainingExpression",
"object": {
"type": "TsNonNullExpression",
"span": {
"start": 898,
"end": 905,
"end": 906,
"ctxt": 0
},
"optional": false,
"base": {
"type": "CallExpression",
"expression": {
"type": "OptionalChainingExpression",
"span": {
"start": 898,
"end": 905,
"ctxt": 0
},
"callee": {
"type": "OptionalChainingExpression",
"optional": false,
"base": {
"type": "CallExpression",
"span": {
"start": 898,
"end": 903,
"end": 905,
"ctxt": 0
},
"optional": true,
"base": {
"type": "MemberExpression",
"callee": {
"type": "OptionalChainingExpression",
"span": {
"start": 898,
"end": 903,
"ctxt": 0
},
"object": {
"type": "Identifier",
"optional": true,
"base": {
"type": "MemberExpression",
"span": {
"start": 898,
"end": 900,
"ctxt": 0
},
"value": "o2",
"optional": false
},
"property": {
"type": "Identifier",
"span": {
"start": 902,
"end": 903,
"ctxt": 0
},
"value": "b",
"optional": false
"object": {
"type": "Identifier",
"span": {
"start": 898,
"end": 900,
"ctxt": 0
},
"value": "o2",
"optional": false
},
"property": {
"type": "Identifier",
"span": {
"start": 902,
"end": 903,
"ctxt": 0
},
"value": "b",
"optional": false
}
}
}
},
"arguments": [],
"typeArguments": null
},
"arguments": [],
"typeArguments": null
}
}
}
},
"property": {
"type": "Identifier",
"span": {
"start": 907,
"end": 915,
"ctxt": 0
},
"value": "toString",
"optional": false
"property": {
"type": "Identifier",
"span": {
"start": 907,
"end": 915,
"ctxt": 0
},
"value": "toString",
"optional": false
}
}
}
},
Expand All @@ -3797,85 +3806,94 @@
"ctxt": 0
},
"expression": {
"type": "MemberExpression",
"type": "OptionalChainingExpression",
"span": {
"start": 917,
"end": 934,
"ctxt": 0
},
"object": {
"type": "TsNonNullExpression",
"optional": false,
"base": {
"type": "MemberExpression",
"span": {
"start": 917,
"end": 925,
"end": 934,
"ctxt": 0
},
"expression": {
"type": "OptionalChainingExpression",
"object": {
"type": "TsNonNullExpression",
"span": {
"start": 917,
"end": 924,
"end": 925,
"ctxt": 0
},
"optional": false,
"base": {
"type": "CallExpression",
"expression": {
"type": "OptionalChainingExpression",
"span": {
"start": 917,
"end": 924,
"ctxt": 0
},
"callee": {
"type": "OptionalChainingExpression",
"optional": false,
"base": {
"type": "CallExpression",
"span": {
"start": 917,
"end": 922,
"end": 924,
"ctxt": 0
},
"optional": true,
"base": {
"type": "MemberExpression",
"callee": {
"type": "OptionalChainingExpression",
"span": {
"start": 917,
"end": 922,
"ctxt": 0
},
"object": {
"type": "Identifier",
"optional": true,
"base": {
"type": "MemberExpression",
"span": {
"start": 917,
"end": 919,
"ctxt": 0
},
"value": "o2",
"optional": false
},
"property": {
"type": "Identifier",
"span": {
"start": 921,
"end": 922,
"ctxt": 0
},
"value": "b",
"optional": false
"object": {
"type": "Identifier",
"span": {
"start": 917,
"end": 919,
"ctxt": 0
},
"value": "o2",
"optional": false
},
"property": {
"type": "Identifier",
"span": {
"start": 921,
"end": 922,
"ctxt": 0
},
"value": "b",
"optional": false
}
}
}
},
"arguments": [],
"typeArguments": null
},
"arguments": [],
"typeArguments": null
}
}
}
},
"property": {
"type": "Identifier",
"span": {
"start": 926,
"end": 934,
"ctxt": 0
},
"value": "toString",
"optional": false
"property": {
"type": "Identifier",
"span": {
"start": 926,
"end": 934,
"ctxt": 0
},
"value": "toString",
"optional": false
}
}
}
}
Expand Down

0 comments on commit 8af6ffb

Please sign in to comment.