From f2cda993cc16d979e8e27e9064dd40a9c08163de Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 4 May 2021 06:45:58 +0200 Subject: [PATCH] Do not include namespace for conflicting member access --- src/ast/nodes/MemberExpression.ts | 11 +++----- src/ast/variables/NamespaceVariable.ts | 18 +++++++------ .../{_expected/es.js => _expected.js} | 0 .../mutations-in-imports/_expected/amd.js | 21 --------------- .../mutations-in-imports/_expected/cjs.js | 19 -------------- .../mutations-in-imports/_expected/iife.js | 22 ---------------- .../mutations-in-imports/_expected/system.js | 26 ------------------- .../mutations-in-imports/_expected/umd.js | 24 ----------------- .../samples/namespace-conflict/_config.js | 4 +++ .../samples/namespace-conflict/_expected.js | 1 + test/form/samples/namespace-conflict/first.js | 1 + test/form/samples/namespace-conflict/main.js | 3 +++ .../samples/namespace-conflict/reexport.js | 2 ++ .../form/samples/namespace-conflict/second.js | 1 + .../samples/pattern-encodings/_config.js | 6 ----- .../samples/pattern-encodings/main.js | 2 -- 16 files changed, 25 insertions(+), 136 deletions(-) rename test/form/samples/mutations-in-imports/{_expected/es.js => _expected.js} (100%) delete mode 100644 test/form/samples/mutations-in-imports/_expected/amd.js delete mode 100644 test/form/samples/mutations-in-imports/_expected/cjs.js delete mode 100644 test/form/samples/mutations-in-imports/_expected/iife.js delete mode 100644 test/form/samples/mutations-in-imports/_expected/system.js delete mode 100644 test/form/samples/mutations-in-imports/_expected/umd.js create mode 100644 test/form/samples/namespace-conflict/_config.js create mode 100644 test/form/samples/namespace-conflict/_expected.js create mode 100644 test/form/samples/namespace-conflict/first.js create mode 100644 test/form/samples/namespace-conflict/main.js create mode 100644 test/form/samples/namespace-conflict/reexport.js create mode 100644 test/form/samples/namespace-conflict/second.js delete mode 100644 test/function/samples/pattern-encodings/_config.js delete mode 100644 test/function/samples/pattern-encodings/main.js diff --git a/src/ast/nodes/MemberExpression.ts b/src/ast/nodes/MemberExpression.ts index 90ecfb4453a..240c487ad7b 100644 --- a/src/ast/nodes/MemberExpression.ts +++ b/src/ast/nodes/MemberExpression.ts @@ -123,14 +123,9 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE if (path.length === 0) this.disallowNamespaceReassignment(); if (this.variable) { this.variable.deoptimizePath(path); - } else { - const propertyKey = this.getPropertyKey(); - if (propertyKey === UnknownKey) { - this.object.deoptimizePath(UNKNOWN_PATH); - } else { - this.wasPathDeoptimizedWhileOptimized = true; - this.object.deoptimizePath([propertyKey, ...path]); - } + } else if (!this.replacement) { + this.wasPathDeoptimizedWhileOptimized = true; + this.object.deoptimizePath([this.getPropertyKey(), ...path]); } } diff --git a/src/ast/variables/NamespaceVariable.ts b/src/ast/variables/NamespaceVariable.ts index a01a59d6678..8fb31629a77 100644 --- a/src/ast/variables/NamespaceVariable.ts +++ b/src/ast/variables/NamespaceVariable.ts @@ -3,7 +3,7 @@ import { RenderOptions } from '../../utils/renderHelpers'; import { RESERVED_NAMES } from '../../utils/reservedNames'; import { getSystemExportStatement } from '../../utils/systemJsRendering'; import Identifier from '../nodes/Identifier'; -import { UNKNOWN_PATH } from '../utils/PathTracker'; +import { ObjectPath, UNKNOWN_PATH } from '../utils/PathTracker'; import Variable from './Variable'; export default class NamespaceVariable extends Variable { @@ -29,14 +29,16 @@ export default class NamespaceVariable extends Variable { this.name = identifier.name; } - // This is only called if "UNKNOWN_PATH" is reassigned as in all other situations, either the - // build fails due to an illegal namespace reassignment or MemberExpression already forwards - // the reassignment to the right variable. This means we lost track of this variable and thus - // need to reassign all exports. - deoptimizePath() { + deoptimizePath(path: ObjectPath) { const memberVariables = this.getMemberVariables(); - for (const key of Object.keys(memberVariables)) { - memberVariables[key].deoptimizePath(UNKNOWN_PATH); + const memberPath = path.length <= 1 ? UNKNOWN_PATH : path.slice(1); + const key = path[0]; + if (typeof key !== 'string') { + for (const key of Object.keys(memberVariables)) { + memberVariables[key].deoptimizePath(memberPath); + } + } else { + memberVariables[key].deoptimizePath(memberPath); } } diff --git a/test/form/samples/mutations-in-imports/_expected/es.js b/test/form/samples/mutations-in-imports/_expected.js similarity index 100% rename from test/form/samples/mutations-in-imports/_expected/es.js rename to test/form/samples/mutations-in-imports/_expected.js diff --git a/test/form/samples/mutations-in-imports/_expected/amd.js b/test/form/samples/mutations-in-imports/_expected/amd.js deleted file mode 100644 index 09c62bf4aae..00000000000 --- a/test/form/samples/mutations-in-imports/_expected/amd.js +++ /dev/null @@ -1,21 +0,0 @@ -define(function () { 'use strict'; - - const x$2 = { a: { b: () => {} } }; - const y$2 = { a: x$2.a }; - - const x$1 = { a: { b: () => {} } }; - const y$1 = { a: x$1.a }; - - const x = { a: { b: () => {} } }; - const y = { a: x.a }; - - y$2.a.b = () => console.log( 'effect' ); - x$2.a.b(); - - y$1.a.b = () => console.log( 'effect' ); - x$1.a.b(); - - y.a.b = () => console.log( 'effect' ); - x.a.b(); - -}); diff --git a/test/form/samples/mutations-in-imports/_expected/cjs.js b/test/form/samples/mutations-in-imports/_expected/cjs.js deleted file mode 100644 index 9572605a3dd..00000000000 --- a/test/form/samples/mutations-in-imports/_expected/cjs.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -const x$2 = { a: { b: () => {} } }; -const y$2 = { a: x$2.a }; - -const x$1 = { a: { b: () => {} } }; -const y$1 = { a: x$1.a }; - -const x = { a: { b: () => {} } }; -const y = { a: x.a }; - -y$2.a.b = () => console.log( 'effect' ); -x$2.a.b(); - -y$1.a.b = () => console.log( 'effect' ); -x$1.a.b(); - -y.a.b = () => console.log( 'effect' ); -x.a.b(); diff --git a/test/form/samples/mutations-in-imports/_expected/iife.js b/test/form/samples/mutations-in-imports/_expected/iife.js deleted file mode 100644 index 4b599c44e60..00000000000 --- a/test/form/samples/mutations-in-imports/_expected/iife.js +++ /dev/null @@ -1,22 +0,0 @@ -(function () { - 'use strict'; - - const x$2 = { a: { b: () => {} } }; - const y$2 = { a: x$2.a }; - - const x$1 = { a: { b: () => {} } }; - const y$1 = { a: x$1.a }; - - const x = { a: { b: () => {} } }; - const y = { a: x.a }; - - y$2.a.b = () => console.log( 'effect' ); - x$2.a.b(); - - y$1.a.b = () => console.log( 'effect' ); - x$1.a.b(); - - y.a.b = () => console.log( 'effect' ); - x.a.b(); - -}()); diff --git a/test/form/samples/mutations-in-imports/_expected/system.js b/test/form/samples/mutations-in-imports/_expected/system.js deleted file mode 100644 index 798c09f8b28..00000000000 --- a/test/form/samples/mutations-in-imports/_expected/system.js +++ /dev/null @@ -1,26 +0,0 @@ -System.register([], function () { - 'use strict'; - return { - execute: function () { - - const x$2 = { a: { b: () => {} } }; - const y$2 = { a: x$2.a }; - - const x$1 = { a: { b: () => {} } }; - const y$1 = { a: x$1.a }; - - const x = { a: { b: () => {} } }; - const y = { a: x.a }; - - y$2.a.b = () => console.log( 'effect' ); - x$2.a.b(); - - y$1.a.b = () => console.log( 'effect' ); - x$1.a.b(); - - y.a.b = () => console.log( 'effect' ); - x.a.b(); - - } - }; -}); diff --git a/test/form/samples/mutations-in-imports/_expected/umd.js b/test/form/samples/mutations-in-imports/_expected/umd.js deleted file mode 100644 index 5e64442e43b..00000000000 --- a/test/form/samples/mutations-in-imports/_expected/umd.js +++ /dev/null @@ -1,24 +0,0 @@ -(function (factory) { - typeof define === 'function' && define.amd ? define(factory) : - factory(); -}((function () { 'use strict'; - - const x$2 = { a: { b: () => {} } }; - const y$2 = { a: x$2.a }; - - const x$1 = { a: { b: () => {} } }; - const y$1 = { a: x$1.a }; - - const x = { a: { b: () => {} } }; - const y = { a: x.a }; - - y$2.a.b = () => console.log( 'effect' ); - x$2.a.b(); - - y$1.a.b = () => console.log( 'effect' ); - x$1.a.b(); - - y.a.b = () => console.log( 'effect' ); - x.a.b(); - -}))); diff --git a/test/form/samples/namespace-conflict/_config.js b/test/form/samples/namespace-conflict/_config.js new file mode 100644 index 00000000000..e0e9e8cf881 --- /dev/null +++ b/test/form/samples/namespace-conflict/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'replaces conflicting namespace properties with undefined', + expectedWarnings: ['NAMESPACE_CONFLICT', 'MISSING_EXPORT'] +}; diff --git a/test/form/samples/namespace-conflict/_expected.js b/test/form/samples/namespace-conflict/_expected.js new file mode 100644 index 00000000000..3f7bf02341c --- /dev/null +++ b/test/form/samples/namespace-conflict/_expected.js @@ -0,0 +1 @@ +console.log(undefined); diff --git a/test/form/samples/namespace-conflict/first.js b/test/form/samples/namespace-conflict/first.js new file mode 100644 index 00000000000..bb1843d113a --- /dev/null +++ b/test/form/samples/namespace-conflict/first.js @@ -0,0 +1 @@ +export const foo = 1; diff --git a/test/form/samples/namespace-conflict/main.js b/test/form/samples/namespace-conflict/main.js new file mode 100644 index 00000000000..5991f689169 --- /dev/null +++ b/test/form/samples/namespace-conflict/main.js @@ -0,0 +1,3 @@ +import * as ns from './reexport'; + +console.log(ns.foo); diff --git a/test/form/samples/namespace-conflict/reexport.js b/test/form/samples/namespace-conflict/reexport.js new file mode 100644 index 00000000000..636e32d8531 --- /dev/null +++ b/test/form/samples/namespace-conflict/reexport.js @@ -0,0 +1,2 @@ +export * from './first'; +export * from './second'; diff --git a/test/form/samples/namespace-conflict/second.js b/test/form/samples/namespace-conflict/second.js new file mode 100644 index 00000000000..cc57a55e257 --- /dev/null +++ b/test/form/samples/namespace-conflict/second.js @@ -0,0 +1 @@ +export const foo = 2; diff --git a/test/function/samples/pattern-encodings/_config.js b/test/function/samples/pattern-encodings/_config.js deleted file mode 100644 index 9aefc4fd6c0..00000000000 --- a/test/function/samples/pattern-encodings/_config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - description: 'throws for invalid patterns', - options: { - output: { entryFileNames: '\0main.js' } - } -}; diff --git a/test/function/samples/pattern-encodings/main.js b/test/function/samples/pattern-encodings/main.js deleted file mode 100644 index bb06158e22d..00000000000 --- a/test/function/samples/pattern-encodings/main.js +++ /dev/null @@ -1,2 +0,0 @@ -console.log('ok'); -