Re: [heycam/webidl] Make interface prototype object creation imperative (#494)

TimothyGu requested changes on this pull request.



> @@ -3264,6 +3264,11 @@ and [=variadic=] operations
 and constructors, there may be multiple items in an effective overload set identifying
 the same operation or constructor.
 
+An [=operation=], [=constructor=], or [=callback function=] whose
+[=effective overload set=] for a given [=interface=] with argument count 0
+is an [=set/is empty|empty=] [=set=],
+has <dfn>no allowable invocations</dfn>.

This definition unfortunately doesn't work. You would need to pass the identifier of the operation to the effective overload set algorithm, because 1) overloaded operations with the same identifier are considered distinct operations and 2) the [effective overload set](https://pr-preview.s3.amazonaws.com/tobie/webidl/pull/494.html#dfn-effective-overload-set) is only defined for operations given a) interface, b) identifier, and c) number of arguments.

The name is also somewhat of a misnomer; would prefer the fact that this only applies to argument length of zero to be included in the name of the definition.

> +    1.  [=Expose the operations=] |operations| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the unforgeable regular operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |operations| be the [=list=] of [=exposed=] [=unforgeable=] [=regular operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |attributes| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the operations</dfn> |attributes| of [=interface=] |interface| on |target|
+    given [=Realm=] |realm| run the following steps:
+
+    1.  [=list/For each=] [=operation=] |op| of |operations|:

For the same reason why "no allowable invocations" doesn't work in its current form, this loop also doesn't take into account overloaded but separate operations. In comparison, the [current wording](https://heycam.github.io/webidl/#es-operations) makes more sense:

> **For each unique identifier** of an exposed operation defined on the interface, there must exist a corresponding property, unless the effective overload set for that identifier and operation and with an argument count of 0 has no entries.

> +</div>
+
+<div algorithm>
+    To <dfn>expose the unforgeable regular operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |operations| be the [=list=] of [=exposed=] [=unforgeable=] [=regular operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |attributes| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the operations</dfn> |attributes| of [=interface=] |interface| on |target|
+    given [=Realm=] |realm| run the following steps:
+
+    1.  [=list/For each=] [=operation=] |op| of |operations|:
+        1.  If |op| has [=no allowable invocations=], then [=iteration/continue=].

Just wondering, is there an example of an interface that is affected by this rule?

>  
-For [=namespaces=], the properties corresponding to each declared operation are described in
-[[#namespace-object]]. (We hope to eventually move interfaces to the same explicit
-property-installation style as namespaces.)
+<div algorithm>
+    To <dfn>expose the static operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |attributes| be the [=list=] of [=exposed=] [=static operations=] that are [=members=] of |interface|.

s/attributes/operations/

> -[[#namespace-object]]. (We hope to eventually move interfaces to the same explicit
-property-installation style as namespaces.)
+<div algorithm>
+    To <dfn>expose the static operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |attributes| be the [=list=] of [=exposed=] [=static operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |operations| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the unforgeable regular operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |operations| be the [=list=] of [=exposed=] [=unforgeable=] [=regular operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |attributes| of |interface| on |target| given |realm|.

s/attributes/operations/

> +    run the following steps:
+
+    1.  Let |attributes| be the [=list=] of [=exposed=] [=static operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |operations| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the unforgeable regular operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |operations| be the [=list=] of [=exposed=] [=unforgeable=] [=regular operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |attributes| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the operations</dfn> |attributes| of [=interface=] |interface| on |target|

s/attributes/operations/

> +
+<div algorithm>
+    To <dfn>expose the unforgeable regular operations</dfn> of [=interface=] |interface| on |target|, given [=Realm=] |realm|, 
+    run the following steps:
+
+    1.  Let |operations| be the [=list=] of [=exposed=] [=unforgeable=] [=regular operations=] that are [=members=] of |interface|.
+    1.  [=Expose the operations=] |attributes| of |interface| on |target| given |realm|.
+</div>
+
+<div algorithm>
+    To <dfn>expose the operations</dfn> |attributes| of [=interface=] |interface| on |target|
+    given [=Realm=] |realm| run the following steps:
+
+    1.  [=list/For each=] [=operation=] |op| of |operations|:
+        1.  If |op| has [=no allowable invocations=], then [=iteration/continue=].
+        1.  Let |method| be the result of [=creating an operation function|creating an operation function=]

Redundant alternate text.

> -*   The location of the property is determined as follows:
-    *   If the attribute is a [=static attribute=],
-        then there is a single corresponding property and it exists on the interface’s [=interface object=].
-    *   Otherwise, if the attribute is [=unforgeable=] on
-        the interface or if the interface was declared with the [{{Global}}] [=extended attribute=],
-        then the property exists on every object that implements the interface.
-    *   Otherwise, the property exists solely on the interface’s [=interface prototype object=].
-*   The property has attributes { \[[Get]]: |G|, \[[Set]]: |S|, \[[Enumerable]]: <emu-val>true</emu-val>, \[[Configurable]]: |configurable| },
-    where:
-    *   |configurable| is <emu-val>false</emu-val> if the attribute was
-        declared with the [{{Unforgeable}}] extended attribute and <emu-val>true</emu-val> otherwise;
-    *   |G| is the [=attribute getter=] created given the attribute, the interface,
-        and the [=relevant Realm=] of the object that is the location of the property; and
-    *   |S| is the [=attribute setter=] created given the attribute, the interface,
-        and the [=relevant Realm=] of the object that is the location of the property.
+[=Static attributes=] are exposed of the [=interface object=].

s/of/on/

>  
-    The [=interface prototype object=]
-    for a given interface |A| must have a
-    \[[Prototype]] [=internal slot=] whose value is returned from
-    the following steps:
+    The [=interface prototype object=] for a given [=interface=] |interface| and [=Realm=] |realm|
+    is created as follows:

I'd like to be able to link to this algorithm easily. I'd do something like `The interface prototype object ... is <dfn lt="create an interface prototype object">created</dfn> as follows`. Ditto with all the other creation algorithms introduced in this PR.

> -        [=interface prototype object=]
-        for the inherited interface.
-    1.  Otherwise, if |A| is declared with the [{{LegacyArrayClass}}]
-        extended attribute, then return {{%ArrayPrototype%}}.
-    1.  Otherwise, return {{%ObjectPrototype%}}.
+    1.  Let |proto| be null.
+    1.  If |interface| is declared with the [{{Global}}] [=extended attribute=],
+        and |interface| [=support named properties|supports named properties=],
+        then set |proto| to the [=named properties object=] of |interface|,
+        as defined in [[#named-properties-object]].
+    1.  Otherwise, if |interface| is declared to inherit from another interface,
+        then set |proto| to the [=interface prototype object=] in |realm|
+        of that [=inherited interface=].
+    1.  Otherwise, if |interface| is declared with the [{{LegacyArrayClass}}] [=extended attribute=],
+        then set |proto| to |realm|.\[[Intrinsics]].[[{{%ArrayPrototype%}}]].
+    1.  Otherwise, set |proto| to |realm|.\[[Intrinsics]].[[{{%ObjectPrototype%}}]].

Maybe add an "Assert: Type(|proto|) is Object" here to make sure the initial null doesn't somehow get carried over.

>  <h4 id="es-constants">Constants</h4>
 
-For each [=exposed=] [=constant=] defined on an [=interface=] |A|,
-there must be a corresponding property.
-The property has the following characteristics:
+[=Constants=] are exposed on [=interface objects=],
+[=legacy callback interface objects=],
+[=interface prototype objects=], and
+on the single object that implements the interface,
+when an interface is declared with the [{{Global}}] [=extended attribute=].

Hmm. In [Chrome](https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/filesystem/WindowFileSystem.idl):

```js
> Object.getOwnPropertyDescriptor(Window, 'PERSISTENT')
{value: 1, writable: false, enumerable: true, configurable: false}
> Object.getOwnPropertyDescriptor(Window.prototype, 'PERSISTENT')
{value: 1, writable: false, enumerable: true, configurable: false}
> Object.getOwnPropertyDescriptor(window, 'PERSISTENT')
undefined
```

This API is apparently nonstandard according to MDN so we don't have to worry about it much, but I haven't been able to find any other constants specified on interfaces declared to be [Global].

-- 
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/494#pullrequestreview-87412767

Received on Tuesday, 9 January 2018 05:12:54 UTC