iterator-create-proxy.js 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. 'use strict';
  2. var call = require('../internals/function-call');
  3. var create = require('../internals/object-create');
  4. var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
  5. var defineBuiltIns = require('../internals/define-built-ins');
  6. var wellKnownSymbol = require('../internals/well-known-symbol');
  7. var InternalStateModule = require('../internals/internal-state');
  8. var getMethod = require('../internals/get-method');
  9. var IteratorPrototype = require('../internals/iterators-core').IteratorPrototype;
  10. var createIterResultObject = require('../internals/create-iter-result-object');
  11. var iteratorClose = require('../internals/iterator-close');
  12. var iteratorCloseAll = require('../internals/iterator-close-all');
  13. var TO_STRING_TAG = wellKnownSymbol('toStringTag');
  14. var ITERATOR_HELPER = 'IteratorHelper';
  15. var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator';
  16. var NORMAL = 'normal';
  17. var THROW = 'throw';
  18. var setInternalState = InternalStateModule.set;
  19. var createIteratorProxyPrototype = function (IS_ITERATOR) {
  20. var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER);
  21. return defineBuiltIns(create(IteratorPrototype), {
  22. next: function next() {
  23. var state = getInternalState(this);
  24. // for simplification:
  25. // for `%WrapForValidIteratorPrototype%.next` or with `state.returnHandlerResult` our `nextHandler` returns `IterResultObject`
  26. // for `%IteratorHelperPrototype%.next` - just a value
  27. if (IS_ITERATOR) return state.nextHandler();
  28. if (state.done) return createIterResultObject(undefined, true);
  29. try {
  30. var result = state.nextHandler();
  31. return state.returnHandlerResult ? result : createIterResultObject(result, state.done);
  32. } catch (error) {
  33. state.done = true;
  34. throw error;
  35. }
  36. },
  37. 'return': function () {
  38. var state = getInternalState(this);
  39. var iterator = state.iterator;
  40. state.done = true;
  41. if (IS_ITERATOR) {
  42. var returnMethod = getMethod(iterator, 'return');
  43. return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true);
  44. }
  45. if (state.inner) try {
  46. iteratorClose(state.inner.iterator, NORMAL);
  47. } catch (error) {
  48. return iteratorClose(iterator, THROW, error);
  49. }
  50. if (state.openIters) try {
  51. iteratorCloseAll(state.openIters, NORMAL);
  52. } catch (error) {
  53. return iteratorClose(iterator, THROW, error);
  54. }
  55. if (iterator) iteratorClose(iterator, NORMAL);
  56. return createIterResultObject(undefined, true);
  57. }
  58. });
  59. };
  60. var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true);
  61. var IteratorHelperPrototype = createIteratorProxyPrototype(false);
  62. createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper');
  63. module.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) {
  64. var IteratorProxy = function Iterator(record, state) {
  65. if (state) {
  66. state.iterator = record.iterator;
  67. state.next = record.next;
  68. } else state = record;
  69. state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER;
  70. state.returnHandlerResult = !!RETURN_HANDLER_RESULT;
  71. state.nextHandler = nextHandler;
  72. state.counter = 0;
  73. state.done = false;
  74. setInternalState(this, state);
  75. };
  76. IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype;
  77. return IteratorProxy;
  78. };