From 67f2416afb73734887d37e12ce5d7f00a511ac27 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 16 May 2023 09:10:45 +0200 Subject: [PATCH] Handle self-referencing namespaces (#4991) Handle self-referencing namespace --- src/ast/variables/NamespaceVariable.ts | 8 +++---- .../self-referencing-namespace/_config.js | 23 +++++++++++++++++++ .../self-referencing-namespace/main.js | 2 ++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 test/function/samples/self-referencing-namespace/_config.js create mode 100644 test/function/samples/self-referencing-namespace/main.js diff --git a/src/ast/variables/NamespaceVariable.ts b/src/ast/variables/NamespaceVariable.ts index 011b3088c5a..3ba0e5a20e2 100644 --- a/src/ast/variables/NamespaceVariable.ts +++ b/src/ast/variables/NamespaceVariable.ts @@ -135,15 +135,15 @@ export default class NamespaceVariable extends Variable { const memberVariables = this.getMemberVariables(); const members: [key: string | null, value: string][] = Object.entries(memberVariables) .filter(([_, variable]) => variable.included) - .map(([name, original]) => { - if (this.referencedEarly || original.isReassigned) { + .map(([name, variable]) => { + if (this.referencedEarly || variable.isReassigned || variable === this) { return [ null, - `get ${name}${_}()${_}{${_}return ${original.getName(getPropertyAccess)}${s}${_}}` + `get ${name}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}` ]; } - return [name, original.getName(getPropertyAccess)]; + return [name, variable.getName(getPropertyAccess)]; }); members.unshift([null, `__proto__:${_}null`]); diff --git a/test/function/samples/self-referencing-namespace/_config.js b/test/function/samples/self-referencing-namespace/_config.js new file mode 100644 index 00000000000..23f72813d34 --- /dev/null +++ b/test/function/samples/self-referencing-namespace/_config.js @@ -0,0 +1,23 @@ +const assert = require('node:assert'); +const path = require('node:path'); + +const ID_MAIN = path.join(__dirname, 'main.js'); + +module.exports = defineTest({ + description: 'supports dynamic namespaces that reference themselves', + options: { + output: { generatedCode: { constBindings: true } } + }, + exports(exports) { + assert.strictEqual(exports.foo, 'foo'); + assert.strictEqual(exports.ns.foo, 'foo'); + assert.strictEqual(exports.ns.ns.foo, 'foo'); + }, + warnings: [ + { + code: 'CIRCULAR_DEPENDENCY', + ids: [ID_MAIN, ID_MAIN], + message: 'Circular dependency: main.js -> main.js' + } + ] +}); diff --git a/test/function/samples/self-referencing-namespace/main.js b/test/function/samples/self-referencing-namespace/main.js new file mode 100644 index 00000000000..53ad7e51e54 --- /dev/null +++ b/test/function/samples/self-referencing-namespace/main.js @@ -0,0 +1,2 @@ +export * as ns from './main.js'; +export const foo = 'foo';