diff --git a/src/ast/nodes/MemberExpression.ts b/src/ast/nodes/MemberExpression.ts index cb77210c11c..c5401379781 100644 --- a/src/ast/nodes/MemberExpression.ts +++ b/src/ast/nodes/MemberExpression.ts @@ -24,12 +24,7 @@ import Identifier from './Identifier'; import Literal from './Literal'; import * as NodeType from './NodeType'; import PrivateIdentifier from './PrivateIdentifier'; -import { - ExpressionEntity, - LiteralValueOrUnknown, - UnknownValue, - UNKNOWN_EXPRESSION -} from './shared/Expression'; +import { ExpressionEntity, LiteralValueOrUnknown, UnknownValue, UNKNOWN_EXPRESSION } from './shared/Expression'; import { ExpressionNode, IncludeChildren, NodeBase } from './shared/Node'; import SpreadElement from './SpreadElement'; import Super from './Super'; @@ -211,12 +206,11 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE } hasEffectsWhenAccessedAtPath(path: ObjectPath, context: HasEffectsContext): boolean { - if (path.length === 0) return false; if (this.variable !== null) { return this.variable.hasEffectsWhenAccessedAtPath(path, context); } if (this.replacement) { - return false; + return true; } return this.object.hasEffectsWhenAccessedAtPath([this.getPropertyKey(), ...path], context); } diff --git a/src/ast/values.ts b/src/ast/values.ts index 49cb6460626..1edfae57d84 100644 --- a/src/ast/values.ts +++ b/src/ast/values.ts @@ -6,8 +6,7 @@ import { EMPTY_PATH, ObjectPath, ObjectPathKey } from './utils/PathTracker'; export interface MemberDescription { callsArgs: number[] | null; - returns: { new (): ExpressionEntity } | null; - returnsPrimitive: ExpressionEntity | null; + returns: ExpressionEntity; } export interface MemberDescriptions { @@ -34,8 +33,7 @@ export const UNDEFINED_EXPRESSION: ExpressionEntity = new (class UndefinedExpres const returnsUnknown: RawMemberDescription = { value: { callsArgs: null, - returns: null, - returnsPrimitive: UNKNOWN_EXPRESSION + returns: UNKNOWN_EXPRESSION } }; @@ -66,8 +64,7 @@ export const UNKNOWN_LITERAL_BOOLEAN: ExpressionEntity = new (class UnknownBoole const returnsBoolean: RawMemberDescription = { value: { callsArgs: null, - returns: null, - returnsPrimitive: UNKNOWN_LITERAL_BOOLEAN + returns: UNKNOWN_LITERAL_BOOLEAN } }; @@ -98,8 +95,7 @@ export const UNKNOWN_LITERAL_NUMBER: ExpressionEntity = new (class UnknownNumber const returnsNumber: RawMemberDescription = { value: { callsArgs: null, - returns: null, - returnsPrimitive: UNKNOWN_LITERAL_NUMBER + returns: UNKNOWN_LITERAL_NUMBER } }; @@ -130,8 +126,7 @@ export const UNKNOWN_LITERAL_STRING: ExpressionEntity = new (class UnknownString const returnsString: RawMemberDescription = { value: { callsArgs: null, - returns: null, - returnsPrimitive: UNKNOWN_LITERAL_STRING + returns: UNKNOWN_LITERAL_STRING } }; @@ -181,8 +176,7 @@ const literalStringMembers: MemberDescriptions = assembleMemberDescriptions( replace: { value: { callsArgs: [1], - returns: null, - returnsPrimitive: UNKNOWN_LITERAL_STRING + returns: UNKNOWN_LITERAL_STRING } }, search: returnsNumber, @@ -247,7 +241,5 @@ export function getMemberReturnExpressionWhenCalled( memberName: ObjectPathKey ): ExpressionEntity { if (typeof memberName !== 'string' || !members[memberName]) return UNKNOWN_EXPRESSION; - return members[memberName].returnsPrimitive !== null - ? members[memberName].returnsPrimitive! - : new members[memberName].returns!(); + return members[memberName].returns; } diff --git a/test/form/samples/namespace-missing-export-effects/_config.js b/test/form/samples/namespace-missing-export-effects/_config.js new file mode 100644 index 00000000000..739a1f55b16 --- /dev/null +++ b/test/form/samples/namespace-missing-export-effects/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'handles interacting with missing namespace members' +}; diff --git a/test/form/samples/namespace-missing-export-effects/_expected.js b/test/form/samples/namespace-missing-export-effects/_expected.js new file mode 100644 index 00000000000..8895a217864 --- /dev/null +++ b/test/form/samples/namespace-missing-export-effects/_expected.js @@ -0,0 +1,5 @@ +if (!undefined) console.log(1); +if (undefined()) console.log(2); +const foo = undefined; +foo.bar; +(0, undefined)(); diff --git a/test/form/samples/namespace-missing-export-effects/main.js b/test/form/samples/namespace-missing-export-effects/main.js new file mode 100644 index 00000000000..e37bad3f8ac --- /dev/null +++ b/test/form/samples/namespace-missing-export-effects/main.js @@ -0,0 +1,7 @@ +import * as ns from './other.js'; + +if (!ns.foo) console.log(1); +if (ns.foo()) console.log(2); +const foo = ns.foo; +foo.bar; +(true && ns.foo)(); diff --git a/test/form/samples/namespace-missing-export-effects/other.js b/test/form/samples/namespace-missing-export-effects/other.js new file mode 100644 index 00000000000..e69de29bb2d