339 lines
11 KiB
JavaScript
339 lines
11 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.GetIterator = GetIterator;
|
|
exports.IteratorStep = IteratorStep;
|
|
exports.IteratorValue = IteratorValue;
|
|
exports.IteratorComplete = IteratorComplete;
|
|
exports.IteratorNext = IteratorNext;
|
|
exports.CreateListIterator = CreateListIterator;
|
|
exports.CreateMapIterator = CreateMapIterator;
|
|
exports.CreateSetIterator = CreateSetIterator;
|
|
exports.IteratorClose = IteratorClose;
|
|
exports.IterableToList = IterableToList;
|
|
|
|
var _completions = require("../completions.js");
|
|
|
|
var _index = require("../values/index.js");
|
|
|
|
var _index2 = require("./index.js");
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var _abstract = require("./abstract.js");
|
|
|
|
var _singletons = require("../singletons.js");
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// ECMA262 7.4.1
|
|
/**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
function GetIterator(realm) {
|
|
var obj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : realm.intrinsics.undefined;
|
|
var method = arguments[2];
|
|
|
|
// 1. If method was not passed, then
|
|
if (!method) {
|
|
// a. Let method be ? GetMethod(obj, @@iterator).
|
|
method = (0, _index2.GetMethod)(realm, obj, realm.intrinsics.SymbolIterator);
|
|
}
|
|
|
|
// 2. Let iterator be ? Call(method, obj).
|
|
var iterator = (0, _index2.Call)(realm, method, obj);
|
|
|
|
// 3. If Type(iterator) is not Object, throw a TypeError exception.
|
|
if (!(iterator instanceof _index.ObjectValue)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 4. Return iterator.
|
|
return iterator;
|
|
}
|
|
|
|
// ECMA262 7.4.5
|
|
function IteratorStep(realm, iterator) {
|
|
// 1. Let result be ? IteratorNext(iterator).
|
|
var result = IteratorNext(realm, iterator);
|
|
|
|
// 2. Let done be ? IteratorComplete(result).
|
|
var done = IteratorComplete(realm, result);
|
|
|
|
// 3. If done is true, return false.
|
|
if (done) return false;
|
|
|
|
// 4. Return result.
|
|
return result;
|
|
}
|
|
|
|
// ECMA262 7.4.4
|
|
function IteratorValue(realm, iterResult) {
|
|
// 1. Assert: Type(iterResult) is Object.
|
|
(0, _invariant2.default)(iterResult instanceof _index.ObjectValue, "expected obj");
|
|
|
|
// 2. Return ? Get(iterResult, "value").
|
|
return (0, _index2.Get)(realm, iterResult, "value");
|
|
}
|
|
|
|
// ECMA262 7.4.2
|
|
function IteratorComplete(realm, iterResult) {
|
|
// 1. Assert: Type(iterResult) is Object.
|
|
(0, _invariant2.default)(iterResult instanceof _index.ObjectValue, "expected obj");
|
|
|
|
// 2. Return ToBoolean(? Get(iterResult, "done")).
|
|
return _singletons.To.ToBooleanPartial(realm, (0, _index2.Get)(realm, iterResult, "done"));
|
|
}
|
|
|
|
// ECMA262 7.4.2
|
|
function IteratorNext(realm, iterator, value) {
|
|
// 1. If value was not passed, then
|
|
var result = void 0;
|
|
if (!value) {
|
|
// a. Let result be ? Invoke(iterator, "next", « »).
|
|
result = (0, _index2.Invoke)(realm, iterator, "next", []);
|
|
} else {
|
|
// 2. Else,
|
|
// a. Let result be ? Invoke(iterator, "next", « value »).
|
|
result = (0, _index2.Invoke)(realm, iterator, "next", [value]);
|
|
}
|
|
|
|
// 3. If Type(result) is not Object, throw a TypeError exception.
|
|
if (!(result instanceof _index.ObjectValue)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 4. Return result.
|
|
return result;
|
|
}
|
|
|
|
// ECMA262 7.4.8
|
|
function CreateListIterator(realm, list) {
|
|
// 1. Let iterator be ObjectCreate(%IteratorPrototype%, « [[IteratorNext]], [[IteratedList]], [[ListIteratorNextIndex]] »).
|
|
var iterator = _singletons.Create.ObjectCreate(realm, realm.intrinsics.IteratorPrototype, {
|
|
$IteratorNext: undefined,
|
|
$IteratedList: undefined,
|
|
$ListIteratorNextIndex: undefined
|
|
});
|
|
|
|
// 2. Set iterator's [[IteratedList]] internal slot to list.
|
|
iterator.$IteratedList = list;
|
|
|
|
// 3. Set iterator's [[ListIteratorNextIndex]] internal slot to 0.
|
|
iterator.$ListIteratorNextIndex = 0;
|
|
|
|
// 4. Let next be a new built-in function object as defined in ListIterator next (7.4.8.1).
|
|
var next = ListIterator_next(realm);
|
|
|
|
// 5. Set iterator's [[IteratorNext]] internal slot to next.
|
|
iterator.$IteratorNext = next;
|
|
|
|
// 6. Perform CreateMethodProperty(iterator, "next", next).
|
|
_singletons.Create.CreateMethodProperty(realm, iterator, new _index.StringValue(realm, "next"), next);
|
|
|
|
// 7. Return iterator.
|
|
return iterator;
|
|
}
|
|
|
|
// ECMA262 7.4.8.1
|
|
function ListIterator_next(realm) {
|
|
var func = new _index.NativeFunctionValue(realm, undefined, "next", 0, function (context) {
|
|
(0, _invariant2.default)(context instanceof _index.ObjectValue);
|
|
|
|
// 1. Let O be the this value.
|
|
var O = context;
|
|
|
|
// 2. Let f be the active function object.
|
|
var f = func;
|
|
|
|
// 3. If O does not have a [[IteratorNext]] internal slot, throw a TypeError exception.
|
|
if (!O.$IteratorNext) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "O does not have an [[IteratorNext]] internal slot");
|
|
}
|
|
|
|
// 4. Let next be the value of the [[IteratorNext]] internal slot of O.
|
|
var next = O.$IteratorNext;
|
|
|
|
// 5. If SameValue(f, next) is false, throw a TypeError exception.
|
|
if (!(0, _abstract.SameValue)(realm, f, next)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 6. If O does not have an [[IteratedList]] internal slot, throw a TypeError exception.
|
|
if (!O.$IteratedList) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "O does not have an [[IteratedList]] internal slot");
|
|
}
|
|
|
|
// 7. Let list be the value of the [[IteratedList]] internal slot of O.
|
|
var list = O.$IteratedList;
|
|
|
|
(0, _invariant2.default)(typeof O.$ListIteratorNextIndex === "number");
|
|
|
|
// 8. Let index be the value of the [[ListIteratorNextIndex]] internal slot of O.
|
|
// Default to 0 for Flow.
|
|
var index = O.$ListIteratorNextIndex;
|
|
|
|
// 9. Let len be the number of elements of list.
|
|
var len = list.length;
|
|
|
|
// 10. If index ≥ len, then
|
|
if (index >= len) {
|
|
// a. Return CreateIterResultObject(undefined, true).
|
|
return _singletons.Create.CreateIterResultObject(realm, realm.intrinsics.undefined, true);
|
|
}
|
|
|
|
// 11. Set the value of the [[ListIteratorNextIndex]] internal slot of O to index+1.
|
|
O.$ListIteratorNextIndex = index + 1;
|
|
|
|
// 12. Return CreateIterResultObject(list[index], false).
|
|
return _singletons.Create.CreateIterResultObject(realm, list[index], false);
|
|
});
|
|
|
|
return func;
|
|
}
|
|
|
|
// ECMA262 23.1.5.1
|
|
function CreateMapIterator(realm, map, kind) {
|
|
// 1. If Type(map) is not Object, throw a TypeError exception.
|
|
if (!(map instanceof _index.ObjectValue)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 2. If map does not have a [[MapData]] internal slot, throw a TypeError exception.
|
|
if (!map.$MapData) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 3. Let iterator be ObjectCreate(%MapIteratorPrototype%, « [[Map]], [[MapNextIndex]], [[MapIterationKind]] »).
|
|
var iterator = _singletons.Create.ObjectCreate(realm, realm.intrinsics.MapIteratorPrototype, {
|
|
$Map: undefined,
|
|
$MapNextIndex: undefined,
|
|
$MapIterationKind: undefined
|
|
});
|
|
|
|
// 4. Set iterator's [[Map]] internal slot to map.
|
|
iterator.$Map = map;
|
|
|
|
// 5. Set iterator's [[MapNextIndex]] internal slot to 0.
|
|
iterator.$MapNextIndex = new _index.NumberValue(realm, 0);
|
|
|
|
// 6. Set iterator's [[MapIterationKind]] internal slot to kind.
|
|
iterator.$MapIterationKind = kind;
|
|
|
|
// 7. Return iterator.
|
|
return iterator;
|
|
}
|
|
|
|
// ECMA262 23.2.5.1
|
|
function CreateSetIterator(realm, set, kind) {
|
|
// 1. If Type(set) is not Object, throw a TypeError exception.
|
|
if (!(set instanceof _index.ObjectValue)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 2. If set does not have a [[SetData]] internal slot, throw a TypeError exception.
|
|
if (!set.$SetData) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 3. Let iterator be ObjectCreate(%SetIteratorPrototype%, « [[IteratedSet]], [[SetNextIndex]], [[SetIterationKind]] »).
|
|
var iterator = _singletons.Create.ObjectCreate(realm, realm.intrinsics.SetIteratorPrototype, {
|
|
$IteratedSet: undefined,
|
|
$SetNextIndex: undefined,
|
|
$SetIterationKind: undefined
|
|
});
|
|
|
|
// 4. Set iterator's [[IteratedSet]] internal slot to set.
|
|
iterator.$IteratedSet = set;
|
|
|
|
// 5. Set iterator's [[SetNextIndex]] internal slot to 0.
|
|
iterator.$SetNextIndex = 0;
|
|
|
|
// 6. Set iterator's [[SetIterationKind]] internal slot to kind.
|
|
iterator.$SetIterationKind = kind;
|
|
|
|
// 7. Return iterator.
|
|
return iterator;
|
|
}
|
|
|
|
// ECMA262 7.4.6
|
|
function IteratorClose(realm, iterator, completion) {
|
|
// 1. Assert: Type(iterator) is Object.
|
|
(0, _invariant2.default)(iterator instanceof _index.ObjectValue, "expected object");
|
|
|
|
// 2. Assert: completion is a Completion Record.
|
|
(0, _invariant2.default)(completion instanceof _completions.Completion, "expected completion record");
|
|
|
|
// 3. Let return be ? GetMethod(iterator, "return").
|
|
var ret = (0, _index2.GetMethod)(realm, iterator, "return");
|
|
|
|
// 4. If return is undefined, return Completion(completion).
|
|
if (ret instanceof _index.UndefinedValue) return completion;
|
|
|
|
// 5. Let innerResult be Call(return, iterator, « »).
|
|
var innerResult = void 0;
|
|
try {
|
|
innerResult = (0, _index2.Call)(realm, ret.throwIfNotConcrete(), iterator, []);
|
|
} catch (error) {
|
|
if (error instanceof _completions.AbruptCompletion) {
|
|
innerResult = error;
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// 6. If completion.[[Type]] is throw, return Completion(completion).
|
|
if (completion instanceof _completions.ThrowCompletion) return completion;
|
|
|
|
// 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
|
|
if (innerResult instanceof _completions.ThrowCompletion) return innerResult;
|
|
|
|
// 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
|
|
if (!(innerResult instanceof _index.ObjectValue)) {
|
|
return realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 9. Return Completion(completion).
|
|
return completion;
|
|
}
|
|
|
|
// ECMA262 22.2.2.1.1
|
|
function IterableToList(realm, items, method) {
|
|
// 1. Let iterator be ? GetIterator(items, method).
|
|
var iterator = GetIterator(realm, items, method);
|
|
|
|
// 2. Let values be a new empty List.
|
|
var values = [];
|
|
|
|
// 3. Let next be true.
|
|
var next = true;
|
|
|
|
// 4. Repeat, while next is not false
|
|
while (next !== false) {
|
|
// a. Let next be ? IteratorStep(iterator).
|
|
next = IteratorStep(realm, iterator);
|
|
|
|
// b. If next is not false, then
|
|
if (next !== false) {
|
|
// i. Let nextValue be ? IteratorValue(next).
|
|
var nextValue = IteratorValue(realm, next);
|
|
|
|
// ii. Append nextValue to the end of the List values.
|
|
values.push(nextValue);
|
|
}
|
|
}
|
|
|
|
// 5. Return values.
|
|
return values;
|
|
}
|
|
//# sourceMappingURL=iterator.js.map
|