Skip to content

Commit f40f59b

Browse files
authoredJan 19, 2024
fix(es/typescript): Fix panic on invalid jsx pragma (#8513)
**Description:** Currently a jsx pragma with an invalid js identifier (eg, with dashes: `@jsx bad-pragma` causes a panic. This PR prevents a panic and will ignore an invalid pragma in a comment. (There may be an argument for showing an error or warning instead, but given a jsx pragma is still valid ES I'm not sure whether that makes sense?) [Original (Deno) issue here](denoland/deno#21927)
1 parent 3c00098 commit f40f59b

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed
 

‎crates/swc_ecma_transforms_typescript/src/typescript.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,12 @@ where
122122
/// Get an [Id] which will used by expression.
123123
///
124124
/// For `React#1.createElement`, this returns `React#1`.
125-
fn id_for_jsx(e: &Expr) -> Id {
125+
fn id_for_jsx(e: &Expr) -> Option<Id> {
126126
match e {
127-
Expr::Ident(i) => i.to_id(),
128-
Expr::Member(MemberExpr { obj, .. }) => id_for_jsx(obj),
129-
Expr::Lit(Lit::Null(..)) => ("null".into(), Default::default()),
130-
_ => {
131-
panic!("failed to determine top-level Id for jsx expression")
132-
}
127+
Expr::Ident(i) => Some(i.to_id()),
128+
Expr::Member(MemberExpr { obj, .. }) => Some(id_for_jsx(obj)).flatten(),
129+
Expr::Lit(Lit::Null(..)) => Some(("null".into(), Default::default())),
130+
_ => None,
133131
}
134132
}
135133

@@ -175,8 +173,8 @@ where
175173
self.top_level_mark,
176174
);
177175

178-
let pragma_id = id_for_jsx(&pragma);
179-
let pragma_frag_id = id_for_jsx(&pragma_frag);
176+
let pragma_id = id_for_jsx(&pragma).unwrap();
177+
let pragma_frag_id = id_for_jsx(&pragma_frag).unwrap();
180178

181179
self.id_usage.insert(pragma_id);
182180
self.id_usage.insert(pragma_frag_id);
@@ -199,13 +197,15 @@ where
199197
});
200198

201199
if let Some(pragma) = pragma {
202-
let pragma_id = id_for_jsx(&pragma);
203-
self.id_usage.insert(pragma_id);
200+
if let Some(pragma_id) = id_for_jsx(&pragma) {
201+
self.id_usage.insert(pragma_id);
202+
}
204203
}
205204

206205
if let Some(pragma_frag) = pragma_frag {
207-
let pragma_frag_id = id_for_jsx(&pragma_frag);
208-
self.id_usage.insert(pragma_frag_id);
206+
if let Some(pragma_frag_id) = id_for_jsx(&pragma_frag) {
207+
self.id_usage.insert(pragma_frag_id);
208+
}
209209
}
210210
}
211211
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/** @jsx bad-pragma */

‎crates/swc_ecma_transforms_typescript/tests/strip.rs

+24
Original file line numberDiff line numberDiff line change
@@ -2797,3 +2797,27 @@ test!(
27972797
console.log(I.A);
27982798
"#
27992799
);
2800+
2801+
test!(
2802+
Syntax::Typescript(TsConfig::default()),
2803+
|t| {
2804+
let unresolved_mark = Mark::new();
2805+
let top_level_mark = Mark::new();
2806+
2807+
chain!(
2808+
resolver(unresolved_mark, top_level_mark, false),
2809+
tsx(
2810+
t.cm.clone(),
2811+
typescript::Config {
2812+
verbatim_module_syntax: false,
2813+
..Default::default()
2814+
},
2815+
TsxConfig::default(),
2816+
t.comments.clone(),
2817+
top_level_mark,
2818+
)
2819+
)
2820+
},
2821+
ts_jsx_bad_pragma,
2822+
r#"/** @jsx bad-pragma */"#
2823+
);

0 commit comments

Comments
 (0)