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.
111 lines
3.6 KiB
111 lines
3.6 KiB
'use strict'; |
|
|
|
var GetIntrinsic = require('get-intrinsic'); |
|
var hasSymbols = require('has-symbols')(); |
|
|
|
var $TypeError = GetIntrinsic('%TypeError%'); |
|
var IteratorPrototype = GetIntrinsic('%IteratorPrototype%', true); |
|
var $defineProperty = GetIntrinsic('%Object.defineProperty%', true); |
|
|
|
var AdvanceStringIndex = require('./AdvanceStringIndex'); |
|
var CreateIterResultObject = require('./CreateIterResultObject'); |
|
var CreateMethodProperty = require('./CreateMethodProperty'); |
|
var Get = require('./Get'); |
|
var OrdinaryObjectCreate = require('./OrdinaryObjectCreate'); |
|
var RegExpExec = require('./RegExpExec'); |
|
var Set = require('./Set'); |
|
var ToLength = require('./ToLength'); |
|
var ToString = require('./ToString'); |
|
var Type = require('./Type'); |
|
|
|
var SLOT = require('internal-slot'); |
|
|
|
var RegExpStringIterator = function RegExpStringIterator(R, S, global, fullUnicode) { |
|
if (Type(S) !== 'String') { |
|
throw new $TypeError('`S` must be a string'); |
|
} |
|
if (Type(global) !== 'Boolean') { |
|
throw new $TypeError('`global` must be a boolean'); |
|
} |
|
if (Type(fullUnicode) !== 'Boolean') { |
|
throw new $TypeError('`fullUnicode` must be a boolean'); |
|
} |
|
SLOT.set(this, '[[IteratingRegExp]]', R); |
|
SLOT.set(this, '[[IteratedString]]', S); |
|
SLOT.set(this, '[[Global]]', global); |
|
SLOT.set(this, '[[Unicode]]', fullUnicode); |
|
SLOT.set(this, '[[Done]]', false); |
|
}; |
|
|
|
if (IteratorPrototype) { |
|
RegExpStringIterator.prototype = OrdinaryObjectCreate(IteratorPrototype); |
|
} |
|
|
|
var RegExpStringIteratorNext = function next() { |
|
var O = this; // eslint-disable-line no-invalid-this |
|
if (Type(O) !== 'Object') { |
|
throw new $TypeError('receiver must be an object'); |
|
} |
|
if ( |
|
!(O instanceof RegExpStringIterator) |
|
|| !SLOT.has(O, '[[IteratingRegExp]]') |
|
|| !SLOT.has(O, '[[IteratedString]]') |
|
|| !SLOT.has(O, '[[Global]]') |
|
|| !SLOT.has(O, '[[Unicode]]') |
|
|| !SLOT.has(O, '[[Done]]') |
|
) { |
|
throw new $TypeError('"this" value must be a RegExpStringIterator instance'); |
|
} |
|
if (SLOT.get(O, '[[Done]]')) { |
|
return CreateIterResultObject(undefined, true); |
|
} |
|
var R = SLOT.get(O, '[[IteratingRegExp]]'); |
|
var S = SLOT.get(O, '[[IteratedString]]'); |
|
var global = SLOT.get(O, '[[Global]]'); |
|
var fullUnicode = SLOT.get(O, '[[Unicode]]'); |
|
var match = RegExpExec(R, S); |
|
if (match === null) { |
|
SLOT.set(O, '[[Done]]', true); |
|
return CreateIterResultObject(undefined, true); |
|
} |
|
if (global) { |
|
var matchStr = ToString(Get(match, '0')); |
|
if (matchStr === '') { |
|
var thisIndex = ToLength(Get(R, 'lastIndex')); |
|
var nextIndex = AdvanceStringIndex(S, thisIndex, fullUnicode); |
|
Set(R, 'lastIndex', nextIndex, true); |
|
} |
|
return CreateIterResultObject(match, false); |
|
} |
|
SLOT.set(O, '[[Done]]', true); |
|
return CreateIterResultObject(match, false); |
|
}; |
|
CreateMethodProperty(RegExpStringIterator.prototype, 'next', RegExpStringIteratorNext); |
|
|
|
if (hasSymbols) { |
|
if (Symbol.toStringTag) { |
|
if ($defineProperty) { |
|
$defineProperty(RegExpStringIterator.prototype, Symbol.toStringTag, { |
|
configurable: true, |
|
enumerable: false, |
|
value: 'RegExp String Iterator', |
|
writable: false |
|
}); |
|
} else { |
|
RegExpStringIterator.prototype[Symbol.toStringTag] = 'RegExp String Iterator'; |
|
} |
|
} |
|
|
|
if (Symbol.iterator && typeof RegExpStringIterator.prototype[Symbol.iterator] !== 'function') { |
|
var iteratorFn = function SymbolIterator() { |
|
return this; |
|
}; |
|
CreateMethodProperty(RegExpStringIterator.prototype, Symbol.iterator, iteratorFn); |
|
} |
|
} |
|
|
|
// https://262.ecma-international.org/11.0/#sec-createregexpstringiterator |
|
module.exports = function CreateRegExpStringIterator(R, S, global, fullUnicode) { |
|
// assert R.global === global && R.unicode === fullUnicode? |
|
return new RegExpStringIterator(R, S, global, fullUnicode); |
|
};
|
|
|