From 04beb4f455a5df1633f3816651cdbfe58b6f81d4 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 12 Nov 2015 17:52:44 +1100 Subject: [PATCH] Fix some problems with iterable declarations. 1. iterable<> declarations with a single type ("value iterators") now always iterates over the object's indexed properties, and disallows its use on objects that don't support indexed properties (and have a "length" attribute). 2. The entries and keys properties of interface prototypes for interfaces that have value iterators are now defined to have values equal to the initial values of Array.prototype.{entries,keys}, similarly to how @@iterator was already defined when indexed properties were present. 3. The definitions of @@iterator and forEach for iterable<> declarations with two types ("pair iterators") are fixed. "Default iterator objects" now work only for pair iterators, since we don't support prose-defined value iterators now. --- index.html | 153 +++++++++++++++++++++++++++++++++-------------------- index.xml | 151 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 191 insertions(+), 113 deletions(-) diff --git a/index.html b/index.html index d0801576..1d415609 100644 --- a/index.html +++ b/index.html @@ -19,7 +19,7 @@ -
W3C

Web IDL (Second Edition)

W3C Editor’s Draft 18 January 2016

This Version:
http://heycam.github.io/webidl/
Latest Version:
http://www.w3.org/TR/WebIDL/
Previous Versions:
http://www.w3.org/TR/2012/CR-WebIDL-20120419/
http://www.w3.org/TR/2012/WD-WebIDL-20120207/
http://www.w3.org/TR/2011/WD-WebIDL-20110927/
http://www.w3.org/TR/2011/WD-WebIDL-20110712/
http://www.w3.org/TR/2010/WD-WebIDL-20101021/
http://www.w3.org/TR/2008/WD-WebIDL-20081219/
http://www.w3.org/TR/2008/WD-WebIDL-20080829/
http://www.w3.org/TR/2008/WD-DOM-Bindings-20080410/
http://www.w3.org/TR/2007/WD-DOM-Bindings-20071017/
Participate:
+
@@ -72,7 +72,7 @@

Status of This Document

report can be found in the W3C technical reports index at http://www.w3.org/TR/.

- This document is the 18 January 2016 Editor’s Draft of the + This document is the 10 February 2016 Editor’s Draft of the Web IDL (Second Edition) specification. Please send comments about this document to @@ -3604,7 +3604,7 @@

3.2.7. Iterable declarations

Note

In the ECMAScript language binding, an interface that is iterable - will have “entries”, “keys”, “values” and @@iterator + will have “entries”, “forEach”, “keys”, “values” and @@iterator properties on its interface prototype object.

@@ -3617,31 +3617,49 @@

3.2.7. Iterable declarations

value associated with the key.

- Prose accompanying an interface with a value iterator - MUST define what the - list of values to iterate over is, - unless the interface also - supports indexed properties, - in which case the values of the indexed properties are implicitly - iterated over. Prose accompanying an interface with a + A value iterator + MUST only be declared on an interface + that supports indexed properties + and has an integer-typed + attribute named “length”. + The value-type of the value iterator + MUST be the same as the type returned by + the indexed property getter. + A value iterator is implicitly + defined to iterate over the object’s indexed properties. +

+

+ A pair iterator + MUST NOT be declared on an interface + that supports indexed properties. + Prose accompanying an interface with a pair iterator MUST define what the list of value pairs to iterate over is.

Note
-

Interfaces that support indexed properties - need to have a “length” attribute for the iterator to work correctly.

+

+ The ECMAScript forEach method that is generated for a + value iterator + invokes its callback like Array.prototype.forEach does, and the forEach + method for a pair iterator + invokes its callback like Map.prototype.forEach does. +

+

+ Since value iterators + are currently allowed only on interfaces that + support indexed properties, + it makes sense to use an Array-like forEach method. + There may be a need for value iterators + (a) on interfaces that do not + support indexed properties, + or (b) with a forEach method that instead invokes its callback like + Set.protoype.forEach (where the key is the same as the value). + If you’re creating an API that needs such a forEach method, please send a request to + public-script-coord@w3.org. +

-

- The prose is responsible for defining that the list of values - or value pairs to iterate over is snapshotted at the time - iteration begins, if that is desired. To handle lists that - can change during iteration, the behavior of an - iterator defined to to loop through the items in order, starting - at index 0, and advancing this index on each iteration. Iteration ends when - the index has gone past the end of the list. -

Note

This is how array iterator objects work. For interfaces that support indexed properties, @@ -3677,7 +3695,7 @@

3.2.7. Iterable declarations

The values to iterate over - are a snapshot of the open Session objects + are the open Session objects on the SessionManager sorted by username.

@@ -3715,12 +3733,6 @@

3.2.7. Iterable declarations

for (let session of sm) { window.alert(session.username); }
-

- If the SessionManager interface supported indexed properties - and had an attribute named “length” - that reflected the number of session objects, we could avoid defining the - values to iterate over. -

@@ -12018,7 +12030,11 @@

4.6.9.1. @@iterator
  • Otherwise, the property exists solely on the interface’s interface prototype object.
  • - If the interface has an iterable declaration, + If the interface defines an indexed property getter, + then the Function object is %ArrayProto_values% ([ECMA-262], section 6.1.7.4). +

    +

    + If the interface has a pair iterator, then the Function, when invoked, MUST behave as follows:

    @@ -12042,11 +12058,6 @@
    4.6.9.1. @@iterator
    for interface with object as its target and iterator kind “value”.
  • Return iterator.
  • -

    - If the interface does not have an iterable declaration - but does define an indexed property getter, - then the Function object is %ArrayProto_values% ([ECMA-262], section 6.1.7.4). -

    If the interface has a maplike declaration or setlike declaration, @@ -12121,26 +12132,36 @@

    4.6.9.2. forEach
  • Otherwise, the property exists solely on the interface’s interface prototype object.
  • - If the interface has an iterable declaration, + If the interface defines an indexed property getter, + then the Function object is + the initial value of the “forEach” data property of %ArrayPrototype% ([ECMA-262], section 6.1.7.4). +

    +

    + If the interface has a pair iterator, then the Function MUST have the same behavior as one that would exist assuming the interface had this operation instead of the iterable declaration:

    -
    IDL
    void forEach(Function callback, optional any thisArg = undefined);
    +
    IDL
    void forEach(Function callback, optional any thisArg);

    with the following prose definition:

      -
    1. Let values be the list of values to iterate over.
    2. -
    3. Let len be the length of values.
    4. -
    5. Initialize k to 0.
    6. -
    7. While k < len: +
    8. Let O be the this value.
    9. +
    10. Let pairs be the list of value pairs to iterate over.
    11. +
    12. Let i be 0.
    13. +
    14. While i is less than the length of pairs:
        -
      1. Let kValue be the value in values at index k.
      2. +
      3. Let pair be the entry in pairs at index i.
      4. +
      5. Let key be pair’s key.
      6. +
      7. Let value be pair’s value.
      8. Invoke callback with thisArg + (or undefined, if the argument was not supplied) as the callback this value and - k and value as its arguments.
      9. + value, key and O as its arguments. +
      10. Update pairs to the current list of value pairs to iterate over.
      11. +
      12. Set i to i + 1.
    @@ -12233,7 +12254,13 @@
    4.6.10.1. entries
  • Otherwise, the property exists solely on the interface’s interface prototype object.
  • - The Function, when invoked, MUST behave as follows: + If the interface has a value iterator, + then the Function object is + the initial value of the “entries” data property of %ArrayPrototype% ([ECMA-262], section 6.1.7.4). +

    +

    + If the interface has a pair iterator, + then the Function, when invoked, MUST behave as follows:

    1. Let object be the result of calling ToObject on the this value.
    2. @@ -12283,7 +12310,13 @@
      4.6.10.2. keys
    3. Otherwise, the property exists solely on the interface’s interface prototype object.
    4. - The Function, when invoked, MUST behave as follows: + If the interface has a value iterator, + then the Function object is + the initial value of the “keys” data property of %ArrayPrototype% ([ECMA-262], section 6.1.7.4). +

      +

      + If the interface has a pair iterator, + then the Function, when invoked, MUST behave as follows:

      1. Let object be the result of calling ToObject on the this value.
      2. @@ -12354,6 +12387,15 @@
        4.6.10.4. Default iterator objects
      3. its kind, which is the iteration kind,
      4. its index, which is the current index into the values value to be iterated.
      +
      Note
      +

      + Default iterator objects are only used for pair iterators; + value iterators, as they are currently + restricted to iterating over an object’s + supported indexed properties, + use standard ECMAScript Array iterator objects. +

      +

      When a default iterator object is first created, its index is set to 0. @@ -12374,8 +12416,8 @@

      4.6.10.5. Iterator prototype object

      The iterator prototype object for a given interface - is an object that exists for every interface that has an - iterable declaration. It serves as the + is an object that exists for every interface that has a + pair iterator. It serves as the prototype for default iterator objects for the interface.

      @@ -12408,29 +12450,25 @@
      4.6.10.5. Iterator prototype object
    5. Let target be object’s target.
    6. Let index be object’s index.
    7. Let kind be object’s kind.
    8. -
    9. Let values be the list of values to iterate over. -
      Note
      -

      Depending on whether prose accompanying the interface defined this to be a snapshot at the time - iteration begins, the list of values might be different from the previous time the next - method was called on this iterator object.

      -
      -
    10. +
    11. Let values be the list of value pairs to iterate over.
    12. Let len be the length of values.
    13. If object’s index is greater than or equal to len, then return CreateIterResultObject(undefined, true).
    14. +
    15. Let pair be the entry in values at index index.
    16. Let result be a value determined by the value of kind:
      key
        -
      1. Let key be the ECMAScript Number value index.
      2. +
      3. Let idlKey be pair’s key.
      4. +
      5. Let key be the result of converting idlKey to an ECMAScript value.
      6. result is key.
      value
        -
      1. Let idlValue be the value in values at index index.
      2. +
      3. Let idlValue be pair’s value.
      4. Let value be the result of converting idlValue to an ECMAScript value.
      5. result is value.
      @@ -12438,8 +12476,9 @@
      4.6.10.5. Iterator prototype object
      key+value
        -
      1. Let key be the ECMAScript Number value index.
      2. -
      3. Let idlValue be the value in values at index index.
      4. +
      5. Let idlKey be pair’s key.
      6. +
      7. Let idlValue be pair’s value.
      8. +
      9. Let key be the result of converting idlKey to an ECMAScript value.
      10. Let value be the result of converting idlValue to an ECMAScript value.
      11. Let array be the result of performing ArrayCreate(2).
      12. Call CreateDataProperty(array, "0", key).
      13. diff --git a/index.xml b/index.xml index c36a5e37..3d751cec 100644 --- a/index.xml +++ b/index.xml @@ -3584,7 +3584,7 @@ iterable<key-type, value-type>;

        In the ECMAScript language binding, an interface that is iterable - will have “entries”, “keys”, “values” and @@iterator + will have “entries”, “forEach”, “keys”, “values” and @@iterator properties on its interface prototype object.

        @@ -3597,31 +3597,49 @@ iterable<key-type, value-type>; value associated with the key.

        - Prose accompanying an interface with a value iterator - MUST define what the - list of values to iterate over is, - unless the interface also - supports indexed properties, - in which case the values of the indexed properties are implicitly - iterated over. Prose accompanying an interface with a + A value iterator + MUST only be declared on an interface + that supports indexed properties + and has an integer-typed + attribute named “length”. + The value-type of the value iterator + MUST be the same as the type returned by + the indexed property getter. + A value iterator is implicitly + defined to iterate over the object’s indexed properties. +

        +

        + A pair iterator + MUST NOT be declared on an interface + that supports indexed properties. + Prose accompanying an interface with a pair iterator MUST define what the list of value pairs to iterate over is.

        -
        -

        Interfaces that support indexed properties - need to have a “length” attribute for the iterator to work correctly.

        +
        +

        + The ECMAScript forEach method that is generated for a + value iterator + invokes its callback like Array.prototype.forEach does, and the forEach + method for a pair iterator + invokes its callback like Map.prototype.forEach does. +

        +

        + Since value iterators + are currently allowed only on interfaces that + support indexed properties, + it makes sense to use an Array-like forEach method. + There may be a need for value iterators + (a) on interfaces that do not + support indexed properties, + or (b) with a forEach method that instead invokes its callback like + Set.protoype.forEach (where the key is the same as the value). + If you’re creating an API that needs such a forEach method, please send a request to + public-script-coord@w3.org. +

        -

        - The prose is responsible for defining that the list of values - or value pairs to iterate over is snapshotted at the time - iteration begins, if that is desired. To handle lists that - can change during iteration, the behavior of an - iterator defined to to loop through the items in order, starting - at index 0, and advancing this index on each iteration. Iteration ends when - the index has gone past the end of the list. -

        This is how array iterator objects work. For interfaces that support indexed properties, @@ -3657,7 +3675,7 @@ interface Session {

        The values to iterate over - are a snapshot of the open Session objects + are the open Session objects on the SessionManager sorted by username.

        @@ -3695,12 +3713,6 @@ for (;;) { for (let session of sm) { window.alert(session.username); } -

        - If the SessionManager interface supported indexed properties - and had an attribute named “length” - that reflected the number of session objects, we could avoid defining the - values to iterate over. -

        @@ -11887,7 +11899,11 @@ interface

      14. Otherwise, the property exists solely on the interface’s interface prototype object.
      15. - If the interface has an iterable declaration, + If the interface defines an indexed property getter, + then the Function object is %ArrayProto_values%. +

        +

        + If the interface has a pair iterator, then the Function, when invoked, MUST behave as follows:

        @@ -11911,11 +11927,6 @@ interface for interface with object as its target and iterator kind “value”.
      16. Return iterator.
      -

      - If the interface does not have an iterable declaration - but does define an indexed property getter, - then the Function object is %ArrayProto_values%. -

      If the interface has a maplike declaration or setlike declaration, @@ -11990,26 +12001,36 @@ interface

    17. Otherwise, the property exists solely on the interface’s interface prototype object.
    18. - If the interface has an iterable declaration, + If the interface defines an indexed property getter, + then the Function object is + the initial value of the “forEach” data property of %ArrayPrototype%. +

      +

      + If the interface has a pair iterator, then the Function MUST have the same behavior as one that would exist assuming the interface had this operation instead of the iterable declaration:

      - void forEach(Function callback, optional any thisArg = undefined); + void forEach(Function callback, optional any thisArg);

      with the following prose definition:

        -
      1. Let values be the list of values to iterate over.
      2. -
      3. Let len be the length of values.
      4. -
      5. Initialize k to 0.
      6. -
      7. While k < len: +
      8. Let O be the this value.
      9. +
      10. Let pairs be the list of value pairs to iterate over.
      11. +
      12. Let i be 0.
      13. +
      14. While i is less than the length of pairs:
          -
        1. Let kValue be the value in values at index k.
        2. +
        3. Let pair be the entry in pairs at index i.
        4. +
        5. Let key be pair’s key.
        6. +
        7. Let value be pair’s value.
        8. Invoke callback with thisArg + (or undefined, if the argument was not supplied) as the callback this value and - k and value as its arguments.
        9. + value, key and O as its arguments. +
        10. Update pairs to the current list of value pairs to iterate over.
        11. +
        12. Set i to i + 1.
      @@ -12102,7 +12123,13 @@ interface
    19. Otherwise, the property exists solely on the interface’s interface prototype object.
    20. - The Function, when invoked, MUST behave as follows: + If the interface has a value iterator, + then the Function object is + the initial value of the “entries” data property of %ArrayPrototype%. +

      +

      + If the interface has a pair iterator, + then the Function, when invoked, MUST behave as follows:

      1. Let object be the result of calling ToObject on the this value.
      2. @@ -12152,7 +12179,13 @@ interface
      3. Otherwise, the property exists solely on the interface’s interface prototype object.
      4. - The Function, when invoked, MUST behave as follows: + If the interface has a value iterator, + then the Function object is + the initial value of the “keys” data property of %ArrayPrototype%. +

        +

        + If the interface has a pair iterator, + then the Function, when invoked, MUST behave as follows:

        1. Let object be the result of calling ToObject on the this value.
        2. @@ -12223,6 +12256,15 @@ interface
        3. its kind, which is the iteration kind,
        4. its index, which is the current index into the values value to be iterated.
        +
        +

        + Default iterator objects are only used for pair iterators; + value iterators, as they are currently + restricted to iterating over an object’s + supported indexed properties, + use standard ECMAScript Array iterator objects. +

        +

        When a default iterator object is first created, its index is set to 0. @@ -12243,8 +12285,8 @@ interface

        The iterator prototype object for a given interface - is an object that exists for every interface that has an - iterable declaration. It serves as the + is an object that exists for every interface that has a + pair iterator. It serves as the prototype for default iterator objects for the interface.

        @@ -12277,29 +12319,25 @@ interface
      5. Let target be object’s target.
      6. Let index be object’s index.
      7. Let kind be object’s kind.
      8. -
      9. Let values be the list of values to iterate over. -
        -

        Depending on whether prose accompanying the interface defined this to be a snapshot at the time - iteration begins, the list of values might be different from the previous time the next - method was called on this iterator object.

        -
        -
      10. +
      11. Let values be the list of value pairs to iterate over.
      12. Let len be the length of values.
      13. If object’s index is greater than or equal to len, then return CreateIterResultObject(undefined, true).
      14. +
      15. Let pair be the entry in values at index index.
      16. Let result be a value determined by the value of kind:
        key
          -
        1. Let key be the ECMAScript Number value index.
        2. +
        3. Let idlKey be pair’s key.
        4. +
        5. Let key be the result of converting idlKey to an ECMAScript value.
        6. result is key.
        value
          -
        1. Let idlValue be the value in values at index index.
        2. +
        3. Let idlValue be pair’s value.
        4. Let value be the result of converting idlValue to an ECMAScript value.
        5. result is value.
        @@ -12307,8 +12345,9 @@ interface
        key+value
          -
        1. Let key be the ECMAScript Number value index.
        2. -
        3. Let idlValue be the value in values at index index.
        4. +
        5. Let idlKey be pair’s key.
        6. +
        7. Let idlValue be pair’s value.
        8. +
        9. Let key be the result of converting idlKey to an ECMAScript value.
        10. Let value be the result of converting idlValue to an ECMAScript value.
        11. Let array be the result of performing ArrayCreate(2).
        12. Call CreateDataProperty(array, "0", key).