From 37126ec0b74342ec494905ad9f5cb1fe8eb6f3d8 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Sun, 16 Jan 2022 16:02:29 +0900 Subject: [PATCH] [New] `namespace`: support arbitrary module namespace names --- CHANGELOG.md | 2 +- src/ExportMap.js | 4 +- src/rules/namespace.js | 2 +- .../files/default-export-namespace-string.js | 1 + tests/files/default-export-string.js | 3 ++ tests/src/rules/namespace.js | 42 +++++++++++++++++-- 6 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 tests/files/default-export-namespace-string.js create mode 100644 tests/files/default-export-string.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dcb2a5b7..739701677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ## [Unreleased] ### Added -- [`no-named-default`, `no-default-export`, `prefer-default-export`, `no-named-export`, `export`, `named`]: support arbitrary module namespace names ([#2358], thanks [@sosukesuzuki]) +- [`no-named-default`, `no-default-export`, `prefer-default-export`, `no-named-export`, `export`, `named`, `namespace`]: support arbitrary module namespace names ([#2358], thanks [@sosukesuzuki]) ### Changed - [Tests] `no-nodejs-modules`: add tests for node protocol URL ([#2367], thanks [@sosukesuzuki]) diff --git a/src/ExportMap.js b/src/ExportMap.js index 564b5d63d..f11a8752f 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -479,11 +479,11 @@ ExportMap.parse = function (path, content, context) { })); return; case 'ExportAllDeclaration': - m.namespace.set(s.exported.name, addNamespace(exportMeta, s.source.value)); + m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.source.value)); return; case 'ExportSpecifier': if (!n.source) { - m.namespace.set(s.exported.name, addNamespace(exportMeta, s.local)); + m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.local)); return; } // else falls through diff --git a/src/rules/namespace.js b/src/rules/namespace.js index 6325b88ba..8a7099df6 100644 --- a/src/rules/namespace.js +++ b/src/rules/namespace.js @@ -69,7 +69,7 @@ module.exports = { case 'ImportSpecifier': { const meta = imports.get( // default to 'default' for default https://i.imgur.com/nj6qAWy.jpg - specifier.imported ? specifier.imported.name : 'default', + specifier.imported ? (specifier.imported.name || specifier.imported.value) : 'default', ); if (!meta || !meta.namespace) { break; } namespaces.set(specifier.local.name, meta.namespace); diff --git a/tests/files/default-export-namespace-string.js b/tests/files/default-export-namespace-string.js new file mode 100644 index 000000000..5b4a01ab7 --- /dev/null +++ b/tests/files/default-export-namespace-string.js @@ -0,0 +1 @@ +export * as "default" from "./named-exports"; diff --git a/tests/files/default-export-string.js b/tests/files/default-export-string.js new file mode 100644 index 000000000..4f68b517e --- /dev/null +++ b/tests/files/default-export-string.js @@ -0,0 +1,3 @@ +function foo() { return 'bar' } + +export { foo as "default" } diff --git a/tests/src/rules/namespace.js b/tests/src/rules/namespace.js index 826637b97..15ab133b1 100644 --- a/tests/src/rules/namespace.js +++ b/tests/src/rules/namespace.js @@ -183,10 +183,35 @@ const valid = [ parserOptions: { ecmaVersion: 2020, }, - })) || []), + })), + // es2022: Arbitrary module namespace identifier names + testVersion('>= 8.7', () => ({ + code: "import * as names from './default-export-string';", + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: "import * as names from './default-export-string'; console.log(names.default)", + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: "import * as names from './default-export-namespace-string';", + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: "import * as names from './default-export-namespace-string'; console.log(names.default)", + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: `import { "b" as b } from "./deep/a"; console.log(b.c.d.e)`, + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: `import { "b" as b } from "./deep/a"; var {c:{d:{e}}} = b`, + parserOptions: { ecmaVersion: 2022 }, + }))), ]; -const invalid = [ +const invalid = [].concat( test({ code: "import * as names from './named-exports'; " + ' console.log(names.c);', errors: [error('c', 'names')] }), @@ -275,7 +300,18 @@ const invalid = [ }, }), -] + // es2022: Arbitrary module namespace identifier names + testVersion('>= 8.7', () => ({ + code: `import { "b" as b } from "./deep/a"; console.log(b.e)`, + errors: [ "'e' not found in imported namespace 'b'." ], + parserOptions: { ecmaVersion: 2022 }, + })), + testVersion('>= 8.7', () => ({ + code: `import { "b" as b } from "./deep/a"; console.log(b.c.e)`, + errors: [ "'e' not found in deeply imported namespace 'b.c'." ], + parserOptions: { ecmaVersion: 2022 }, + })), +) /////////////////////// // deep dereferences //