Stage 0 Draft / June 10, 2019

Weak Imports

Introduction

Weak imports allow specific named import bindings to be undefined when not resolved against the imported module.

1Module Environment Records

A module Environment Record is a declarative Environment Record that is used to represent the outer scope of an ECMAScript Module. In additional to normal mutable and immutable bindings, module Environment Records also provide immutable import bindings which are bindings that provide indirect access to a target binding that exists in another Environment Record.

Module Environment Records support all of the declarative Environment Record methods listed in Table 15 and share the same specifications for all of those methods except for GetBindingValue, DeleteBinding, HasThisBinding and GetThisBinding. In addition, module Environment Records support the methods listed in Table 1:

Table 1: Additional Methods of Module Environment Records
Method Purpose
CreateImportBinding(N, M, N2) Create an immutable indirect binding in a module Environment Record. The String value N is the text of the bound name. M is a Module Record, and N2 is a binding that exists in M's module Environment Record.
CreateUndefinedWeakImportBinding(N) Create an immutable unbound weak import binding representing an unresolved weak named import.
GetThisBinding() Return the value of this Environment Record's this binding.

The behaviour of the additional concrete specification methods for module Environment Records are defined by the following algorithms:

1.1CreateUndefinedWeakImportBinding ( N )

The concrete Environment Record method CreateUndefinedWeakImportBinding for module Environment Records creates a new uninitialized binding for the unresolved weak named import.

  1. Let envRec be the module Environment Record for which the method was invoked.
  2. Assert: envRec does not already have a binding for N.
  3. Create an immutable binding in envRec for N.
  4. Perform envRec.InitializeBinding(N, undefined).
  5. Return NormalCompletion(empty).

2Source Text Module Records

2.1InitializeEnvironment ( ) Concrete Method

The InitializeEnvironment concrete method of a Source Text Module Record implements the corresponding Cyclic Module Record abstract method.

This abstract method performs the following steps:

  1. Let module be this Source Text Module Record.
  2. For each ExportEntry Record e in module.[[IndirectExportEntries]], do
    1. Let resolution be ? module.ResolveExport(e.[[ExportName]]).
    2. If resolution is null or "ambiguous", throw a SyntaxError exception.
    3. Assert: resolution is a ResolvedBinding Record.
  3. Assert: All named exports from module are resolvable.
  4. Let realm be module.[[Realm]].
  5. Assert: realm is not undefined.
  6. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  7. Set module.[[Environment]] to env.
  8. Let envRec be env's EnvironmentRecord.
  9. For each ImportEntry Record in in module.[[ImportEntries]], do
    1. Let importedModule be ! HostResolveImportedModule(module, in.[[ModuleRequest]]).
    2. NOTE: The above call cannot fail because imported module requests are a subset of module.[[RequestedModules]], and these have been resolved earlier in this algorithm.
    3. If in.[[ImportName]] is "*", then
      1. Let namespace be ? GetModuleNamespace(importedModule).
      2. Perform ! envRec.CreateImmutableBinding(in.[[LocalName]], true).
      3. Call envRec.InitializeBinding(in.[[LocalName]], namespace).
    4. Else,
      1. Let resolution be ? importedModule.ResolveExport(in.[[ImportName]]).
      2. If resolution is null or "ambiguous", throw a SyntaxError exception.
      3. If resolution is null, then
        1. If in.[[Weak]] is false, throw a SyntaxError exception.
        2. Call envRec.CreateUndefinedWeakImportBinding(in.[[LocalName]]).
      4. Otherwise,
        1. Call envRec.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  10. Let code be module.[[ECMAScriptCode]].
  11. Let varDeclarations be the VarScopedDeclarations of code.
  12. Let declaredVarNames be a new empty List.
  13. For each element d in varDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If dn is not an element of declaredVarNames, then
        1. Perform ! envRec.CreateMutableBinding(dn, false).
        2. Call envRec.InitializeBinding(dn, undefined).
        3. Append dn to declaredVarNames.
  14. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  15. For each element d in lexDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! envRec.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! envRec.CreateMutableBinding(dn, false).
      3. If d is a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration, then
        1. Let fo be the result of performing InstantiateFunctionObject for d with argument env.
        2. Call envRec.InitializeBinding(dn, fo).
  16. Return NormalCompletion(empty).
Table 2: ImportEntry Record Fields
Field Name Value Type Meaning
[[ModuleRequest]] String String value of the ModuleSpecifier of the ImportDeclaration.
[[ImportName]] String The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value "*" indicates that the import request is for the target module's namespace object.
[[LocalName]] String The name that is used to locally access the imported value from within the importing module.
[[Weak]] Boolean Boolean value indicating if the given import record corresponds to a weakly imported binding.
Note

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

Table 3 (Informative): Import Forms Mappings to ImportEntry Records
Import Statement Form [[ModuleRequest]] [[ImportName]] [[LocalName]] [[Weak]]
import v from "mod"; "mod" "default" "v" false
import * as ns from "mod"; "mod" "*" "ns" false
import {x} from "mod"; "mod" "x" "x" false
import {x as v} from "mod"; "mod" "x" "v" false
import {weak x as v} from "mod"; "mod" "x" "v" true
import "mod"; An ImportEntry Record is not created.

2.2Imports

Syntax

ImportDeclaration:importImportClauseFromClause; importModuleSpecifier; ImportClause:ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding,NameSpaceImport ImportedDefaultBinding,NamedImports ImportedDefaultBinding:ImportedBinding NameSpaceImport:*asImportedBinding NamedImports:{} {ImportsList} {ImportsList,} FromClause:fromModuleSpecifier ImportsList:ImportSpecifier ImportsList,ImportSpecifier ImportSpecifier:WeakImportSpecifier ImportBindingSpecifier ImportedBinding IdentifierNameasImportedBinding WeakImportSpecifier:weakImportBindingSpecifier ImportBindingSpecifier:ImportedBinding IdentifierNameasImportedBinding ModuleSpecifier:StringLiteral ImportedBinding:BindingIdentifier[~Yield, ~Await]

2.2.1Static Semantics: Early Errors

ModuleItem:ImportDeclaration
  • It is a Syntax Error if the BoundNames of ImportDeclaration contains any duplicate entries.

2.2.2Static Semantics: BoundNames

ImportDeclaration:importImportClauseFromClause;
  1. Return the BoundNames of ImportClause.
ImportDeclaration:importModuleSpecifier;
  1. Return a new empty List.
ImportClause:ImportedDefaultBinding,NameSpaceImport
  1. Let names be the BoundNames of ImportedDefaultBinding.
  2. Append to names the elements of the BoundNames of NameSpaceImport.
  3. Return names.
ImportClause:ImportedDefaultBinding,NamedImports
  1. Let names be the BoundNames of ImportedDefaultBinding.
  2. Append to names the elements of the BoundNames of NamedImports.
  3. Return names.
NamedImports:{}
  1. Return a new empty List.
ImportsList:ImportsList,ImportSpecifier
  1. Let names be the BoundNames of ImportsList.
  2. Append to names the elements of the BoundNames of ImportSpecifier.
  3. Return names.
ImportSpecifier:ImportBindingSpecifier
  1. Return the BoundNames of ImportedBinding.

2.2.3Static Semantics: ImportEntries

ImportDeclaration:importImportClauseFromClause;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Return ImportEntriesForModule of ImportClause with argument module.
ImportDeclaration:importModuleSpecifier;
  1. Return a new empty List.

2.2.4Static Semantics: ImportEntriesForModule

With parameter module.

ImportClause:ImportedDefaultBinding,NameSpaceImport
  1. Let entries be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Append to entries the elements of the ImportEntriesForModule of NameSpaceImport with argument module.
  3. Return entries.
ImportClause:ImportedDefaultBinding,NamedImports
  1. Let entries be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Append to entries the elements of the ImportEntriesForModule of NamedImports with argument module.
  3. Return entries.
ImportedDefaultBinding:ImportedBinding
  1. Let localName be the sole element of BoundNames of ImportedBinding.
  2. Let defaultEntry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName, [[Weak]]: false }.
  3. Return a new List containing defaultEntry.
NameSpaceImport:*asImportedBinding
  1. Let localName be the StringValue of ImportedBinding.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "*", [[LocalName]]: localName, [[Weak]]: false }.
  3. Return a new List containing entry.
NamedImports:{}
  1. Return a new empty List.
ImportsList:ImportsList,ImportSpecifier
  1. Let specs be the ImportEntriesForModule of ImportsList with argument module.
  2. Append to specs the elements of the ImportEntriesForModule of ImportSpecifier with argument module.
  3. Return specs.
ImportSpecifier : WeakImportSpecifier
  1. Let localName be the sole element of BoundNames of WeakImportSpecifier.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName, [[Weak]]: true }.
  3. Return a new List containing entry.
ImportSpecifier : ImportBindingSpecifier
  1. Let localName be the sole element of BoundNames of ImportBindingSpecifier.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName, [[Weak]]: false }.
  3. Return a new List containing entry.
WeakImportSpecifier:ImportBindingSpecifier
  1. Let importName be the StringValue of IdentifierName.
  2. Let localName be the StringValue of ImportedBinding.
  3. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[Weak]]: false }.
  4. Return a new List containing entry.
Import:BindingSpecifier
  1. Let importName be the StringValue of IdentifierName.
  2. Let localName be the StringValue of ImportedBinding.
  3. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[Weak]]: true }.
  4. Return a new List containing entry.

2.2.5Static Semantics: ModuleRequests

ImportDeclaration:importImportClauseFromClause;
  1. Return ModuleRequests of FromClause.
ModuleSpecifier:StringLiteral
  1. Return a List containing the StringValue of StringLiteral.