1'use strict';
2
3var regexpFlags = require('./_flags');
4
5var nativeExec = RegExp.prototype.exec;
6// This always refers to the native implementation, because the
7// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
8// which loads this file before patching the method.
9var nativeReplace = String.prototype.replace;
10
11var patchedExec = nativeExec;
12
13var LAST_INDEX = 'lastIndex';
14
15var UPDATES_LAST_INDEX_WRONG = (function () {
16  var re1 = /a/,
17      re2 = /b*/g;
18  nativeExec.call(re1, 'a');
19  nativeExec.call(re2, 'a');
20  return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
21})();
22
23// nonparticipating capturing group, copied from es5-shim's String#split patch.
24var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
25
26var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
27
28if (PATCH) {
29  patchedExec = function exec(str) {
30    var re = this;
31    var lastIndex, reCopy, match, i;
32
33    if (NPCG_INCLUDED) {
34      reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
35    }
36    if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];
37
38    match = nativeExec.call(re, str);
39
40    if (UPDATES_LAST_INDEX_WRONG && match) {
41      re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
42    }
43    if (NPCG_INCLUDED && match && match.length > 1) {
44      // Fix browsers whose `exec` methods don't consistently return `undefined`
45      // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
46      // eslint-disable-next-line no-loop-func
47      nativeReplace.call(match[0], reCopy, function () {
48        for (i = 1; i < arguments.length - 2; i++) {
49          if (arguments[i] === undefined) match[i] = undefined;
50        }
51      });
52    }
53
54    return match;
55  };
56}
57
58module.exports = patchedExec;
59