iterator-create-proxy.js 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. var done = state.done;
  41. state.done = true;
  42. if (IS_ITERATOR) {
  43. var returnMethod = getMethod(iterator, 'return');
  44. return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true);
  45. }
  46. if (done) return createIterResultObject(undefined, true);
  47. if (state.inner) try {
  48. iteratorClose(state.inner.iterator, NORMAL);
  49. } catch (error) {
  50. return iteratorClose(iterator, THROW, error);
  51. }
  52. if (state.openIters) try {
  53. iteratorCloseAll(state.openIters, NORMAL);
  54. } catch (error) {
  55. if (iterator) return iteratorClose(iterator, THROW, error);
  56. throw error;
  57. }
  58. if (iterator) iteratorClose(iterator, NORMAL);
  59. return createIterResultObject(undefined, true);
  60. }
  61. });
  62. };
  63. var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true);
  64. var IteratorHelperPrototype = createIteratorProxyPrototype(false);
  65. createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper');
  66. module.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) {
  67. var IteratorProxy = function Iterator(record, state) {
  68. if (state) {
  69. state.iterator = record.iterator;
  70. state.next = record.next;
  71. } else state = record;
  72. state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER;
  73. state.returnHandlerResult = !!RETURN_HANDLER_RESULT;
  74. state.nextHandler = nextHandler;
  75. state.counter = 0;
  76. state.done = false;
  77. setInternalState(this, state);
  78. };
  79. IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype;
  80. return IteratorProxy;
  81. };