You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.4 KiB

2 years ago
'use strict';
var InternalStateModule = require('../internals/internal-state');
var createIteratorConstructor = require('../internals/create-iterator-constructor');
var isObject = require('../internals/is-object');
var defineProperties = require('../internals/object-define-properties').f;
var DESCRIPTORS = require('../internals/descriptors');
var INCORRECT_RANGE = 'Incorrect Number.range arguments';
var NUMERIC_RANGE_ITERATOR = 'NumericRangeIterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(NUMERIC_RANGE_ITERATOR);
var $RangeError = RangeError;
var $TypeError = TypeError;
var $RangeIterator = createIteratorConstructor(function NumericRangeIterator(start, end, option, type, zero, one) {
if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) {
throw new $TypeError(INCORRECT_RANGE);
}
if (start === Infinity || start === -Infinity) {
throw new $RangeError(INCORRECT_RANGE);
}
var ifIncrease = end > start;
var inclusiveEnd = false;
var step;
if (option === undefined) {
step = undefined;
} else if (isObject(option)) {
step = option.step;
inclusiveEnd = !!option.inclusive;
} else if (typeof option == type) {
step = option;
} else {
throw new $TypeError(INCORRECT_RANGE);
}
if (step == null) {
step = ifIncrease ? one : -one;
}
if (typeof step != type) {
throw new $TypeError(INCORRECT_RANGE);
}
if (step === Infinity || step === -Infinity || (step === zero && start !== end)) {
throw new $RangeError(INCORRECT_RANGE);
}
// eslint-disable-next-line no-self-compare -- NaN check
var hitsEnd = start != start || end != end || step != step || (end > start) !== (step > zero);
setInternalState(this, {
type: NUMERIC_RANGE_ITERATOR,
start: start,
end: end,
step: step,
inclusiveEnd: inclusiveEnd,
hitsEnd: hitsEnd,
currentCount: zero,
zero: zero
});
if (!DESCRIPTORS) {
this.start = start;
this.end = end;
this.step = step;
this.inclusive = inclusiveEnd;
}
}, NUMERIC_RANGE_ITERATOR, function next() {
var state = getInternalState(this);
if (state.hitsEnd) return { value: undefined, done: true };
var start = state.start;
var end = state.end;
var step = state.step;
var currentYieldingValue = start + (step * state.currentCount++);
if (currentYieldingValue === end) state.hitsEnd = true;
var inclusiveEnd = state.inclusiveEnd;
var endCondition;
if (end > start) {
endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end;
} else {
endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue;
}
if (endCondition) {
return { value: undefined, done: state.hitsEnd = true };
} return { value: currentYieldingValue, done: false };
});
var getter = function (fn) {
return { get: fn, set: function () { /* empty */ }, configurable: true, enumerable: false };
};
if (DESCRIPTORS) {
defineProperties($RangeIterator.prototype, {
start: getter(function () {
return getInternalState(this).start;
}),
end: getter(function () {
return getInternalState(this).end;
}),
inclusive: getter(function () {
return getInternalState(this).inclusiveEnd;
}),
step: getter(function () {
return getInternalState(this).step;
})
});
}
module.exports = $RangeIterator;