iterator-create-proxy.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 TO_STRING_TAG = wellKnownSymbol('toStringTag');
  13. var ITERATOR_HELPER = 'IteratorHelper';
  14. var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator';
  15. var setInternalState = InternalStateModule.set;
  16. var createIteratorProxyPrototype = function (IS_ITERATOR) {
  17. var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER);
  18. return defineBuiltIns(create(IteratorPrototype), {
  19. next: function next() {
  20. var state = getInternalState(this);
  21. // for simplification:
  22. // for `%WrapForValidIteratorPrototype%.next` or with `state.returnHandlerResult` our `nextHandler` returns `IterResultObject`
  23. // for `%IteratorHelperPrototype%.next` - just a value
  24. if (IS_ITERATOR) return state.nextHandler();
  25. if (state.done) return createIterResultObject(undefined, true);
  26. try {
  27. var result = state.nextHandler();
  28. return state.returnHandlerResult ? result : createIterResultObject(result, state.done);
  29. } catch (error) {
  30. state.done = true;
  31. throw error;
  32. }
  33. },
  34. 'return': function () {
  35. var state = getInternalState(this);
  36. var iterator = state.iterator;
  37. state.done = true;
  38. if (IS_ITERATOR) {
  39. var returnMethod = getMethod(iterator, 'return');
  40. return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true);
  41. }
  42. if (state.inner) try {
  43. iteratorClose(state.inner.iterator, 'normal');
  44. } catch (error) {
  45. return iteratorClose(iterator, 'throw', error);
  46. }
  47. if (iterator) iteratorClose(iterator, 'normal');
  48. return createIterResultObject(undefined, true);
  49. }
  50. });
  51. };
  52. var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true);
  53. var IteratorHelperPrototype = createIteratorProxyPrototype(false);
  54. createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper');
  55. module.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) {
  56. var IteratorProxy = function Iterator(record, state) {
  57. if (state) {
  58. state.iterator = record.iterator;
  59. state.next = record.next;
  60. } else state = record;
  61. state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER;
  62. state.returnHandlerResult = !!RETURN_HANDLER_RESULT;
  63. state.nextHandler = nextHandler;
  64. state.counter = 0;
  65. state.done = false;
  66. setInternalState(this, state);
  67. };
  68. IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype;
  69. return IteratorProxy;
  70. };