diff --git a/crates/swc/tests/fixture/issues-7xxx/7938/input/.swcrc b/crates/swc/tests/fixture/issues-7xxx/7938/input/.swcrc new file mode 100644 index 00000000000..4617fdd2b7a --- /dev/null +++ b/crates/swc/tests/fixture/issues-7xxx/7938/input/.swcrc @@ -0,0 +1,19 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true + }, + "target": "es2019", + "loose": false, + "minify": { + "compress": false, + "mangle": false + } + }, + "module": { + "type": "es6" + }, + "minify": false, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-7xxx/7938/input/1.js b/crates/swc/tests/fixture/issues-7xxx/7938/input/1.js new file mode 100644 index 00000000000..44e97cd2d12 --- /dev/null +++ b/crates/swc/tests/fixture/issues-7xxx/7938/input/1.js @@ -0,0 +1 @@ +/** @jsx foo-bar */ diff --git a/crates/swc/tests/fixture/issues-8xxx/8572/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8572/input/.swcrc new file mode 100644 index 00000000000..5e56088a8fa --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8572/input/.swcrc @@ -0,0 +1,25 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true + }, + "target": "es2022", + "loose": false, + "minify": { + "compress": false, + "mangle": false + }, + "transform": { + "react": { + "importSource": "npm:react", + "runtime": "automatic" + } + } + }, + "module": { + "type": "es6" + }, + "minify": false, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8572/input/1.js b/crates/swc/tests/fixture/issues-8xxx/8572/input/1.js new file mode 100644 index 00000000000..e48eb63782d --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8572/input/1.js @@ -0,0 +1 @@ +/** @jsx a- */ \ No newline at end of file diff --git a/crates/swc_ecma_transforms_react/src/jsx/mod.rs b/crates/swc_ecma_transforms_react/src/jsx/mod.rs index be97d9f2fb3..f157d9923f5 100644 --- a/crates/swc_ecma_transforms_react/src/jsx/mod.rs +++ b/crates/swc_ecma_transforms_react/src/jsx/mod.rs @@ -118,7 +118,7 @@ pub fn parse_expr_for_jsx( src: String, top_level_mark: Mark, ) -> Arc> { - let fm = cm.new_source_file(FileName::Internal(format!("", name)), src); + let fm = cm.new_source_file(FileName::Internal(format!("jsx-config-{}.js", name)), src); parse_file_as_expr( &fm, @@ -131,7 +131,7 @@ pub fn parse_expr_for_jsx( if HANDLER.is_set() { HANDLER.with(|h| { e.into_diagnostic(h) - .note("error detected while parsing option for classic jsx transform") + .note("Failed to parse jsx pragma") .emit() }) } @@ -339,30 +339,34 @@ impl JsxDirectives { } Some("@jsxFrag") => { if let Some(src) = val { - // TODO: Optimize - let mut e = (*parse_expr_for_jsx( - cm, - "module-jsx-pragma-frag", - src.to_string(), - top_level_mark, - )) - .clone(); - respan(&mut e, cmt.span); - res.pragma_frag = Some(e.into()) + if is_valid_for_pragma(src) { + // TODO: Optimize + let mut e = (*parse_expr_for_jsx( + cm, + "module-jsx-pragma-frag", + src.to_string(), + top_level_mark, + )) + .clone(); + respan(&mut e, cmt.span); + res.pragma_frag = Some(e.into()) + } } } Some("@jsx") => { if let Some(src) = val { - // TODO: Optimize - let mut e = (*parse_expr_for_jsx( - cm, - "module-jsx-pragma", - src.to_string(), - top_level_mark, - )) - .clone(); - respan(&mut e, cmt.span); - res.pragma = Some(e.into()); + if is_valid_for_pragma(src) { + // TODO: Optimize + let mut e = (*parse_expr_for_jsx( + cm, + "module-jsx-pragma", + src.to_string(), + top_level_mark, + )) + .clone(); + respan(&mut e, cmt.span); + res.pragma = Some(e.into()); + } } } _ => {} @@ -375,6 +379,24 @@ impl JsxDirectives { } } +fn is_valid_for_pragma(s: &str) -> bool { + if s.is_empty() { + return false; + } + + if !s.starts_with(|c: char| Ident::is_valid_start(c)) { + return false; + } + + for c in s.chars() { + if !Ident::is_valid_continue(c) && c != '.' { + return false; + } + } + + true +} + impl Jsx where C: Comments,