Re: [heycam/webidl] [WIP] Define Web IDL Modules (#675)

Ms2ger commented on this pull request.

Some initial thoughts, mostly editorial, below.

> +        [Exposed=Window, SecureContext]
+        module "std:timezone" {
+          interface Timezone {
+            readonly attribute USVString name;
+            long long offsetMs(long long unixTime);
+          };
+          Timezone getCurrentTimezone();
+          readonly attribute Timezone initialTimezone;
+        };
+    </pre>
+
+    <blockquote>
+        The [=module evaluation steps=] of "std:timezone" are as follows:
+            1.  [=set a module attribute|Set the attribute=]
+                "initialTimezone" of "std:timezone" in the
+                [=current Realm=] to an instance of <code>Timezone</code>

"to a [=new=] <code>Timezone</code>"

> +                1.  Perform ! [=SetSyntheticModuleExport=](|moduleRecord|, |id|,
+                    |method|).
+            1.  Otherwise:
+                1.  Assert: |member| is an [=attribute=].
+                1.  Note: Attributes are expected to be initialized by the
+                          module evaluation steps.
+        1.  Run the [=module evaluation steps=] for the [=module specifier=] of
+            |module|, if any are present.
+    1.  Return |moduleRecord|.
+</div>
+
+<div algorithm>
+  To <dfn>initialize the module map</dfn> of a [=Realm=] |realm| with [=interface=] |interface|:
+
+    1.  Let |map| be the [=module map=] associated with |realm|'s [=relevant settings object=].
+    1.  For every [=module=] |module| that is [=exposed=] in |interface|,

There's no such thing as being exposed in an interface, only in a realm, because of SecureContext.

> @@ -13202,6 +13361,67 @@ The characteristics of a namespace object are described in [[#namespace-object]]
 </div>
 
 
+<h3 id="es-modules">Modules</h3>
+
+Modules are reified as entries in the [=module map=] as [=Synthetic Module
+Records=], allowing them to be imported as ECMAScript modules.
+
+<div algorithm>
+  To <dfn>create a synthetic module record</dfn> for a [=module=] |module| in a
+  [=Realm=] |realm|, perform the following steps:
+
+    1.  Let |exports| be « ».
+    1.  For each member |member| of |module|:

We should probably explicitly define that modules have an infra-list of members and xref that here

> +            1.  Let |id| be |member|'s [=identifier=].
+            1.  If |member| is an [=interface=]:
+                1.  Let |interfaceObject| be the result of [=create an interface
+                    object|creating an interface object=] for |member| with |id|
+                    in |realm|.
+                1.  Perform ! [=SetSyntheticModuleExport=](|moduleRecord|, |id|,
+                    |interfaceObject|).
+            1.  Otherwise, if |member| is an [=operation=]:
+                1.  Let |method| be the result of [=creating an operation function=]
+                    given |member|, |module|, and |realm|.
+                1.  Perform ! [=SetSyntheticModuleExport=](|moduleRecord|, |id|,
+                    |method|).
+            1.  Otherwise:
+                1.  Assert: |member| is an [=attribute=].
+                1.  Note: Attributes are expected to be initialized by the
+                          module evaluation steps.

Should we add an assertion that they are initialized after? Also add a MUST on specifications to define them.

> +</div>
+
+<div algorithm>
+  To <dfn>initialize the module map</dfn> of a [=Realm=] |realm| with [=interface=] |interface|:
+
+    1.  Let |map| be the [=module map=] associated with |realm|'s [=relevant settings object=].
+    1.  For every [=module=] |module| that is [=exposed=] in |interface|,
+        1.  Let |name| be the [=module specifier=] of |module|.
+        1.  Let |record| be the result of [=create a synthetic module record=]
+            for |module| in |realm|.
+        1.  [=map/Set=] |map|[|name|] to |record|.
+</div>
+
+<div algorithm>
+  To <dfn>set a module attribute</dfn> |attribute| of a module specifier |specifier| in a
+  [=Realm=] |realm| to an ECMAScript value |value|:

This should take an IDL value of the type the attribute is declared as.

> +        [Exposed=Window, SecureContext]
+        module "std:timezone" {
+          interface Timezone {
+            readonly attribute USVString name;
+            long long offsetMs(long long unixTime);
+          };
+          Timezone getCurrentTimezone();
+          readonly attribute Timezone initialTimezone;
+        };
+    </pre>
+
+    <blockquote>
+        The [=module evaluation steps=] of "std:timezone" are as follows:
+            1.  [=set a module attribute|Set the attribute=]
+                "initialTimezone" of "std:timezone" in the
+                [=current Realm=] to an instance of <code>Timezone</code>

Is the current Realm the one we want?

> @@ -4445,6 +4465,139 @@ Of the extended attributes defined in this specification, only the [{{Exposed}}]
 </div>
 
 
+<h3 id="idl-modules">Modules</h3>
+
+A <dfn id="dfn-module" export>module</dfn> is a definition (matching

I would like to reduce the conflation of IDL concepts and the grammar used to define them, and since this is a whole new section, I'd like to start here. Feel free to call scope creep, though, and defer it to a followup.

If you agree, I'd suggest reorganizing these two paragraphs roughly as follows:

> `A <dfn id="dfn-module" export>module</dfn> is a structure(?) that exposes a collection of interfaces, readonly attributes, and operations as a logical unit. A [=module=] has a <dfn for=module>specifier</dfn> that uniquely identifies it.`
>
> `For every string in an [=IDL fragment=] matching the <emu-nt><a href="#prod-Module">Module</a></emu-nt> nonterminal symbol, there must exist a [=module=] whose [=module/specifier=] is given by the <a href="#prod-string">string</a> immediately following the <emu-t>module</emu-t> terminal symbol.`

and then probably something similar with the members.

> +    };
+</pre>
+
+Note: As with partial interface definitions, partial module definitions are
+intended for use as a specification editorial aide, allowing the definition
+of a module to be separated over more than one section of the document, and
+sometimes multiple documents.
+
+The order that members appear in has significance for property enumeration in
+the <a href="#es-modules">ECMAScript binding</a>.
+
+Note that like namespaces, modules do not create types.
+
+Of the extended attributes defined in this specification, only the [{{Exposed}}]
+and [{{SecureContext}}] extended attributes are applicable to modules. No
+extended attributes are applicable to [=partial modules=].

I'm not sure if this "applicable" reference is sufficient, or if there should be a MUST on IDL fragments.

> +[=Module members=], [=partial modules=], and [=interface members=] of
+[=interfaces=] and [=partial interfaces=] which are [=module members=], must not
+be annotated with the [{{Exposed}}] or [{{SecureContext}}] extended attributes.
+
+Note: This restriction could be relaxed if there is a sufficient use case;
+it is omitted here for simplicity of specification and implementation, and a
+lack of clear use cases. Please <a
+href="https://github.com/heycam/webidl/issues/new?title=Fine%20grained%20exposure%20in%20modules">
+file an issue</a> if you see a need for this feature.
+
+Each module may have <dfn>module evaluation steps</dfn> which are executed
+when the module is first imported. These steps may throw an [=exception=], which
+prevents the module from being accessed.
+
+Rather than defining behavior when accessed, the attributes of a [=module=] act
+as a simple storage location. The steps to "set a module attribute" in a

xref "set a module attribute"?

> +        1.  [=map/Set=] |map|[|name|] to |record|.
+</div>
+
+<div algorithm>
+  To <dfn>set a module attribute</dfn> |attribute| of a module specifier |specifier| in a
+  [=Realm=] |realm| to an ECMAScript value |value|:
+
+    1.  Let |map| be the [=module map=] associated with |realm|'s [=relevant
+        settings object=].
+    1.  Assert: |map|[|specifier|] exists.
+    1.  Let |moduleRecord| be |map|[|specifier|].
+    1.  Assert: |moduleRecord|.\[[ExportNames]] [=list/contains=] |attribute|.
+    1.  Perform ! [=SetSyntheticModuleExport=](|moduleRecord|, |attribute|,
+        |value|).
+</div>
+

Nit: probably two empty lines

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/heycam/webidl/pull/675#pullrequestreview-210048444

Received on Monday, 4 March 2019 11:01:47 UTC