diff --git a/.eslintrc b/.eslintrc index 113c77a..5634ee5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -38,8 +38,8 @@ "IteratorClose", "IteratorComplete", "IteratorNext", + "IteratorStepValue", "IteratorStep", - "IteratorValue", "NormalCompletion", "OrdinaryHasInstance", "OrdinaryObjectCreate", diff --git a/Iterator.prototype.drop/implementation.js b/Iterator.prototype.drop/implementation.js index 4de2406..db186bb 100644 --- a/Iterator.prototype.drop/implementation.js +++ b/Iterator.prototype.drop/implementation.js @@ -10,7 +10,7 @@ var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IteratorClose = require('../aos/IteratorClose'); var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var ToIntegerOrInfinity = require('es-abstract/2023/ToIntegerOrInfinity'); var ToNumber = require('es-abstract/2023/ToNumber'); @@ -70,14 +70,12 @@ module.exports = function drop(limit) { } } // while (true) { // step 6.c - next = IteratorStep(iterated); // step 6.c.i - if (!next) { - // return void undefined; // step 6.c.ii - return sentinel; - } try { - var value = IteratorValue(next); // step 6.c.iii - return value; // step 6.c.iii + var value = IteratorStepValue(iterated); // step 6.b.i + if (iterated['[[Done]]']) { + return sentinel; // step 6.b.ii + } + return value; } catch (e) { // close iterator // step 6.c.icv closeIfAbrupt(ThrowCompletion(e)); diff --git a/Iterator.prototype.every/implementation.js b/Iterator.prototype.every/implementation.js index 36113e2..274092b 100644 --- a/Iterator.prototype.every/implementation.js +++ b/Iterator.prototype.every/implementation.js @@ -8,8 +8,7 @@ var Call = require('es-abstract/2023/Call'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var NormalCompletion = require('es-abstract/2023/NormalCompletion'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var ToBoolean = require('es-abstract/2023/ToBoolean'); @@ -35,28 +34,27 @@ module.exports = function every(predicate) { // eslint-disable-next-line no-constant-condition while (true) { // step 6 - var next = IteratorStep(iterated); // step 6.a - if (!next) { + var value = IteratorStepValue(iterated); // step 6.a + if (iterated['[[Done]]']) { return true; // step 6.b } - var value = IteratorValue(next); // step 6.c var result; try { - result = Call(predicate, void undefined, [value, counter]); // step 6.d + result = Call(predicate, void undefined, [value, counter]); // step 6.c } catch (e) { - // close iterator // step 6.e + // close iterator // step 6.d IteratorClose( iterated, ThrowCompletion(e) ); } finally { - counter += 1; // step 6.g + counter += 1; // step 6.f } if (!ToBoolean(result)) { return IteratorClose( iterated, NormalCompletion(false) - ); // step 6.f + ); // step 6.e } } }; diff --git a/Iterator.prototype.filter/implementation.js b/Iterator.prototype.filter/implementation.js index e5179fb..ee58fe9 100644 --- a/Iterator.prototype.filter/implementation.js +++ b/Iterator.prototype.filter/implementation.js @@ -10,8 +10,7 @@ var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var ToBoolean = require('es-abstract/2023/ToBoolean'); var Type = require('es-abstract/2023/Type'); @@ -51,12 +50,11 @@ module.exports = function filter(predicate) { var closure = function () { // eslint-disable-next-line no-constant-condition while (true) { // step 6.b - var next = IteratorStep(iterated); // step 6.b.i - if (!next) { - // return void undefined; // step 6.b.ii - return sentinel; + var value = IteratorStepValue(iterated); // step 6.b.i + if (iterated['[[Done]]']) { + return sentinel; // step 6.b.ii } - var value = IteratorValue(next); // step 6.b.iii + var selected; try { selected = Call(predicate, void undefined, [value, counter]); // step 6.b.iv diff --git a/Iterator.prototype.find/implementation.js b/Iterator.prototype.find/implementation.js index 936de8a..10abc2c 100644 --- a/Iterator.prototype.find/implementation.js +++ b/Iterator.prototype.find/implementation.js @@ -8,8 +8,7 @@ var Call = require('es-abstract/2023/Call'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var NormalCompletion = require('es-abstract/2023/NormalCompletion'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var ToBoolean = require('es-abstract/2023/ToBoolean'); @@ -36,28 +35,27 @@ module.exports = function find(predicate) { // eslint-disable-next-line no-constant-condition while (true) { // step 6 - var next = IteratorStep(iterated); // step 6.a - if (!next) { + var value = IteratorStepValue(iterated); // step 6.a + if (iterated['[[Done]]']) { return void undefined; // step 6.b } - var value = IteratorValue(next); // step 6.c var result; try { - result = Call(predicate, void undefined, [value, counter]); // step 6.d + result = Call(predicate, void undefined, [value, counter]); // step 6.c } catch (e) { - // close iterator // step 6.e + // close iterator // step 6.d IteratorClose( iterated, ThrowCompletion(e) ); } finally { - counter += 1; // step 6.g + counter += 1; // step 6.f } if (ToBoolean(result)) { return IteratorClose( iterated, NormalCompletion(value) - ); // step 6.f + ); // step 6.e } } }; diff --git a/Iterator.prototype.flatMap/implementation.js b/Iterator.prototype.flatMap/implementation.js index a680963..57b4eb1 100644 --- a/Iterator.prototype.flatMap/implementation.js +++ b/Iterator.prototype.flatMap/implementation.js @@ -11,8 +11,7 @@ var GetIteratorDirect = require('../aos/GetIteratorDirect'); var GetIteratorFlattenable = require('../aos/GetIteratorFlattenable'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var Type = require('es-abstract/2023/Type'); @@ -65,14 +64,13 @@ module.exports = function flatMap(mapper) { var closure = function () { // while (true) { // step 5.b if (innerIterator === sentinel) { - var next = IteratorStep(iterated); // step 5.b.i - if (!next) { + var value = IteratorStepValue(iterated); // step 5.b.i + if (iterated['[[Done]]']) { innerAlive = false; innerIterator = sentinel; // return void undefined; // step 5.b.ii return sentinel; } - var value = IteratorValue(next); // step 5.b.iii } if (innerIterator === sentinel) { @@ -91,27 +89,20 @@ module.exports = function flatMap(mapper) { } // while (innerAlive) { // step 5.b.ix if (innerAlive) { - var innerNext; - try { - innerNext = IteratorStep(innerIterator); // step 5.b.ix.1 - } catch (e) { - innerIterator = sentinel; - closeIfAbrupt(ThrowCompletion(e)); // step 5.b.ix.2 - } - if (!innerNext) { - innerAlive = false; // step 5.b.ix.3.a - innerIterator = sentinel; - return closure(); - } // step 5.b.ix.4 var innerValue; try { - innerValue = IteratorValue(innerNext); // step 5.b.ix.4.a + innerValue = IteratorStepValue(innerIterator); // step 5.b.ix.4.a } catch (e) { innerAlive = false; innerIterator = sentinel; closeIfAbrupt(ThrowCompletion(e)); // step 5.b.ix.4.b } + if (innerIterator['[[Done]]']) { + innerAlive = false; + innerIterator = sentinel; + return closure(); + } return innerValue; // step 5.b.ix.4.c } // } diff --git a/Iterator.prototype.forEach/implementation.js b/Iterator.prototype.forEach/implementation.js index cfb9fb6..94e914f 100644 --- a/Iterator.prototype.forEach/implementation.js +++ b/Iterator.prototype.forEach/implementation.js @@ -8,8 +8,7 @@ var Call = require('es-abstract/2023/Call'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var Type = require('es-abstract/2023/Type'); @@ -33,21 +32,20 @@ module.exports = function forEach(fn) { // eslint-disable-next-line no-constant-condition while (true) { // step 6 - var next = IteratorStep(iterated); // step 6.a - if (!next) { + var value = IteratorStepValue(iterated); // step 6.a + if (iterated['[[Done]]']) { return void undefined; // step 6.b } - var value = IteratorValue(next); // step 6.c try { - Call(fn, void undefined, [value, counter]); // step 6.d + Call(fn, void undefined, [value, counter]); // step 6.c } catch (e) { IteratorClose( iterated, ThrowCompletion(e) - ); // steps 6.e + ); // steps 6.d throw e; } finally { - counter += 1; // step 6.f + counter += 1; // step 6.e } } }; diff --git a/Iterator.prototype.map/implementation.js b/Iterator.prototype.map/implementation.js index 4c4e26a..be69634 100644 --- a/Iterator.prototype.map/implementation.js +++ b/Iterator.prototype.map/implementation.js @@ -10,8 +10,7 @@ var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var Type = require('es-abstract/2023/Type'); @@ -49,16 +48,14 @@ module.exports = function map(mapper) { var counter = 0; // step 6.a var closure = function () { // while (true) { // step 6.b - var next = IteratorStep(iterated); // step 6.b.i - - if (!next) { - // return void undefined; // step 6.b.ii - return sentinel; + var value = IteratorStepValue(iterated); // step 6.b.i + if (iterated['[[Done]]']) { + return sentinel; // step 6.b.ii } - var value = IteratorValue(next); // step 6.b.iii + var mapped; try { - mapped = Call(mapper, void undefined, [value, counter]); // step 6.b.iv + mapped = Call(mapper, void undefined, [value, counter]); // step 6.b.iii // yield mapped // step 6.b.vi return mapped; } catch (e) { diff --git a/Iterator.prototype.reduce/implementation.js b/Iterator.prototype.reduce/implementation.js index 643cf30..bd70861 100644 --- a/Iterator.prototype.reduce/implementation.js +++ b/Iterator.prototype.reduce/implementation.js @@ -8,8 +8,7 @@ var Call = require('es-abstract/2023/Call'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var Type = require('es-abstract/2023/Type'); @@ -31,13 +30,11 @@ module.exports = function reduce(reducer) { var accumulator; var counter; - var next; if (arguments.length < 2) { // step 6 - next = IteratorStep(iterated); // step 6.a - if (!next) { - throw new $TypeError('Reduce of empty iterator with no initial value'); // step 6.b + accumulator = IteratorStepValue(iterated); // step 6.a + if (iterated['[[Done]]']) { + throw new $TypeError('Reduce of empty iterator with no initial value'); } - accumulator = IteratorValue(next); // step 6.c counter = 1; } else { // step 7 accumulator = arguments[1]; // step 7.a @@ -46,11 +43,10 @@ module.exports = function reduce(reducer) { // eslint-disable-next-line no-constant-condition while (true) { // step 8 - next = IteratorStep(iterated); // step 8.a - if (!next) { + var value = IteratorStepValue(iterated); // step 8.a + if (iterated['[[Done]]']) { return accumulator; // step 8.b } - var value = IteratorValue(next); // step 8.c try { var result = Call(reducer, void undefined, [accumulator, value, counter]); // step 8.d accumulator = result; // step 8.f diff --git a/Iterator.prototype.some/implementation.js b/Iterator.prototype.some/implementation.js index 640830d..215e121 100644 --- a/Iterator.prototype.some/implementation.js +++ b/Iterator.prototype.some/implementation.js @@ -8,8 +8,7 @@ var Call = require('es-abstract/2023/Call'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IsCallable = require('es-abstract/2023/IsCallable'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var NormalCompletion = require('es-abstract/2023/NormalCompletion'); var ThrowCompletion = require('es-abstract/2023/ThrowCompletion'); var ToBoolean = require('es-abstract/2023/ToBoolean'); @@ -35,28 +34,27 @@ module.exports = function some(predicate) { // eslint-disable-next-line no-constant-condition while (true) { // step 6 - var next = IteratorStep(iterated); // step 6.a - if (!next) { + var value = IteratorStepValue(iterated); // step 6.a + if (iterated['[[Done]]']) { return false; // step 6.b } - var value = IteratorValue(next); // step 6.c var result; try { - result = Call(predicate, void undefined, [value, counter]); // step 6.d + result = Call(predicate, void undefined, [value, counter]); // step 6.c } catch (e) { - // close iterator // step 6.e + // close iterator // step 6.d IteratorClose( iterated, ThrowCompletion(e) ); } finally { - counter += 1; // step 6.g + counter += 1; // step 6.f } if (ToBoolean(result)) { return IteratorClose( iterated, NormalCompletion(true) - ); // step 6.f + ); // step 6.e } } }; diff --git a/Iterator.prototype.take/implementation.js b/Iterator.prototype.take/implementation.js index 77f131f..10fa7af 100644 --- a/Iterator.prototype.take/implementation.js +++ b/Iterator.prototype.take/implementation.js @@ -9,8 +9,7 @@ var CompletionRecord = require('es-abstract/2023/CompletionRecord'); var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); var IteratorClose = require('../aos/IteratorClose'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var NormalCompletion = require('es-abstract/2023/NormalCompletion'); var ToIntegerOrInfinity = require('es-abstract/2023/ToIntegerOrInfinity'); var ToNumber = require('es-abstract/2023/ToNumber'); @@ -68,13 +67,11 @@ module.exports = function take(limit) { remaining -= 1; // step 9.b.ii.1 } - var next = IteratorStep(iterated); // step 9.b.iii - if (!next) { - // return void undefined; // step 9.b.iv - return sentinel; + var value = IteratorStepValue(iterated); // step 6.b.i + if (iterated['[[Done]]']) { + return sentinel; // step 6.b.ii } - var value = IteratorValue(next); // step 9.b.iii return value; // step 9.b.iv // } }; diff --git a/Iterator.prototype.toArray/implementation.js b/Iterator.prototype.toArray/implementation.js index f63f8f1..25cb294 100644 --- a/Iterator.prototype.toArray/implementation.js +++ b/Iterator.prototype.toArray/implementation.js @@ -5,8 +5,7 @@ var GetIntrinsic = require('get-intrinsic'); var $TypeError = GetIntrinsic('%TypeError%'); var GetIteratorDirect = require('../aos/GetIteratorDirect'); -var IteratorStep = require('es-abstract/2023/IteratorStep'); -var IteratorValue = require('es-abstract/2023/IteratorValue'); +var IteratorStepValue = require('../aos/IteratorStepValue'); var Type = require('es-abstract/2023/Type'); var callBound = require('call-bind/callBound'); @@ -30,11 +29,10 @@ module.exports = function toArray() { // eslint-disable-next-line no-constant-condition while (true) { // step 5 - var next = IteratorStep(iterated); // step 5.a - if (!next) { + var value = IteratorStepValue(iterated); // step 5.a + if (iterated['[[Done]]']) { return items; // step 5.b } - var value = IteratorValue(next); // step 5.c $push(items, value); // step 5.d } }; diff --git a/aos/CreateIteratorFromClosure.js b/aos/CreateIteratorFromClosure.js index a2f5cd2..9779ab1 100644 --- a/aos/CreateIteratorFromClosure.js +++ b/aos/CreateIteratorFromClosure.js @@ -8,7 +8,6 @@ var GeneratorStart = require('./GeneratorStart'); var IsArray = require('es-abstract/2023/IsArray'); var IsCallable = require('es-abstract/2023/IsCallable'); var OrdinaryObjectCreate = require('es-abstract/2023/OrdinaryObjectCreate'); -var Type = require('es-abstract/2023/Type'); var every = require('es-abstract/helpers/every'); @@ -17,14 +16,14 @@ var SLOT = require('internal-slot'); var safeConcat = require('safe-array-concat'); var isString = function isString(slot) { - return Type(slot) === 'String'; + return typeof slot === 'string'; }; module.exports = function CreateIteratorFromClosure(closure, generatorBrand, proto) { if (!IsCallable(closure)) { throw new $TypeError('`closure` must be a function'); } - if (Type(generatorBrand) !== 'String') { + if (typeof generatorBrand !== 'string') { throw new $TypeError('`generatorBrand` must be a string'); } var extraSlots = arguments.length > 3 ? arguments[3] : []; diff --git a/aos/IteratorStepValue.js b/aos/IteratorStepValue.js new file mode 100644 index 0000000..5b3ef4c --- /dev/null +++ b/aos/IteratorStepValue.js @@ -0,0 +1,47 @@ +'use strict'; + +var Get = require('es-abstract/2023/Get'); +var IteratorComplete = require('es-abstract/2023/IteratorComplete'); +var IteratorNext = require('es-abstract/2023/IteratorNext'); +var Type = require('es-abstract/2023/Type'); + +var assertRecord = require('es-abstract/helpers/assertRecord'); + +// https://262.ecma-international.org/15.0/#sec-iteratorstepvalue + +module.exports = function IteratorStepValue(iteratorRecord) { + assertRecord(Type, 'Iterator Record', 'iteratorRecord', iteratorRecord); + /* eslint no-param-reassign: 0 */ + + var result; + try { + result = IteratorNext(iteratorRecord); // step 1 + } catch (e) { // step 2 + iteratorRecord['[[Done]]'] = true; // step 2.a + throw e; // step 2.b + } + + var done; + try { + done = IteratorComplete(result); // step 4 + } catch (e) { // step 5 + iteratorRecord['[[Done]]'] = true; // step 5.a + throw e; // step 5.b + } + + if (done) { // step 7 + iteratorRecord['[[Done]]'] = true; // step 7.a + return 'DONE'; // step 7.b + } + + var value; + try { + value = Get(result, 'value'); // step 8 + } catch (e) { // step 9 + iteratorRecord['[[Done]]'] = true; // step 9.a + throw e; // step 10 + } + + return value; // step 10 +}; +