Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Breaking] 2018/2019: GetIterator: Add hint parameter #67

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,6 @@
2018/DeletePropertyOrThrow.js spackled linguist-generated=true
2018/FromPropertyDescriptor.js spackled linguist-generated=true
2018/Get.js spackled linguist-generated=true
2018/GetIterator.js spackled linguist-generated=true
2018/GetMethod.js spackled linguist-generated=true
2018/GetOwnPropertyKeys.js spackled linguist-generated=true
2018/GetPrototypeFromConstructor.js spackled linguist-generated=true
Expand All @@ -302,7 +301,6 @@
2018/IsPromise.js spackled linguist-generated=true
2018/IsPropertyKey.js spackled linguist-generated=true
2018/IsRegExp.js spackled linguist-generated=true
2018/IterableToList.js spackled linguist-generated=true
2018/IteratorClose.js spackled linguist-generated=true
2018/IteratorComplete.js spackled linguist-generated=true
2018/IteratorNext.js spackled linguist-generated=true
Expand Down Expand Up @@ -519,6 +517,7 @@
2020/EnumerableOwnPropertyNames.js spackled linguist-generated=true
2020/FromPropertyDescriptor.js spackled linguist-generated=true
2020/Get.js spackled linguist-generated=true
2020/GetIterator.js spackled linguist-generated=true
2020/GetMethod.js spackled linguist-generated=true
2020/GetOwnPropertyKeys.js spackled linguist-generated=true
2020/GetPrototypeFromConstructor.js spackled linguist-generated=true
Expand All @@ -543,6 +542,7 @@
2020/IsPropertyKey.js spackled linguist-generated=true
2020/IsRegExp.js spackled linguist-generated=true
2020/IsStringPrefix.js spackled linguist-generated=true
2020/IterableToList.js spackled linguist-generated=true
2020/IteratorClose.js spackled linguist-generated=true
2020/IteratorComplete.js spackled linguist-generated=true
2020/IteratorNext.js spackled linguist-generated=true
Expand Down
45 changes: 36 additions & 9 deletions 2018/GetIterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
var GetIntrinsic = require('../GetIntrinsic');

var $TypeError = GetIntrinsic('%TypeError%');
var $asyncIterator = GetIntrinsic('%Symbol.asyncIterator%', true);

var inspect = require('object-inspect');
var hasSymbols = require('has-symbols')();

var getIteratorMethod = require('../helpers/getIteratorMethod');
var AdvanceStringIndex = require('./AdvanceStringIndex');
Expand All @@ -11,25 +15,48 @@ var GetMethod = require('./GetMethod');
var IsArray = require('./IsArray');
var Type = require('./Type');

// https://ecma-international.org/ecma-262/6.0/#sec-getiterator

module.exports = function GetIterator(obj, method) {
var actualMethod = method;
// https://ecma-international.org/ecma-262/9.0/#sec-getiterator
module.exports = function GetIterator(obj, hint, method) {
var actualHint = hint;
if (arguments.length < 2) {
actualMethod = getIteratorMethod(
{
actualHint = 'sync';
}
if (actualHint !== 'sync' && actualHint !== 'async') {
throw new $TypeError("Assertion failed: `hint` must be one of 'sync' or 'async', got " + inspect(hint));
}
var actualMethod = method;
if (arguments.length < 3) {
if (actualHint === 'async') {
if (hasSymbols && $asyncIterator) {
actualMethod = GetMethod(obj, $asyncIterator);
}
if (actualMethod === undefined) {
throw new $TypeError("async from sync iterators aren't currently supported");
}
} else {
actualMethod = getIteratorMethod({
AdvanceStringIndex: AdvanceStringIndex,
GetMethod: GetMethod,
IsArray: IsArray,
Type: Type
},
obj
);
}, obj);
}
}

var iterator = Call(actualMethod, obj);
if (Type(iterator) !== 'Object') {
throw new $TypeError('iterator must return an object');
}

return iterator;

// TODO: This should return an IteratorRecord
/*
var nextMethod = GetV(iterator, 'next');
return {
'[[Iterator]]': iterator,
'[[NextMethod]]': nextMethod,
'[[Done]]': false
};
*/
};
4 changes: 2 additions & 2 deletions 2018/IterableToList.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ var GetIterator = require('./GetIterator');
var IteratorStep = require('./IteratorStep');
var IteratorValue = require('./IteratorValue');

// https://www.ecma-international.org/ecma-262/8.0/#sec-iterabletolist
// https://www.ecma-international.org/ecma-262/9.0/#sec-iterabletolist

module.exports = function IterableToList(items, method) {
var iterator = GetIterator(items, method);
var iterator = GetIterator(items, 'sync', method);
var values = [];
var next = true;
while (next) {
Expand Down
45 changes: 36 additions & 9 deletions 2019/GetIterator.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions 2019/IterableToList.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 7 additions & 10 deletions 2020/GetIterator.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4000,6 +4000,56 @@ var es2018 = function ES2018(ES, ops, expectedMissing, skips) {
t.end();
});

test('GetIterator', function (t) {
try {
ES.GetIterator({}, null);
} catch (e) {
t.ok(e.message.indexOf("Assertion failed: `hint` must be one of 'sync' or 'async'" >= 0));
}

var arr = [1, 2];
testIterator(t, ES.GetIterator(arr), arr);

testIterator(t, ES.GetIterator('abc'), 'abc'.split(''));

t.test('Symbol.iterator', { skip: !v.hasSymbols }, function (st) {
var m = new Map();
m.set(1, 'a');
m.set(2, 'b');

testIterator(st, ES.GetIterator(m), [[1, 'a'], [2, 'b']]);

st.end();
});

t.test('Symbol.asyncIterator', { skip: !v.hasSymbols || !Symbol.asyncIterator }, function (st) {
try {
ES.GetIterator(arr, 'async');
} catch (e) {
st.ok(e.message.indexOf("async from sync iterators aren't currently supported") >= 0);
}

/** @type {AsyncIterator<any>} */
var it = {
next: function () {
return Promise.resolve({
done: true
});
}
};
var obj = {};
obj[Symbol.asyncIterator] = function () {
return it;
};

st.equal(ES.GetIterator(obj, 'async'), it);

st.end();
});

t.end();
});

test('PromiseResolve', function (t) {
t.test('Promises unsupported', { skip: typeof Promise === 'function' }, function (st) {
st['throws'](
Expand Down