implementation.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. 'use strict';
  2. var $TypeError = require('es-errors/type');
  3. var AdvanceStringIndex = require('es-abstract/2024/AdvanceStringIndex');
  4. var Call = require('es-abstract/2024/Call');
  5. var CompletionRecord = require('es-abstract/2024/CompletionRecord');
  6. var CreateIteratorFromClosure = require('../aos/CreateIteratorFromClosure');
  7. var GetIteratorDirect = require('../aos/GetIteratorDirect');
  8. var GetMethod = require('es-abstract/2024/GetMethod');
  9. var IsArray = require('es-abstract/2024/IsArray');
  10. var IteratorCloseAll = require('../aos/IteratorCloseAll');
  11. var IteratorStepValue = require('es-abstract/2024/IteratorStepValue');
  12. var Type = require('es-abstract/2024/Type');
  13. var forEach = require('es-abstract/helpers/forEach');
  14. var getIteratorMethod = require('es-abstract/helpers/getIteratorMethod');
  15. var iterHelperProto = require('../IteratorHelperPrototype');
  16. var SLOT = require('internal-slot');
  17. module.exports = function concat() {
  18. if (this instanceof concat) {
  19. throw new $TypeError('`Iterator.concat` is not a constructor');
  20. }
  21. var iterables = []; // step 1
  22. forEach(arguments, function (item) { // step 2
  23. if (Type(item) !== 'Object') {
  24. throw new $TypeError('`Iterator.concat` requires all arguments to be objects'); // step 2.1
  25. }
  26. // var method = GetMethod(item, Symbol.iterator); // step 2.2
  27. var method = getIteratorMethod(
  28. {
  29. AdvanceStringIndex: AdvanceStringIndex,
  30. GetMethod: GetMethod,
  31. IsArray: IsArray
  32. },
  33. item
  34. );
  35. if (typeof method === 'undefined') {
  36. throw new $TypeError('`Iterator.concat` requires all arguments to be iterable'); // step 2.3
  37. }
  38. iterables[iterables.length] = { '[[OpenMethod]]': method, '[[Iterable]]': item }; // step 2.4
  39. });
  40. var sentinel = {};
  41. var iterablesIndex = 0;
  42. var iteratorRecord;
  43. var innerAlive = false;
  44. var closure = function () { // step 3
  45. if (iterablesIndex >= iterables.length) {
  46. return sentinel;
  47. }
  48. var iterable = iterables[iterablesIndex]; // step 3.a
  49. if (!innerAlive) {
  50. var iter = Call(iterable['[[OpenMethod]]'], iterable['[[Iterable]]']); // step 3.a.i
  51. if (Type(iter) !== 'Object') {
  52. throw new $TypeError('`Iterator.concat` iterator method did not return an object'); // step 3.a.ii
  53. }
  54. iteratorRecord = GetIteratorDirect(iter); // step 3.a.iii
  55. innerAlive = true; // step 3.a.iv
  56. }
  57. if (innerAlive) { // step 3.a.v
  58. var innerValue = IteratorStepValue(iteratorRecord); // step 3.a.v.1
  59. if (iteratorRecord['[[Done]]']) { // step 3.a.v.2
  60. innerAlive = false; // step 3.a.v.2.a
  61. } else { // step 3.a.v.3
  62. // 1. Let completion be Completion(Yield(innerValue)).
  63. return innerValue; // step 3.a.v.3.a
  64. }
  65. }
  66. iterablesIndex += 1;
  67. return closure();
  68. };
  69. var closeIfAbrupt = function (abruptCompletion) {
  70. if (!(abruptCompletion instanceof CompletionRecord)) {
  71. throw new $TypeError('`abruptCompletion` must be a Completion Record');
  72. }
  73. iterablesIndex = iterables.length;
  74. innerAlive = false;
  75. if (iteratorRecord) {
  76. IteratorCloseAll(
  77. [iteratorRecord],
  78. abruptCompletion
  79. );
  80. }
  81. };
  82. SLOT.set(closure, '[[Sentinel]]', sentinel); // for the userland implementation
  83. SLOT.set(closure, '[[CloseIfAbrupt]]', closeIfAbrupt); // for the userland implementation
  84. var gen = CreateIteratorFromClosure(closure, 'Iterator Helper', iterHelperProto, ['[[UnderlyingIterators]]']); // step 5
  85. SLOT.set(gen, '[[UnderlyingIterators]]', []); // step 6
  86. return gen; // step 7
  87. };