re2js 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  * re2js
3
3
  * RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
4
4
  *
5
- * @version v0.3.3
5
+ * @version v0.4.0
6
6
  * @author Alexey Vasiliev
7
7
  * @homepage https://github.com/le0pard/re2js#readme
8
8
  * @repository github:le0pard/re2js
@@ -423,6 +423,8 @@
423
423
  // equalsIgnoreCase performs case-insensitive equality comparison
424
424
  // on the given runes |r1| and |r2|, with special consideration
425
425
  // for the likely scenario where both runes are ASCII characters.
426
+ // If non-ASCII, Unicode case folding will be performed on |r1|
427
+ // to compare it to |r2|.
426
428
  // -1 is interpreted as the end-of-file mark.
427
429
  static equalsIgnoreCase(r1, r2) {
428
430
  // Runes already match, or one of them is EOF
@@ -681,9 +683,7 @@
681
683
  // example
682
684
  // Encoding[(Encoding['UTF_16'] = 0)] = 'UTF_16'
683
685
  // Encoding[(Encoding['UTF_8'] = 1)] = 'UTF_8'
684
- const createEnum = function () {
685
- let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
686
- let initNum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
686
+ const createEnum = (values = [], initNum = 0) => {
687
687
  const enumObject = {};
688
688
  for (let i = 0; i < values.length; i++) {
689
689
  const val = values[i];
@@ -818,8 +818,7 @@
818
818
  * An exception thrown by the parser if the pattern was invalid.
819
819
  */
820
820
  class RE2JSSyntaxException extends RE2JSException {
821
- constructor(error) {
822
- let input = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
821
+ constructor(error, input = null) {
823
822
  let message = `error parsing regexp: ${error}`;
824
823
  if (input) {
825
824
  message += `: \`${input}\``;
@@ -992,8 +991,7 @@
992
991
  * @param {string|number} [group=0]
993
992
  * @returns {string}
994
993
  */
995
- start() {
996
- let group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
994
+ start(group = 0) {
997
995
  if (typeof group === 'string') {
998
996
  const groupInt = this.namedGroups[group];
999
997
  if (!Number.isFinite(groupInt)) {
@@ -1011,8 +1009,7 @@
1011
1009
  * @param {string|number} [group=0]
1012
1010
  * @returns {string}
1013
1011
  */
1014
- end() {
1015
- let group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
1012
+ end(group = 0) {
1016
1013
  if (typeof group === 'string') {
1017
1014
  const groupInt = this.namedGroups[group];
1018
1015
  if (!Number.isFinite(groupInt)) {
@@ -1029,8 +1026,7 @@
1029
1026
  * @param {string|number} [group=0]
1030
1027
  * @returns {string}
1031
1028
  */
1032
- group() {
1033
- let group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
1029
+ group(group = 0) {
1034
1030
  if (typeof group === 'string') {
1035
1031
  const groupInt = this.namedGroups[group];
1036
1032
  if (!Number.isFinite(groupInt)) {
@@ -1110,8 +1106,7 @@
1110
1106
  * @returns {boolean} if it finds a match
1111
1107
  * @throws IndexOutOfBoundsException if start is not a valid input position
1112
1108
  */
1113
- find() {
1114
- let start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1109
+ find(start = null) {
1115
1110
  if (start !== null) {
1116
1111
  if (start < 0 || start > this.matcherInputLength) {
1117
1112
  throw new RE2JSGroupException(`start index out of bounds: ${start}`);
@@ -1194,8 +1189,7 @@
1194
1189
  * @throws IndexOutOfBoundsException if replacement refers to an invalid group
1195
1190
  * @private
1196
1191
  */
1197
- appendReplacement(replacement) {
1198
- let perlMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1192
+ appendReplacement(replacement, perlMode = false) {
1199
1193
  let res = '';
1200
1194
  const s = this.start();
1201
1195
  const e = this.end();
@@ -1379,8 +1373,7 @@
1379
1373
  * @returns {string} the input string with the matches replaced
1380
1374
  * @throws IndexOutOfBoundsException if replacement refers to an invalid group and perlMode is false
1381
1375
  */
1382
- replaceAll(replacement) {
1383
- let perlMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1376
+ replaceAll(replacement, perlMode = false) {
1384
1377
  return this.replace(replacement, true, perlMode);
1385
1378
  }
1386
1379
 
@@ -1393,8 +1386,7 @@
1393
1386
  * @returns {string} the input string with the first match replaced
1394
1387
  * @throws IndexOutOfBoundsException if replacement refers to an invalid group and perlMode is false
1395
1388
  */
1396
- replaceFirst(replacement) {
1397
- let perlMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1389
+ replaceFirst(replacement, perlMode = false) {
1398
1390
  return this.replace(replacement, false, perlMode);
1399
1391
  }
1400
1392
 
@@ -1406,9 +1398,7 @@
1406
1398
  * @returns {string}
1407
1399
  * @private
1408
1400
  */
1409
- replace(replacement) {
1410
- let all = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1411
- let perlMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1401
+ replace(replacement, all = true, perlMode = false) {
1412
1402
  let res = '';
1413
1403
  this.reset();
1414
1404
  while (this.find()) {
@@ -2004,6 +1994,10 @@
2004
1994
  // class.
2005
1995
  if (this.runes.length === 1) {
2006
1996
  const r0 = this.runes[0];
1997
+ // If this pattern is case-insensitive, apply Unicode case folding to compare the two runes.
1998
+ // Note that this may result in a case-folding loop when executed,
1999
+ // so attempt to reduce the chance of that occurring
2000
+ // by performing case folding on |r0| from the pattern rather than |r| from the input.
2007
2001
  if ((this.arg & RE2Flags.FOLD_CASE) !== 0) {
2008
2002
  return Unicode.equalsIgnoreCase(r0, r);
2009
2003
  }
@@ -2235,10 +2229,7 @@
2235
2229
  * @class
2236
2230
  */
2237
2231
  class Frag {
2238
- constructor() {
2239
- let i = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
2240
- let out = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
2241
- let nullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
2232
+ constructor(i = 0, out = 0, nullable = false) {
2242
2233
  this.i = i; // an instruction address (pc).
2243
2234
  this.out = out; // a patch list; see explanation in Prog.js
2244
2235
  this.nullable = nullable; // whether the fragment can match the empty string
@@ -2731,8 +2722,7 @@
2731
2722
  CharClass.qsortIntPair(array, i, right);
2732
2723
  }
2733
2724
  }
2734
- constructor() {
2735
- let r = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Utils.emptyInts();
2725
+ constructor(r = Utils.emptyInts()) {
2736
2726
  this.r = r; // inclusive ranges, pairs of [lo,hi]. r.length is even.
2737
2727
  this.len = r.length; // prefix of |r| that is defined. Even.
2738
2728
  }
@@ -3406,8 +3396,7 @@
3406
3396
  static concatRunes(x, y) {
3407
3397
  return [...x, ...y];
3408
3398
  }
3409
- constructor(wholeRegexp) {
3410
- let flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3399
+ constructor(wholeRegexp, flags = 0) {
3411
3400
  this.wholeRegexp = wholeRegexp;
3412
3401
  // Flags control the behavior of the parser and record information about
3413
3402
  // regexp context.
@@ -4149,21 +4138,22 @@
4149
4138
  // support all three as well. EcmaScript 4 uses only the Python form.
4150
4139
  //
4151
4140
  // In both the open source world (via Code Search) and the
4152
- // Google source tree, (?P<expr>name) is the dominant form,
4153
- // so that's the one we implement. One is enough.
4141
+ // Google source tree, (?P<name>expr) and (?<name>expr) are the
4142
+ // dominant forms of named captures and both are supported.
4154
4143
  const s = t.rest();
4155
- if (s.startsWith('(?P<')) {
4144
+ if (s.startsWith('(?P<') || s.startsWith('(?<')) {
4156
4145
  // Pull out name.
4146
+ const begin = s.charAt(2) === 'P' ? 4 : 3;
4157
4147
  const end = s.indexOf('>');
4158
4148
  if (end < 0) {
4159
4149
  throw new RE2JSSyntaxException(Parser.ERR_INVALID_NAMED_CAPTURE, s);
4160
4150
  }
4161
- const name = s.substring(4, end); // "name"
4151
+ const name = s.substring(begin, end); // "name"
4162
4152
  t.skipString(name);
4163
- t.skip(5); // "(?P<>"
4153
+ t.skip(begin + 1); // "(?P<>" or "(?<>"
4164
4154
  if (!Parser.isValidCaptureName(name)) {
4165
4155
  // "(?P<name>"
4166
- throw new RE2JSSyntaxException(Parser.ERR_INVALID_NAMED_CAPTURE, s.substring(0, end));
4156
+ throw new RE2JSSyntaxException(Parser.ERR_INVALID_NAMED_CAPTURE, s.substring(0, end + 1)); // "(?P<name>" or "(?<name>"
4167
4157
  }
4168
4158
  // Like ordinary capture, but named.
4169
4159
  const re = this.op(Regexp.Op.LEFT_PAREN);
@@ -4635,8 +4625,7 @@
4635
4625
  }
4636
4626
 
4637
4627
  // Frees all threads on the thread queue, returning them to the free pool.
4638
- freeQueue(queue) {
4639
- let from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
4628
+ freeQueue(queue, from = 0) {
4640
4629
  const numberOfThread = queue.size - from;
4641
4630
  const requiredPoolLength = this.poolSize + numberOfThread;
4642
4631
  if (this.pool.length < requiredPoolLength) {
@@ -4966,9 +4955,7 @@
4966
4955
  static match(pattern, s) {
4967
4956
  return RE2.compile(pattern).match(s);
4968
4957
  }
4969
- constructor(expr, prog) {
4970
- let numSubexp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
4971
- let longest = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
4958
+ constructor(expr, prog, numSubexp = 0, longest = 0) {
4972
4959
  this.expr = expr; // as passed to Compile
4973
4960
  this.prog = prog; // compiled program
4974
4961
  this.numSubexp = numSubexp;
@@ -5202,8 +5189,7 @@
5202
5189
  }
5203
5190
 
5204
5191
  // Find matches in input.
5205
- allMatches(input, n) {
5206
- let deliverFun = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : v => v;
5192
+ allMatches(input, n, deliverFun = v => v) {
5207
5193
  let result = [];
5208
5194
  const end = input.endPos();
5209
5195
  if (n < 0) {