Skip to content

Commit fc2e4e5

Browse files
committed
Rebase #11163
1 parent 53be991 commit fc2e4e5

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

crates/swc_ecma_parser/src/parser/typescript.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fmt::Write;
1+
use std::{fmt::Write, mem};
22

33
use either::Either;
44
use swc_atoms::{atom, Atom, Wtf8Atom};
@@ -954,8 +954,10 @@ impl<I: Tokens> Parser<I> {
954954
debug_assert!(self.input().syntax().typescript());
955955

956956
let start = self.cur_pos();
957-
// Computed property names are grammar errors in an enum, so accept just string
958-
// literal or identifier.
957+
// TypeScript allows computed property names with literal expressions in enums.
958+
// Non-literal computed properties (like ["a" + "b"]) are rejected.
959+
// We normalize literal computed properties (["\t"] → "\t") to keep AST simple.
960+
// See https://github.com/swc-project/swc/issues/11160
959961
let cur = self.input().cur();
960962
let id = if cur == Token::Str {
961963
TsEnumMemberId::Str(self.parse_str_lit())
@@ -979,10 +981,35 @@ impl<I: Tokens> Parser<I> {
979981
})
980982
} else if cur == Token::LBracket {
981983
self.assert_and_bump(Token::LBracket);
982-
let _ = self.parse_expr()?;
983-
self.emit_err(self.span(start), SyntaxError::TS1164);
984+
let expr = self.parse_expr()?;
984985
self.assert_and_bump(Token::RBracket);
985-
TsEnumMemberId::Ident(Ident::new_no_ctxt(atom!(""), self.span(start)))
986+
let bracket_span = self.span(start);
987+
988+
match *expr {
989+
Expr::Lit(Lit::Str(str_lit)) => {
990+
// String literal: ["\t"] → "\t"
991+
TsEnumMemberId::Str(str_lit)
992+
}
993+
Expr::Tpl(mut tpl) if tpl.exprs.is_empty() => {
994+
// Template literal without substitution: [`hello`] → "hello"
995+
996+
let tpl = mem::take(tpl.quasis.first_mut().unwrap());
997+
998+
let span = tpl.span;
999+
let value = tpl.cooked.unwrap();
1000+
1001+
TsEnumMemberId::Str(Str {
1002+
span,
1003+
value,
1004+
raw: None,
1005+
})
1006+
}
1007+
_ => {
1008+
// Non-literal expression: report error
1009+
self.emit_err(bracket_span, SyntaxError::TS1164);
1010+
TsEnumMemberId::Ident(Ident::new_no_ctxt(atom!(""), bracket_span))
1011+
}
1012+
}
9861013
} else if cur == Token::Error {
9871014
let err = self.input_mut().expect_error_token_and_bump();
9881015
return Err(err);

0 commit comments

Comments
 (0)