init
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
var GetIntrinsic = require('get-intrinsic');
|
||||
|
||||
var $SyntaxError = require('es-errors/syntax');
|
||||
var $TypeError = require('es-errors/type');
|
||||
var $Promise = GetIntrinsic('%Promise%', true);
|
||||
|
||||
var Call = require('./Call');
|
||||
var CompletionRecord = require('./CompletionRecord');
|
||||
var GetMethod = require('./GetMethod');
|
||||
var Type = require('./Type');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
var callBound = require('call-bind/callBound');
|
||||
|
||||
var $then = callBound('Promise.prototype.then', true);
|
||||
|
||||
// https://262.ecma-international.org/12.0/#sec-asynciteratorclose
|
||||
|
||||
module.exports = function AsyncIteratorClose(iteratorRecord, completion) {
|
||||
if (!isIteratorRecord(iteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
|
||||
}
|
||||
|
||||
if (!(completion instanceof CompletionRecord)) {
|
||||
throw new $TypeError('Assertion failed: completion is not a Completion Record instance'); // step 2
|
||||
}
|
||||
|
||||
if (!$then) {
|
||||
throw new $SyntaxError('This environment does not support Promises.');
|
||||
}
|
||||
|
||||
var iterator = iteratorRecord['[[Iterator]]']; // step 3
|
||||
|
||||
return $then(
|
||||
$then(
|
||||
$then(
|
||||
new $Promise(function (resolve) {
|
||||
resolve(GetMethod(iterator, 'return')); // step 4
|
||||
// resolve(Call(ret, iterator, [])); // step 6
|
||||
}),
|
||||
function (returnV) { // step 5.a
|
||||
if (typeof returnV === 'undefined') {
|
||||
return completion; // step 5.b
|
||||
}
|
||||
return Call(returnV, iterator); // step 5.c, 5.d.
|
||||
}
|
||||
),
|
||||
null,
|
||||
function (e) {
|
||||
if (completion.type() === 'throw') {
|
||||
completion['?'](); // step 6
|
||||
} else {
|
||||
throw e; // step 7
|
||||
}
|
||||
}
|
||||
),
|
||||
function (innerResult) { // step 8
|
||||
if (completion.type() === 'throw') {
|
||||
completion['?'](); // step 6
|
||||
}
|
||||
if (Type(innerResult) !== 'Object') {
|
||||
throw new $TypeError('`innerResult` must be an Object'); // step 10
|
||||
}
|
||||
return completion;
|
||||
}
|
||||
);
|
||||
};
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
var $SyntaxError = require('es-errors/syntax');
|
||||
|
||||
var SLOT = require('internal-slot');
|
||||
|
||||
// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type
|
||||
|
||||
var CompletionRecord = function CompletionRecord(type, value) {
|
||||
if (!(this instanceof CompletionRecord)) {
|
||||
return new CompletionRecord(type, value);
|
||||
}
|
||||
if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') {
|
||||
throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"');
|
||||
}
|
||||
SLOT.set(this, '[[Type]]', type);
|
||||
SLOT.set(this, '[[Value]]', value);
|
||||
// [[Target]] slot?
|
||||
};
|
||||
|
||||
CompletionRecord.prototype.type = function Type() {
|
||||
return SLOT.get(this, '[[Type]]');
|
||||
};
|
||||
|
||||
CompletionRecord.prototype.value = function Value() {
|
||||
return SLOT.get(this, '[[Value]]');
|
||||
};
|
||||
|
||||
CompletionRecord.prototype['?'] = function ReturnIfAbrupt() {
|
||||
var type = SLOT.get(this, '[[Type]]');
|
||||
var value = SLOT.get(this, '[[Value]]');
|
||||
|
||||
if (type === 'throw') {
|
||||
throw value;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
CompletionRecord.prototype['!'] = function assert() {
|
||||
var type = SLOT.get(this, '[[Type]]');
|
||||
|
||||
if (type !== 'normal') {
|
||||
throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"');
|
||||
}
|
||||
return SLOT.get(this, '[[Value]]');
|
||||
};
|
||||
|
||||
module.exports = CompletionRecord;
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
'use strict';
|
||||
|
||||
var GetIntrinsic = require('get-intrinsic');
|
||||
|
||||
var $SyntaxError = require('es-errors/syntax');
|
||||
var $TypeError = require('es-errors/type');
|
||||
var $Promise = GetIntrinsic('%Promise%', true);
|
||||
|
||||
var AsyncFromSyncIteratorContinuation = require('./AsyncFromSyncIteratorContinuation');
|
||||
var Call = require('./Call');
|
||||
var CreateIterResultObject = require('./CreateIterResultObject');
|
||||
var Get = require('./Get');
|
||||
var GetMethod = require('./GetMethod');
|
||||
var IteratorNext = require('./IteratorNext');
|
||||
var OrdinaryObjectCreate = require('./OrdinaryObjectCreate');
|
||||
var Type = require('./Type');
|
||||
|
||||
var SLOT = require('internal-slot');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
var $AsyncFromSyncIteratorPrototype = GetIntrinsic('%AsyncFromSyncIteratorPrototype%', true) || {
|
||||
next: function next(value) {
|
||||
if (!$Promise) {
|
||||
throw new $SyntaxError('This environment does not support Promises.');
|
||||
}
|
||||
|
||||
var O = this; // step 1
|
||||
|
||||
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
|
||||
|
||||
var argsLength = arguments.length;
|
||||
|
||||
return new $Promise(function (resolve) { // step 3
|
||||
var syncIteratorRecord = SLOT.get(O, '[[SyncIteratorRecord]]'); // step 4
|
||||
var result;
|
||||
if (argsLength > 0) {
|
||||
result = IteratorNext(syncIteratorRecord, value); // step 5.a
|
||||
} else { // step 6
|
||||
result = IteratorNext(syncIteratorRecord);// step 6.a
|
||||
}
|
||||
resolve(AsyncFromSyncIteratorContinuation(result)); // step 8
|
||||
});
|
||||
},
|
||||
'return': function () {
|
||||
if (!$Promise) {
|
||||
throw new $SyntaxError('This environment does not support Promises.');
|
||||
}
|
||||
|
||||
var O = this; // step 1
|
||||
|
||||
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
|
||||
|
||||
var valueIsPresent = arguments.length > 0;
|
||||
var value = valueIsPresent ? arguments[0] : void undefined;
|
||||
|
||||
return new $Promise(function (resolve, reject) { // step 3
|
||||
var syncIterator = SLOT.get(O, '[[SyncIteratorRecord]]')['[[Iterator]]']; // step 4
|
||||
var iteratorReturn = GetMethod(syncIterator, 'return'); // step 5
|
||||
|
||||
if (typeof iteratorReturn === 'undefined') { // step 7
|
||||
var iterResult = CreateIterResultObject(value, true); // step 7.a
|
||||
Call(resolve, undefined, [iterResult]); // step 7.b
|
||||
return;
|
||||
}
|
||||
var result;
|
||||
if (valueIsPresent) { // step 8
|
||||
result = Call(iteratorReturn, syncIterator, [value]); // step 8.a
|
||||
} else { // step 9
|
||||
result = Call(iteratorReturn, syncIterator); // step 9.a
|
||||
}
|
||||
if (Type(result) !== 'Object') { // step 11
|
||||
Call(reject, undefined, [new $TypeError('Iterator `return` method returned a non-object value.')]); // step 11.a
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(AsyncFromSyncIteratorContinuation(result)); // step 12
|
||||
});
|
||||
},
|
||||
'throw': function () {
|
||||
if (!$Promise) {
|
||||
throw new $SyntaxError('This environment does not support Promises.');
|
||||
}
|
||||
|
||||
var O = this; // step 1
|
||||
|
||||
SLOT.assert(O, '[[SyncIteratorRecord]]'); // step 2
|
||||
|
||||
var valueIsPresent = arguments.length > 0;
|
||||
var value = valueIsPresent ? arguments[0] : void undefined;
|
||||
|
||||
return new $Promise(function (resolve, reject) { // step 3
|
||||
var syncIterator = SLOT.get(O, '[[SyncIteratorRecord]]')['[[Iterator]]']; // step 4
|
||||
|
||||
var throwMethod = GetMethod(syncIterator, 'throw'); // step 5
|
||||
|
||||
if (typeof throwMethod === 'undefined') { // step 7
|
||||
Call(reject, undefined, [value]); // step 7.a
|
||||
return;
|
||||
}
|
||||
|
||||
var result;
|
||||
if (valueIsPresent) { // step 8
|
||||
result = Call(throwMethod, syncIterator, [value]); // step 8.a
|
||||
} else { // step 9
|
||||
result = Call(throwMethod, syncIterator); // step 9.a
|
||||
}
|
||||
if (Type(result) !== 'Object') { // step 11
|
||||
Call(reject, undefined, [new $TypeError('Iterator `throw` method returned a non-object value.')]); // step 11.a
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(AsyncFromSyncIteratorContinuation(result/* , promiseCapability */)); // step 12
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// https://262.ecma-international.org/14.0/#sec-createasyncfromsynciterator
|
||||
|
||||
module.exports = function CreateAsyncFromSyncIterator(syncIteratorRecord) {
|
||||
if (!isIteratorRecord(syncIteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `syncIteratorRecord` must be an Iterator Record');
|
||||
}
|
||||
|
||||
// var asyncIterator = OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »); // step 1
|
||||
var asyncIterator = OrdinaryObjectCreate($AsyncFromSyncIteratorPrototype);
|
||||
|
||||
SLOT.set(asyncIterator, '[[SyncIteratorRecord]]', syncIteratorRecord); // step 2
|
||||
|
||||
var nextMethod = Get(asyncIterator, 'next'); // step 3
|
||||
|
||||
return { // steps 3-4
|
||||
'[[Iterator]]': asyncIterator,
|
||||
'[[NextMethod]]': nextMethod,
|
||||
'[[Done]]': false
|
||||
};
|
||||
};
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var Call = require('./Call');
|
||||
var CompletionRecord = require('./CompletionRecord');
|
||||
var GetMethod = require('./GetMethod');
|
||||
var IsCallable = require('./IsCallable');
|
||||
var Type = require('./Type');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
// https://262.ecma-international.org/14.0/#sec-iteratorclose
|
||||
|
||||
module.exports = function IteratorClose(iteratorRecord, completion) {
|
||||
if (!isIteratorRecord(iteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
|
||||
}
|
||||
if (Type(iteratorRecord['[[Iterator]]']) !== 'Object') {
|
||||
throw new $TypeError('Assertion failed: iteratorRecord.[[Iterator]] must be an Object'); // step 1
|
||||
}
|
||||
|
||||
if (!IsCallable(completion) && !(completion instanceof CompletionRecord)) { // step 2
|
||||
throw new $TypeError('Assertion failed: completion is not a thunk representing a Completion Record, nor a Completion Record instance');
|
||||
}
|
||||
var completionThunk = completion instanceof CompletionRecord ? function () { return completion['?'](); } : completion;
|
||||
|
||||
var iterator = iteratorRecord['[[Iterator]]']; // step 3
|
||||
|
||||
var iteratorReturn;
|
||||
try {
|
||||
iteratorReturn = GetMethod(iterator, 'return'); // step 4
|
||||
} catch (e) {
|
||||
completionThunk(); // throws if `completion` is a throw completion // step 6
|
||||
completionThunk = null; // ensure it's not called twice.
|
||||
throw e; // step 7
|
||||
}
|
||||
if (typeof iteratorReturn === 'undefined') {
|
||||
return completionThunk(); // step 5.a - 5.b
|
||||
}
|
||||
|
||||
var innerResult;
|
||||
try {
|
||||
innerResult = Call(iteratorReturn, iterator, []);
|
||||
} catch (e) {
|
||||
// if we hit here, then "e" is the innerResult completion that needs re-throwing
|
||||
|
||||
completionThunk(); // throws if `completion` is a throw completion // step 6
|
||||
completionThunk = null; // ensure it's not called twice.
|
||||
|
||||
// if not, then return the innerResult completion
|
||||
throw e; // step 7
|
||||
}
|
||||
var completionRecord = completionThunk(); // if innerResult worked, then throw if the completion does
|
||||
completionThunk = null; // ensure it's not called twice.
|
||||
|
||||
if (Type(innerResult) !== 'Object') {
|
||||
throw new $TypeError('iterator .return must return an object');
|
||||
}
|
||||
|
||||
return completionRecord;
|
||||
};
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var Call = require('./Call');
|
||||
var Type = require('./Type');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
// https://262.ecma-international.org/14.0/#sec-iteratornext
|
||||
|
||||
module.exports = function IteratorNext(iteratorRecord) {
|
||||
if (!isIteratorRecord(iteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
|
||||
}
|
||||
|
||||
var result;
|
||||
if (arguments.length < 2) { // step 1
|
||||
result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]']); // step 1.a
|
||||
} else { // step 2
|
||||
result = Call(iteratorRecord['[[NextMethod]]'], iteratorRecord['[[Iterator]]'], [arguments[1]]); // step 2.a
|
||||
}
|
||||
|
||||
if (Type(result) !== 'Object') {
|
||||
throw new $TypeError('iterator next must return an object'); // step 3
|
||||
}
|
||||
return result; // step 4
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var IteratorComplete = require('./IteratorComplete');
|
||||
var IteratorNext = require('./IteratorNext');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
// https://262.ecma-international.org/14.0/#sec-iteratorstep
|
||||
|
||||
module.exports = function IteratorStep(iteratorRecord) {
|
||||
if (!isIteratorRecord(iteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
|
||||
}
|
||||
|
||||
var result = IteratorNext(iteratorRecord); // step 1
|
||||
var done = IteratorComplete(result); // step 2
|
||||
return done === true ? false : result; // steps 3-4
|
||||
};
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
var $TypeError = require('es-errors/type');
|
||||
|
||||
var callBound = require('call-bind/callBound');
|
||||
|
||||
var $arrayPush = callBound('Array.prototype.push');
|
||||
|
||||
var IteratorStep = require('./IteratorStep');
|
||||
var IteratorValue = require('./IteratorValue');
|
||||
|
||||
var isIteratorRecord = require('../helpers/records/iterator-record-2023');
|
||||
|
||||
// https://262.ecma-international.org/14.0/#sec-iteratortolist
|
||||
|
||||
module.exports = function IteratorToList(iteratorRecord) {
|
||||
if (!isIteratorRecord(iteratorRecord)) {
|
||||
throw new $TypeError('Assertion failed: `iteratorRecord` must be an Iterator Record'); // step 1
|
||||
}
|
||||
|
||||
var values = []; // step 1
|
||||
var next = true; // step 2
|
||||
while (next) { // step 3
|
||||
next = IteratorStep(iteratorRecord); // step 3.a
|
||||
if (next) {
|
||||
var nextValue = IteratorValue(next); // step 3.b.i
|
||||
$arrayPush(values, nextValue); // step 3.b.ii
|
||||
}
|
||||
}
|
||||
return values; // step 4
|
||||
};
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
var GetIntrinsic = require('get-intrinsic');
|
||||
|
||||
var $TypeError = require('es-errors/type');
|
||||
var $fromCharCode = GetIntrinsic('%String.fromCharCode%');
|
||||
|
||||
var isLeadingSurrogate = require('../helpers/isLeadingSurrogate');
|
||||
var isTrailingSurrogate = require('../helpers/isTrailingSurrogate');
|
||||
|
||||
// https://262.ecma-international.org/12.0/#sec-utf16decodesurrogatepair
|
||||
|
||||
module.exports = function UTF16SurrogatePairToCodePoint(lead, trail) {
|
||||
if (!isLeadingSurrogate(lead) || !isTrailingSurrogate(trail)) {
|
||||
throw new $TypeError('Assertion failed: `lead` must be a leading surrogate char code, and `trail` must be a trailing surrogate char code');
|
||||
}
|
||||
// var cp = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
|
||||
return $fromCharCode(lead) + $fromCharCode(trail);
|
||||
};
|
||||
Reference in New Issue
Block a user