From 736e677e79cec44825c64ddbd58da2e7997c7c0c Mon Sep 17 00:00:00 2001 From: Caio Lima Date: Thu, 16 Apr 2026 16:08:02 -0300 Subject: [PATCH 1/2] [export-defer] Add export defer namespace-object evaluation-triggers cases Test the observable deferred evaluation semantics of `export defer` namespace objects. The proposal only inserts EvaluateModuleSync into [[Get]], so only operations that route through [[Get]] on the namespace object trigger deferred source evaluation. Tests use three template families that reflect this classification: trigger-on-exported/ (4 variants: string-exported, string-not-exported, then-exported, then-not-exported) For operations that route through [[Get]] and trigger evaluation when the key is a deferred-reexported name. The string-not-exported and then-not-exported variants verify that non-exported keys do NOT trigger (the [[Get]] returns undefined before reaching GetOptionalIndirectExportsModuleRequests). no-trigger-on-exported/ (4 variants: string-exported, string-not-exported, then-exported, then-not-exported) For key-sensitive operations that never route through [[Get]]. no-trigger/ (1 variant: no key) For operations that take no property key or where the key is irrelevanr, ns evaluation is never triggered. --- src/export-defer/defineOwnProperty.case | 20 ++++++ src/export-defer/delete.case | 20 ++++++ src/export-defer/get-in-prototype.case | 19 ++++++ src/export-defer/get.case | 18 +++++ src/export-defer/getOwnProperty.case | 19 ++++++ .../hasProperty-in-prototype.case | 19 ++++++ src/export-defer/hasProperty.case | 18 +++++ .../string-exported.template | 30 +++++++++ .../string-not-exported.template | 30 +++++++++ .../then-exported.template | 30 +++++++++ .../then-not-exported.template | 30 +++++++++ .../no-trigger/no-trigger.template | 28 ++++++++ src/export-defer/ownPropertyKey-names.case | 17 +++++ src/export-defer/ownPropertyKeys-symbols.case | 17 +++++ src/export-defer/ownPropertyKeys.case | 17 +++++ src/export-defer/set-string-exported.case | 17 +++++ src/export-defer/set-string-not-exported.case | 17 +++++ src/export-defer/super-get.case | 25 +++++++ src/export-defer/super-property-define.case | 36 ++++++++++ .../super-property-set-exported.case | 66 +++++++++++++++++++ .../string-exported.template | 39 +++++++++++ .../string-not-exported.template | 39 +++++++++++ .../then-exported.template | 39 +++++++++++ .../then-not-exported.template | 40 +++++++++++ .../barrel-then_FIXTURE.js | 6 ++ .../evaluation-triggers/barrel_FIXTURE.js | 6 ++ .../evaluation-triggers/dep-then_FIXTURE.js | 6 ++ .../evaluation-triggers/dep_FIXTURE.js | 6 ++ .../evaluation-triggers/setup_FIXTURE.js | 4 ++ 29 files changed, 678 insertions(+) create mode 100644 src/export-defer/defineOwnProperty.case create mode 100644 src/export-defer/delete.case create mode 100644 src/export-defer/get-in-prototype.case create mode 100644 src/export-defer/get.case create mode 100644 src/export-defer/getOwnProperty.case create mode 100644 src/export-defer/hasProperty-in-prototype.case create mode 100644 src/export-defer/hasProperty.case create mode 100644 src/export-defer/no-trigger-on-exported/string-exported.template create mode 100644 src/export-defer/no-trigger-on-exported/string-not-exported.template create mode 100644 src/export-defer/no-trigger-on-exported/then-exported.template create mode 100644 src/export-defer/no-trigger-on-exported/then-not-exported.template create mode 100644 src/export-defer/no-trigger/no-trigger.template create mode 100644 src/export-defer/ownPropertyKey-names.case create mode 100644 src/export-defer/ownPropertyKeys-symbols.case create mode 100644 src/export-defer/ownPropertyKeys.case create mode 100644 src/export-defer/set-string-exported.case create mode 100644 src/export-defer/set-string-not-exported.case create mode 100644 src/export-defer/super-get.case create mode 100644 src/export-defer/super-property-define.case create mode 100644 src/export-defer/super-property-set-exported.case create mode 100644 src/export-defer/trigger-on-exported/string-exported.template create mode 100644 src/export-defer/trigger-on-exported/string-not-exported.template create mode 100644 src/export-defer/trigger-on-exported/then-exported.template create mode 100644 src/export-defer/trigger-on-exported/then-not-exported.template create mode 100644 test/language/export/export-defer/evaluation-triggers/barrel-then_FIXTURE.js create mode 100644 test/language/export/export-defer/evaluation-triggers/barrel_FIXTURE.js create mode 100644 test/language/export/export-defer/evaluation-triggers/dep-then_FIXTURE.js create mode 100644 test/language/export/export-defer/evaluation-triggers/dep_FIXTURE.js create mode 100644 test/language/export/export-defer/evaluation-triggers/setup_FIXTURE.js diff --git a/src/export-defer/defineOwnProperty.case b/src/export-defer/defineOwnProperty.case new file mode 100644 index 00000000000..98f852b5a40 --- /dev/null +++ b/src/export-defer/defineOwnProperty.case @@ -0,0 +1,20 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-defineownproperty-p-desc +desc: _ [[DefineOwnProperty]] +info: | + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + +template: trigger-on-exported +---*/ + +//- body +try { + Object.defineProperty(ns, key, { value: "hi" }); +} catch (_) {} diff --git a/src/export-defer/delete.case b/src/export-defer/delete.case new file mode 100644 index 00000000000..f3292c2910b --- /dev/null +++ b/src/export-defer/delete.case @@ -0,0 +1,20 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-delete-p +desc: _ [[Delete]] +info: | + [[Delete]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryDelete(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *false*. + 1. Return *true*. + +template: no-trigger-on-exported +---*/ + +//- body +try { + delete ns[key]; +} catch (_) {} diff --git a/src/export-defer/get-in-prototype.case b/src/export-defer/get-in-prototype.case new file mode 100644 index 00000000000..3dd0b26636a --- /dev/null +++ b/src/export-defer/get-in-prototype.case @@ -0,0 +1,19 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-get-p-receiver +desc: _ [[Get]] when namespace object is in the prototype chain +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +template: trigger-on-exported +---*/ + +//- body +const obj = Object.create(ns); +obj[key]; diff --git a/src/export-defer/get.case b/src/export-defer/get.case new file mode 100644 index 00000000000..c07e1e78e06 --- /dev/null +++ b/src/export-defer/get.case @@ -0,0 +1,18 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-get-p-receiver +desc: _ [[Get]] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +template: trigger-on-exported +---*/ + +//- body +ns[key]; diff --git a/src/export-defer/getOwnProperty.case b/src/export-defer/getOwnProperty.case new file mode 100644 index 00000000000..94207163319 --- /dev/null +++ b/src/export-defer/getOwnProperty.case @@ -0,0 +1,19 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-getownproperty-p +desc: _ [[GetOwnProperty]] +info: | + [[GetOwnProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryGetOwnProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let value be ? _O_.[[Get]](_P_, _O_). + 1. Return PropertyDescriptor { [[Value]]: _value_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *false* }. + +template: trigger-on-exported +---*/ + +//- body +Object.getOwnPropertyDescriptor(ns, key); diff --git a/src/export-defer/hasProperty-in-prototype.case b/src/export-defer/hasProperty-in-prototype.case new file mode 100644 index 00000000000..8375ea61848 --- /dev/null +++ b/src/export-defer/hasProperty-in-prototype.case @@ -0,0 +1,19 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-hasproperty-p +desc: _ [[HasProperty]] when namespace object is in the prototype chain +info: | + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +template: no-trigger-on-exported +---*/ + +//- body +const obj = Object.create(ns); +key in obj; diff --git a/src/export-defer/hasProperty.case b/src/export-defer/hasProperty.case new file mode 100644 index 00000000000..209590dfebc --- /dev/null +++ b/src/export-defer/hasProperty.case @@ -0,0 +1,18 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-hasproperty-p +desc: _ [[HasProperty]] +info: | + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +template: no-trigger-on-exported +---*/ + +//- body +key in ns; diff --git a/src/export-defer/no-trigger-on-exported/string-exported.template b/src/export-defer/no-trigger-on-exported/string-exported.template new file mode 100644 index 00000000000..81755cf51f3 --- /dev/null +++ b/src/export-defer/no-trigger-on-exported/string-exported.template @@ -0,0 +1,30 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-exported-string- +name: of a string that is a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/src/export-defer/no-trigger-on-exported/string-not-exported.template b/src/export-defer/no-trigger-on-exported/string-not-exported.template new file mode 100644 index 00000000000..ff4549dd254 --- /dev/null +++ b/src/export-defer/no-trigger-on-exported/string-not-exported.template @@ -0,0 +1,30 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-not-exported-string- +name: of a string that is not a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/src/export-defer/no-trigger-on-exported/then-exported.template b/src/export-defer/no-trigger-on-exported/then-exported.template new file mode 100644 index 00000000000..4c5289c6d07 --- /dev/null +++ b/src/export-defer/no-trigger-on-exported/then-exported.template @@ -0,0 +1,30 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-exported-then- +name: of "then" when it is a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/src/export-defer/no-trigger-on-exported/then-not-exported.template b/src/export-defer/no-trigger-on-exported/then-not-exported.template new file mode 100644 index 00000000000..765c86883dd --- /dev/null +++ b/src/export-defer/no-trigger-on-exported/then-not-exported.template @@ -0,0 +1,30 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-not-exported-then- +name: of "then" when it is not a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/src/export-defer/no-trigger/no-trigger.template b/src/export-defer/no-trigger/no-trigger.template new file mode 100644 index 00000000000..bc68a8af5ad --- /dev/null +++ b/src/export-defer/no-trigger/no-trigger.template @@ -0,0 +1,28 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore- +name: does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/src/export-defer/ownPropertyKey-names.case b/src/export-defer/ownPropertyKey-names.case new file mode 100644 index 00000000000..ef6ef7a14e5 --- /dev/null +++ b/src/export-defer/ownPropertyKey-names.case @@ -0,0 +1,17 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-ownpropertykeys +desc: _ [[OwnPropertyKeys]] +info: | + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +template: no-trigger +---*/ + +//- body +Object.getOwnPropertyNames(ns); diff --git a/src/export-defer/ownPropertyKeys-symbols.case b/src/export-defer/ownPropertyKeys-symbols.case new file mode 100644 index 00000000000..0056c5496b6 --- /dev/null +++ b/src/export-defer/ownPropertyKeys-symbols.case @@ -0,0 +1,17 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-ownpropertykeys +desc: _ [[OwnPropertyKeys]] +info: | + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +template: no-trigger +---*/ + +//- body +Object.getOwnPropertySymbols(ns); diff --git a/src/export-defer/ownPropertyKeys.case b/src/export-defer/ownPropertyKeys.case new file mode 100644 index 00000000000..8cbce85e18d --- /dev/null +++ b/src/export-defer/ownPropertyKeys.case @@ -0,0 +1,17 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-ownpropertykeys +desc: _ [[OwnPropertyKeys]] +info: | + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +template: no-trigger +---*/ + +//- body +Reflect.ownKeys(ns); diff --git a/src/export-defer/set-string-exported.case b/src/export-defer/set-string-exported.case new file mode 100644 index 00000000000..f2d72e90477 --- /dev/null +++ b/src/export-defer/set-string-exported.case @@ -0,0 +1,17 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-set-p-v-receiver +desc: _ [[Set]] of a string which is an export name +info: | + [[Set]] ( _P_, _V_, _Receiver_ ) + 1. Return *false*. + +template: no-trigger +---*/ + +//- body +try { + ns.exported = "hi"; +} catch (_) {} diff --git a/src/export-defer/set-string-not-exported.case b/src/export-defer/set-string-not-exported.case new file mode 100644 index 00000000000..35e8c51ce15 --- /dev/null +++ b/src/export-defer/set-string-not-exported.case @@ -0,0 +1,17 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-set-p-v-receiver +desc: _ [[Set]] of a string which is not an export name +info: | + [[Set]] ( _P_, _V_, _Receiver_ ) + 1. Return *false*. + +template: no-trigger +---*/ + +//- body +try { + ns.notExported = "hi"; +} catch (_) {} diff --git a/src/export-defer/super-get.case b/src/export-defer/super-get.case new file mode 100644 index 00000000000..9b18bd7ee6d --- /dev/null +++ b/src/export-defer/super-get.case @@ -0,0 +1,25 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-get-p-receiver +desc: _ [[Get]] when namespace is aliased by super +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +template: trigger-on-exported +---*/ + +//- body +let obj = { + superGet(key) { + return super[key]; + } +} + +Object.setPrototypeOf(obj, ns); +obj.superGet(key); diff --git a/src/export-defer/super-property-define.case b/src/export-defer/super-property-define.case new file mode 100644 index 00000000000..3c8430298d8 --- /dev/null +++ b/src/export-defer/super-property-define.case @@ -0,0 +1,36 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-defineownproperty-p-desc +desc: _ [[DefineOwnProperty]] called from class field definition +info: | + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + + DefineField ( receiver, fieldRecord ) + 1. Let fieldName be fieldRecord.[[Name]]. + 1. Let initializer be fieldRecord.[[Initializer]]. + 1. ... + 1. If fieldName is a Private Name, then + a. Perform ? PrivateFieldAdd(receiver, fieldName, initValue). + 1. Else, + 1. Assert: fieldName is a property key. + a. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue). + 1. Return unused. + +template: trigger-on-exported +---*/ + +//- body +class A { constructor() { return ns; } }; +class B extends A { + [key] = 10; +}; + +try { + new B(); +} catch (_) {} diff --git a/src/export-defer/super-property-set-exported.case b/src/export-defer/super-property-set-exported.case new file mode 100644 index 00000000000..d978bc5d6b6 --- /dev/null +++ b/src/export-defer/super-property-set-exported.case @@ -0,0 +1,66 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-module-namespace-exotic-objects-getownproperty-p +desc: _ [[GetOwnProperty]] called on super access +info: | + SuperProperty : super [ Expression ] + 1. Let _env_ be GetThisEnvironment(). + 1. Let _actualThis_ be ? _env_.GetThisBinding(). + 1. Let _propertyNameReference_ be ? Evaluation of |Expression|. + 1. Let _propertyNameValue_ be ? GetValue(_propertyNameReference_). + 1. Let _strict_ be IsStrict(this |SuperProperty|). + 1. Return MakeSuperPropertyReference(_actualThis_, _propertyNameValue_, _strict_). + + MakeSuperPropertyReference ( _actualThis_, _propertyKey_, _strict_ ) + 1. Let _env_ be GetThisEnvironment(). + 1. Assert: _env_.HasSuperBinding() is *true*. + 1. Assert: _env_ is a Function Environment Record. + 1. Let _baseValue_ be GetSuperBase(_env_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _propertyKey_, [[Strict]]: _strict_, [[ThisValue]]: _actualThis_ }. + + PutValue ( _V_, _W_ ) + 1. If _V_ is not a Reference Record, throw a *ReferenceError* exception. + ... + 1. If IsPropertyReference(_V_) is *true*, then + 1. Let _baseObj_ be ? ToObject(_V_.[[Base]]). + ... + 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). + 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. + 1. Return ~unused~. + ... + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + 1. Let _parent_ be ? _O_.[[GetPrototypeOf]](). + 1. If _parent_ is not *null*, return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + 1. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. If IsDataDescriptor(_ownDesc_) is *true*, then + 1. If _ownDesc_.[[Writable]] is *false*, return *false*. + 1. If _Receiver_ is not an Object, return *false*. + 1. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + 1. If _existingDescriptor_ is *undefined*, then + 1. Assert: _Receiver_ does not currently have a property _P_. + 1. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + 1. If IsAccessorDescriptor(_existingDescriptor_) is *true*, return *false*. + 1. If _existingDescriptor_.[[Writable]] is *false*, return *false*. + 1. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + 1. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + ... + +template: trigger-on-exported +---*/ + +//- body +class A { constructor() { return ns; } }; +class B extends A { + constructor() { + super(); + super[key] = 14; + } +}; + +try { + new B(); +} catch (_) {} diff --git a/src/export-defer/trigger-on-exported/string-exported.template b/src/export-defer/trigger-on-exported/string-exported.template new file mode 100644 index 00000000000..7fde9c56f08 --- /dev/null +++ b/src/export-defer/trigger-on-exported/string-exported.template @@ -0,0 +1,39 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/trigger-exported-string- +name: of a string that is a deferred-reexported name, triggers evaluation +esid: sec-module-namespace-exotic-objects +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/src/export-defer/trigger-on-exported/string-not-exported.template b/src/export-defer/trigger-on-exported/string-not-exported.template new file mode 100644 index 00000000000..f2bf5750699 --- /dev/null +++ b/src/export-defer/trigger-on-exported/string-not-exported.template @@ -0,0 +1,39 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-not-exported-string- +name: of a string that is not a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/src/export-defer/trigger-on-exported/then-exported.template b/src/export-defer/trigger-on-exported/then-exported.template new file mode 100644 index 00000000000..a89e2cf4a57 --- /dev/null +++ b/src/export-defer/trigger-on-exported/then-exported.template @@ -0,0 +1,39 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/trigger-exported-then- +name: of "then" when it is a deferred-reexported name, triggers evaluation +esid: sec-module-namespace-exotic-objects +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/src/export-defer/trigger-on-exported/then-not-exported.template b/src/export-defer/trigger-on-exported/then-not-exported.template new file mode 100644 index 00000000000..8f13488fdb6 --- /dev/null +++ b/src/export-defer/trigger-on-exported/then-not-exported.template @@ -0,0 +1,40 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +path: language/export/export-defer/evaluation-triggers/ignore-not-exported-then- +name: of "then" when it is not a deferred-reexported name, does not trigger evaluation +esid: sec-module-namespace-exotic-objects +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + +flags: [module] +features: [export-defer] +includes: [compareArray.js] +---*/ + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +/*{ body }*/ + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/barrel-then_FIXTURE.js b/test/language/export/export-defer/evaluation-triggers/barrel-then_FIXTURE.js new file mode 100644 index 00000000000..912f3f2ce47 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/barrel-then_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.evaluations.push("barrel"); + +export defer { then } from "./dep-then_FIXTURE.js"; diff --git a/test/language/export/export-defer/evaluation-triggers/barrel_FIXTURE.js b/test/language/export/export-defer/evaluation-triggers/barrel_FIXTURE.js new file mode 100644 index 00000000000..f536167f4bd --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/barrel_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.evaluations.push("barrel"); + +export defer { exported } from "./dep_FIXTURE.js"; diff --git a/test/language/export/export-defer/evaluation-triggers/dep-then_FIXTURE.js b/test/language/export/export-defer/evaluation-triggers/dep-then_FIXTURE.js new file mode 100644 index 00000000000..43b3b0b06f9 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/dep-then_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.evaluations.push("dep"); + +export let then = 3; diff --git a/test/language/export/export-defer/evaluation-triggers/dep_FIXTURE.js b/test/language/export/export-defer/evaluation-triggers/dep_FIXTURE.js new file mode 100644 index 00000000000..0be6376896b --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/dep_FIXTURE.js @@ -0,0 +1,6 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.evaluations.push("dep"); + +export let exported = 3; diff --git a/test/language/export/export-defer/evaluation-triggers/setup_FIXTURE.js b/test/language/export/export-defer/evaluation-triggers/setup_FIXTURE.js new file mode 100644 index 00000000000..c72aabeac21 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/setup_FIXTURE.js @@ -0,0 +1,4 @@ +// Copyright (C) 2026 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +globalThis.evaluations = []; From c367836d3bfa3e5688460a0de626ec0be34b1172 Mon Sep 17 00:00:00 2001 From: Caio Lima Date: Thu, 16 Apr 2026 16:30:19 -0300 Subject: [PATCH 2/2] Adding generated tests --- .../ignore-exported-string-delete.js | 39 ++++++++ ...xported-string-hasProperty-in-prototype.js | 38 ++++++++ .../ignore-exported-string-hasProperty.js | 37 ++++++++ .../ignore-exported-then-delete.js | 39 ++++++++ ...-exported-then-hasProperty-in-prototype.js | 38 ++++++++ .../ignore-exported-then-hasProperty.js | 37 ++++++++ ...e-not-exported-string-defineOwnProperty.js | 48 ++++++++++ .../ignore-not-exported-string-delete.js | 39 ++++++++ ...re-not-exported-string-get-in-prototype.js | 47 +++++++++ .../ignore-not-exported-string-get.js | 46 +++++++++ ...nore-not-exported-string-getOwnProperty.js | 47 +++++++++ ...xported-string-hasProperty-in-prototype.js | 38 ++++++++ .../ignore-not-exported-string-hasProperty.js | 37 ++++++++ .../ignore-not-exported-string-super-get.js | 53 +++++++++++ ...t-exported-string-super-property-define.js | 64 +++++++++++++ ...rted-string-super-property-set-exported.js | 94 ++++++++++++++++++ ...ore-not-exported-then-defineOwnProperty.js | 49 ++++++++++ .../ignore-not-exported-then-delete.js | 39 ++++++++ ...nore-not-exported-then-get-in-prototype.js | 48 ++++++++++ .../ignore-not-exported-then-get.js | 47 +++++++++ ...ignore-not-exported-then-getOwnProperty.js | 48 ++++++++++ ...-exported-then-hasProperty-in-prototype.js | 38 ++++++++ .../ignore-not-exported-then-hasProperty.js | 37 ++++++++ .../ignore-not-exported-then-super-get.js | 54 +++++++++++ ...not-exported-then-super-property-define.js | 65 +++++++++++++ ...ported-then-super-property-set-exported.js | 95 +++++++++++++++++++ .../ignore-ownPropertyKey-names.js | 34 +++++++ .../ignore-ownPropertyKeys-symbols.js | 34 +++++++ .../ignore-ownPropertyKeys.js | 34 +++++++ .../ignore-set-string-exported.js | 34 +++++++ .../ignore-set-string-not-exported.js | 34 +++++++ ...igger-exported-string-defineOwnProperty.js | 48 ++++++++++ ...rigger-exported-string-get-in-prototype.js | 47 +++++++++ .../trigger-exported-string-get.js | 46 +++++++++ .../trigger-exported-string-getOwnProperty.js | 47 +++++++++ .../trigger-exported-string-super-get.js | 53 +++++++++++ ...r-exported-string-super-property-define.js | 64 +++++++++++++ ...rted-string-super-property-set-exported.js | 94 ++++++++++++++++++ ...trigger-exported-then-defineOwnProperty.js | 48 ++++++++++ .../trigger-exported-then-get-in-prototype.js | 47 +++++++++ .../trigger-exported-then-get.js | 46 +++++++++ .../trigger-exported-then-getOwnProperty.js | 47 +++++++++ .../trigger-exported-then-super-get.js | 53 +++++++++++ ...ger-exported-then-super-property-define.js | 64 +++++++++++++ ...ported-then-super-property-set-exported.js | 94 ++++++++++++++++++ 45 files changed, 2229 insertions(+) create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-string-delete.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-then-delete.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-defineOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-delete.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-getOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-define.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-set-exported.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-defineOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-delete.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-getOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-define.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-set-exported.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKey-names.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys-symbols.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-set-string-exported.js create mode 100644 test/language/export/export-defer/evaluation-triggers/ignore-set-string-not-exported.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-defineOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-getOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-define.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-set-exported.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-defineOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get-in-prototype.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-getOwnProperty.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-get.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-define.js create mode 100644 test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-set-exported.js diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-delete.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-delete.js new file mode 100644 index 00000000000..8e013fcb326 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-delete.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/delete.case +// - src/export-defer/no-trigger-on-exported/string-exported.template +/*--- +description: _ [[Delete]] (of a string that is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Delete]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryDelete(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *false*. + 1. Return *true*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +try { + delete ns[key]; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty-in-prototype.js new file mode 100644 index 00000000000..8f9214eaeaa --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty-in-prototype.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty-in-prototype.case +// - src/export-defer/no-trigger-on-exported/string-exported.template +/*--- +description: _ [[HasProperty]] when namespace object is in the prototype chain (of a string that is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +const obj = Object.create(ns); +key in obj; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty.js new file mode 100644 index 00000000000..e865c612399 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-string-hasProperty.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty.case +// - src/export-defer/no-trigger-on-exported/string-exported.template +/*--- +description: _ [[HasProperty]] (of a string that is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +key in ns; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-delete.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-delete.js new file mode 100644 index 00000000000..76d1d28ff8f --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-delete.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/delete.case +// - src/export-defer/no-trigger-on-exported/then-exported.template +/*--- +description: _ [[Delete]] (of "then" when it is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Delete]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryDelete(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *false*. + 1. Return *true*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +try { + delete ns[key]; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty-in-prototype.js new file mode 100644 index 00000000000..451d3c6ee60 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty-in-prototype.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty-in-prototype.case +// - src/export-defer/no-trigger-on-exported/then-exported.template +/*--- +description: _ [[HasProperty]] when namespace object is in the prototype chain (of "then" when it is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +const obj = Object.create(ns); +key in obj; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty.js new file mode 100644 index 00000000000..831b0753dcd --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-exported-then-hasProperty.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty.case +// - src/export-defer/no-trigger-on-exported/then-exported.template +/*--- +description: _ [[HasProperty]] (of "then" when it is a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +key in ns; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-defineOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-defineOwnProperty.js new file mode 100644 index 00000000000..e15edcafb8d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-defineOwnProperty.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/defineOwnProperty.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[DefineOwnProperty]] (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +try { + Object.defineProperty(ns, key, { value: "hi" }); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-delete.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-delete.js new file mode 100644 index 00000000000..ce034b9490d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-delete.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/delete.case +// - src/export-defer/no-trigger-on-exported/string-not-exported.template +/*--- +description: _ [[Delete]] (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Delete]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryDelete(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *false*. + 1. Return *true*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +try { + delete ns[key]; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get-in-prototype.js new file mode 100644 index 00000000000..12f4a22caba --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get-in-prototype.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get-in-prototype.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[Get]] when namespace object is in the prototype chain (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +const obj = Object.create(ns); +obj[key]; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get.js new file mode 100644 index 00000000000..0f3fbdef402 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-get.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[Get]] (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +ns[key]; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-getOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-getOwnProperty.js new file mode 100644 index 00000000000..f023fca7081 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-getOwnProperty.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/getOwnProperty.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[GetOwnProperty]] (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[GetOwnProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryGetOwnProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let value be ? _O_.[[Get]](_P_, _O_). + 1. Return PropertyDescriptor { [[Value]]: _value_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *false* }. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +Object.getOwnPropertyDescriptor(ns, key); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty-in-prototype.js new file mode 100644 index 00000000000..805e1817a66 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty-in-prototype.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty-in-prototype.case +// - src/export-defer/no-trigger-on-exported/string-not-exported.template +/*--- +description: _ [[HasProperty]] when namespace object is in the prototype chain (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +const obj = Object.create(ns); +key in obj; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty.js new file mode 100644 index 00000000000..ff0d08cc59d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-hasProperty.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty.case +// - src/export-defer/no-trigger-on-exported/string-not-exported.template +/*--- +description: _ [[HasProperty]] (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +key in ns; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-get.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-get.js new file mode 100644 index 00000000000..ae5a4f5bc38 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-get.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-get.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[Get]] when namespace is aliased by super (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +let obj = { + superGet(key) { + return super[key]; + } +} + +Object.setPrototypeOf(obj, ns); +obj.superGet(key); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-define.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-define.js new file mode 100644 index 00000000000..e185ffe8b44 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-define.js @@ -0,0 +1,64 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-define.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[DefineOwnProperty]] called from class field definition (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + + DefineField ( receiver, fieldRecord ) + 1. Let fieldName be fieldRecord.[[Name]]. + 1. Let initializer be fieldRecord.[[Initializer]]. + 1. ... + 1. If fieldName is a Private Name, then + a. Perform ? PrivateFieldAdd(receiver, fieldName, initValue). + 1. Else, + 1. Assert: fieldName is a property key. + a. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue). + 1. Return unused. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +class A { constructor() { return ns; } }; +class B extends A { + [key] = 10; +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-set-exported.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-set-exported.js new file mode 100644 index 00000000000..78ba337be23 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-string-super-property-set-exported.js @@ -0,0 +1,94 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-set-exported.case +// - src/export-defer/trigger-on-exported/string-not-exported.template +/*--- +description: _ [[GetOwnProperty]] called on super access (of a string that is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name is not in [[Exports]], so [[Get]] short-circuits at step 3 + before reaching the GetOptionalIndirectExportsModuleRequests check. + The deferred source is not evaluated. + + + SuperProperty : super [ Expression ] + 1. Let _env_ be GetThisEnvironment(). + 1. Let _actualThis_ be ? _env_.GetThisBinding(). + 1. Let _propertyNameReference_ be ? Evaluation of |Expression|. + 1. Let _propertyNameValue_ be ? GetValue(_propertyNameReference_). + 1. Let _strict_ be IsStrict(this |SuperProperty|). + 1. Return MakeSuperPropertyReference(_actualThis_, _propertyNameValue_, _strict_). + + MakeSuperPropertyReference ( _actualThis_, _propertyKey_, _strict_ ) + 1. Let _env_ be GetThisEnvironment(). + 1. Assert: _env_.HasSuperBinding() is *true*. + 1. Assert: _env_ is a Function Environment Record. + 1. Let _baseValue_ be GetSuperBase(_env_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _propertyKey_, [[Strict]]: _strict_, [[ThisValue]]: _actualThis_ }. + + PutValue ( _V_, _W_ ) + 1. If _V_ is not a Reference Record, throw a *ReferenceError* exception. + ... + 1. If IsPropertyReference(_V_) is *true*, then + 1. Let _baseObj_ be ? ToObject(_V_.[[Base]]). + ... + 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). + 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. + 1. Return ~unused~. + ... + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + 1. Let _parent_ be ? _O_.[[GetPrototypeOf]](). + 1. If _parent_ is not *null*, return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + 1. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. If IsDataDescriptor(_ownDesc_) is *true*, then + 1. If _ownDesc_.[[Writable]] is *false*, return *false*. + 1. If _Receiver_ is not an Object, return *false*. + 1. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + 1. If _existingDescriptor_ is *undefined*, then + 1. Assert: _Receiver_ does not currently have a property _P_. + 1. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + 1. If IsAccessorDescriptor(_existingDescriptor_) is *true*, return *false*. + 1. If _existingDescriptor_.[[Writable]] is *false*, return *false*. + 1. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + 1. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "notExported"; + +class A { constructor() { return ns; } }; +class B extends A { + constructor() { + super(); + super[key] = 14; + } +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported name does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-defineOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-defineOwnProperty.js new file mode 100644 index 00000000000..8c779d40d2f --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-defineOwnProperty.js @@ -0,0 +1,49 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/defineOwnProperty.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[DefineOwnProperty]] (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +try { + Object.defineProperty(ns, key, { value: "hi" }); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-delete.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-delete.js new file mode 100644 index 00000000000..2a2fd33c131 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-delete.js @@ -0,0 +1,39 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/delete.case +// - src/export-defer/no-trigger-on-exported/then-not-exported.template +/*--- +description: _ [[Delete]] (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Delete]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryDelete(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *false*. + 1. Return *true*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +try { + delete ns[key]; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get-in-prototype.js new file mode 100644 index 00000000000..d05d3a17002 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get-in-prototype.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get-in-prototype.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[Get]] when namespace object is in the prototype chain (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +const obj = Object.create(ns); +obj[key]; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get.js new file mode 100644 index 00000000000..9031e7e2248 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-get.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[Get]] (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +ns[key]; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-getOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-getOwnProperty.js new file mode 100644 index 00000000000..65abecdda9e --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-getOwnProperty.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/getOwnProperty.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[GetOwnProperty]] (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[GetOwnProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryGetOwnProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let value be ? _O_.[[Get]](_P_, _O_). + 1. Return PropertyDescriptor { [[Value]]: _value_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *false* }. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +Object.getOwnPropertyDescriptor(ns, key); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty-in-prototype.js new file mode 100644 index 00000000000..7a761c24696 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty-in-prototype.js @@ -0,0 +1,38 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty-in-prototype.case +// - src/export-defer/no-trigger-on-exported/then-not-exported.template +/*--- +description: _ [[HasProperty]] when namespace object is in the prototype chain (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +const obj = Object.create(ns); +key in obj; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty.js new file mode 100644 index 00000000000..cd91b492c7d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-hasProperty.js @@ -0,0 +1,37 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/hasProperty.case +// - src/export-defer/no-trigger-on-exported/then-not-exported.template +/*--- +description: _ [[HasProperty]] (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[HasProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryHasProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ contains _P_, return *true*. + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +key in ns; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-get.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-get.js new file mode 100644 index 00000000000..e21349ee7da --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-get.js @@ -0,0 +1,54 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-get.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[Get]] when namespace is aliased by super (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +let obj = { + superGet(key) { + return super[key]; + } +} + +Object.setPrototypeOf(obj, ns); +obj.superGet(key); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-define.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-define.js new file mode 100644 index 00000000000..242632e5bce --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-define.js @@ -0,0 +1,65 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-define.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[DefineOwnProperty]] called from class field definition (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + + DefineField ( receiver, fieldRecord ) + 1. Let fieldName be fieldRecord.[[Name]]. + 1. Let initializer be fieldRecord.[[Initializer]]. + 1. ... + 1. If fieldName is a Private Name, then + a. Perform ? PrivateFieldAdd(receiver, fieldName, initValue). + 1. Else, + 1. Assert: fieldName is a property key. + a. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue). + 1. Return unused. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +class A { constructor() { return ns; } }; +class B extends A { + [key] = 10; +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-set-exported.js b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-set-exported.js new file mode 100644 index 00000000000..41ec9289f0a --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-not-exported-then-super-property-set-exported.js @@ -0,0 +1,95 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-set-exported.case +// - src/export-defer/trigger-on-exported/then-not-exported.template +/*--- +description: _ [[GetOwnProperty]] called on super access (of "then" when it is not a deferred-reexported name, does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The name "then" is not in [[Exports]] of this barrel, so [[Get]] + short-circuits at step 3 before reaching the + GetOptionalIndirectExportsModuleRequests check. The deferred source + is not evaluated. + + + SuperProperty : super [ Expression ] + 1. Let _env_ be GetThisEnvironment(). + 1. Let _actualThis_ be ? _env_.GetThisBinding(). + 1. Let _propertyNameReference_ be ? Evaluation of |Expression|. + 1. Let _propertyNameValue_ be ? GetValue(_propertyNameReference_). + 1. Let _strict_ be IsStrict(this |SuperProperty|). + 1. Return MakeSuperPropertyReference(_actualThis_, _propertyNameValue_, _strict_). + + MakeSuperPropertyReference ( _actualThis_, _propertyKey_, _strict_ ) + 1. Let _env_ be GetThisEnvironment(). + 1. Assert: _env_.HasSuperBinding() is *true*. + 1. Assert: _env_ is a Function Environment Record. + 1. Let _baseValue_ be GetSuperBase(_env_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _propertyKey_, [[Strict]]: _strict_, [[ThisValue]]: _actualThis_ }. + + PutValue ( _V_, _W_ ) + 1. If _V_ is not a Reference Record, throw a *ReferenceError* exception. + ... + 1. If IsPropertyReference(_V_) is *true*, then + 1. Let _baseObj_ be ? ToObject(_V_.[[Base]]). + ... + 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). + 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. + 1. Return ~unused~. + ... + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + 1. Let _parent_ be ? _O_.[[GetPrototypeOf]](). + 1. If _parent_ is not *null*, return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + 1. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. If IsDataDescriptor(_ownDesc_) is *true*, then + 1. If _ownDesc_.[[Writable]] is *false*, return *false*. + 1. If _Receiver_ is not an Object, return *false*. + 1. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + 1. If _existingDescriptor_ is *undefined*, then + 1. Assert: _Receiver_ does not currently have a property _P_. + 1. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + 1. If IsAccessorDescriptor(_existingDescriptor_) is *true*, return *false*. + 1. If _existingDescriptor_.[[Writable]] is *false*, return *false*. + 1. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + 1. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +class A { constructor() { return ns; } }; +class B extends A { + constructor() { + super(); + super[key] = 14; + } +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation on non-exported 'then' does not trigger deferred-source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKey-names.js b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKey-names.js new file mode 100644 index 00000000000..57f00c4d142 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKey-names.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/ownPropertyKey-names.case +// - src/export-defer/no-trigger/no-trigger.template +/*--- +description: _ [[OwnPropertyKeys]] (does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +Object.getOwnPropertyNames(ns); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys-symbols.js b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys-symbols.js new file mode 100644 index 00000000000..d5e6b8fb99f --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys-symbols.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/ownPropertyKeys-symbols.case +// - src/export-defer/no-trigger/no-trigger.template +/*--- +description: _ [[OwnPropertyKeys]] (does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +Object.getOwnPropertySymbols(ns); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys.js b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys.js new file mode 100644 index 00000000000..1d2b786400b --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-ownPropertyKeys.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/ownPropertyKeys.case +// - src/export-defer/no-trigger/no-trigger.template +/*--- +description: _ [[OwnPropertyKeys]] (does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[OwnPropertyKeys]] ( ) + 1. Let _exports_ be _O_.[[Exports]]. + 1. Let _symbolKeys_ be OrdinaryOwnPropertyKeys(_O_). + 1. Return the list-concatenation of _exports_ and _symbolKeys_. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +Reflect.ownKeys(ns); + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-set-string-exported.js b/test/language/export/export-defer/evaluation-triggers/ignore-set-string-exported.js new file mode 100644 index 00000000000..48b73a6ded6 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-set-string-exported.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/set-string-exported.case +// - src/export-defer/no-trigger/no-trigger.template +/*--- +description: _ [[Set]] of a string which is an export name (does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Set]] ( _P_, _V_, _Receiver_ ) + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +try { + ns.exported = "hi"; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/ignore-set-string-not-exported.js b/test/language/export/export-defer/evaluation-triggers/ignore-set-string-not-exported.js new file mode 100644 index 00000000000..35fffc33fb5 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/ignore-set-string-not-exported.js @@ -0,0 +1,34 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/set-string-not-exported.case +// - src/export-defer/no-trigger/no-trigger.template +/*--- +description: _ [[Set]] of a string which is not an export name (does not trigger evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + EvaluateModuleSync is only inserted into [[Get]] by this proposal. + Operations that do not route through [[Get]] do not reach it, + even for a deferred-reexported name. + + + [[Set]] ( _P_, _V_, _Receiver_ ) + 1. Return *false*. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +try { + ns.notExported = "hi"; +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel"], + "operation does not route through [[Get]], so deferred source is not evaluated"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-defineOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-defineOwnProperty.js new file mode 100644 index 00000000000..a66220efef3 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-defineOwnProperty.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/defineOwnProperty.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[DefineOwnProperty]] (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +try { + Object.defineProperty(ns, key, { value: "hi" }); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get-in-prototype.js new file mode 100644 index 00000000000..801892153e0 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get-in-prototype.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get-in-prototype.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[Get]] when namespace object is in the prototype chain (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +const obj = Object.create(ns); +obj[key]; + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get.js new file mode 100644 index 00000000000..570262888e8 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-get.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[Get]] (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +ns[key]; + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-getOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-getOwnProperty.js new file mode 100644 index 00000000000..c4775f1f519 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-getOwnProperty.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/getOwnProperty.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[GetOwnProperty]] (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[GetOwnProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryGetOwnProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let value be ? _O_.[[Get]](_P_, _O_). + 1. Return PropertyDescriptor { [[Value]]: _value_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *false* }. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +Object.getOwnPropertyDescriptor(ns, key); + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-get.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-get.js new file mode 100644 index 00000000000..3d456573ead --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-get.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-get.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[Get]] when namespace is aliased by super (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +let obj = { + superGet(key) { + return super[key]; + } +} + +Object.setPrototypeOf(obj, ns); +obj.superGet(key); + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-define.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-define.js new file mode 100644 index 00000000000..cb946995cf1 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-define.js @@ -0,0 +1,64 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-define.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[DefineOwnProperty]] called from class field definition (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + + DefineField ( receiver, fieldRecord ) + 1. Let fieldName be fieldRecord.[[Name]]. + 1. Let initializer be fieldRecord.[[Initializer]]. + 1. ... + 1. If fieldName is a Private Name, then + a. Perform ? PrivateFieldAdd(receiver, fieldName, initValue). + 1. Else, + 1. Assert: fieldName is a property key. + a. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue). + 1. Return unused. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +class A { constructor() { return ns; } }; +class B extends A { + [key] = 10; +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-set-exported.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-set-exported.js new file mode 100644 index 00000000000..d54458f909b --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-string-super-property-set-exported.js @@ -0,0 +1,94 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-set-exported.case +// - src/export-defer/trigger-on-exported/string-exported.template +/*--- +description: _ [[GetOwnProperty]] called on super access (of a string that is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + SuperProperty : super [ Expression ] + 1. Let _env_ be GetThisEnvironment(). + 1. Let _actualThis_ be ? _env_.GetThisBinding(). + 1. Let _propertyNameReference_ be ? Evaluation of |Expression|. + 1. Let _propertyNameValue_ be ? GetValue(_propertyNameReference_). + 1. Let _strict_ be IsStrict(this |SuperProperty|). + 1. Return MakeSuperPropertyReference(_actualThis_, _propertyNameValue_, _strict_). + + MakeSuperPropertyReference ( _actualThis_, _propertyKey_, _strict_ ) + 1. Let _env_ be GetThisEnvironment(). + 1. Assert: _env_.HasSuperBinding() is *true*. + 1. Assert: _env_ is a Function Environment Record. + 1. Let _baseValue_ be GetSuperBase(_env_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _propertyKey_, [[Strict]]: _strict_, [[ThisValue]]: _actualThis_ }. + + PutValue ( _V_, _W_ ) + 1. If _V_ is not a Reference Record, throw a *ReferenceError* exception. + ... + 1. If IsPropertyReference(_V_) is *true*, then + 1. Let _baseObj_ be ? ToObject(_V_.[[Base]]). + ... + 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). + 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. + 1. Return ~unused~. + ... + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + 1. Let _parent_ be ? _O_.[[GetPrototypeOf]](). + 1. If _parent_ is not *null*, return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + 1. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. If IsDataDescriptor(_ownDesc_) is *true*, then + 1. If _ownDesc_.[[Writable]] is *false*, return *false*. + 1. If _Receiver_ is not an Object, return *false*. + 1. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + 1. If _existingDescriptor_ is *undefined*, then + 1. Assert: _Receiver_ does not currently have a property _P_. + 1. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + 1. If IsAccessorDescriptor(_existingDescriptor_) is *true*, return *false*. + 1. If _existingDescriptor_.[[Writable]] is *false*, return *false*. + 1. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + 1. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "exported"; + +class A { constructor() { return ns; } }; +class B extends A { + constructor() { + super(); + super[key] = 14; + } +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported name triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-defineOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-defineOwnProperty.js new file mode 100644 index 00000000000..3f8cef2bc9d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-defineOwnProperty.js @@ -0,0 +1,48 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/defineOwnProperty.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[DefineOwnProperty]] (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +try { + Object.defineProperty(ns, key, { value: "hi" }); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get-in-prototype.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get-in-prototype.js new file mode 100644 index 00000000000..36e83f9ffa3 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get-in-prototype.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get-in-prototype.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[Get]] when namespace object is in the prototype chain (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +const obj = Object.create(ns); +obj[key]; + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get.js new file mode 100644 index 00000000000..82a107b3fff --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-get.js @@ -0,0 +1,46 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/get.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[Get]] (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +ns[key]; + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-getOwnProperty.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-getOwnProperty.js new file mode 100644 index 00000000000..928e4551033 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-getOwnProperty.js @@ -0,0 +1,47 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/getOwnProperty.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[GetOwnProperty]] (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[GetOwnProperty]] ( _P_ ) + 1. If _P_ is a Symbol, return OrdinaryGetOwnProperty(_O_, _P_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let value be ? _O_.[[Get]](_P_, _O_). + 1. Return PropertyDescriptor { [[Value]]: _value_, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *false* }. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +Object.getOwnPropertyDescriptor(ns, key); + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-get.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-get.js new file mode 100644 index 00000000000..16799004c3d --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-get.js @@ -0,0 +1,53 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-get.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[Get]] when namespace is aliased by super (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +let obj = { + superGet(key) { + return super[key]; + } +} + +Object.setPrototypeOf(obj, ns); +obj.superGet(key); + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-define.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-define.js new file mode 100644 index 00000000000..1f7e57d8482 --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-define.js @@ -0,0 +1,64 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-define.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[DefineOwnProperty]] called from class field definition (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + [[DefineOwnProperty]] ( _P_, _Desc_ ) + 1. If _P_ is a Symbol, return OrdinaryDefineOwnProperty(_O_, _P_, _Desc_). + 1. Let _current_ be ? _O_.[[GetOwnProperty]](_P_). + 1. If _current_ is *undefined*, return *false*. + 1. ... + + DefineField ( receiver, fieldRecord ) + 1. Let fieldName be fieldRecord.[[Name]]. + 1. Let initializer be fieldRecord.[[Initializer]]. + 1. ... + 1. If fieldName is a Private Name, then + a. Perform ? PrivateFieldAdd(receiver, fieldName, initValue). + 1. Else, + 1. Assert: fieldName is a property key. + a. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue). + 1. Return unused. + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +class A { constructor() { return ns; } }; +class B extends A { + [key] = 10; +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation"); diff --git a/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-set-exported.js b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-set-exported.js new file mode 100644 index 00000000000..d1dbe08a3ea --- /dev/null +++ b/test/language/export/export-defer/evaluation-triggers/trigger-exported-then-super-property-set-exported.js @@ -0,0 +1,94 @@ +// This file was procedurally generated from the following sources: +// - src/export-defer/super-property-set-exported.case +// - src/export-defer/trigger-on-exported/then-exported.template +/*--- +description: _ [[GetOwnProperty]] called on super access (of "then" when it is a deferred-reexported name, triggers evaluation) +esid: sec-module-namespace-exotic-objects +features: [export-defer] +flags: [generated, module] +includes: [compareArray.js] +info: | + [[Get]] ( _P_, _Receiver_ ) + 1. If _P_ is a Symbol, return OrdinaryGet(_O_, _P_, _Receiver_). + 1. Let _exports_ be _O_.[[Exports]]. + 1. If _exports_ does not contain _P_, return *undefined*. + 1. Let _m_ be _O_.[[Module]]. + 1. If _m_ is a Cyclic Module Record and _m_.GetOptionalIndirectExportsModuleRequests(« _P_ ») is not empty, then + 1. Perform ? EvaluateModuleSync(_m_, « _P_ »). + 1. ... + + The namespace is an ordinary module namespace (not deferred), so + [[Deferred]] is false. The trigger is inside [[Get]] at the + GetOptionalIndirectExportsModuleRequests check for the given name. + + + SuperProperty : super [ Expression ] + 1. Let _env_ be GetThisEnvironment(). + 1. Let _actualThis_ be ? _env_.GetThisBinding(). + 1. Let _propertyNameReference_ be ? Evaluation of |Expression|. + 1. Let _propertyNameValue_ be ? GetValue(_propertyNameReference_). + 1. Let _strict_ be IsStrict(this |SuperProperty|). + 1. Return MakeSuperPropertyReference(_actualThis_, _propertyNameValue_, _strict_). + + MakeSuperPropertyReference ( _actualThis_, _propertyKey_, _strict_ ) + 1. Let _env_ be GetThisEnvironment(). + 1. Assert: _env_.HasSuperBinding() is *true*. + 1. Assert: _env_ is a Function Environment Record. + 1. Let _baseValue_ be GetSuperBase(_env_). + 1. Return the Reference Record { [[Base]]: _baseValue_, [[ReferencedName]]: _propertyKey_, [[Strict]]: _strict_, [[ThisValue]]: _actualThis_ }. + + PutValue ( _V_, _W_ ) + 1. If _V_ is not a Reference Record, throw a *ReferenceError* exception. + ... + 1. If IsPropertyReference(_V_) is *true*, then + 1. Let _baseObj_ be ? ToObject(_V_.[[Base]]). + ... + 1. Let _succeeded_ be ? _baseObj_.[[Set]](_V_.[[ReferencedName]], _W_, GetThisValue(_V_)). + 1. If _succeeded_ is *false* and _V_.[[Strict]] is *true*, throw a *TypeError* exception. + 1. Return ~unused~. + ... + + OrdinarySetWithOwnDescriptor ( _O_, _P_, _V_, _Receiver_, _ownDesc_ ) + 1. If _ownDesc_ is *undefined*, then + 1. Let _parent_ be ? _O_.[[GetPrototypeOf]](). + 1. If _parent_ is not *null*, return ? _parent_.[[Set]](_P_, _V_, _Receiver_). + 1. Set _ownDesc_ to the PropertyDescriptor { [[Value]]: *undefined*, [[Writable]]: *true*, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. If IsDataDescriptor(_ownDesc_) is *true*, then + 1. If _ownDesc_.[[Writable]] is *false*, return *false*. + 1. If _Receiver_ is not an Object, return *false*. + 1. Let _existingDescriptor_ be ? _Receiver_.[[GetOwnProperty]](_P_). + 1. If _existingDescriptor_ is *undefined*, then + 1. Assert: _Receiver_ does not currently have a property _P_. + 1. Return ? CreateDataProperty(_Receiver_, _P_, _V_). + 1. If IsAccessorDescriptor(_existingDescriptor_) is *true*, return *false*. + 1. If _existingDescriptor_.[[Writable]] is *false*, return *false*. + 1. Let _valueDesc_ be the PropertyDescriptor { [[Value]]: _V_ }. + 1. Return ? _Receiver_.[[DefineOwnProperty]](_P_, _valueDesc_). + ... + +---*/ + + +import "./setup_FIXTURE.js"; + +import * as ns from "./barrel-then_FIXTURE.js"; + +assert.compareArray(globalThis.evaluations, ["barrel"], + "barrel evaluated eagerly; deferred source not yet evaluated"); + +var key = "then"; + +class A { constructor() { return ns; } }; +class B extends A { + constructor() { + super(); + super[key] = 14; + } +}; + +try { + new B(); +} catch (_) {} + +assert.compareArray(globalThis.evaluations, ["barrel", "dep"], + "operation on deferred-reexported 'then' triggers source evaluation");