-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat/symbol conflict special case (#1279)
* test: ✅ add case for issue #1274 * fix: 🐛 conflict Symbol conflict case * release: @umijs/mako@0.6.1-canary.20240614.1 * chore: 🚨 lint happy * chore: ⬆️ update pnpm-lock
- Loading branch information
1 parent
e892555
commit 73e29df
Showing
14 changed files
with
178 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// a workaround for the issue https://github.com/umijs/mako/issues/1274 | ||
// https://github.com/swc-project/swc/issues/9045 | ||
|
||
use std::collections::HashSet; | ||
|
||
use swc_core::common::{Mark, SyntaxContext}; | ||
use swc_core::ecma::ast::{Id, Ident, Module}; | ||
use swc_core::ecma::utils::IdentRenamer; | ||
use swc_core::ecma::visit::{VisitMut, VisitMutWith}; | ||
|
||
pub(crate) struct FixSymbolConflict { | ||
idents_named_symbol: HashSet<Id>, | ||
top_level_ctxt: SyntaxContext, | ||
} | ||
|
||
impl FixSymbolConflict { | ||
pub fn new(top_level_mark: Mark) -> Self { | ||
Self { | ||
idents_named_symbol: Default::default(), | ||
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark), | ||
} | ||
} | ||
} | ||
|
||
impl VisitMut for FixSymbolConflict { | ||
fn visit_mut_ident(&mut self, n: &mut Ident) { | ||
if n.sym.eq("Symbol") && n.span.ctxt == self.top_level_ctxt { | ||
self.idents_named_symbol.insert(n.to_id()); | ||
} | ||
} | ||
|
||
fn visit_mut_module(&mut self, n: &mut Module) { | ||
n.visit_mut_children_with(self); | ||
|
||
if !self.idents_named_symbol.is_empty() { | ||
let rename_map = self | ||
.idents_named_symbol | ||
.iter() | ||
.map(|id| { | ||
let new_sym = format!("_$m_{}", id.0); | ||
(id.clone(), (new_sym.into(), id.1)) | ||
}) | ||
.collect(); | ||
|
||
let mut renamer = IdentRenamer::new(&rename_map); | ||
|
||
n.visit_mut_with(&mut renamer); | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use swc_core::common::GLOBALS; | ||
|
||
use super::*; | ||
use crate::ast::tests::TestUtils; | ||
|
||
#[test] | ||
fn test_global_symbol() { | ||
assert_eq!( | ||
run_with("console.log(Symbol.iterator)"), | ||
"console.log(Symbol.iterator);" | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_top_level_redefine_symbol() { | ||
assert_eq!( | ||
run_with("class Symbol {} Symbol.iterator; export { Symbol }"), | ||
r#" | ||
class _$m_Symbol { | ||
} | ||
_$m_Symbol.iterator; | ||
export { _$m_Symbol as Symbol }; | ||
"# | ||
.trim() | ||
) | ||
} | ||
|
||
#[test] | ||
fn test_redefine_symbol_in_nested_scope() { | ||
assert_eq!( | ||
run_with( | ||
r#" | ||
Symbol.iterator; | ||
(function(){ | ||
class Symbol {} | ||
})();"#, | ||
), | ||
r#" | ||
Symbol.iterator; | ||
(function() { | ||
class Symbol1 { | ||
} | ||
})(); | ||
"# | ||
.trim() | ||
); | ||
} | ||
|
||
fn run_with(code: &str) -> String { | ||
let mut tu = TestUtils::gen_js_ast(code); | ||
let mark = tu.ast.js().top_level_mark; | ||
let mut v = GLOBALS.set(&tu.context.meta.script.globals, || { | ||
FixSymbolConflict::new(mark) | ||
}); | ||
tu.ast.js_mut().ast.visit_mut_with(&mut v); | ||
tu.js_ast_to_code() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const assert = require("assert"); | ||
const { | ||
parseBuildResult, | ||
moduleReg, | ||
injectSimpleJest, | ||
} = require("../../../scripts/test-utils"); | ||
const { files } = parseBuildResult(__dirname); | ||
const content = files["index.js"]; | ||
|
||
injectSimpleJest(); | ||
require("./dist/index.js"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{ "targets": { "ie": 11 } } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
function forOf(y) { | ||
let r = []; | ||
for (let x of y) { | ||
r.push(x + 1); | ||
} | ||
return r; | ||
} | ||
|
||
it("for-of should work", () => { | ||
expect(forOf([1])).toStrictEqual([2]); | ||
}); | ||
|
||
class Symbol { | ||
name() { | ||
return "AnotherSymbol"; | ||
} | ||
} | ||
|
||
it("should overwrite Symbol", () => { | ||
let s = new Symbol(); | ||
expect(s.name()).toBe("AnotherSymbol"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.