From 2f01aba978415add87994f9b20e3e2db83fc48b6 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Wed, 27 Sep 2023 08:55:22 +0800 Subject: [PATCH] fix(es/typescript): Handle qualified access in assign pat (#8012) **Related issue:** - Closes #8011 - https://github.com/swc-project/swc/discussions/5186 --- ...umentsWithStringLiteralTypes01.1.normal.js | 90 +++++++++---------- ...entsWithStringLiteralTypes01.2.minified.js | 18 ++-- .../src/transform.rs | 11 +++ .../tests/fixture/issue-8011/input.ts | 10 +++ .../tests/fixture/issue-8011/output.js | 10 +++ 5 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/input.ts create mode 100644 crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/output.js diff --git a/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.1.normal.js b/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.1.normal.js index 90064c092b9..d066285b55e 100644 --- a/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.1.normal.js +++ b/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.1.normal.js @@ -22,23 +22,23 @@ var n1; n1.d = fun2("Hello", "Hello"); n1.e = fun3("Hello", "Hello", "World", "Foo"); // Should be valid - a = takeReturnString(n1.a); - b = takeReturnString(n1.b); - c = takeReturnString(n1.c); - d = takeReturnString(n1.d); - e = takeReturnString(n1.e); + n1.a = takeReturnString(n1.a); + n1.b = takeReturnString(n1.b); + n1.c = takeReturnString(n1.c); + n1.d = takeReturnString(n1.d); + n1.e = takeReturnString(n1.e); // Passing these as arguments should cause an error. - a = takeReturnHello(n1.a); - b = takeReturnHello(n1.b); - c = takeReturnHello(n1.c); - d = takeReturnHello(n1.d); - e = takeReturnHello(n1.e); + n1.a = takeReturnHello(n1.a); + n1.b = takeReturnHello(n1.b); + n1.c = takeReturnHello(n1.c); + n1.d = takeReturnHello(n1.d); + n1.e = takeReturnHello(n1.e); // Passing these as arguments should cause an error. - a = takeReturnHelloWorld(n1.a); - b = takeReturnHelloWorld(n1.b); - c = takeReturnHelloWorld(n1.c); - d = takeReturnHelloWorld(n1.d); - e = takeReturnHelloWorld(n1.e); + n1.a = takeReturnHelloWorld(n1.a); + n1.b = takeReturnHelloWorld(n1.b); + n1.c = takeReturnHelloWorld(n1.c); + n1.d = takeReturnHelloWorld(n1.d); + n1.e = takeReturnHelloWorld(n1.e); })(n1 || (n1 = {})); var n2; (function(n2) { @@ -50,23 +50,23 @@ var n2; n2.d = fun2("Hello", "World"); n2.e = fun3("Hello", "World"); // Assignment from the returned value should cause an error. - a = takeReturnString(n2.a); - b = takeReturnString(n2.b); - c = takeReturnString(n2.c); - d = takeReturnString(n2.d); - e = takeReturnString(n2.e); + n2.a = takeReturnString(n2.a); + n2.b = takeReturnString(n2.b); + n2.c = takeReturnString(n2.c); + n2.d = takeReturnString(n2.d); + n2.e = takeReturnString(n2.e); // Should be valid - a = takeReturnHello(n2.a); - b = takeReturnHello(n2.b); - c = takeReturnHello(n2.c); - d = takeReturnHello(n2.d); - e = takeReturnHello(n2.e); + n2.a = takeReturnHello(n2.a); + n2.b = takeReturnHello(n2.b); + n2.c = takeReturnHello(n2.c); + n2.d = takeReturnHello(n2.d); + n2.e = takeReturnHello(n2.e); // Assignment from the returned value should cause an error. - a = takeReturnHelloWorld(n2.a); - b = takeReturnHelloWorld(n2.b); - c = takeReturnHelloWorld(n2.c); - d = takeReturnHelloWorld(n2.d); - e = takeReturnHelloWorld(n2.e); + n2.a = takeReturnHelloWorld(n2.a); + n2.b = takeReturnHelloWorld(n2.b); + n2.c = takeReturnHelloWorld(n2.c); + n2.d = takeReturnHelloWorld(n2.d); + n2.e = takeReturnHelloWorld(n2.e); })(n2 || (n2 = {})); var n3; (function(n3) { @@ -78,21 +78,21 @@ var n3; n3.d = fun2("World", "World"); n3.e = fun3("Hello", "World"); // Assignment from the returned value should cause an error. - a = takeReturnString(n3.a); - b = takeReturnString(n3.b); - c = takeReturnString(n3.c); - d = takeReturnString(n3.d); - e = takeReturnString(n3.e); + n3.a = takeReturnString(n3.a); + n3.b = takeReturnString(n3.b); + n3.c = takeReturnString(n3.c); + n3.d = takeReturnString(n3.d); + n3.e = takeReturnString(n3.e); // Passing these as arguments should cause an error. - a = takeReturnHello(n3.a); - b = takeReturnHello(n3.b); - c = takeReturnHello(n3.c); - d = takeReturnHello(n3.d); - e = takeReturnHello(n3.e); + n3.a = takeReturnHello(n3.a); + n3.b = takeReturnHello(n3.b); + n3.c = takeReturnHello(n3.c); + n3.d = takeReturnHello(n3.d); + n3.e = takeReturnHello(n3.e); // Both should be valid. - a = takeReturnHelloWorld(n3.a); - b = takeReturnHelloWorld(n3.b); - c = takeReturnHelloWorld(n3.c); - d = takeReturnHelloWorld(n3.d); - e = takeReturnHelloWorld(n3.e); + n3.a = takeReturnHelloWorld(n3.a); + n3.b = takeReturnHelloWorld(n3.b); + n3.c = takeReturnHelloWorld(n3.c); + n3.d = takeReturnHelloWorld(n3.d); + n3.e = takeReturnHelloWorld(n3.e); })(n3 || (n3 = {})); diff --git a/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.2.minified.js b/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.2.minified.js index 26fc1a9caa9..3ad41365f7f 100644 --- a/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.2.minified.js +++ b/crates/swc/tests/tsc-references/typeArgumentsWithStringLiteralTypes01.2.minified.js @@ -11,12 +11,12 @@ function fun3() { return args[+randBool()]; } (n11 = n1 || (n1 = {})).a = fun1("Hello", "World"), n11.b = fun1("Hello", "Hello"), n11.c = fun2("Hello", "World"), n11.d = fun2("Hello", "Hello"), n11.e = fun3("Hello", "Hello", "World", "Foo"), // Should be valid -a = takeReturnString(n11.a), b = takeReturnString(n11.b), c = takeReturnString(n11.c), d = takeReturnString(n11.d), e = takeReturnString(n11.e), // Passing these as arguments should cause an error. -a = takeReturnHello(n11.a), b = takeReturnHello(n11.b), c = takeReturnHello(n11.c), d = takeReturnHello(n11.d), e = takeReturnHello(n11.e), // Passing these as arguments should cause an error. -a = takeReturnHelloWorld(n11.a), b = takeReturnHelloWorld(n11.b), c = takeReturnHelloWorld(n11.c), d = takeReturnHelloWorld(n11.d), e = takeReturnHelloWorld(n11.e), (n21 = n2 || (n2 = {})).a = fun1("Hello", "Hello"), n21.b = fun1("Hello", "World"), n21.c = fun2("Hello", "Hello"), n21.d = fun2("Hello", "World"), n21.e = fun3("Hello", "World"), // Assignment from the returned value should cause an error. -a = takeReturnString(n21.a), b = takeReturnString(n21.b), c = takeReturnString(n21.c), d = takeReturnString(n21.d), e = takeReturnString(n21.e), // Should be valid -a = takeReturnHello(n21.a), b = takeReturnHello(n21.b), c = takeReturnHello(n21.c), d = takeReturnHello(n21.d), e = takeReturnHello(n21.e), // Assignment from the returned value should cause an error. -a = takeReturnHelloWorld(n21.a), b = takeReturnHelloWorld(n21.b), c = takeReturnHelloWorld(n21.c), d = takeReturnHelloWorld(n21.d), e = takeReturnHelloWorld(n21.e), (n31 = n3 || (n3 = {})).a = fun2("Hello", "World"), n31.b = fun2("World", "Hello"), n31.c = fun2("Hello", "Hello"), n31.d = fun2("World", "World"), n31.e = fun3("Hello", "World"), // Assignment from the returned value should cause an error. -a = takeReturnString(n31.a), b = takeReturnString(n31.b), c = takeReturnString(n31.c), d = takeReturnString(n31.d), e = takeReturnString(n31.e), // Passing these as arguments should cause an error. -a = takeReturnHello(n31.a), b = takeReturnHello(n31.b), c = takeReturnHello(n31.c), d = takeReturnHello(n31.d), e = takeReturnHello(n31.e), // Both should be valid. -a = takeReturnHelloWorld(n31.a), b = takeReturnHelloWorld(n31.b), c = takeReturnHelloWorld(n31.c), d = takeReturnHelloWorld(n31.d), e = takeReturnHelloWorld(n31.e); +n11.a = takeReturnString(n11.a), n11.b = takeReturnString(n11.b), n11.c = takeReturnString(n11.c), n11.d = takeReturnString(n11.d), n11.e = takeReturnString(n11.e), // Passing these as arguments should cause an error. +n11.a = takeReturnHello(n11.a), n11.b = takeReturnHello(n11.b), n11.c = takeReturnHello(n11.c), n11.d = takeReturnHello(n11.d), n11.e = takeReturnHello(n11.e), // Passing these as arguments should cause an error. +n11.a = takeReturnHelloWorld(n11.a), n11.b = takeReturnHelloWorld(n11.b), n11.c = takeReturnHelloWorld(n11.c), n11.d = takeReturnHelloWorld(n11.d), n11.e = takeReturnHelloWorld(n11.e), (n21 = n2 || (n2 = {})).a = fun1("Hello", "Hello"), n21.b = fun1("Hello", "World"), n21.c = fun2("Hello", "Hello"), n21.d = fun2("Hello", "World"), n21.e = fun3("Hello", "World"), // Assignment from the returned value should cause an error. +n21.a = takeReturnString(n21.a), n21.b = takeReturnString(n21.b), n21.c = takeReturnString(n21.c), n21.d = takeReturnString(n21.d), n21.e = takeReturnString(n21.e), // Should be valid +n21.a = takeReturnHello(n21.a), n21.b = takeReturnHello(n21.b), n21.c = takeReturnHello(n21.c), n21.d = takeReturnHello(n21.d), n21.e = takeReturnHello(n21.e), // Assignment from the returned value should cause an error. +n21.a = takeReturnHelloWorld(n21.a), n21.b = takeReturnHelloWorld(n21.b), n21.c = takeReturnHelloWorld(n21.c), n21.d = takeReturnHelloWorld(n21.d), n21.e = takeReturnHelloWorld(n21.e), (n31 = n3 || (n3 = {})).a = fun2("Hello", "World"), n31.b = fun2("World", "Hello"), n31.c = fun2("Hello", "Hello"), n31.d = fun2("World", "World"), n31.e = fun3("Hello", "World"), // Assignment from the returned value should cause an error. +n31.a = takeReturnString(n31.a), n31.b = takeReturnString(n31.b), n31.c = takeReturnString(n31.c), n31.d = takeReturnString(n31.d), n31.e = takeReturnString(n31.e), // Passing these as arguments should cause an error. +n31.a = takeReturnHello(n31.a), n31.b = takeReturnHello(n31.b), n31.c = takeReturnHello(n31.c), n31.d = takeReturnHello(n31.d), n31.e = takeReturnHello(n31.e), // Both should be valid. +n31.a = takeReturnHelloWorld(n31.a), n31.b = takeReturnHelloWorld(n31.b), n31.c = takeReturnHelloWorld(n31.c), n31.d = takeReturnHelloWorld(n31.d), n31.e = takeReturnHelloWorld(n31.e); diff --git a/crates/swc_ecma_transforms_typescript/src/transform.rs b/crates/swc_ecma_transforms_typescript/src/transform.rs index ecb3b904a95..1f98738d7be 100644 --- a/crates/swc_ecma_transforms_typescript/src/transform.rs +++ b/crates/swc_ecma_transforms_typescript/src/transform.rs @@ -1190,6 +1190,17 @@ struct ExportRefRewrriter { impl VisitMut for ExportRefRewrriter { noop_visit_mut_type!(); + fn visit_mut_pat(&mut self, n: &mut Pat) { + match n { + Pat::Ident(BindingIdent { id, .. }) => { + if self.export_id_list.contains(&id.to_id()) { + *n = Pat::Expr(Box::new(self.namesapce_id.clone().make_member(id.take()))); + } + } + _ => n.visit_mut_children_with(self), + } + } + fn visit_mut_expr(&mut self, n: &mut Expr) { if let Expr::Ident(ref_ident) = n { if self.export_id_list.contains(&ref_ident.to_id()) { diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/input.ts b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/input.ts new file mode 100644 index 00000000000..dee6147c83e --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/input.ts @@ -0,0 +1,10 @@ +namespace API { + export let url = "/"; + + export function update(value: string) { + url = value; + } +} + +API.update("/new"); +console.log(API.url); diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/output.js b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/output.js new file mode 100644 index 00000000000..de07cfa2761 --- /dev/null +++ b/crates/swc_ecma_transforms_typescript/tests/fixture/issue-8011/output.js @@ -0,0 +1,10 @@ +var API; +(function(API) { + API.url = "/"; + function update(value) { + API.url = value; + } + API.update = update; +})(API || (API = {})); +API.update("/new"); +console.log(API.url);