Skip to content

Commit

Permalink
fix(es/typescript): Handle exported JSX binding name in TypeScript na…
Browse files Browse the repository at this point in the history
…mespace (#8596)

**Related issue:**

 - Closes #8594
  • Loading branch information
magic-akari authored Feb 3, 2024
1 parent 190c4e2 commit 2a70a6b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 3 deletions.
19 changes: 19 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8594/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2015",
"loose": false,
"minify": {
"compress": false,
"mangle": false
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}
6 changes: 6 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8594/input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react';

export namespace FooNs {
export const Shared = () => 'I\'m shared component';
export const Main = () => <Shared/>;
}
6 changes: 6 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8594/output/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react';
export var FooNs;
(function(FooNs) {
FooNs.Shared = ()=>'I\'m shared component';
FooNs.Main = ()=>React.createElement(FooNs.Shared, null);
})(FooNs || (FooNs = {}));
5 changes: 5 additions & 0 deletions crates/swc_ecma_transforms_module/src/module_ref_rewriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ impl QueryRef for ImportQuery {
None
}

fn query_jsx(&self, _: &Ident) -> Option<JSXElementName> {
// We do not need to handle JSX since there is no jsx preserve option in swc
None
}

fn should_fix_this(&self, ident: &Ident) -> bool {
if self.helper_ctxt.iter().any(|ctxt| ctxt == &ident.span.ctxt) {
return false;
Expand Down
10 changes: 10 additions & 0 deletions crates/swc_ecma_transforms_typescript/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,16 @@ impl QueryRef for ExportQuery {
self.query_ref(ident)
}

fn query_jsx(&self, ident: &Ident) -> Option<JSXElementName> {
self.export_id_list.contains(&ident.to_id()).then(|| {
JSXMemberExpr {
obj: JSXObject::Ident(self.namesapce_id.clone().into()),
prop: ident.clone(),
}
.into()
})
}

fn should_fix_this(&self, _: &Ident) -> bool {
// tsc does not care about `this` in namespace.
false
Expand Down
26 changes: 23 additions & 3 deletions crates/swc_ecma_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3021,11 +3021,21 @@ impl VisitMut for IdentRenamer<'_> {
}

pub trait QueryRef {
fn query_ref(&self, ident: &Ident) -> Option<Expr>;
fn query_lhs(&self, ident: &Ident) -> Option<Expr>;
fn query_ref(&self, _ident: &Ident) -> Option<Expr> {
None
}
fn query_lhs(&self, _ident: &Ident) -> Option<Expr> {
None
}
/// ref used in JSX
fn query_jsx(&self, _ident: &Ident) -> Option<JSXElementName> {
None
}
/// when `foo()` is replaced with `bar.baz()`,
/// should `bar.baz` be indirect call?
fn should_fix_this(&self, ident: &Ident) -> bool;
fn should_fix_this(&self, _ident: &Ident) -> bool {
false
}
}

/// Replace `foo` with `bar` or `bar.baz`
Expand Down Expand Up @@ -3129,6 +3139,16 @@ where
*n = n.take().into_indirect()
}
}

fn visit_mut_jsx_element_name(&mut self, n: &mut JSXElementName) {
n.visit_mut_children_with(self);

if let JSXElementName::Ident(ident) = n {
if let Some(expr) = self.query.query_jsx(ident) {
*n = expr;
}
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 2a70a6b

Please sign in to comment.