This repository has been archived by the owner on Jan 25, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
/
spec.html
217 lines (177 loc) · 11.7 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<pre class="metadata">
title: import()
status: proposal
stage: 4
location: https://tc39.github.io/proposal-dynamic-import/
copyright: false
contributors: Domenic Denicola
</pre>
<script src="ecmarkup.js" defer></script>
<link rel="stylesheet" href="ecmarkup.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/solarized_light.min.css">
<emu-intro id="introduction">
<h1>Introduction</h1>
<p>Background explanatory material for this specification can be found in the <a href="https://github.com/tc39/proposal-dynamic-import">tc39/proposal-dynamic-import</a> repository. See also the <a href="https://github.com/tc39/proposal-dynamic-import/issues">issues</a> and the <a href="https://github.com/tc39/proposal-dynamic-import/blob/master/HTML%20Integration.md">HTML integration spec</a> that builds on top of the below JavaScript specification.</p>
</emu-intro>
<emu-clause id="sec-modules">
<h1>Modules</h1>
<emu-clause id="sec-module-semantics">
<h1>Module Semantics</h1>
<emu-clause id="sec-hostresolveimportedmodule" aoid="HostResolveImportedModule">
<h1>Runtime Semantics: HostResolveImportedModule ( <del>_referencingModule_</del><ins>_referencingScriptOrModule_</ins>, _specifier_ )</h1>
<p>HostResolveImportedModule is an implementation defined abstract operation that provides the concrete Module Record subclass instance that corresponds to the |ModuleSpecifier| String, _specifier_, occurring within the context of the <ins>script or </ins>module represented by the <ins>Script Record or </ins>Module Record <del>_referencingModule_</del><ins>_referencingScriptOrModule_</ins>. <ins>_referencingScriptOrModule_ may also be *null*, if the resolution is being performed in the context of an `import()` expression, and there is no active script or module at that time.</ins></p>
<emu-note>
<p>An example of when _referencingScriptOrModule_ can be *null* is in a web browser host. There, if a user clicks on a control given by</p>
<pre><code class="html"><button onclick="import('./foo.mjs')">Click me</button></code></pre>
<p>there will be no active script or module at the time the `import()` expression runs. More generally, this can happen in any situation where the host pushes execution contexts with *null* ScriptOrModule components onto the execution context stack.</p>
</emu-note>
<p>The implementation of HostResolveImportedModule must conform to the following requirements:</p>
<ul>
<li>
The normal return value must be an instance of a concrete subclass of Module Record.
</li>
<li>
If a Module Record corresponding to the pair <del>_referencingModule_</del><ins>_referencingScriptOrModule_</ins>, _specifier_ does not exist or cannot be created, an exception must be thrown.
</li>
<li>
This operation must be idempotent if it completes normally. Each time it is called with a specific <del>_referencingModule_</del><ins>_referencingScriptOrModule_</ins>, _specifier_ pair as arguments it must return the same Module Record instance.
</li>
</ul>
<p>Multiple different <del>_referencingModule_</del><ins>_referencingScriptOrModule_</ins>, _specifier_ pairs may map to the same Module Record instance. The actual mapping semantic is implementation defined but typically a normalization process is applied to _specifier_ as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.</p>
</emu-clause>
<emu-clause id="sec-hostimportmoduledynamically" aoid="HostImportModuleDynamically">
<h1><ins>Runtime Semantics: HostImportModuleDynamically ( _referencingScriptOrModule_, _specifier_, _promiseCapability_ )</ins></h1>
<p>HostImportModuleDynamically is an implementation defined abstract operation that performs any necessary setup work in order to make available the module corresponding to the |ModuleSpecifier| String, _specifier_, occurring within the context of the script or module represented by the Script Record or Module Record _referencingScriptOrModule_. (_referencingScriptOrModule_ may also be *null*, if there is no active script or module when the `import()` expression occurs.) It then performs FinishDynamicImport to finish the dynamic import process.</p>
<p>The implementation of HostImportModuleDynamically must conform to the following requirements:</p>
<ul>
<li>
The abstract operation must always complete normally with *undefined*. Success or failure must instead be signaled as discussed below.
</li>
<li>
The host environment must conform to one of the two following sets of requirements:
<dl>
<dt>Success path</dt>
<dd>
<ul>
<li>At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, _specifier_, _promiseCapability_, NormalCompletion(*undefined*)).</li>
<li>Any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_ and _specifier_, must complete normally.</li>
<li>The completion value of any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments _referencingScriptOrModule_ and _specifier_, must be a module which has already been evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion.</li>
</ul>
</dd>
<dt>Failure path</dt>
<dd>
<ul>
<li>At some future time, the host environment must perform FinishDynamicImport(_referencingScriptOrModule_, _specifier_, _promiseCapability_, an abrupt completion), with the abrupt completion representing the cause of failure.</li>
</ul>
</dd>
</dl>
<p>The intent of this specification is to not violate run to completion semantics. The spec-level formalization of this is a work-in-progress.</p>
</li>
<li>
Every call to HostImportModuleDynamically with the same _referencingScriptOrModule_ and _specifier_ arguments must conform to the <em>same</em> set of requirements above as previous calls do. That is, if the host environment takes the success path once for a given _referencingScriptOrModule_, _specifier_ pair, it must always do so, and the same for the failure path.
</li>
<li>
The operation must not call _promiseCapability_.[[Resolve]] or _promiseCapability_.[[Reject]], but instead must treat _promiseCapability_ as an opaque identifying value to be passed through to FinishDynamicImport.
</li>
</ul>
<p>The actual process performed is implementation defined, but typically consists of performing whatever I/O operations are necessary to allow HostResolveImportedModule to synchronously retrieve the appropriate Module Record, and then calling its Evaluate concrete method. This might require performing similar normalization as HostResolveImportedModule does.</p>
</emu-clause>
<emu-clause id="sec-finishdynamicimport" aoid="FinishDynamicImport">
<h1><ins>Runtime Semantics: FinishDynamicImport ( _referencingScriptOrModule_, _specifier_, _promiseCapability_, _completion_ )</ins></h1>
<p>FinishDynamicImport completes the process of a dynamic import originally started by an `import()` call, resolving or rejecting the promise returned by that call as appropriate according to _completion_. It is performed by host environments as part of HostImportModuleDynamically.</p>
<emu-alg>
1. If _completion_ is an abrupt completion, then perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _completion_.[[Value]] »).
1. Otherwise,
1. Assert: _completion_ is a normal completion and _completion_.[[Value]] is *undefined*.
1. Let _moduleRecord_ be ! HostResolveImportedModule(_referencingScriptOrModule_, _specifier_).
1. Assert: Evaluate has already been invoked on _moduleRecord_ and successfully completed.
1. Let _namespace_ be GetModuleNamespace(_moduleRecord_).
1. If _namespace_ is an abrupt completion, perform ! Call(_promiseCapability_.[[Reject]], *undefined*, « _namespace_.[[Value]] »).
1. Otherwise, perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, « _namespace_.[[Value]] »).
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-left-hand-side-expressions">
<h1>Left-Hand-Side Expressions</h1>
<h2>Syntax</h2>
<emu-grammar>
CallExpression[Yield, Await] :
MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
SuperCall[?Yield, ?Await]
<ins>ImportCall[?Yield, ?Await]</ins>
CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
CallExpression[?Yield, ?Await] `.` IdentifierName
CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await]
<ins>ImportCall[Yield, Await] :
`import` `(` AssignmentExpression[+In, ?Yield, ?Await] `)`</ins>
</emu-grammar>
<emu-clause id="sec-static-semantics">
<h1>Static Semantics</h1>
<emu-clause oldids="sec-static-semantics-static-semantics-isvalidsimpleassignmenttarget" id="sec-static-semantics-static-semantics-assignmenttargettype">
<h1>Static Semantics: AssignmentTargetType</h1>
<emu-see-also-para op="AssignmentTargetType"></emu-see-also-para>
<emu-grammar>
CallExpression :
CallExpression `[` Expression `]`
CallExpression `.` IdentifierName
MemberExpression :
MemberExpression `[` Expression `]`
MemberExpression `.` IdentifierName
SuperProperty
</emu-grammar>
<emu-alg>
1. Return ~simple~.
</emu-alg>
<emu-grammar>
CallExpression :
CoverCallExpressionAndAsyncArrowHead
SuperCall
<ins>ImportCall</ins>
CallExpression Arguments
CallExpression TemplateLiteral
NewExpression :
`new` NewExpression
MemberExpression :
MemberExpression TemplateLiteral
`new` MemberExpression Arguments
NewTarget :
`new` `.` `target`
</emu-grammar>
<emu-alg>
1. Return ~invalid~.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-import-calls">
<h1><ins>Import Calls</ins></h1>
<emu-clause id="sec-import-call-runtime-semantics-evaluation">
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>ImportCall : `import` `(` AssignmentExpression `)`</emu-grammar>
<emu-alg>
1. Let _referencingScriptOrModule_ be ! GetActiveScriptOrModule().
1. Let _argRef_ be the result of evaluating |AssignmentExpression|.
1. Let _specifier_ be ? GetValue(_argRef_).
1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%).
1. Let _specifierString_ be ToString(_specifier_).
1. IfAbruptRejectPromise(_specifierString_, _promiseCapability_).
1. Perform ! HostImportModuleDynamically(_referencingScriptOrModule_, _specifierString_, _promiseCapability_).
1. Return _promiseCapability_.[[Promise]].
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-forbidden-extensions">
<h1>Forbidden Extensions</h1>
<p>An implementation must not extend this specification in the following ways:</p>
<ul>
<li>
...
</li>
<li>
<ins>|ImportCall| must not be extended.</ins>
<!-- This is so that in the future we can potentially add new arguments or support ArgumentList. -->
</li>
</ul>
</emu-clause>