diff --git a/spec.emu b/spec.emu index b152571..17ac3be 100644 --- a/spec.emu +++ b/spec.emu @@ -13,6 +13,79 @@ contributors: Nicolò Ribaudo

NOTE: The diff markers are on top of https://tc39.es/proposal-defer-import-eval/.

+ +

Executable Code and Execution Contexts

+ + +

Environment Records

+ + +

The Environment Record Type Hierarchy

+ + +

Module Environment Records

+ + +

+ GetBindingValue ( + _name_: a String, + _strict_: a Boolean, + ): either a normal completion containing an ECMAScript language value or a throw completion +

+
+
for
+
a Module Environment Record _envRec_
+ +
description
+
It returns the value of its bound identifier whose name is _name_. However, if the binding is an indirect binding the value of the target binding is returned. If the binding exists but is uninitialized a *ReferenceError* is thrown.
+
+ + 1. Assert: _strict_ is *true*. + 1. Assert: _envRec_ has a binding for _name_. + 1. If the binding for _name_ is an indirect binding, then + 1. Let _module_ and _targetName_ be the indirection values provided when this binding for _name_ was created. + 1. Let _targetEnv_ be _module_.[[Environment]]. + 1. If _targetEnv_ is ~empty~, throw a *ReferenceError* exception. + 1. Return ? _targetEnv_.GetBindingValue(_targetName_, *true*). + 1. If the binding for _name_ in _envRec_ is an uninitialized binding, then + 1. If the binding for _name_ in _envRec_ is a deferred initialization binding, then + 1. Let _initializationSteps_ be the deferred initialization steps provided for _name_ when this binding was created. + 1. Let _value_ be _initializationSteps_(). + 1. Perform ! _envRec_.InitializeBinding(_name_, _value_). + 1. Else, + 1. Throw a *ReferenceError* exception. + 1. Return the value currently bound to _name_ in _envRec_. + + +

_strict_ will always be *true* because a |Module| is always strict mode code.

+
+
+ + +

+ + CreateDeferredInitializationBinding ( + _envRec_: a Module Environment Record, + _name_: a String, + _initializationSteps_: an Abstract Closure that takes no arguments and returns an ECMAScript language value + ): ~unused~ + +

+
+
description
+
It creates a deferred initialization binding (a binding that is automatically initialized on first access) for the name _name_. A binding must not already exist in _envRec_ for _name_.
+
+ + 1. Assert: _envRec_ does not already have a binding for _name_. + 1. Create an imutable deferred initialization binding in _envRec_ for _name_ whose deferred initialization steps is _initializationSteps_, and record that the binding is uninitialized and that it is a strict binding. + 1. Return ~unused~. + +
+
+
+
+
+

Ordinary and Exotic Objects Behaviours

@@ -49,9 +122,9 @@ contributors: Nicolò Ribaudo 1. Let _targetModule_ be _binding_.[[Module]]. 1. Assert: _targetModule_ is not *undefined*. 1. If _binding_.[[BindingName]] is ~namespace~, then - 1. Return GetModuleNamespace(_targetModule_, ~evaluation~). + 1. Return GetModuleNamespace(_targetModule_, ~evaluation~, ~all~). 1. If _binding_.[[BindingName]] is ~deferred-namespace~, then - 1. Return GetModuleNamespace(_targetModule_, ~defer~). + 1. Return GetModuleNamespace(_targetModule_, ~defer~, ~all~). 1. Let _targetEnv_ be _targetModule_.[[Environment]]. 1. If _targetEnv_ is ~empty~, throw a *ReferenceError* exception. 1. Return ? _targetEnv_.GetBindingValue(_binding_.[[BindingName]], *true*). @@ -60,6 +133,40 @@ contributors: Nicolò Ribaudo

ResolveExport is side-effect free. Each time this operation is called with a specific _exportName_, _resolveSet_ pair as arguments it must return the same result. An implementation might choose to pre-compute or cache the ResolveExport results for the [[Exports]] of each module namespace exotic object.

+ + +

+ ModuleNamespaceCreate ( + _module_: a Module Record, + _exports_: a List of Strings, + _phase_: ~defer~ or ~evaluation~, + ): a module namespace exotic object +

+
+
description
+
It is used to specify the creation of new module namespace exotic objects.
+
+ + 1. Let _internalSlotsList_ be the internal slots listed in . + 1. Let _M_ be MakeBasicObject(_internalSlotsList_). + 1. Set _M_'s essential internal methods to the definitions specified in . + 1. Set _M_.[[Module]] to _module_. + 1. Let _sortedExports_ be a List whose elements are the elements of _exports_, sorted according to lexicographic code unit order. + 1. Set _M_.[[Exports]] to _sortedExports_. + 1. If _phase_ is ~defer~, then + 1. Assert: _module_.[[DeferredNamespace]] is ~empty~. + 1. Set _module_.[[DeferredNamespace]] to _M_. + 1. Set _M_.[[Deferred]] to *true*. + 1. Let _toStringTag_ be *"Deferred Module"*. + 1. Else, + 1. Assert: _module_.[[Namespace]] is ~empty~. + 1. Set _module_.[[Namespace]] to _M_. + 1. Set _M_.[[Deferred]] to *false*. + 1. Let _toStringTag_ be *"Module"*. + 1. Create an own data property of _M_ named %Symbol.toStringTag% whose [[Value]] is _toStringTag_ and whose [[Writable]], [[Enumerable]], and [[Configurable]] attributes are *false*. + 1. Return _M_. + +
@@ -147,7 +254,7 @@ contributors: Nicolò Ribaudo 1. Perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _link_.[[Value]] »). 1. Return ~unused~. 1. Let _fulfilledClosure_ be a new Abstract Closure with no parameters that captures _module_, _phase_, and _promiseCapability_ and performs the following steps when called: - 1. Let _namespace_ be GetModuleNamespace(_module_, _phase_). + 1. Let _namespace_ be GetModuleNamespace(_module_, _phase_, ~all~). 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _namespace_ »). 1. Return ~unused~. 1. If _phase_ is ~defer~, then @@ -323,7 +430,6 @@ contributors: Nicolò Ribaudo 1. Let _specifier_ be SV of |FromClause|. 1. Let _importedNames_ be ImportedNames of |NameSpaceImport|. - 1. Assert: _importedNames_ is ~all~. 1. Return a List whose sole element is the ModuleRequest Record { [[Specifier]]: _specifier_, [[Attributes]]: « », [[Phase]]: ~defer~, [[ImportedNames]]: _importedNames_ }. @@ -333,7 +439,6 @@ contributors: Nicolò Ribaudo 1. Let _specifier_ be SV of |FromClause|. 1. Let _attributes_ be WithClauseToAttributes of |WithClause|. 1. Let _importedNames_ be ImportedNames of |NameSpaceImport|. - 1. Assert: _importedNames_ is ~all~. 1. Return a List whose sole element is the ModuleRequest Record { [[Specifier]]: _specifier_, [[Attributes]]: _attributes_, [[Phase]]: ~defer~, [[ImportedNames]]: _importedNames_ }. @@ -448,7 +553,18 @@ contributors: Nicolò Ribaudo an Object or ~empty~ - The Module Namespace Object () if one has been created for this module. + The Module Namespace Object () whose [[Deferred]] slot is *false*, if one has been created for this module. + + + + + [[DeferredNamespace]] + + + an Object or ~empty~ + + + The Module Namespace Object () whose [[Deferred]] slot is *true*, if one has been created for this module. @@ -519,7 +635,7 @@ contributors: Nicolò Ribaudo ): a ResolvedBinding Record, *null*, or ~ambiguous~ -

It returns the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form { [[Module]]: Module Record, [[BindingName]]: String | ~namespace~ | ~deferred-namespace~ }. If the export is a Module Namespace Object without a direct binding in any module, [[BindingName]] will be set to ~namespace~ or ~deferred-namespace~ (depending on whether the binding comes from a deferred import or not). It returns *null* if the name cannot be resolved, or ~ambiguous~ if multiple bindings were found.

+

It returns the binding of a name exported by this module. Bindings are represented by ResolvedBinding Records a ResolvedBinding Record, of the form { [[Module]]: Module Record, [[BindingName]]: String | ~namespace~| ~deferred-namespace~ }. If the export is a Module Namespace Object without a direct binding in any module, [[BindingName]] will be set to ~namespace~ or ~deferred-namespace~ (depending on whether the binding comes from a deferred import or not). It returns *null* if the name cannot be resolved, or ~ambiguous~ if multiple bindings were found.

Each time this operation is called with a specific _exportName_, _resolveSet_ pair as arguments it must return the same result.

LoadRequestedModules must have completed successfully prior to invoking this method.

@@ -563,6 +679,45 @@ contributors: Nicolò Ribaudo +

A ResolvedBinding Record has the following fields:

+ + + + + + + + + + + + + + + + + +
+ Field Name + + Value Type + + Meaning +
+ [[Module]] + + a Module Record + + The module that provides the binding +
+ [[BindingName]] + + a String or ~namespace~ + + The name of the binding within that module, or ~namespace~ if the export is the module's namespace object. +
+
+

EvaluateModuleSync ( @@ -1522,6 +1677,503 @@ contributors: Nicolò Ribaudo +

An ImportEntry Record is a Record that digests information about a single declarative import. Each ImportEntry Record has the fields defined in :

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field Name + + Value Type + + Meaning +
+ [[ModuleRequest]] + + a ModuleRequest Record + + ModuleRequest Record representing the |ModuleSpecifier| and import attributes of the |ImportDeclaration|. +
+ [[ImportName]] + + a String, ~namespace-object~, or ~filtered-namespace-object~ + + The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value ~namespace-object~ indicates that the import request is for the target module's namespace object, and the value ~filtered-namespace-object~ indicates that the import request is for a filtered namespace created from the module. +
+ [[LocalName]] + + a String + + The name that is used to locally access the imported value from within the importing module. +
+ [[NamespaceNamesFilter]] + + a List of Strings or ~empty~ + + When [[ImportName]] is ~filtered-namespace-object~, this field contains the list of export names to include in the namespace object. For all other values of [[ImportName]], this field is ~empty~. +
+
+ +

gives examples of ImportEntry records fields used to represent the syntactic import forms:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Import Statement Form + + [[ModuleRequest]] + + [[ImportName]] + + [[LocalName]] + + [[NamespaceNamesFilter]] +
+ `import v from "mod";` + + *"mod"* + + *"default"* + + *"v"* + + ~empty~ +
+ `import * as ns from "mod";` + + *"mod"* + + ~namespace-object~ + + *"ns"* + + ~empty~ +
+ `import {x} from "mod";` + + *"mod"* + + *"x"* + + *"x"* + + ~empty~ +
+ `import {x as v} from "mod";` + + *"mod"* + + *"x"* + + *"v"* + + ~empty~ +
+ `import {x, y} as ns from "mod";` + + *"mod"* + + ~filtered-namespace-object~ + + *"ns"* + + « *"x"*, *"y"* » +
+
+
+ +

An ExportEntry Record is a Record that digests information about a single declarative export. Each ExportEntry Record has the fields defined in :

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Field Name + + Value Type + + Meaning +
+ [[ExportName]] + + a String or *null* + + The name used to export this binding by this module. +
+ [[ModuleRequest]] + + a ModuleRequest Record or *null* + + The ModuleRequest Record representing the |ModuleSpecifier| and import attributes of the |ExportDeclaration|. *null* if the |ExportDeclaration| does not have a |ModuleSpecifier|. +
+ [[ImportName]] + + a String, *null*, ~all~, ~all-but-default~, or ~filtered-namespace~ + + The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. *null* if the |ExportDeclaration| does not have a |ModuleSpecifier|. ~all~ is used for `export * as ns from "mod"` declarations. ~all-but-default~ is used for `export * from "mod"` declarations. ~filtered-namespace~ is used for `export {x, y} as ns from "mod"` declarations where only selected exports are included in the namespace. +
+ [[LocalName]] + + a String or *null* + + The name that is used to locally access the exported value from within the importing module. *null* if the exported value is not locally accessible from within the module. +
+ [[NamespaceNamesFilter]] + + a List of Strings or ~empty~ + + When [[ImportName]] is ~filtered-namespace~, this field contains the list of export names to include in the namespace object. For all other values of [[ImportName]], this field is ~empty~. +
+
+ +

gives examples of the ExportEntry record fields used to represent the syntactic export forms:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Export Statement Form + + [[ExportName]] + + [[ModuleRequest]] + + [[ImportName]] + + [[LocalName]] + + [[NamespaceNamesFilter]] +
+ `export var v;` + + *"v"* + + *null* + + *null* + + *"v"* + + ~empty~ +
+ `export default function f() {}` + + *"default"* + + *null* + + *null* + + *"f"* + + ~empty~ +
+ `export default function () {}` + + *"default"* + + *null* + + *null* + + *"\*default\*"* + + ~empty~ +
+ `export default 42;` + + *"default"* + + *null* + + *null* + + *"\*default\*"* + + ~empty~ +
+ `export {x};` + + *"x"* + + *null* + + *null* + + *"x"* + + ~empty~ +
+ `export {v as x};` + + *"x"* + + *null* + + *null* + + *"v"* + + ~empty~ +
+ `export {x} from "mod";` + + *"x"* + + *"mod"* + + *"x"* + + *null* + + ~empty~ +
+ `export {v as x} from "mod";` + + *"x"* + + *"mod"* + + *"v"* + + *null* + + ~empty~ +
+ `export * from "mod";` + + *null* + + *"mod"* + + ~all-but-default~ + + *null* + + ~empty~ +
+ `export * as ns from "mod";` + + *"ns"* + + *"mod"* + + ~all~ + + *null* + + ~empty~ +
+ `export {x, y} as ns from "mod";` + + *"ns"* + + *"mod"* + + ~filtered-namespace~ + + *null* + + « *"x"*, *"y"* » +
+
+
+

ParseModule ( @@ -1554,9 +2206,12 @@ contributors: Nicolò Ribaudo 1. If _ie_.[[ImportName]] is ~namespace-object~, then 1. NOTE: This is a re-export of an imported module namespace object. 1. Append the ExportEntry Record { [[ModuleRequest]]: _ie_.[[ModuleRequest]], [[ImportName]]: ~all~, [[LocalName]]: *null*, [[ExportName]]: _ee_.[[ExportName]] } to _indirectExportEntries_. + 1. Else if _ie_.[[ImportName]] is ~filtered-namespace-object~, then + 1. NOTE: This is a re-export of an imported filtered namespace object. + 1. Append the ExportEntry Record { [[ModuleRequest]]: _ie_.[[ModuleRequest]], [[ImportName]]: ~filtered-namespace~, [[LocalName]]: *null*, [[ExportName]]: _ee_.[[ExportName]], [[NamespaceNamesFilter]]: _ie_.[[NamespaceNamesFilter]] } to _indirectExportEntries_. 1. Else, 1. NOTE: This is a re-export of a single name. - 1. Append the ExportEntry Record { [[ModuleRequest]]: _ie_.[[ModuleRequest]], [[ImportName]]: _ie_.[[ImportName]], [[LocalName]]: *null*, [[ExportName]]: _ee_.[[ExportName]] } to _indirectExportEntries_. + 1. Append the ExportEntry Record { [[ModuleRequest]]: _ie_.[[ModuleRequest]], [[ImportName]]: _ie_.[[ImportName]], [[LocalName]]: *null*, [[ExportName]]: _ee_.[[ExportName]], [[NamespaceNamesFilter]]: ~empty~ } to _indirectExportEntries_. 1. Else if _ee_.[[ImportName]] is ~all-but-default~, then 1. Assert: _ee_.[[ExportName]] is *null*. 1. Append _ee_ to _starExportEntries_. @@ -1620,7 +2275,7 @@ contributors: Nicolò Ribaudo ResolveExport ( _exportName_: a String, optional _resolveSet_: a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String), - optional _deferNamespaceExportSet_: a List of Module Records + optional _deferNamespaceExportSet_: a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String) ): a ResolvedBinding Record, *null*, or ~ambiguous~

@@ -1638,10 +2293,11 @@ contributors: Nicolò Ribaudo 1. Assert: _module_.[[Status]] is not ~new~. 1. If _resolveSet_ is not present, set _resolveSet_ to a new empty List. 1. If _deferNamespaceExportSet_ is not present, set _deferNamespaceExportSet_ to a new empty List. - 1. For each Record { [[Module]], [[ExportName]] } _r_ of _resolveSet_, do - 1. If _module_ and _r_.[[Module]] are the same Module Record and _exportName_ is _r_.[[ExportName]], then - 1. Assert: This is a circular import request. - 1. Return *null*. + 1. For each Record { [[Module]], [[ExportName]] } _r_ of _resolveSet_, do + 1. If _module_ and _r_.[[Module]] are the same Module Record and _exportName_ is _r_.[[ExportName]], then + 1. If ResolveSetContains(_resolveSet_, _module_, _exportName_) is *true*, then + 1. Assert: This is a circular import request. + 1. Return *null*. 1. Append the Record { [[Module]]: _module_, [[ExportName]]: _exportName_ } to _resolveSet_. 1. For each ExportEntry Record _e_ of _module_.[[LocalExportEntries]], do 1. If _e_.[[ExportName]] is _exportName_, then @@ -1654,16 +2310,19 @@ contributors: Nicolò Ribaudo 1. Let _importedModule_ be GetImportedModule(_module_, _e_.[[ModuleRequest]]). 1. If _e_.[[ImportName]] is ~all~, then 1. Assert: _module_ does not provide the direct binding for this export. - 1. If _module_.[[OptionalIndirectExportEntries]] contains _e_ and _deferNamespaceExportSet_ does not contain _importedModule_, then - 1. Append _importedModule_ to _deferNamespaceExportSet_. - 1. For each String _name_ of _importedModule_.GetExportedNames(), do - 1. Let _resolution_ be _importedModule_.ResolveExport(_name_, « », _deferNamespaceExportSet_). - 1. If _resolution_ is *null*, return *null*. + 1. Assert: _e_.[[NamespaceNamesFilter]] is ~empty~. + 1. If _module_.[[OptionalIndirectExportEntries]] contains _e_ and NamespaceMemberIsUnresolvableOptional(_deferNamespaceExportSet_, _module_, _exportName_, _importedModule_, _importedModule_.GetExportedNames(), ~allow-ambiguous~) is *true*, return *null*. 1. If _e_.[[ModuleRequest]].[[Phase]] is ~defer~, then 1. Return ResolvedBinding Record { [[Module]]: _importedModule_, [[BindingName]]: ~deferred-namespace~ }. 1. Else, 1. Assert: _e_.[[Phase]] is ~evaluation~. 1. Return ResolvedBinding Record { [[Module]]: _importedModule_, [[BindingName]]: ~namespace~ }. + 1. Else if _e_.[[ImportName]] is ~filtered-namespace~, then + 1. Assert: _e_.[[NamespaceNamesFilter]] is a List of Strings. + 1. If _module_.[[OptionalIndirectExportEntries]] contains _e_ and NamespaceMemberIsUnresolvableOptional(_deferNamespaceExportSet_, _module_, _exportName_, _importedModule_, _e_.[[NamespaceNamesFilter]], ~disallow-ambiguous~) is *true*, return *null*. + 1. NOTE: `export { ... } as ns from "mod"` introduces a local internal binding in the module that contains the |ExportDeclaration|. That binding is created by InitializeEnvironment. + 1. Let _localName_ be the string-concatenation of *"\*"*, _exportName_, and *"\*"*. + 1. Return ResolvedBinding Record { [[Module]]: _module_, [[BindingName]]: _localName_ }. 1. Else, 1. Assert: _module_ imports a specific binding for this export. 1. Assert: _e_.[[ImportName]] is a String. @@ -1690,6 +2349,54 @@ contributors: Nicolò Ribaudo 1. If _resolution_.[[BindingName]] is a String, _starResolution_.[[BindingName]] is a String, and _resolution_.[[BindingName]] is not _starResolution_.[[BindingName]], return ~ambiguous~. 1. Return _starResolution_. + + +

+ + ResolveSetContains ( + _resolveSet_: a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String), + _module_: a Module Record, + _exportName_: a String, + ): a Boolean + +

+
+
description
+
It checks whether _resolveSet_ contains a Record whose [[Module]] is _module_ and whose [[ExportName]] is _exportName_.
+
+ + 1. For each Record { [[Module]], [[ExportName]] } _r_ of _resolveSet_, do + 1. If _r_.[[Module]] is _module_ and _r_.[[ExportName]] is _exportName_, then + 1. Return *true*. + 1. Return *false*. + +
+ + +

+ + NamespaceMemberIsUnresolvableOptional ( + _deferNamespaceExportSet_: a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String), + _reexporterModule_: a Module Record, + _exportName_: a String, + _namespaceModule_: a Module Record, + _namespaceNames_: a List of Strings, + _onAmbiguous_: ~allow-ambiguous~ or ~disallow-ambiguous~, + ): a Boolean + +

+
+ + 1. If ResolveSetContains(_deferNamespaceExportSet_, _reexporterModule_, _exportName_) is *true*, return *false*. + 1. Append the Record { [[Module]]: _reexporterModule_, [[ExportName]]: _exportName_ } to _deferNamespaceExportSet_. + 1. Assert: ResolveSetContains(_deferNamespaceExportSet_, _reexporterModule_, _exportName_) is *true*. + 1. For each String _name_ of _namespaceNames_, do + 1. Let _resolution_ be _namespaceModule_.ResolveExport(_name_, « », _deferNamespaceExportSet_). + 1. If _resolution_ is *null*, return *true*. + 1. If _resolution_ is ~ambiguous~ and _onAmbiguous_ is ~disallow-ambiguous~, return *true*. + 1. Return *false*. + +
@@ -1707,14 +2414,15 @@ contributors: Nicolò Ribaudo 1. For each ExportEntry Record _e_ of _module_.[[IndirectExportEntries]], do - 1. Let _resolution_ be _module_.ResolveExport(_e_.[[ExportName]]). - 1. If _resolution_ is either *null* or ~ambiguous~, throw a *SyntaxError* exception. - 1. Assert: _resolution_ is a ResolvedBinding Record. + 1. Let _resolution_ be _module_.ResolveExport(_e_.[[ExportName]]). + 1. If _resolution_ is either *null* or ~ambiguous~, throw a *SyntaxError* exception. + 1. Assert: _resolution_ is a ResolvedBinding Record. + 1. Perform ? EnsureResolvableBinding(_module_, _e_.[[ExportName]], ~disallow-ambiguous~). 1. For each ExportEntry Record _e_ of _module_.[[StarExportEntries]], do 1. Let _importedModule_ be GetImportedModule(_module_, _e_.[[ModuleRequest]]). 1. For each String _name_ of _importedModule_.GetExportedNames(), do 1. NOTE: All exports of _importedModule_ other than `export defer` ones are also validated by the InitializeEnvironment call on _importedModule_ itself, and it is not observable which of the two InitializeEnvironment calls throws the *SyntaxError*. - 1. If _name_ is not *"default"* and _importedModule_.ResolveExport(_name_) is *null*, throw a *SyntaxError* exception. + 1. If _name_ is not *"default"*, perform ? EnsureResolvableBinding(_importedModule_, _name_, ~disallow-ambiguous~). 1. Assert: All named exports from _module_ are resolvable. 1. Let _realm_ be _module_.[[Realm]]. 1. Assert: _realm_ is not *undefined*. @@ -1725,20 +2433,41 @@ contributors: Nicolò Ribaudo 1. If _in_.[[ImportName]] is ~namespace-object~, then 1. For each String _name_ of _importedModule_.GetExportedNames(), do 1. NOTE: All exports of _importedModule_ other than `export defer` ones are also validated by the InitializeEnvironment call on _importedModule_ itself, and it is not observable which of the two InitializeEnvironment calls throws the *SyntaxError*. - 1. If _importedModule_.ResolveExport(_name_) is *null*, throw a *SyntaxError* exception. - 1. Let _namespace_ be GetModuleNamespace(_importedModule_, _in_.[[ModuleRequest]].[[Phase]]). + 1. Perform ? EnsureResolvableBinding(_importedModule_, _name_, ~allow-ambiguous~). + 1. Let _namespace_ be GetModuleNamespace(_importedModule_, _in_.[[ModuleRequest]].[[Phase]], ~all~). 1. Perform ! _env_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_). + 1. Else if _in_.[[ImportName]] is ~filtered-namespace-object~, then + 1. For each String _name_ of _in_.[[NamespaceNamesFilter]], perform ? EnsureResolvableBinding(_importedModule_, _name_, ~disallow-ambiguous~). + 1. Let _namespace_ be GetModuleNamespace(_importedModule_, _in_.[[ModuleRequest]].[[Phase]], _in_.[[NamespaceNamesFilter]]). + 1. Perform ! _env_.CreateImmutableBinding(_in_.[[LocalName]], *true*). + 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, 1. Let _resolution_ be _importedModule_.ResolveExport(_in_.[[ImportName]]). 1. If _resolution_ is either *null* or ~ambiguous~, throw a *SyntaxError* exception. 1. If _resolution_.[[BindingName]] is ~namespace~ or ~deferred-namespace~, then 1. If _resolution_.[[BindingName]] is ~namespace~ let _phase_ be ~evaluation~, else let _phase_ be ~defer~. - 1. Let _namespace_ be GetModuleNamespace(_resolution_.[[Module]], _phase_). + 1. Let _namespace_ be GetModuleNamespace(_resolution_.[[Module]], _phase_, ~all~). 1. Perform ! _env_.CreateImmutableBinding(_in_.[[LocalName]], *true*). 1. Perform ! _env_.InitializeBinding(_in_.[[LocalName]], _namespace_). 1. Else, 1. Perform CreateImportBinding(_env_, _in_.[[LocalName]], _resolution_.[[Module]], _resolution_.[[BindingName]]). + 1. For each ExportEntry Record _ie_ of _module_.[[IndirectExportEntries]], do + 1. If _ie_.[[ImportName]] is ~filtered-namespace~, then + 1. Let _localName_ be the string-concatenation of *"\*"*, _ie_.[[ExportName]], and *"\*"*. + 1. Let _importedModule_ be GetImportedModule(_module_, _ie_.[[ModuleRequest]]). + 1. For each String _name_ of _ie_.[[NamespaceNamesFilter]], perform ? EnsureResolvableBinding(_importedModule_, _name_, ~disallow-ambiguous~). + 1. Let _filteredNamespace_ be be GetModuleNamespace(_importedModule_, _ie_.[[ModuleRequest]].[[Phase]], _ie_.[[NamespaceNamesFilter]]). + 1. Perform ! _env_.CreateImmutableBinding(_localName_, *true*). + 1. Perform ! _env_.InitializeBinding(_localName_, _filteredNamespace_). + 1. For each ExportEntry Record _oie_ of _module_.[[OptionalIndirectExportEntries]], do + 1. If _oie_.[[ImportName]] is ~filtered-namespace~, then + 1. Let _localName_ be the string-concatenation of *"\*"*, _oie_.[[ExportName]], and *"\*"*. + 1. Let _initializationSteps_ be a new Abstract Closure with no parameters that captures _module_ and _oie_ and performs the following steps when called: + 1. Let _importedModule_ be GetImportedModule(_module_, _oie_.[[ModuleRequest]]). + 1. Return GetModuleNamespace(_importedModule_, _oie_.[[ModuleRequest]].[[Phase]], _oie_.[[NamespaceNamesFilter]]). + 1. Perform CreateDeferredInitializationBinding(_env_, _localName_, _initializationSteps_). + 1. NOTE: The _localName_ binding of `export defer { ...} as ns from "mod"` is initialized on first access, as whether the corresponding module is available or not depends on _module_'s importers. If any of _module_'s importers causes this binding to be imported, they will also validate it through EnsureResolvableBinding. 1. Let _moduleContext_ be a new ECMAScript code execution context. 1. Set the Function of _moduleContext_ to *null*. 1. Assert: _module_.[[Realm]] is not *undefined*. @@ -1772,6 +2501,30 @@ contributors: Nicolò Ribaudo 1. Remove _moduleContext_ from the execution context stack. 1. Return ~unused~. + + +

+ + EnsureResolvableBinding ( + _module_: a Module Record, + _name_: a String, + _onAmbiguous_: ~allow-ambiguous~ or ~disallow-ambiguous~, + ): either a normal completion containing ~unused~, or a throw completion + +

+
+
description
+
It throws an error if _module_ does not have unabiguous exports for all _names_.
+
+ + 1. Let _resolution_ be _module_.ResolveExport(_names_). + 1. If _resolution_ is *null*, throw a *SyntaxError* exception. + 1. If _onAmbiguous_ is ~disallow-ambiguous~, then + 1. If _resolution_ is ~ambiguous~, throw a *SyntaxError* exception. + 1. Assert: _resolution_ is a ResolvedBinding Record. + 1. Return ~unused~. + +
@@ -1797,8 +2550,9 @@ contributors: Nicolò Ribaudo 1. If _existingRequest_ is ~empty~ and ModuleRequestsKeyEqual(_r_, _nextRequest_) is *true* and _r_.[[Phase]] is _nextRequest_.[[Phase]], then 1. Set _existingRequest_ to _r_. 1. Let _newImportedNames_ be ~all~. - 1. Assert: _oie_.[[ImportName]] is a String or ~all~. + 1. Assert: _oie_.[[ImportName]] is a String, ~filtered-namespace~, or ~all~. 1. If _oie_.[[ImportName]] is a String, set _newImportedNames_ to « _oie_.[[ImportName]] ». + 1. If _oie_.[[ImportName]] is ~filtered-namespace~, set _newImportedNames_ to _oie_.[[NamespaceNamesFilter]]. 1. If _existingRequest_ is ~empty~, then 1. Let _request_ be the ModuleRequest Record { [[Specifier]]: _nextRequest_.[[Specifier]], [[Attributes]]: _nextRequest_.[[Attributes]], [[Phase]]: _nextRequest_.[[Phase]], [[ImportedNames]]: _newImportedNames_ }. 1. Append _request_ to _requests_. @@ -1836,11 +2590,156 @@ contributors: Nicolò Ribaudo 1. Return ~unused~. + + +

+ GetModuleNamespace ( + _module_: an instance of a concrete subclass of Module Record, + _phase_: ~defer~ or ~evaluation~, + _importedNames_: ~all~ or a List of Strings + ): a Module Namespace Object +

+
+
description
+
It retrieves the Module Namespace Object representing _module_'s exports, lazily creating it the first time it was requested, and if _importedNames_ is ~all~ storing it in _module_.[[Namespace]] for future retrieval.
+
+ + + 1. Assert: If _module_ is a Cyclic Module Record, then _module_.[[Status]] is not ~new~ or ~unlinked~. + 1. Let _namespace_ be ~empty~. + 1. If _importedNames_ is ~all~, then + 1. If _phase_ is ~defer~, let set _namespace_ be to _module_.[[DeferredNamespace]]. + 1. Else, let set _namespace_ be to _module_.[[Namespace]]. + 1. If _namespace_ is ~empty~, then + 1. Let _exportedNames_ be _module_.GetExportedNames(). + 1. Let _unambiguousNames_ be a new empty List. + 1. For each element _name_ of _exportedNames_, do + 1. If _importedNames_ is ~all~ or, _importedNames_ contains _name_, then + 1. If _phase_ is not ~defer~ or _name_ is not *"then"*, then + 1. Let _resolution_ be _module_.ResolveExport(_name_). + 1. If _resolution_ is a ResolvedBinding Record, append _name_ to _unambiguousNames_. + 1. Set _namespace_ to ModuleNamespaceCreate(_module_, _unambiguousNames_, _phase_). + 1. If _importedNames_ is ~all~, then + 1. If _phase_ is ~defer~, set _module_.[[DeferredNamespace]] to _namespace_. + 1. Else, set _module_.[[Namespace]] to _namespace_. + 1. Return _namespace_. + + +

GetModuleNamespace never throws. Instead, unresolvable names are simply excluded from the namespace at this point. They will lead to a real linking error later unless they are all ambiguous star exports that are not explicitly requested anywhere.

+
+

Imports

+

Syntax

+ + ImportDeclaration : + `import` ImportClause FromClause WithClause? `;` + `import` `defer` NameSpaceImport FromClause WithClause? `;` + `import` ModuleSpecifier WithClause? `;` + + ImportClause : + ImportedDefaultBinding + NameSpaceImport + NamedImports + ImportedDefaultBinding `,` NameSpaceImport + ImportedDefaultBinding `,` NamedImports + + ImportedDefaultBinding : + ImportedBinding + + NameSpaceImport : + `*` `as` ImportedBinding + NamedImports `as` ImportedBinding + + NamedImports : + `{` `}` + `{` ImportsList `}` + `{` ImportsList `,` `}` + + FromClause : + `from` ModuleSpecifier + + ImportsList : + ImportSpecifier + ImportsList `,` ImportSpecifier + + ImportSpecifier : + ImportedBinding + ModuleExportName `as` ImportedBinding + ModuleExportName + AliasedImportSpecifier + + AliasedImportSpecifier : + ModuleExportName `as` ImportedBinding + + ModuleSpecifier : + StringLiteral + + ImportedBinding : + BindingIdentifier[~Yield, +Await] + + WithClause : + `with` `{` `}` + `with` `{` WithEntries `,`? `}` + + WithEntries : + AttributeKey `:` StringLiteral + AttributeKey `:` StringLiteral `,` WithEntries + + AttributeKey : + IdentifierName + StringLiteral + + + +

Static Semantics: Early Errors

+ ModuleItem : ImportDeclaration +
    +
  • + It is a Syntax Error if the BoundNames of |ImportDeclaration| contains any duplicate entries. +
  • +
+ + + + ImportClause : + NamedImports + ImportedDefaultBinding `,` NamedImports + + +
    +
  • + It is a Syntax Error if LocalBindings of |NamedImports| contains any |StringLiteral|s. +
  • +
  • + For each |IdentifierName| _n_ in LocalBindings of |NamedImports|: It is a Syntax Error if StringValue of _n_ is a |ReservedWord| or the StringValue of _n_ is one of *"arguments"*, *"await"*, *"eval"*, *"implements"*, *"interface"*, *"let"*, *"package"*, *"private"*, *"protected"*, *"public"*, *"static"*, or *"yield"*. +
  • +
+ +

The above rules mean that each LocalBindings of |NamedImports| is treated as an |ImportedBinding|.

+
+ + NameSpaceImport : NamedImports `as` ImportedBinding +
    +
  • + It is a Syntax Error if the |NamedImports| Contains |AliasedImportSpecifier|. +
  • +
  • + It is a Syntax Error if the FilteredNamespaceNames of |NamedImports| contains any duplicate entries. +
  • +
+ + WithClause : `with` `{` WithEntries `,`? `}` +
    +
  • + It is a Syntax Error if WithClauseToAttributes of |WithClause| has two different entries _a_ and _b_ such that _a_.[[Key]] is _b_.[[Key]]. +
  • +
+
+

Static Semantics: ImportEntries ( ): a List of ImportEntry Records

@@ -1897,15 +2796,22 @@ contributors: Nicolò Ribaudo ImportedDefaultBinding : ImportedBinding 1. Let _localName_ be the sole element of the BoundNames of |ImportedBinding|. - 1. Let _defaultEntry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: *"default"*, [[LocalName]]: _localName_ }. + 1. Let _defaultEntry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: *"default"*, [[LocalName]]: _localName_, [[NamespaceNamesFilter]]: ~empty~ }. 1. Return « _defaultEntry_ ». NameSpaceImport : `*` `as` ImportedBinding 1. Let _localName_ be the StringValue of |ImportedBinding|. - 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~namespace-object~, [[LocalName]]: _localName_ }. + 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~namespace-object~, [[LocalName]]: _localName_, [[NamespaceNamesFilter]]: ~empty~ }. 1. Return « _entry_ ». + NameSpaceImport : NamedImports `as` ImportedBinding + + 1. Let _localName_ be the StringValue of |ImportedBinding|. + 1. Let _importedNames_ be the ImportedNames of |NamedImports|. + 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~filtered-namespace-object~, [[LocalName]]: _localName_, [[NamespaceNamesFilter]]: _importedNames_ }. + 1. Return « _entry_ ». + NamedImports : `{` `}` 1. Return a new empty List. @@ -1919,14 +2825,14 @@ contributors: Nicolò Ribaudo ImportSpecifier : ImportedBinding 1. Let _localName_ be the sole element of the BoundNames of |ImportedBinding|. - 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _localName_, [[LocalName]]: _localName_ }. + 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _localName_, [[LocalName]]: _localName_, [[NamespaceNamesFilter]]: ~empty~ }. 1. Return « _entry_ ». ImportSpecifier : ModuleExportName `as` ImportedBinding 1. Let _importName_ be the StringValue of |ModuleExportName|. 1. Let _localName_ be the StringValue of |ImportedBinding|. - 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _importName_, [[LocalName]]: _localName_ }. + 1. Let _entry_ be the ImportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _importName_, [[LocalName]]: _localName_, [[NamespaceNamesFilter]]: ~empty~ }. 1. Return « _entry_ ». @@ -1934,18 +2840,16 @@ contributors: Nicolò Ribaudo

- Static Semantics: ImportedNames ( ): ~all~, ~all-but-default~, or a List of Strings + Static Semantics: ImportedNames ( ): ~all~, ~all-but-default~, or a List of unique Strings

- - ImportClause : - NameSpaceImport - ImportedDefaultBinding `,` NameSpaceImport - + ImportClause : ImportedDefaultBinding `,` NameSpaceImport - 1. Return ~all~. + 1. Let _names1_ be the ImportedNames of |ImportedDefaultBinding|. + 1. Let _names2_ be the ImportedNames of |NameSpaceImport|. + 1. Return MergeImportedNames(_names1_, _names2_). ImportClause : ImportedDefaultBinding `,` NamedImports @@ -1957,6 +2861,14 @@ contributors: Nicolò Ribaudo 1. Return « *"default"* ». + NameSpaceImport : `*` `as` ImportedBinding + + 1. Return ~all~. + + NameSpaceImport : NamedImports `as` ImportedBinding + + 1. Return the ImportedNames of |NamedImports|. + NamedImports : `{` `}` 1. Return « ». @@ -1981,7 +2893,7 @@ contributors: Nicolò Ribaudo 1. Return ~all-but-default~. - ExportFromClause : NamedNamespaceExport + ExportFromClause : `*` `as` ModuleExportName 1. Return ~all~. @@ -2063,6 +2975,82 @@ contributors: Nicolò Ribaudo
+ + +

+ Static Semantics: LocalBindings ( ): a List of either |StringLiteral| or |IdentifierName| Parse Nodes +

+
+
+ NamedImports : `{` `}` + + 1. Return a new empty List. + + ImportsList : ImportsList `,` ImportSpecifier + + 1. Let _bindings1_ be LocalBindings of |ImportsList|. + 1. Let _bindings2_ be LocalBindings of |ImportSpecifier|. + 1. Return the list-concatenation of _bindings1_ and _bindings2_. + + AliasedImportSpecifier : ModuleExportName `as` ImportedBinding + + 1. Return the LocalBindings of |ImportedBinding|. + + ModuleExportName : IdentifierName + Identifier : IdentifierName + + 1. Return a List whose sole element is |IdentifierName|. + + ModuleExportName : StringLiteral + + 1. Return a List whose sole element is |StringLiteral|. + +
+ + +

+ + Static Semantics: FilteredNamespaceNames ( ): a List of Strings + +

+
+
+ + NamedImports : `{` `}` + NamedExports : `{` `}` + + + ImportsList : ImportsList `,` ImportSpecifier + + + 1. Let _names1_ be FilteredNamespaceNames of |ImportsList|. + 1. Let _names2_ be FilteredNamespaceNames of |ImportSpecifier|. + 1. Return the list-concatenation of _names1_ and _names2_. + + + ExportsList : ExportsList `,` ExportSpecifier + + + 1. Let _names1_ be FilteredNamespaceNames of |ExportsList|. + 1. Let _names2_ be FilteredNamespaceNames of |ExportSpecifier|. + 1. Return the list-concatenation of _names1_ and _names2_. + + + ImportSpecifier : ModuleExportName + ExportSpecifier : ModuleExportName + + + 1. Return a List whose sole element is the StringValue of |ModuleExportName|. + + + ImportSpecifier : AliasedImportSpecifier + ExportSpecifier : AliasedExportSpecifier + + + 1. NOTE: It is an early error if a filtered namespace contains an |AliasedImportSpecifier| or |AliasedExportSpecifier| (see and ). + 1. Return a new empty List. + +
@@ -2081,14 +3069,9 @@ contributors: Nicolò Ribaudo ExportFromClause : `*` - `*` `as` ModuleExportName - NamedNamespaceExport - NamedExports - - - NamedNamespaceExport : `*` `as` ModuleExportName - + NamedExports + NamedExports `as` ModuleExportName NamedExports : `{` `}` @@ -2101,7 +3084,11 @@ contributors: Nicolò Ribaudo ExportSpecifier : ModuleExportName - ModuleExportName `as` ModuleExportName + ModuleExportName `as` ModuleExportName + AliasedExportSpecifier + + AliasedExportSpecifier : + ModuleExportName `as` ModuleExportName @@ -2124,6 +3111,15 @@ contributors: Nicolò Ribaudo It is a Syntax Error if |ExportFromClause| is `*`. + ExportFromClause : NamedExports `as` ModuleExportName +
    +
  • + It is a Syntax Error if the |NamedExports| Contains |AliasedExportSpecifier|. +
  • +
  • + It is a Syntax Error if the FilteredNamespaceNames of |NamedExports| contains any duplicate entries. +
  • +
@@ -2159,7 +3155,11 @@ contributors: Nicolò Ribaudo 1. Return a new empty List. - ExportFromClause : `*` `as` ModuleExportName + + ExportFromClause : + `*` `as` ModuleExportName + NamedExports `as` ModuleExportName + 1. Return a List whose sole element is the StringValue of |ModuleExportName|. @@ -2228,7 +3228,7 @@ contributors: Nicolò Ribaudo
ExportDeclaration : `export` ExportFromClause FromClause WithClause? `;` - 1. Let _module_ be the sole element of ModuleRequests of |FromClause|. + 1. Let _module_ be the sole element of ModuleRequests of |FromClause||ExportDeclaration|. 1. Return ExportEntriesForModule of |ExportFromClause| with argument _module_. ExportDeclaration : `export` `defer` ExportFromClause FromClause WithClause? `;` @@ -2244,7 +3244,7 @@ contributors: Nicolò Ribaudo 1. Let _entries_ be a new empty List. 1. Let _names_ be the BoundNames of |VariableStatement|. 1. For each element _name_ of _names_, do - 1. Append the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _name_, [[ExportName]]: _name_ } to _entries_. + 1. Append the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _name_, [[ExportName]]: _name_, [[NamespaceNamesFilter]]: ~empty~ } to _entries_. 1. Return _entries_. ExportDeclaration : `export` Declaration @@ -2252,24 +3252,24 @@ contributors: Nicolò Ribaudo 1. Let _entries_ be a new empty List. 1. Let _names_ be the BoundNames of |Declaration|. 1. For each element _name_ of _names_, do - 1. Append the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _name_, [[ExportName]]: _name_ } to _entries_. + 1. Append the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _name_, [[ExportName]]: _name_, [[NamespaceNamesFilter]]: ~empty~ } to _entries_. 1. Return _entries_. ExportDeclaration : `export` `default` HoistableDeclaration 1. Let _names_ be BoundNames of |HoistableDeclaration|. 1. Let _localName_ be the sole element of _names_. - 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _localName_, [[ExportName]]: *"default"* }. + 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _localName_, [[ExportName]]: *"default"*, [[NamespaceNamesFilter]]: ~empty~ }. ExportDeclaration : `export` `default` ClassDeclaration 1. Let _names_ be BoundNames of |ClassDeclaration|. 1. Let _localName_ be the sole element of _names_. - 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _localName_, [[ExportName]]: *"default"* }. + 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: _localName_, [[ExportName]]: *"default"*, [[NamespaceNamesFilter]]: ~empty~ }. ExportDeclaration : `export` `default` AssignmentExpression `;` - 1. Let _entry_ be the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: *"\*default\*"*, [[ExportName]]: *"default"* }. + 1. Let _entry_ be the ExportEntry Record { [[ModuleRequest]]: *null*, [[ImportName]]: *null*, [[LocalName]]: *"\*default\*"*, [[ExportName]]: *"default"*, [[NamespaceNamesFilter]]: ~empty~ }. 1. Return « _entry_ ». @@ -2277,6 +3277,67 @@ contributors: Nicolò Ribaudo + +

+ Static Semantics: ExportEntriesForModule ( + _module_: a ModuleRequest Record or *null*, + ): a List of ExportEntry Records +

+
+
+ ExportFromClause : `*` + + 1. Let _entry_ be the ExportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~all-but-default~, [[LocalName]]: *null*, [[ExportName]]: *null*, [[NamespaceNamesFilter]]: ~empty~ }. + 1. Return « _entry_ ». + + ExportFromClause : `*` `as` ModuleExportName + + 1. Let _exportName_ be the StringValue of |ModuleExportName|. + 1. Let _entry_ be the ExportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~all~, [[LocalName]]: *null*, [[ExportName]]: _exportName_, [[NamespaceNamesFilter]]: ~empty~ }. + 1. Return « _entry_ ». + + ExportFromClause : NamedExports `as` ModuleExportName + + 1. Let _exportName_ be the StringValue of |ModuleExportName|. + 1. Let _importedNames_ be the ImportedNames of |NamedExports|. + 1. Let _entry_ be the ExportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: ~filtered-namespace~, [[LocalName]]: *null*, [[ExportName]]: _exportName_, [[NamespaceNamesFilter]]: _importedNames_ }. + 1. Return « _entry_ ». + + NamedExports : `{` `}` + + 1. Return a new empty List. + + ExportsList : ExportsList `,` ExportSpecifier + + 1. Let _specs1_ be the ExportEntriesForModule of |ExportsList| with argument _module_. + 1. Let _specs2_ be the ExportEntriesForModule of |ExportSpecifier| with argument _module_. + 1. Return the list-concatenation of _specs1_ and _specs2_. + + ExportSpecifier : ModuleExportName + + 1. Let _sourceName_ be the StringValue of |ModuleExportName|. + 1. If _module_ is *null*, then + 1. Let _localName_ be _sourceName_. + 1. Let _importName_ be *null*. + 1. Else, + 1. Let _localName_ be *null*. + 1. Let _importName_ be _sourceName_. + 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _importName_, [[LocalName]]: _localName_, [[ExportName]]: _sourceName_, [[NamespaceNamesFilter]]: ~empty~ }. + + ExportSpecifier : ModuleExportName `as` ModuleExportName + + 1. Let _sourceName_ be the StringValue of the first |ModuleExportName|. + 1. Let _exportName_ be the StringValue of the second |ModuleExportName|. + 1. If _module_ is *null*, then + 1. Let _localName_ be _sourceName_. + 1. Let _importName_ be *null*. + 1. Else, + 1. Let _localName_ be *null*. + 1. Let _importName_ be _sourceName_. + 1. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: _module_, [[ImportName]]: _importName_, [[LocalName]]: _localName_, [[ExportName]]: _exportName_, [[NamespaceNamesFilter]]: ~empty~ }. + +
+