diff --git a/packages/module-source/DESIGN.md b/packages/module-source/DESIGN.md index 1df2ec7d89..3ede3ed6c3 100644 --- a/packages/module-source/DESIGN.md +++ b/packages/module-source/DESIGN.md @@ -77,7 +77,7 @@ the module needs to be linked to and how to link their imports and exports. The functor source, the module transformed into a program, has the following shape. -The names are additionally obscured with Unicode zero-width-joiners to avoid +The names are additionally obscured with invisible joiner characters to avoid collisions with sensibly constructed modules, and the transformation preserves line numbers. diff --git a/packages/module-source/TESTS.md b/packages/module-source/TESTS.md index 9c51b9e540..19de65cd0c 100644 --- a/packages/module-source/TESTS.md +++ b/packages/module-source/TESTS.md @@ -12,7 +12,7 @@ Pairs of module source vs functor source. The output was generated. ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: bb };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: bb };$h͏_once.default($c͏_default); }) ``` @@ -24,7 +24,7 @@ Pairs of module source vs functor source. The output was generated. ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: class {valueOf() {return 45;}} };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: class {valueOf() {return 45;}} };$h͏_once.default($c͏_default); }) ``` @@ -36,8 +36,8 @@ export default 123 ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); //#! /usr/bin/env node -const { default: $c‍_default } = { default: 123 };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); //#! /usr/bin/env node +const { default: $c͏_default } = { default: 123 };$h͏_once.default($c͏_default); }) ``` @@ -48,7 +48,7 @@ const { default: $c‍_default } = { default: 123 };$h‍_once.default($c‍_def ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: arguments };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: arguments };$h͏_once.default($c͏_default); }) ``` @@ -59,7 +59,7 @@ const { default: $c‍_default } = { default: 123 };$h‍_once.default($c‍_def ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: this };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: this };$h͏_once.default($c͏_default); }) ``` @@ -77,11 +77,11 @@ export const ghi = 789; ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); let abc = 123;$h‍_once.abc(abc); -let $c‍_def = 456;$h‍_live.def($c‍_def); -let def2 = def;$h‍_once.def2(def2); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); let abc = 123;$h͏_once.abc(abc); +let $c͏_def = 456;$h͏_live.def($c͏_def); +let def2 = def;$h͏_once.def2(def2); def++; -const ghi = 789;$h‍_once.ghi(ghi); +const ghi = 789;$h͏_once.ghi(ghi); }) ``` @@ -94,8 +94,8 @@ export const { def, nest: [, ghi, ...nestrest], ...rest } = { def: 456, nest: [ ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const abc = 123;$h‍_once.abc(abc); -const { def, nest: [, ghi, ...nestrest], ...rest } = { def: 456, nest: ['skip', 789, 'a', 'b'], other: 999, and: 998 };$h‍_once.def(def);$h‍_once.ghi(ghi);$h‍_once.nestrest(nestrest);$h‍_once.rest(rest); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const abc = 123;$h͏_once.abc(abc); +const { def, nest: [, ghi, ...nestrest], ...rest } = { def: 456, nest: ['skip', 789, 'a', 'b'], other: 999, and: 998 };$h͏_once.def(def);$h͏_once.ghi(ghi);$h͏_once.nestrest(nestrest);$h͏_once.rest(rest); }) ``` @@ -107,8 +107,8 @@ export const abc = 123; ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const abc2 = abc; -const abc = 123;$h‍_once.abc(abc); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const abc2 = abc; +const abc = 123;$h͏_once.abc(abc); }) ``` @@ -120,8 +120,8 @@ export let abc = 123; ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const abc2 = abc; -let abc = 123;$h‍_once.abc(abc); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const abc2 = abc; +let abc = 123;$h͏_once.abc(abc); }) ``` @@ -134,9 +134,9 @@ export const abc3 = abc; ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []);$h‍_live.abc(); const abc2 = abc;$h‍_once.abc2(abc2); -var $c‍_abc = 123;abc = $c‍_abc; -const abc3 = abc;$h‍_once.abc3(abc3); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []);$h͏_live.abc(); const abc2 = abc;$h͏_once.abc2(abc2); +var $c͏_abc = 123;abc = $c͏_abc; +const abc3 = abc;$h͏_once.abc3(abc3); }) ``` @@ -151,11 +151,11 @@ export const fn3 = fn; ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []);Object.defineProperty($c‍_fn, 'name', {value: "fn"});$h‍_live.fn($c‍_fn); const fn2 = fn;$h‍_once.fn2(fn2); -function $c‍_fn() { + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []);Object.defineProperty($c͏_fn, 'name', {value: "fn"});$h͏_live.fn($c͏_fn); const fn2 = fn;$h͏_once.fn2(fn2); +function $c͏_fn() { return 'foo'; } -const fn3 = fn;$h‍_once.fn3(fn3); +const fn3 = fn;$h͏_once.fn3(fn3); }) ``` @@ -167,8 +167,8 @@ export class C {} if (C) { count += 1; } ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); let $c‍_count = 0;$h‍_live.count($c‍_count);{ - class C {}$h‍_live.C(C);}if (C) {count += 1;} + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); let $c͏_count = 0;$h͏_live.count($c͏_count);{ + class C {}$h͏_live.C(C);}if (C) {count += 1;} }) ``` @@ -179,7 +179,7 @@ export class C {} if (C) { count += 1; } ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: class C {} };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: class C {} };$h͏_once.default($c͏_default); }) ``` @@ -190,7 +190,7 @@ export class C {} if (C) { count += 1; } ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: class {} };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: class {} };$h͏_once.default($c͏_default); }) ``` @@ -201,7 +201,7 @@ export class C {} if (C) { count += 1; } ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: class {} };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: class {} };$h͏_once.default($c͏_default); }) ``` @@ -213,8 +213,8 @@ export function F(arg) { return arg; } ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []);Object.defineProperty($c‍_F, 'name', {value: "F"});$h‍_live.F($c‍_F); F(123); -function $c‍_F(arg) {return arg;} + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []);Object.defineProperty($c͏_F, 'name', {value: "F"});$h͏_live.F($c͏_F); F(123); +function $c͏_F(arg) {return arg;} }) ``` @@ -225,7 +225,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: async function F(arg) {return arg;} };$h‍_once.default($c‍_default); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: async function F(arg) {return arg;} };$h͏_once.default($c͏_default); }) ``` @@ -236,7 +236,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([]), []); const { default: $c‍_default } = { default: async function (arg) {return arg;} };$h‍_once.default($c‍_default);; + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([]), []); const { default: $c͏_default } = { default: async function (arg) {return arg;} };$h͏_once.default($c͏_default);; }) ``` @@ -249,7 +249,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { let ns;$h‍_imports(new Map([["module", new Map([["*", [$h‍_a => (ns = $h‍_a)]]])]]), []); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { let ns;$h͏_imports(new Map([["module", new Map([["*", [$h͏_a => (ns = $h͏_a)]]])]]), []); }) ``` @@ -260,7 +260,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { let foo,bar;$h‍_imports(new Map([["module", new Map([["foo", [$h‍_a => (foo = $h‍_a)]],["bar", [$h‍_a => (bar = $h‍_a)]]])]]), []); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { let foo,bar;$h͏_imports(new Map([["module", new Map([["foo", [$h͏_a => (foo = $h͏_a)]],["bar", [$h͏_a => (bar = $h͏_a)]]])]]), []); }) ``` #### Case 3 @@ -270,7 +270,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { let myName;$h‍_imports(new Map([["module", new Map([["default", [$h‍_a => (myName = $h‍_a)]]])]]), []); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { let myName;$h͏_imports(new Map([["module", new Map([["default", [$h͏_a => (myName = $h͏_a)]]])]]), []); }) ``` @@ -282,7 +282,7 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { let myName,other;$h‍_imports(new Map([["module", new Map([["default", [$h‍_a => (myName = $h‍_a)]],["otherName", [$h‍_a => (other = $h‍_a)]]])]]), []); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { let myName,other;$h͏_imports(new Map([["module", new Map([["default", [$h͏_a => (myName = $h͏_a)]],["otherName", [$h͏_a => (other = $h͏_a)]]])]]), []); }) ``` @@ -294,6 +294,6 @@ function $c‍_F(arg) {return arg;} ``` ```js - (({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, }) => { $h‍_imports(new Map([["module", new Map([])]]), []); + (({ imports: $h͏_imports, liveVar: $h͏_live, onceVar: $h͏_once, }) => { $h͏_imports(new Map([["module", new Map([])]]), []); }) ``` diff --git a/packages/module-source/src/hidden.js b/packages/module-source/src/hidden.js index 8a08920613..a84b6db521 100644 --- a/packages/module-source/src/hidden.js +++ b/packages/module-source/src/hidden.js @@ -1,5 +1,5 @@ -export const HIDDEN_PREFIX = '$h\u200d_'; -export const HIDDEN_CONST_VAR_PREFIX = '$c\u200d_'; +export const HIDDEN_PREFIX = '$h\u034f_'; +export const HIDDEN_CONST_VAR_PREFIX = '$c\u034f_'; export const HIDDEN_A = `${HIDDEN_PREFIX}a`; export const HIDDEN_IMPORT = `${HIDDEN_PREFIX}import`; export const HIDDEN_IMPORT_SELF = `${HIDDEN_PREFIX}importSelf`; diff --git a/packages/module-source/test/module-source.test.js b/packages/module-source/test/module-source.test.js index 833ec7887b..21d40fb10b 100644 --- a/packages/module-source/test/module-source.test.js +++ b/packages/module-source/test/module-source.test.js @@ -442,22 +442,22 @@ export default async function (arg) { return arg; } t.is(await ret, 'foo', 'F returns correctly'); }); -test('zero width joiner is reserved', t => { +test('invisible joiner character is reserved', t => { t.throws(() => { - const _ = new ModuleSource(`const $h\u200d_import = 123; $h\u200d_import`); + const _ = new ModuleSource(`const $h\u034f_import = 123; $h\u034f_import`); }); }); -test('zero width joiner in constified variable is reserved', t => { +test('invisible joiner character in constified variable is reserved', t => { t.throws(() => { - const _ = new ModuleSource(`const $c\u200d_myVar = 123; $c\u200d_myVar`); + const _ = new ModuleSource(`const $c\u034f_myVar = 123; $c\u034f_myVar`); }); }); -test('zero width joiner is allowed in non-reserved words', t => { +test('invisible joiner character is allowed in non-reserved words', t => { const { namespace } = initialize( t, - `const $h\u200d_import2 = 123; export default $h\u200d_import2`, + `const $h\u034f_import2 = 123; export default $h\u034f_import2`, ); const { default: name } = namespace; t.is(name, 123); @@ -729,6 +729,7 @@ test('source map generation', t => { const { __syncModuleProgram__ } = new ModuleSource(`'Hello, World!'`, { sourceUrl: 'must-appear-in-source.js', sourceMapUrl: 'must-not-appear-in-source.js', + // @ts-expect-error SourceMapHookDetails do not have those properties! sourceMapHook(sourceMap, { sourceUrl, sourceMapUrl, source }) { t.log(sourceMap); t.is(sourceMapUrl, 'must-not-appear-in-source.js');