Skip to content

Commit

Permalink
Rename "named constructors" to "legacy factory functions"
Browse files Browse the repository at this point in the history
Closes #277. This includes renaming the extended attribute, which is part of #350.

Also, since we don't anticipate this being used again, we remove the zero-argument form, which has no current users.

As a bonus, this removes some leftover references to "constructor extended attributes".
  • Loading branch information
domenic committed Apr 20, 2020
1 parent 9fa4955 commit 6c11bcd
Showing 1 changed file with 63 additions and 64 deletions.
127 changes: 63 additions & 64 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ The following extended attributes are applicable to interfaces:
[{{Exposed}}],
[{{Global}}],
[{{LegacyWindowAlias}}],
[{{NamedConstructor}}],
[{{LegacyFactoryFunction}}],
[{{NoInterfaceObject}}],
[{{LegacyOverrideBuiltIns}}], and
[{{SecureContext}}].
Expand Down Expand Up @@ -2212,7 +2212,7 @@ is the final argument in the operation’s argument list.

[=Extended attributes=]
that [=takes an argument list|take an argument list=]
([{{NamedConstructor}}], of those
([{{LegacyFactoryFunction}}], of those
defined in this specification) and [=callback functions=]
are also considered to be [=variadic=]
when the <emu-t>...</emu-t> token is used in their argument lists.
Expand Down Expand Up @@ -3353,7 +3353,7 @@ definitions.
</pre>

Note that [=constructor operations=] and
[{{NamedConstructor}}]
[{{LegacyFactoryFunction}}]
[=extended attributes=] are disallowed from appearing
on [=partial interface=] definitions,
so there is no need to also disallow overloading for constructors.
Expand All @@ -3364,7 +3364,7 @@ An <dfn id="dfn-effective-overload-set" export>effective overload set</dfn>
represents the allowable invocations for a particular
[=operation=],
constructor (specified with a [=constructor operation=]
or [{{NamedConstructor}}]), or
or [{{LegacyFactoryFunction}}]), or
[=callback function=].
The algorithm to [=compute the effective overload set=]
operates on one of the following four types of IDL constructs, and listed with them below are
Expand All @@ -3378,9 +3378,9 @@ the inputs to the algorithm needed to compute the set.
: For constructors
:: * the [=interface=] on which the [=constructor operations=] are to be found
* the number of arguments to be passed
: For named constructors
:: * the [=interface=] on which the [{{NamedConstructor}}] [=extended attributes=] are to be found
* the [=identifier=] of the named constructors
: For legacy factory functions
:: * the [=interface=] on which the [{{LegacyFactoryFunction}}] [=extended attributes=] are to be found
* the [=identifier=] of the legacy factory function
* the number of arguments to be passed

An [=effective overload set=] is used, among other things, to determine whether there are
Expand All @@ -3393,7 +3393,7 @@ whose [=tuple/items=] are described below:
* A <dfn for="effective overload set tuple">callable</dfn> is an [=operation=]
if the [=effective overload set=] is for [=regular operations=],
[=static operations=], or [=constructor operations=]; and it is an [=extended attribute=]
if the [=effective overload set=] is for [=named constructors=].
if the [=effective overload set=] is for [=legacy factory functions=].
* A <dfn>type list</dfn> is a [=list=] of IDL types.
* An <dfn>optionality list</dfn> is a [=list=] of
three possible <dfn id="dfn-optionality-value" export>optionality values</dfn>
Expand All @@ -3413,7 +3413,7 @@ the same operation or constructor.
The algorithm below describes how to <dfn>compute the effective overload set</dfn>.
The following input variables are used, if they are required:

* the identifier of the operation or named constructor is |A|
* the identifier of the operation or legacy factory function is |A|
* the argument count is |N|
* the interface is |I|

Expand All @@ -3434,17 +3434,17 @@ the same operation or constructor.
: For constructors
:: The elements of |F| are the
[=constructor operations=] on interface |I|.
: For named constructors
: For legacy factory functions
:: The elements of |F| are the
[{{NamedConstructor}}]
[{{LegacyFactoryFunction}}]
[=extended attributes=] on interface |I| whose
[=takes a named argument list|named argument lists’=]
identifiers are |A|.
</dl>

1. Let |maxarg| be the maximum number of arguments the operations,
constructor extended attributes or callback functions in |F| are declared to take.
For [=variadic=] operations and constructor extended attributes,
legacy factory functions, or callback functions in |F| are declared to take.
For [=variadic=] operations and legacy factory functions,
the argument on which the ellipsis appears counts as a single argument.

Note: So <code>void f(long x, long... y);</code> is considered to be declared to take two arguments.
Expand Down Expand Up @@ -6949,7 +6949,7 @@ which form (or forms) it is in:
<dfn id="dfn-xattr-named-argument-list" for="extended attribute" export>takes a named argument list</dfn>
</td>
<td>
<code>[NamedConstructor=Image(DOMString src)]</code>
<code>[LegacyFactoryFunction=Image(DOMString src)]</code>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -7202,7 +7202,7 @@ and comprise the following:

* [=interface objects=]
* [=legacy callback interface objects=]
* [=named constructors=]
* [=legacy factory functions=]
* [=interface prototype objects=]
* [=named properties objects=]
* [=iterator prototype objects=]
Expand Down Expand Up @@ -9703,7 +9703,7 @@ The <emu-t class="regex"><a href="#prod-identifier">identifier</a></emu-t>s that
Each of the [=LegacyWindowAlias identifier|identifiers=] of [{{LegacyWindowAlias}}]
must not be the same as one used by a [{{LegacyWindowAlias}}]
extended attribute on this interface or another interface,
must not be the same as the [=NamedConstructor identifier|identifier=] used by a [{{NamedConstructor}}]
must not be the same as the [=LegacyFactoryFunction identifier|identifier=] used by a [{{LegacyFactoryFunction}}]
extended attribute on this interface or another interface,
must not be the same as an [=identifier=] of an interface that has an [=interface object=],
and must not be one of the [=reserved identifiers=].
Expand Down Expand Up @@ -9915,52 +9915,48 @@ is to be implemented.
</div>


<h4 id="NamedConstructor" extended-attribute lt="NamedConstructor">[NamedConstructor]</h4>
<h4 id="LegacyFactoryFunction" extended-attribute lt="LegacyFactoryFunction">[LegacyFactoryFunction]</h4>

<div class="advisement">

[{{NamedConstructor}}] [=extended attribute=] is an undesirable feature.
[{{LegacyFactoryFunction}}] [=extended attribute=] is an undesirable feature.
It exists only so that legacy Web platform features can be specified.
It should not be used in specifications
unless required to specify the behavior of legacy APIs,
or for consistency with these APIs.
Editors who wish to use this feature are strongly advised to discuss this
by <a href="https://github.com/heycam/webidl/issues/new?title=Intent%20to%20use%20[NamedConstructor]">filing an issue</a>
by <a href="https://github.com/heycam/webidl/issues/new?title=Intent%20to%20use%20[LegacyFactoryFunction]">filing an issue</a>
before proceeding.

<small class="non-normative">
The [{{NamedConstructor}}] [=extended attribute=] appears on the following [=interfaces=]:
The [{{LegacyFactoryFunction}}] [=extended attribute=] appears on the following [=interfaces=]:
{{HTMLAudioElement}},
{{HTMLOptionElement}}, and
{{HTMLImageElement}}. [[HTML]]
</small>

</div>

If the [{{NamedConstructor}}]
If the [{{LegacyFactoryFunction}}]
[=extended attribute=]
appears on an [=interface=],
it indicates that the ECMAScript global object will have a property with the
specified name whose value is a [=constructor=] that can
specified name whose value is a function that can
create objects that implement the interface.
Multiple [{{NamedConstructor}}] extended
Multiple [{{LegacyFactoryFunction}}] extended
attributes may appear on a given interface.

The [{{NamedConstructor}}] extended attribute must either
[=takes an identifier|take an identifier=] or
The [{{LegacyFactoryFunction}}] extended attribute must
[=takes a named argument list|take a named argument list=].
The <emu-t class="regex"><a href="#prod-identifier">identifier</a></emu-t> that occurs directly after the
“<emu-t>=</emu-t>” is the [{{NamedConstructor}}]'s <dfn lt="NamedConstructor identifier">identifier</dfn>.
The first form, <code>[NamedConstructor=<emu-t class="regex"><a href="#prod-identifier">identifier</a></emu-t>]</code>,
has the same meaning as using an empty argument list,
<code>[NamedConstructor=<emu-t class="regex"><a href="#prod-identifier">identifier</a></emu-t>()]</code>.
For each [{{NamedConstructor}}] extended attribute on the interface,
“<emu-t>=</emu-t>” is the [{{LegacyFactoryFunction}}]'s <dfn lt="LegacyFactoryFunction identifier">identifier</dfn>.
For each [{{LegacyFactoryFunction}}] extended attribute on the interface,
there will be a way to construct an object that
[=implements=] the interface by passing the specified arguments to the [=constructor=]
that is the value of the aforementioned property.

The [=NamedConstructor identifier|identifier=] used for the named constructor must not
be the same as that used by a [{{NamedConstructor}}]
The [=LegacyFactoryFunction identifier|identifier=] used for the legacy factory function must not
be the same as that used by a [{{LegacyFactoryFunction}}]
extended attribute on another interface, must not
be the same as an [=LegacyWindowAlias identifier|identifier=] used by a [{{LegacyWindowAlias}}]
extended attribute on this interface or another interface,
Expand All @@ -9969,41 +9965,43 @@ that has an [=interface object=],
and must not be one of the
[=reserved identifiers=].

The [{{NamedConstructor}}] and [{{Global}}] [=extended attributes=] must not be specified on the
The [{{LegacyFactoryFunction}}] and [{{Global}}] [=extended attributes=] must not be specified on the
same [=interface=].

See [[#named-constructors]] for details on how named constructors
See [[#legacy-factory-functions]] for details on how legacy factory functions
are to be implemented.

<div class="example">

The following IDL defines an interface that uses the
[{{NamedConstructor}}] extended
[{{LegacyFactoryFunction}}] extended
attribute.

<pre highlight="webidl">
[Exposed=Window,
NamedConstructor=Audio,
NamedConstructor=Audio(DOMString src)]
LegacyFactoryFunction=Audio(DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {
// ...
};
</pre>

An ECMAScript implementation that supports this interface will
allow the construction of <code class="idl">HTMLAudioElement</code>
objects using the <code class="idl">Audio</code> [=constructor=].
objects using the <code class="idl">Audio</code> function.

<pre highlight="js">
typeof Audio; // Evaluates to 'function'.

var a1 = new Audio(); // Creates a new object that implements
// HTMLAudioElement, using the zero-argument
// constructor.

var a2 = new Audio('a.flac'); // Creates an HTMLAudioElement using the
// one-argument constructor.
</pre>

As an additional legacy quirk, these factory functions will have a <code>prototype</code>
property equal to the <code>prototype</code> of the original interface:

<pre highlight="js">
console.assert(Audio.prototype === HTMLAudioElement.prototype);
</pre>
</div>


Expand Down Expand Up @@ -10109,7 +10107,7 @@ The [{{NoInterfaceObject}}] extended attribute
must not be specified on an interface that has any
[=constructors=] or [=static operations=] defined on it.

Note: Combining the [{{NoInterfaceObject}}] and [{{NamedConstructor}}] extended attribute is not
Note: Combining the [{{NoInterfaceObject}}] and [{{LegacyFactoryFunction}}] extended attribute is not
forbidden, however.

An interface that does not have the [{{NoInterfaceObject}}] extended
Expand Down Expand Up @@ -11269,12 +11267,12 @@ there exists a corresponding property on the {{Window}} global object.
The name of the property is the given [=LegacyWindowAlias identifier|identifier=],
and its value is a reference to the [=interface object=] for the [=interface=].

In addition, for every [{{NamedConstructor}}] extended attribute on an [=exposed=] interface,
In addition, for every [{{LegacyFactoryFunction}}] extended attribute on an [=exposed=] interface,
a corresponding property exists on the ECMAScript global object.
The name of the property is the [{{NamedConstructor}}]'s [=NamedConstructor identifier|identifier=],
and its value is an object called a <dfn id="dfn-named-constructor" export>named constructor</dfn>,
which allows construction of objects that implement the interface.
The characteristics of a named constructor are described in [[#named-constructors]].
The name of the property is the [{{LegacyFactoryFunction}}]'s [=LegacyFactoryFunction identifier|identifier=],
and its value is an object called a <dfn id="dfn-legacy-factory-function" export oldids="dfn-named-constructor">legacy factory function</dfn>,
which allows creation of objects that implement the interface.
The characteristics of a legacy factory function are described in [[#legacy-factory-functions]].


<h4 id="interface-object" oldids="es-interface-call,es-constructible-interfaces">Interface object</h4>
Expand Down Expand Up @@ -11377,27 +11375,27 @@ default interfaces do not have such steps.
</div>


<h4 id="named-constructors">Named constructors</h4>
<h4 id="legacy-factory-functions" oldids="named-constructors">Legacy factory functions</h4>

A [=named constructor=] that exists due to one or more
[{{NamedConstructor}}] [=extended attributes=]
with a given [=NamedConstructor identifier|identifier=] is a [=built-in function object=].
A [=legacy factory function=] that exists due to one or more
[{{LegacyFactoryFunction}}] [=extended attributes=]
with a given [=LegacyFactoryFunction identifier|identifier=] is a [=built-in function object=].
It allows constructing objects that
implement the interface on which the
[{{NamedConstructor}}] extended attributes appear.
[{{LegacyFactoryFunction}}] extended attributes appear.

<div algorithm>

The [=named constructor=] with [=NamedConstructor identifier|identifier=] |id|
The [=legacy factory function=] with [=LegacyFactoryFunction identifier|identifier=] |id|
for a given [=interface=] |I| in Realm |realm|
is <dfn lt="create a named constructor">created</dfn> as follows:
is <dfn lt="create a legacy factory function">created</dfn> as follows:

1. Let |steps| be the following steps:
1. If {{NewTarget}} is <emu-val>undefined</emu-val>, then
[=ECMAScript/throw=] a {{ECMAScript/TypeError}}.
1. Let |args| be the passed arguments.
1. Let |n| be the [=list/size=] of |args|.
1. [=Compute the effective overload set=] for named constructors with [=identifier=] |id|
1. [=Compute the effective overload set=] for legacy factory functions with [=identifier=] |id|
on [=interface=] |I| and with argument count |n|, and let |S| be the result.
1. Let &lt;|constructor|, |values|&gt; be the result of passing |S| and
|args| to the [=overload resolution algorithm=].
Expand All @@ -11413,7 +11411,7 @@ implement the interface on which the
1. Return |O|.
1. Let |F| be [=!=] <a abstract-op>CreateBuiltinFunction</a>(|steps|, « », |realm|).
1. Perform [=!=] <a abstract-op>SetFunctionName</a>(|F|, |id|).
1. [=Compute the effective overload set=] for named constructors with [=identifier=] |id|
1. [=Compute the effective overload set=] for legacy factory functions with [=identifier=] |id|
on [=interface=] |I| and with argument count 0, and let |S| be the result.
1. Let |length| be the length of the shortest argument list of the entries in |S|.
1. Perform [=!=] <a abstract-op>SetFunctionLength</a>(|F|, |length|).
Expand Down Expand Up @@ -13251,13 +13249,14 @@ the Realm given as an argument.
1. [=list/iterate|For every=] [=LegacyWindowAlias identifier|identifier=] |id| in
[{{LegacyWindowAlias}}]'s [=LegacyWindowAlias identifier|identifiers=]:
1. Perform [=!=] [$CreateMethodProperty$](|target|, |id|, |interfaceObject|).
1. If the |interface| is declared with a [{{NamedConstructor}}] [=extended attribute=],
1. If the |interface| is declared with a [{{LegacyFactoryFunction}}] [=extended attribute=],
then:
1. [=list/iterate|For every=] [=NamedConstructor identifier|identifier=] |id| in
[{{NamedConstructor}}]'s [=NamedConstructor identifier|identifiers=]:
1. Let |namedConstructor| be the result of [=create a named constructor|creating
a named constructor=] with |id| for |interface| in |realm|.
1. Perform [=!=] [$CreateMethodProperty$](|target|, |id|, |namedConstructor|).
1. [=list/iterate|For every=] [=LegacyFactoryFunction identifier|identifier=] |id| in
[{{LegacyFactoryFunction}}]'s [=LegacyFactoryFunction identifier|identifiers=]:
1. Let |legacyFactoryFunction| be the result of
[=create a legacy factory function|creating a legacy factory function=] with
|id| for |interface| in |realm|.
1. Perform [=!=] [$CreateMethodProperty$](|target|, |id|, |legacyFactoryFunction|).
1. [=list/iterate|For every=] [=callback interface=] |interface| that is [=exposed=] in
|realm| and on which [=constants=] are defined:
1. Let |id| be |interface|'s [=identifier=].
Expand Down Expand Up @@ -14908,7 +14907,7 @@ terminal symbol <emu-t>const</emu-t>, an
"<code>A</code>" is distinct from one named "<code>a</code>", and an
[=extended attribute=]
[<code class="idl">namedconstructor</code>] will not be recognized as
the [{{NamedConstructor}}]
the [{{LegacyFactoryFunction}}]
extended attribute.

Implicitly, any number of <emu-t class="regex"><a href="#prod-whitespace">whitespace</a></emu-t> and
Expand Down

0 comments on commit 6c11bcd

Please sign in to comment.