mirror of
https://github.com/swc-project/swc.git
synced 2024-12-29 16:42:28 +03:00
fix(es/parser): Parse types in CallExpression
inside templates (#6611)
**Related issue:** - Closes https://github.com/swc-project/swc/issues/6601.
This commit is contained in:
parent
66b52824e5
commit
c44f1d0a7f
@ -369,9 +369,6 @@ pub struct Context {
|
|||||||
|
|
||||||
in_forced_jsx_context: bool,
|
in_forced_jsx_context: bool,
|
||||||
|
|
||||||
/// If true, `:` should not be treated as a type annotation.
|
|
||||||
dont_parse_colon_as_type_ann: bool,
|
|
||||||
|
|
||||||
// If true, allow super.x and super[x]
|
// If true, allow super.x and super[x]
|
||||||
allow_direct_super: bool,
|
allow_direct_super: bool,
|
||||||
|
|
||||||
|
@ -218,7 +218,6 @@ impl<I: Tokens> Parser<I> {
|
|||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
in_cond_expr: true,
|
in_cond_expr: true,
|
||||||
will_expect_colon_for_cond: false,
|
will_expect_colon_for_cond: false,
|
||||||
dont_parse_colon_as_type_ann: false,
|
|
||||||
..self.ctx()
|
..self.ctx()
|
||||||
};
|
};
|
||||||
let alt = self.with_ctx(ctx).parse_assignment_expr()?;
|
let alt = self.with_ctx(ctx).parse_assignment_expr()?;
|
||||||
@ -306,7 +305,6 @@ impl<I: Tokens> Parser<I> {
|
|||||||
tok!('[') => {
|
tok!('[') => {
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
will_expect_colon_for_cond: false,
|
will_expect_colon_for_cond: false,
|
||||||
dont_parse_colon_as_type_ann: false,
|
|
||||||
..self.ctx()
|
..self.ctx()
|
||||||
};
|
};
|
||||||
return self.with_ctx(ctx).parse_array_lit();
|
return self.with_ctx(ctx).parse_array_lit();
|
||||||
@ -378,8 +376,13 @@ impl<I: Tokens> Parser<I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tok!('`') => {
|
tok!('`') => {
|
||||||
|
let ctx = Context {
|
||||||
|
will_expect_colon_for_cond: false,
|
||||||
|
..self.ctx()
|
||||||
|
};
|
||||||
|
|
||||||
// parse template literal
|
// parse template literal
|
||||||
return Ok(Box::new(Expr::Tpl(self.parse_tpl(false)?)));
|
return Ok(Box::new(Expr::Tpl(self.with_ctx(ctx).parse_tpl(false)?)));
|
||||||
}
|
}
|
||||||
|
|
||||||
tok!('(') => {
|
tok!('(') => {
|
||||||
@ -841,7 +844,6 @@ impl<I: Tokens> Parser<I> {
|
|||||||
let return_type = if !self.ctx().will_expect_colon_for_cond
|
let return_type = if !self.ctx().will_expect_colon_for_cond
|
||||||
&& self.input.syntax().typescript()
|
&& self.input.syntax().typescript()
|
||||||
&& is!(self, ':')
|
&& is!(self, ':')
|
||||||
&& !self.ctx().dont_parse_colon_as_type_ann
|
|
||||||
{
|
{
|
||||||
self.try_parse_ts(|p| {
|
self.try_parse_ts(|p| {
|
||||||
let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?;
|
let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?;
|
||||||
@ -1470,7 +1472,12 @@ impl<I: Tokens> Parser<I> {
|
|||||||
|
|
||||||
// MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
|
// MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
|
||||||
if is!(self, '`') {
|
if is!(self, '`') {
|
||||||
let tpl = self.parse_tagged_tpl(expr, None)?;
|
let ctx = Context {
|
||||||
|
will_expect_colon_for_cond: false,
|
||||||
|
..self.ctx()
|
||||||
|
};
|
||||||
|
|
||||||
|
let tpl = self.with_ctx(ctx).parse_tagged_tpl(expr, None)?;
|
||||||
return Ok((Box::new(Expr::TaggedTpl(tpl)), true));
|
return Ok((Box::new(Expr::TaggedTpl(tpl)), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ impl<I: Tokens> Parser<I> {
|
|||||||
{
|
{
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
will_expect_colon_for_cond: false,
|
will_expect_colon_for_cond: false,
|
||||||
dont_parse_colon_as_type_ann: false,
|
|
||||||
..self.ctx()
|
..self.ctx()
|
||||||
};
|
};
|
||||||
self.with_ctx(ctx).parse_with(|p| {
|
self.with_ctx(ctx).parse_with(|p| {
|
||||||
|
@ -610,15 +610,8 @@ impl<'a, I: Tokens> Parser<I> {
|
|||||||
let is_case = is!(p, "case");
|
let is_case = is!(p, "case");
|
||||||
let case_start = cur_pos!(p);
|
let case_start = cur_pos!(p);
|
||||||
bump!(p);
|
bump!(p);
|
||||||
let ctx = Context {
|
|
||||||
dont_parse_colon_as_type_ann: true,
|
|
||||||
..p.ctx()
|
|
||||||
};
|
|
||||||
let test = if is_case {
|
let test = if is_case {
|
||||||
p.with_ctx(ctx)
|
p.include_in_expr(true).parse_expr().map(Some)?
|
||||||
.include_in_expr(true)
|
|
||||||
.parse_expr()
|
|
||||||
.map(Some)?
|
|
||||||
} else {
|
} else {
|
||||||
if let Some(previous) = span_of_previous_default {
|
if let Some(previous) = span_of_previous_default {
|
||||||
syntax_error!(p, SyntaxError::MultipleDefault { previous });
|
syntax_error!(p, SyntaxError::MultipleDefault { previous });
|
||||||
|
104
crates/swc_ecma_parser/tests/typescript/issue-6601/index.tsx
Normal file
104
crates/swc_ecma_parser/tests/typescript/issue-6601/index.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
function exampleFunction1() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? `<button
|
||||||
|
@click="${(): void => console.log('this line causes a syntax error')}"
|
||||||
|
></button>`
|
||||||
|
: `<button
|
||||||
|
@click="${(): void => console.log('this line does NOT causes a syntax error')}"
|
||||||
|
></button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction2() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? `<bar></bar>` + `<button
|
||||||
|
@click="${(): void => console.log('this line causes a syntax error')}"
|
||||||
|
></button>`
|
||||||
|
: `<bar></bar>` + `<button
|
||||||
|
@click="${(): void => console.log('this line does NOT causes a syntax error')}"
|
||||||
|
></button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction3() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? (): void => console.log('this line causes a syntax error')
|
||||||
|
: (): void => console.log('this line does NOT causes a syntax error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction4() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? function (): void { console.log('this line causes a syntax error') }
|
||||||
|
: function (): void { console.log('this line does NOT causes a syntax error') };
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction5() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? (function (): void { console.log('this line causes a syntax error') })
|
||||||
|
: (function (): void { console.log('this line does NOT causes a syntax error') });
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction6() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? "test" == "test"
|
||||||
|
? `<button @click="${(): void => console.log('this line causes a syntax error')}"></button>`
|
||||||
|
: "bar"
|
||||||
|
: `<button
|
||||||
|
@click="${(): void => console.log('this line does NOT causes a syntax error')}"
|
||||||
|
></button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function exampleFunction6() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? `<button @click="${(): void => console.log('this line causes a syntax error')}"></button>`
|
||||||
|
: "test" == "test"
|
||||||
|
? `<button @click="${(): void => console.log('this line causes a syntax error')}"></button>`
|
||||||
|
: "bar";
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction7() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? foo`<button @click="${(): void => console.log('this line causes a syntax error')}"></button>`
|
||||||
|
: bar`<button @click="${(): void => console.log('this line does NOT causes a syntax error')}"></button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction8() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? ((): void => console.log('this line causes a syntax error'))
|
||||||
|
: ((): void => console.log('this line does NOT causes a syntax error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction9() {
|
||||||
|
return Math.random() > 0.5
|
||||||
|
? async (): Promise<void> => console.log('this line causes a syntax error')
|
||||||
|
: async (): Promise<void> => console.log('this line causes a syntax error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction10() {
|
||||||
|
const foo = "Oranges";
|
||||||
|
|
||||||
|
switch (foo) {
|
||||||
|
case 'Oranges': {
|
||||||
|
return `<button @click="${(): void => console.log('this line causes a syntax error')}" ></button>`;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
console.log(`Sorry, we are out of test.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction11() {
|
||||||
|
switch (true) {
|
||||||
|
case ((): boolean => true)(): {
|
||||||
|
console.log('This shape is a square.');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exampleFunction12() {
|
||||||
|
switch (((): boolean => true)()) {
|
||||||
|
case ((): boolean => true)(): {
|
||||||
|
console.log('This shape is a square.');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4191
crates/swc_ecma_parser/tests/typescript/issue-6601/index.tsx.json
Normal file
4191
crates/swc_ecma_parser/tests/typescript/issue-6601/index.tsx.json
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user