mirror of
https://github.com/shivammathur/setup-php.git
synced 2025-07-25 08:09:08 +07:00
Improve code quality and write tests
This commit is contained in:
16
node_modules/regexp-tree/dist/bin/regexp-tree.js
generated
vendored
Normal file
16
node_modules/regexp-tree/dist/bin/regexp-tree.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function main() {
|
||||
console.info('\n =========================================================\n * CLI commands are moved to the \x1B[1mregexp-tree-cli\x1B[0m package *\n =========================================================\n\n \x1B[1mInstallation:\x1B[0m\n\n npm install -g regexp-tree-cli\n\n \x1B[1mUsage:\x1B[0m\n\n regexp-tree-cli --help\n ');
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
50
node_modules/regexp-tree/dist/compat-transpiler/index.js
generated
vendored
Normal file
50
node_modules/regexp-tree/dist/compat-transpiler/index.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var compatTransforms = require('./transforms');
|
||||
var _transform = require('../transform');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Translates a regexp in new syntax to equivalent regexp in old syntax.
|
||||
*
|
||||
* @param string|RegExp|AST - regexp
|
||||
* @param Array transformsWhitelist - names of the transforms to apply
|
||||
*/
|
||||
transform: function transform(regexp) {
|
||||
var transformsWhitelist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||||
|
||||
var transformToApply = transformsWhitelist.length > 0 ? transformsWhitelist : Object.keys(compatTransforms);
|
||||
|
||||
var result = void 0;
|
||||
|
||||
// Collect extra data per transform.
|
||||
var extra = {};
|
||||
|
||||
transformToApply.forEach(function (transformName) {
|
||||
|
||||
if (!compatTransforms.hasOwnProperty(transformName)) {
|
||||
throw new Error('Unknown compat-transform: ' + transformName + '. ' + 'Available transforms are: ' + Object.keys(compatTransforms).join(', '));
|
||||
}
|
||||
|
||||
var handler = compatTransforms[transformName];
|
||||
|
||||
result = _transform.transform(regexp, handler);
|
||||
regexp = result.getAST();
|
||||
|
||||
// Collect `extra` transform result.
|
||||
if (typeof handler.getExtra === 'function') {
|
||||
extra[transformName] = handler.getExtra();
|
||||
}
|
||||
});
|
||||
|
||||
// Set the final extras for all transforms.
|
||||
result.setExtra(extra);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
123
node_modules/regexp-tree/dist/compat-transpiler/runtime/index.js
generated
vendored
Normal file
123
node_modules/regexp-tree/dist/compat-transpiler/runtime/index.js
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The `RegExpTree` class provides runtime support for `compat-transpiler`
|
||||
* module from `regexp-tree`.
|
||||
*
|
||||
* E.g. it tracks names of the capturing groups, in order to access the
|
||||
* names on the matched result.
|
||||
*
|
||||
* It's a thin-wrapper on top of original regexp.
|
||||
*/
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var RegExpTree = function () {
|
||||
/**
|
||||
* Initializes a `RegExpTree` instance.
|
||||
*
|
||||
* @param RegExp - a regular expression
|
||||
*
|
||||
* @param Object state:
|
||||
*
|
||||
* An extra state which may store any related to transformation
|
||||
* data, for example, names of the groups.
|
||||
*
|
||||
* - flags - original flags
|
||||
* - groups - names of the groups, and their indices
|
||||
* - source - original source
|
||||
*/
|
||||
function RegExpTree(re, _ref) {
|
||||
var flags = _ref.flags,
|
||||
groups = _ref.groups,
|
||||
source = _ref.source;
|
||||
|
||||
_classCallCheck(this, RegExpTree);
|
||||
|
||||
this._re = re;
|
||||
this._groups = groups;
|
||||
|
||||
// Original props.
|
||||
this.flags = flags;
|
||||
this.source = source || re.source;
|
||||
this.dotAll = flags.includes('s');
|
||||
|
||||
// Inherited directly from `re`.
|
||||
this.global = re.global;
|
||||
this.ignoreCase = re.ignoreCase;
|
||||
this.multiline = re.multiline;
|
||||
this.sticky = re.sticky;
|
||||
this.unicode = re.unicode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Facade wrapper for RegExp `test` method.
|
||||
*/
|
||||
|
||||
|
||||
_createClass(RegExpTree, [{
|
||||
key: 'test',
|
||||
value: function test(string) {
|
||||
return this._re.test(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Facade wrapper for RegExp `compile` method.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'compile',
|
||||
value: function compile(string) {
|
||||
return this._re.compile(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Facade wrapper for RegExp `toString` method.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'toString',
|
||||
value: function toString() {
|
||||
if (!this._toStringResult) {
|
||||
this._toStringResult = '/' + this.source + '/' + this.flags;
|
||||
}
|
||||
return this._toStringResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Facade wrapper for RegExp `exec` method.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'exec',
|
||||
value: function exec(string) {
|
||||
var result = this._re.exec(string);
|
||||
|
||||
if (!this._groups || !result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.groups = {};
|
||||
|
||||
for (var group in this._groups) {
|
||||
var groupNumber = this._groups[group];
|
||||
result.groups[group] = result[groupNumber];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}]);
|
||||
|
||||
return RegExpTree;
|
||||
}();
|
||||
|
||||
module.exports = {
|
||||
RegExpTree: RegExpTree
|
||||
};
|
69
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-dotall-s-transform.js
generated
vendored
Normal file
69
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-dotall-s-transform.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to translate `/./s` to `/[\0-\uFFFF]/`.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
|
||||
// Whether `u` flag present. In which case we transform to
|
||||
// \u{10FFFF} instead of \uFFFF.
|
||||
_hasUFlag: false,
|
||||
|
||||
// Only run this plugin if we have `s` flag.
|
||||
shouldRun: function shouldRun(ast) {
|
||||
var shouldRun = ast.flags.includes('s');
|
||||
|
||||
if (!shouldRun) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Strip the `s` flag.
|
||||
ast.flags = ast.flags.replace('s', '');
|
||||
|
||||
// Whether we have also `u`.
|
||||
this._hasUFlag = ast.flags.includes('u');
|
||||
|
||||
return true;
|
||||
},
|
||||
Char: function Char(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.kind !== 'meta' || node.value !== '.') {
|
||||
return;
|
||||
}
|
||||
|
||||
var toValue = '\\uFFFF';
|
||||
var toSymbol = '\uFFFF';
|
||||
|
||||
if (this._hasUFlag) {
|
||||
toValue = '\\u{10FFFF}';
|
||||
toSymbol = '\uDBFF\uDFFF';
|
||||
}
|
||||
|
||||
path.replace({
|
||||
type: 'CharacterClass',
|
||||
expressions: [{
|
||||
type: 'ClassRange',
|
||||
from: {
|
||||
type: 'Char',
|
||||
value: '\\0',
|
||||
kind: 'decimal',
|
||||
symbol: '\0'
|
||||
},
|
||||
to: {
|
||||
type: 'Char',
|
||||
value: toValue,
|
||||
kind: 'unicode',
|
||||
symbol: toSymbol
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
};
|
59
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-named-capturing-groups-transform.js
generated
vendored
Normal file
59
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-named-capturing-groups-transform.js
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to translate `/(?<name>a)\k<name>/` to `/(a)\1/`.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// To track the names of the groups, and return them
|
||||
// in the transform result state.
|
||||
//
|
||||
// A map from name to number: {foo: 2, bar: 4}
|
||||
_groupNames: {},
|
||||
|
||||
/**
|
||||
* Initialises the trasnform.
|
||||
*/
|
||||
init: function init() {
|
||||
this._groupNames = {};
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Returns extra state, which eventually is returned to
|
||||
*/
|
||||
getExtra: function getExtra() {
|
||||
return this._groupNames;
|
||||
},
|
||||
Group: function Group(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (!node.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Record group name.
|
||||
this._groupNames[node.name] = node.number;
|
||||
|
||||
delete node.name;
|
||||
delete node.nameRaw;
|
||||
},
|
||||
Backreference: function Backreference(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.kind !== 'name') {
|
||||
return;
|
||||
}
|
||||
|
||||
node.kind = 'number';
|
||||
node.reference = node.number;
|
||||
delete node.referenceRaw;
|
||||
}
|
||||
};
|
23
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-x-flag-transform.js
generated
vendored
Normal file
23
node_modules/regexp-tree/dist/compat-transpiler/transforms/compat-x-flag-transform.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to remove `x` flag `/foo/x` to `/foo/`.
|
||||
*
|
||||
* Note: other features of `x` flags (whitespace, comments) are
|
||||
* already removed at parsing stage.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
RegExp: function RegExp(_ref) {
|
||||
var node = _ref.node;
|
||||
|
||||
if (node.flags.includes('x')) {
|
||||
node.flags = node.flags.replace('x', '');
|
||||
}
|
||||
}
|
||||
};
|
17
node_modules/regexp-tree/dist/compat-transpiler/transforms/index.js
generated
vendored
Normal file
17
node_modules/regexp-tree/dist/compat-transpiler/transforms/index.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
// "dotAll" `s` flag
|
||||
dotAll: require('./compat-dotall-s-transform'),
|
||||
|
||||
// Named capturing groups.
|
||||
namedCapturingGroups: require('./compat-named-capturing-groups-transform'),
|
||||
|
||||
// `x` flag
|
||||
xFlag: require('./compat-x-flag-transform')
|
||||
};
|
177
node_modules/regexp-tree/dist/generator/index.js
generated
vendored
Normal file
177
node_modules/regexp-tree/dist/generator/index.js
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Helper `gen` function calls node type handler.
|
||||
*/
|
||||
|
||||
function gen(node) {
|
||||
return node ? generator[node.type](node) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* AST handler.
|
||||
*/
|
||||
var generator = {
|
||||
RegExp: function RegExp(node) {
|
||||
return '/' + gen(node.body) + '/' + node.flags;
|
||||
},
|
||||
Alternative: function Alternative(node) {
|
||||
return (node.expressions || []).map(gen).join('');
|
||||
},
|
||||
Disjunction: function Disjunction(node) {
|
||||
return gen(node.left) + '|' + gen(node.right);
|
||||
},
|
||||
Group: function Group(node) {
|
||||
var expression = gen(node.expression);
|
||||
|
||||
if (node.capturing) {
|
||||
// A named group.
|
||||
if (node.name) {
|
||||
return '(?<' + (node.nameRaw || node.name) + '>' + expression + ')';
|
||||
}
|
||||
|
||||
return '(' + expression + ')';
|
||||
}
|
||||
|
||||
return '(?:' + expression + ')';
|
||||
},
|
||||
Backreference: function Backreference(node) {
|
||||
switch (node.kind) {
|
||||
case 'number':
|
||||
return '\\' + node.reference;
|
||||
case 'name':
|
||||
return '\\k<' + (node.referenceRaw || node.reference) + '>';
|
||||
default:
|
||||
throw new TypeError('Unknown Backreference kind: ' + node.kind);
|
||||
}
|
||||
},
|
||||
Assertion: function Assertion(node) {
|
||||
switch (node.kind) {
|
||||
case '^':
|
||||
case '$':
|
||||
case '\\b':
|
||||
case '\\B':
|
||||
return node.kind;
|
||||
|
||||
case 'Lookahead':
|
||||
{
|
||||
var assertion = gen(node.assertion);
|
||||
|
||||
if (node.negative) {
|
||||
return '(?!' + assertion + ')';
|
||||
}
|
||||
|
||||
return '(?=' + assertion + ')';
|
||||
}
|
||||
|
||||
case 'Lookbehind':
|
||||
{
|
||||
var _assertion = gen(node.assertion);
|
||||
|
||||
if (node.negative) {
|
||||
return '(?<!' + _assertion + ')';
|
||||
}
|
||||
|
||||
return '(?<=' + _assertion + ')';
|
||||
}
|
||||
|
||||
default:
|
||||
throw new TypeError('Unknown Assertion kind: ' + node.kind);
|
||||
}
|
||||
},
|
||||
CharacterClass: function CharacterClass(node) {
|
||||
var expressions = node.expressions.map(gen).join('');
|
||||
|
||||
if (node.negative) {
|
||||
return '[^' + expressions + ']';
|
||||
}
|
||||
|
||||
return '[' + expressions + ']';
|
||||
},
|
||||
ClassRange: function ClassRange(node) {
|
||||
return gen(node.from) + '-' + gen(node.to);
|
||||
},
|
||||
Repetition: function Repetition(node) {
|
||||
return '' + gen(node.expression) + gen(node.quantifier);
|
||||
},
|
||||
Quantifier: function Quantifier(node) {
|
||||
var quantifier = void 0;
|
||||
var greedy = node.greedy ? '' : '?';
|
||||
|
||||
switch (node.kind) {
|
||||
case '+':
|
||||
case '?':
|
||||
case '*':
|
||||
quantifier = node.kind;
|
||||
break;
|
||||
case 'Range':
|
||||
// Exact: {1}
|
||||
if (node.from === node.to) {
|
||||
quantifier = '{' + node.from + '}';
|
||||
}
|
||||
// Open: {1,}
|
||||
else if (!node.to) {
|
||||
quantifier = '{' + node.from + ',}';
|
||||
}
|
||||
// Closed: {1,3}
|
||||
else {
|
||||
quantifier = '{' + node.from + ',' + node.to + '}';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new TypeError('Unknown Quantifier kind: ' + node.kind);
|
||||
}
|
||||
|
||||
return '' + quantifier + greedy;
|
||||
},
|
||||
Char: function Char(node) {
|
||||
var value = node.value;
|
||||
|
||||
switch (node.kind) {
|
||||
case 'simple':
|
||||
{
|
||||
if (node.escaped) {
|
||||
return '\\' + value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
case 'hex':
|
||||
case 'unicode':
|
||||
case 'oct':
|
||||
case 'decimal':
|
||||
case 'control':
|
||||
case 'meta':
|
||||
return value;
|
||||
|
||||
default:
|
||||
throw new TypeError('Unknown Char kind: ' + node.kind);
|
||||
}
|
||||
},
|
||||
UnicodeProperty: function UnicodeProperty(node) {
|
||||
var escapeChar = node.negative ? 'P' : 'p';
|
||||
var namePart = void 0;
|
||||
|
||||
if (!node.shorthand && !node.binary) {
|
||||
namePart = node.name + '=';
|
||||
} else {
|
||||
namePart = '';
|
||||
}
|
||||
|
||||
return '\\' + escapeChar + '{' + namePart + node.value + '}';
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Generates a regexp string from an AST.
|
||||
*
|
||||
* @param Object ast - an AST node
|
||||
*/
|
||||
generate: gen
|
||||
};
|
412
node_modules/regexp-tree/dist/interpreter/finite-automaton/dfa/dfa-minimizer.js
generated
vendored
Normal file
412
node_modules/regexp-tree/dist/interpreter/finite-automaton/dfa/dfa-minimizer.js
generated
vendored
Normal file
@ -0,0 +1,412 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// DFA minization.
|
||||
|
||||
/**
|
||||
* Map from state to current set it goes.
|
||||
*/
|
||||
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
var currentTransitionMap = null;
|
||||
|
||||
/**
|
||||
* Takes a DFA, and returns a minimized version of it
|
||||
* compressing some states to groups (using standard, 0-, 1-,
|
||||
* 2-, ... N-equivalence algorithm).
|
||||
*/
|
||||
function minimize(dfa) {
|
||||
var table = dfa.getTransitionTable();
|
||||
var allStates = Object.keys(table);
|
||||
var alphabet = dfa.getAlphabet();
|
||||
var accepting = dfa.getAcceptingStateNumbers();
|
||||
|
||||
currentTransitionMap = {};
|
||||
|
||||
var nonAccepting = new Set();
|
||||
|
||||
allStates.forEach(function (state) {
|
||||
state = Number(state);
|
||||
var isAccepting = accepting.has(state);
|
||||
|
||||
if (isAccepting) {
|
||||
currentTransitionMap[state] = accepting;
|
||||
} else {
|
||||
nonAccepting.add(state);
|
||||
currentTransitionMap[state] = nonAccepting;
|
||||
}
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Step 1: build equivalent sets.
|
||||
|
||||
// All [1..N] equivalent sets.
|
||||
var all = [
|
||||
// 0-equivalent sets.
|
||||
[nonAccepting, accepting].filter(function (set) {
|
||||
return set.size > 0;
|
||||
})];
|
||||
|
||||
var current = void 0;
|
||||
var previous = void 0;
|
||||
|
||||
// Top of the stack is the current list of sets to analyze.
|
||||
current = all[all.length - 1];
|
||||
|
||||
// Previous set (to check whether we need to stop).
|
||||
previous = all[all.length - 2];
|
||||
|
||||
// Until we'll not have the same N and N-1 equivalent rows.
|
||||
|
||||
var _loop = function _loop() {
|
||||
var newTransitionMap = {};
|
||||
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = current[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var _set = _step3.value;
|
||||
|
||||
// Handled states for this set.
|
||||
var handledStates = {};
|
||||
|
||||
var _set2 = _toArray(_set),
|
||||
first = _set2[0],
|
||||
rest = _set2.slice(1);
|
||||
|
||||
handledStates[first] = new Set([first]);
|
||||
|
||||
// Have to compare each from the rest states with
|
||||
// the already handled states, and see if they are equivalent.
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
restSets: for (var _iterator4 = rest[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var state = _step4.value;
|
||||
var _iteratorNormalCompletion5 = true;
|
||||
var _didIteratorError5 = false;
|
||||
var _iteratorError5 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator5 = Object.keys(handledStates)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
||||
var handledState = _step5.value;
|
||||
|
||||
// This and some previously handled state are equivalent --
|
||||
// just append this state to the same set.
|
||||
if (areEquivalent(state, handledState, table, alphabet)) {
|
||||
handledStates[handledState].add(state);
|
||||
handledStates[state] = handledStates[handledState];
|
||||
continue restSets;
|
||||
}
|
||||
}
|
||||
// Else, this state is not equivalent to any of the
|
||||
// handled states -- allocate a new set for it.
|
||||
} catch (err) {
|
||||
_didIteratorError5 = true;
|
||||
_iteratorError5 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
||||
_iterator5.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError5) {
|
||||
throw _iteratorError5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handledStates[state] = new Set([state]);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add these handled states to all states map.
|
||||
|
||||
|
||||
Object.assign(newTransitionMap, handledStates);
|
||||
}
|
||||
|
||||
// Update current transition map for the handled row.
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTransitionMap = newTransitionMap;
|
||||
|
||||
var newSets = new Set(Object.keys(newTransitionMap).map(function (state) {
|
||||
return newTransitionMap[state];
|
||||
}));
|
||||
|
||||
all.push([].concat(_toConsumableArray(newSets)));
|
||||
|
||||
// Top of the stack is the current.
|
||||
current = all[all.length - 1];
|
||||
|
||||
// Previous set.
|
||||
previous = all[all.length - 2];
|
||||
};
|
||||
|
||||
while (!sameRow(current, previous)) {
|
||||
_loop();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Step 2: build minimized table from the equivalent sets.
|
||||
|
||||
// Remap state numbers from sets to index-based.
|
||||
var remaped = new Map();
|
||||
var idx = 1;
|
||||
current.forEach(function (set) {
|
||||
return remaped.set(set, idx++);
|
||||
});
|
||||
|
||||
// Build the minimized table from the calculated equivalent sets.
|
||||
var minimizedTable = {};
|
||||
|
||||
var minimizedAcceptingStates = new Set();
|
||||
|
||||
var updateAcceptingStates = function updateAcceptingStates(set, idx) {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = set[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var state = _step.value;
|
||||
|
||||
if (accepting.has(state)) {
|
||||
minimizedAcceptingStates.add(idx);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = remaped.entries()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var _ref = _step2.value;
|
||||
|
||||
var _ref2 = _slicedToArray(_ref, 2);
|
||||
|
||||
var set = _ref2[0];
|
||||
var _idx = _ref2[1];
|
||||
|
||||
minimizedTable[_idx] = {};
|
||||
var _iteratorNormalCompletion6 = true;
|
||||
var _didIteratorError6 = false;
|
||||
var _iteratorError6 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator6 = alphabet[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
|
||||
var symbol = _step6.value;
|
||||
|
||||
updateAcceptingStates(set, _idx);
|
||||
|
||||
// Determine original transition for this symbol from the set.
|
||||
var originalTransition = void 0;
|
||||
var _iteratorNormalCompletion7 = true;
|
||||
var _didIteratorError7 = false;
|
||||
var _iteratorError7 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator7 = set[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
|
||||
var originalState = _step7.value;
|
||||
|
||||
originalTransition = table[originalState][symbol];
|
||||
if (originalTransition) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError7 = true;
|
||||
_iteratorError7 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion7 && _iterator7.return) {
|
||||
_iterator7.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError7) {
|
||||
throw _iteratorError7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (originalTransition) {
|
||||
minimizedTable[_idx][symbol] = remaped.get(currentTransitionMap[originalTransition]);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError6 = true;
|
||||
_iteratorError6 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion6 && _iterator6.return) {
|
||||
_iterator6.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError6) {
|
||||
throw _iteratorError6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the table, and accepting states on the original DFA.
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dfa.setTransitionTable(minimizedTable);
|
||||
dfa.setAcceptingStateNumbers(minimizedAcceptingStates);
|
||||
|
||||
return dfa;
|
||||
}
|
||||
|
||||
function sameRow(r1, r2) {
|
||||
if (!r2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (r1.length !== r2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < r1.length; i++) {
|
||||
var s1 = r1[i];
|
||||
var s2 = r2[i];
|
||||
|
||||
if (s1.size !== s2.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([].concat(_toConsumableArray(s1)).sort().join(',') !== [].concat(_toConsumableArray(s2)).sort().join(',')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether two states are N-equivalent, i.e. whether they go
|
||||
* to the same set on a symbol.
|
||||
*/
|
||||
function areEquivalent(s1, s2, table, alphabet) {
|
||||
var _iteratorNormalCompletion8 = true;
|
||||
var _didIteratorError8 = false;
|
||||
var _iteratorError8 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator8 = alphabet[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
|
||||
var symbol = _step8.value;
|
||||
|
||||
if (!goToSameSet(s1, s2, table, symbol)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError8 = true;
|
||||
_iteratorError8 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion8 && _iterator8.return) {
|
||||
_iterator8.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError8) {
|
||||
throw _iteratorError8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether states go to the same set.
|
||||
*/
|
||||
function goToSameSet(s1, s2, table, symbol) {
|
||||
if (!currentTransitionMap[s1] || !currentTransitionMap[s2]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var originalTransitionS1 = table[s1][symbol];
|
||||
var originalTransitionS2 = table[s2][symbol];
|
||||
|
||||
// If no actual transition on this symbol, treat it as positive.
|
||||
if (!originalTransitionS1 && !originalTransitionS2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, check if they are in the same sets.
|
||||
return currentTransitionMap[s1].has(originalTransitionS1) && currentTransitionMap[s2].has(originalTransitionS2);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
minimize: minimize
|
||||
};
|
380
node_modules/regexp-tree/dist/interpreter/finite-automaton/dfa/dfa.js
generated
vendored
Normal file
380
node_modules/regexp-tree/dist/interpreter/finite-automaton/dfa/dfa.js
generated
vendored
Normal file
@ -0,0 +1,380 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var DFAMinimizer = require('./dfa-minimizer');
|
||||
|
||||
var _require = require('../special-symbols'),
|
||||
EPSILON_CLOSURE = _require.EPSILON_CLOSURE;
|
||||
|
||||
/**
|
||||
* DFA is build by converting from NFA (subset construction).
|
||||
*/
|
||||
|
||||
|
||||
var DFA = function () {
|
||||
function DFA(nfa) {
|
||||
_classCallCheck(this, DFA);
|
||||
|
||||
this._nfa = nfa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimizes DFA.
|
||||
*/
|
||||
|
||||
|
||||
_createClass(DFA, [{
|
||||
key: 'minimize',
|
||||
value: function minimize() {
|
||||
this.getTransitionTable();
|
||||
|
||||
this._originalAcceptingStateNumbers = this._acceptingStateNumbers;
|
||||
this._originalTransitionTable = this._transitionTable;
|
||||
|
||||
DFAMinimizer.minimize(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns alphabet for this DFA.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getAlphabet',
|
||||
value: function getAlphabet() {
|
||||
return this._nfa.getAlphabet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns accepting states.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getAcceptingStateNumbers',
|
||||
value: function getAcceptingStateNumbers() {
|
||||
if (!this._acceptingStateNumbers) {
|
||||
// Accepting states are determined during table construction.
|
||||
this.getTransitionTable();
|
||||
}
|
||||
|
||||
return this._acceptingStateNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns original accepting states.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getOriginaAcceptingStateNumbers',
|
||||
value: function getOriginaAcceptingStateNumbers() {
|
||||
if (!this._originalAcceptingStateNumbers) {
|
||||
// Accepting states are determined during table construction.
|
||||
this.getTransitionTable();
|
||||
}
|
||||
|
||||
return this._originalAcceptingStateNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transition table.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'setTransitionTable',
|
||||
value: function setTransitionTable(table) {
|
||||
this._transitionTable = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets accepting states.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'setAcceptingStateNumbers',
|
||||
value: function setAcceptingStateNumbers(stateNumbers) {
|
||||
this._acceptingStateNumbers = stateNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* DFA transition table is built from NFA table.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getTransitionTable',
|
||||
value: function getTransitionTable() {
|
||||
var _this = this;
|
||||
|
||||
if (this._transitionTable) {
|
||||
return this._transitionTable;
|
||||
}
|
||||
|
||||
// Calculate from NFA transition table.
|
||||
var nfaTable = this._nfa.getTransitionTable();
|
||||
var nfaStates = Object.keys(nfaTable);
|
||||
|
||||
this._acceptingStateNumbers = new Set();
|
||||
|
||||
// Start state of DFA is E(S[nfa])
|
||||
var startState = nfaTable[nfaStates[0]][EPSILON_CLOSURE];
|
||||
|
||||
// Init the worklist (states which should be in the DFA).
|
||||
var worklist = [startState];
|
||||
|
||||
var alphabet = this.getAlphabet();
|
||||
var nfaAcceptingStates = this._nfa.getAcceptingStateNumbers();
|
||||
|
||||
var dfaTable = {};
|
||||
|
||||
// Determine whether the combined DFA state is accepting.
|
||||
var updateAcceptingStates = function updateAcceptingStates(states) {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = nfaAcceptingStates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var nfaAcceptingState = _step.value;
|
||||
|
||||
// If any of the states from NFA is accepting, DFA's
|
||||
// state is accepting as well.
|
||||
if (states.indexOf(nfaAcceptingState) !== -1) {
|
||||
_this._acceptingStateNumbers.add(states.join(','));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
while (worklist.length > 0) {
|
||||
var states = worklist.shift();
|
||||
var dfaStateLabel = states.join(',');
|
||||
dfaTable[dfaStateLabel] = {};
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = alphabet[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var symbol = _step2.value;
|
||||
|
||||
var onSymbol = [];
|
||||
|
||||
// Determine whether the combined state is accepting.
|
||||
updateAcceptingStates(states);
|
||||
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = states[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var state = _step3.value;
|
||||
|
||||
var nfaStatesOnSymbol = nfaTable[state][symbol];
|
||||
if (!nfaStatesOnSymbol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = nfaStatesOnSymbol[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var nfaStateOnSymbol = _step4.value;
|
||||
|
||||
if (!nfaTable[nfaStateOnSymbol]) {
|
||||
continue;
|
||||
}
|
||||
onSymbol.push.apply(onSymbol, _toConsumableArray(nfaTable[nfaStateOnSymbol][EPSILON_CLOSURE]));
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dfaStatesOnSymbolSet = new Set(onSymbol);
|
||||
var dfaStatesOnSymbol = [].concat(_toConsumableArray(dfaStatesOnSymbolSet));
|
||||
|
||||
if (dfaStatesOnSymbol.length > 0) {
|
||||
var dfaOnSymbolStr = dfaStatesOnSymbol.join(',');
|
||||
|
||||
dfaTable[dfaStateLabel][symbol] = dfaOnSymbolStr;
|
||||
|
||||
if (!dfaTable.hasOwnProperty(dfaOnSymbolStr)) {
|
||||
worklist.unshift(dfaStatesOnSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this._transitionTable = this._remapStateNumbers(dfaTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remaps state numbers in the resulting table:
|
||||
* combined states '1,2,3' -> 1, '3,4' -> 2, etc.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: '_remapStateNumbers',
|
||||
value: function _remapStateNumbers(calculatedDFATable) {
|
||||
var newStatesMap = {};
|
||||
|
||||
this._originalTransitionTable = calculatedDFATable;
|
||||
var transitionTable = {};
|
||||
|
||||
Object.keys(calculatedDFATable).forEach(function (originalNumber, newNumber) {
|
||||
newStatesMap[originalNumber] = newNumber + 1;
|
||||
});
|
||||
|
||||
for (var originalNumber in calculatedDFATable) {
|
||||
var originalRow = calculatedDFATable[originalNumber];
|
||||
var row = {};
|
||||
|
||||
for (var symbol in originalRow) {
|
||||
row[symbol] = newStatesMap[originalRow[symbol]];
|
||||
}
|
||||
|
||||
transitionTable[newStatesMap[originalNumber]] = row;
|
||||
}
|
||||
|
||||
// Remap accepting states.
|
||||
this._originalAcceptingStateNumbers = this._acceptingStateNumbers;
|
||||
this._acceptingStateNumbers = new Set();
|
||||
|
||||
var _iteratorNormalCompletion5 = true;
|
||||
var _didIteratorError5 = false;
|
||||
var _iteratorError5 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator5 = this._originalAcceptingStateNumbers[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
||||
var _originalNumber = _step5.value;
|
||||
|
||||
this._acceptingStateNumbers.add(newStatesMap[_originalNumber]);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError5 = true;
|
||||
_iteratorError5 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
||||
_iterator5.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError5) {
|
||||
throw _iteratorError5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return transitionTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns original DFA table, where state numbers
|
||||
* are combined numbers from NFA.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getOriginalTransitionTable',
|
||||
value: function getOriginalTransitionTable() {
|
||||
if (!this._originalTransitionTable) {
|
||||
// Original table is determined during table construction.
|
||||
this.getTransitionTable();
|
||||
}
|
||||
return this._originalTransitionTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this DFA accepts a string.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'matches',
|
||||
value: function matches(string) {
|
||||
var state = 1;
|
||||
var i = 0;
|
||||
var table = this.getTransitionTable();
|
||||
|
||||
while (string[i]) {
|
||||
state = table[state][string[i++]];
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.getAcceptingStateNumbers().has(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}]);
|
||||
|
||||
return DFA;
|
||||
}();
|
||||
|
||||
module.exports = DFA;
|
59
node_modules/regexp-tree/dist/interpreter/finite-automaton/index.js
generated
vendored
Normal file
59
node_modules/regexp-tree/dist/interpreter/finite-automaton/index.js
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var NFA = require('./nfa/nfa');
|
||||
var DFA = require('./dfa/dfa');
|
||||
|
||||
var nfaFromRegExp = require('./nfa/nfa-from-regexp');
|
||||
var builders = require('./nfa/builders');
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Export NFA and DFA classes.
|
||||
*/
|
||||
NFA: NFA,
|
||||
DFA: DFA,
|
||||
|
||||
/**
|
||||
* Expose builders.
|
||||
*/
|
||||
builders: builders,
|
||||
|
||||
/**
|
||||
* Builds an NFA for the passed regexp.
|
||||
*
|
||||
* @param string | AST | RegExp:
|
||||
*
|
||||
* a regular expression in different representations: a string,
|
||||
* a RegExp object, or an AST.
|
||||
*/
|
||||
toNFA: function toNFA(regexp) {
|
||||
return nfaFromRegExp.build(regexp);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Builds DFA for the passed regexp.
|
||||
*
|
||||
* @param string | AST | RegExp:
|
||||
*
|
||||
* a regular expression in different representations: a string,
|
||||
* a RegExp object, or an AST.
|
||||
*/
|
||||
toDFA: function toDFA(regexp) {
|
||||
return new DFA(this.toNFA(regexp));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if regexp accepts the string.
|
||||
*/
|
||||
test: function test(regexp, string) {
|
||||
return this.toDFA(regexp).matches(string);
|
||||
}
|
||||
};
|
227
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/builders.js
generated
vendored
Normal file
227
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/builders.js
generated
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var NFA = require('./nfa');
|
||||
var NFAState = require('./nfa-state');
|
||||
|
||||
var _require = require('../special-symbols'),
|
||||
EPSILON = _require.EPSILON;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Char NFA fragment: `c`
|
||||
|
||||
/**
|
||||
* Char factory.
|
||||
*
|
||||
* Creates an NFA fragment for a single char.
|
||||
*
|
||||
* [in] --c--> [out]
|
||||
*/
|
||||
|
||||
|
||||
function char(c) {
|
||||
var inState = new NFAState();
|
||||
var outState = new NFAState({
|
||||
accepting: true
|
||||
});
|
||||
|
||||
return new NFA(inState.addTransition(c, outState), outState);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Epsilon NFA fragment
|
||||
|
||||
/**
|
||||
* Epsilon factory.
|
||||
*
|
||||
* Creates an NFA fragment for ε (recognizes an empty string).
|
||||
*
|
||||
* [in] --ε--> [out]
|
||||
*/
|
||||
function e() {
|
||||
return char(EPSILON);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Alteration NFA fragment: `abc`
|
||||
|
||||
/**
|
||||
* Creates a connection between two NFA fragments on epsilon transition.
|
||||
*
|
||||
* [in-a] --a--> [out-a] --ε--> [in-b] --b--> [out-b]
|
||||
*/
|
||||
function altPair(first, second) {
|
||||
first.out.accepting = false;
|
||||
second.out.accepting = true;
|
||||
|
||||
first.out.addTransition(EPSILON, second.in);
|
||||
|
||||
return new NFA(first.in, second.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alteration factory.
|
||||
*
|
||||
* Creates a alteration NFA for (at least) two NFA-fragments.
|
||||
*/
|
||||
function alt(first) {
|
||||
for (var _len = arguments.length, fragments = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
fragments[_key - 1] = arguments[_key];
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = fragments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var fragment = _step.value;
|
||||
|
||||
first = altPair(first, fragment);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Disjunction NFA fragment: `a|b`
|
||||
|
||||
/**
|
||||
* Creates a disjunction choice between two fragments.
|
||||
*/
|
||||
function orPair(first, second) {
|
||||
var inState = new NFAState();
|
||||
var outState = new NFAState();
|
||||
|
||||
inState.addTransition(EPSILON, first.in);
|
||||
inState.addTransition(EPSILON, second.in);
|
||||
|
||||
outState.accepting = true;
|
||||
first.out.accepting = false;
|
||||
second.out.accepting = false;
|
||||
|
||||
first.out.addTransition(EPSILON, outState);
|
||||
second.out.addTransition(EPSILON, outState);
|
||||
|
||||
return new NFA(inState, outState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disjunction factory.
|
||||
*
|
||||
* Creates a disjunction NFA for (at least) two NFA-fragments.
|
||||
*/
|
||||
function or(first) {
|
||||
for (var _len2 = arguments.length, fragments = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
fragments[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = fragments[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var fragment = _step2.value;
|
||||
|
||||
first = orPair(first, fragment);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Kleene-closure
|
||||
|
||||
/**
|
||||
* Kleene star/closure.
|
||||
*
|
||||
* a*
|
||||
*/
|
||||
function repExplicit(fragment) {
|
||||
var inState = new NFAState();
|
||||
var outState = new NFAState({
|
||||
accepting: true
|
||||
});
|
||||
|
||||
// 0 or more.
|
||||
inState.addTransition(EPSILON, fragment.in);
|
||||
inState.addTransition(EPSILON, outState);
|
||||
|
||||
fragment.out.accepting = false;
|
||||
fragment.out.addTransition(EPSILON, outState);
|
||||
outState.addTransition(EPSILON, fragment.in);
|
||||
|
||||
return new NFA(inState, outState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized Kleene-star: just adds ε-transitions from
|
||||
* input to the output, and back.
|
||||
*/
|
||||
function rep(fragment) {
|
||||
fragment.in.addTransition(EPSILON, fragment.out);
|
||||
fragment.out.addTransition(EPSILON, fragment.in);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized Plus: just adds ε-transitions from
|
||||
* the output to the input.
|
||||
*/
|
||||
function plusRep(fragment) {
|
||||
fragment.out.addTransition(EPSILON, fragment.in);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized ? repetition: just adds ε-transitions from
|
||||
* the input to the output.
|
||||
*/
|
||||
function questionRep(fragment) {
|
||||
fragment.in.addTransition(EPSILON, fragment.out);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
alt: alt,
|
||||
char: char,
|
||||
e: e,
|
||||
or: or,
|
||||
rep: rep,
|
||||
repExplicit: repExplicit,
|
||||
plusRep: plusRep,
|
||||
questionRep: questionRep
|
||||
};
|
94
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa-from-regexp.js
generated
vendored
Normal file
94
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa-from-regexp.js
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
var parser = require('../../../parser');
|
||||
|
||||
var _require = require('./builders'),
|
||||
alt = _require.alt,
|
||||
char = _require.char,
|
||||
or = _require.or,
|
||||
rep = _require.rep,
|
||||
plusRep = _require.plusRep,
|
||||
questionRep = _require.questionRep;
|
||||
|
||||
/**
|
||||
* Helper `gen` function calls node type handler.
|
||||
*/
|
||||
|
||||
|
||||
function gen(node) {
|
||||
if (node && !generator[node.type]) {
|
||||
throw new Error(node.type + ' is not supported in NFA/DFA interpreter.');
|
||||
}
|
||||
|
||||
return node ? generator[node.type](node) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* AST handler.
|
||||
*/
|
||||
var generator = {
|
||||
RegExp: function RegExp(node) {
|
||||
if (node.flags !== '') {
|
||||
throw new Error('NFA/DFA: Flags are not supported yet.');
|
||||
}
|
||||
|
||||
return gen(node.body);
|
||||
},
|
||||
Alternative: function Alternative(node) {
|
||||
var fragments = (node.expressions || []).map(gen);
|
||||
return alt.apply(undefined, _toConsumableArray(fragments));
|
||||
},
|
||||
Disjunction: function Disjunction(node) {
|
||||
return or(gen(node.left), gen(node.right));
|
||||
},
|
||||
Repetition: function Repetition(node) {
|
||||
switch (node.quantifier.kind) {
|
||||
case '*':
|
||||
return rep(gen(node.expression));
|
||||
case '+':
|
||||
return plusRep(gen(node.expression));
|
||||
case '?':
|
||||
return questionRep(gen(node.expression));
|
||||
default:
|
||||
throw new Error('Unknown repeatition: ' + node.quantifier.kind + '.');
|
||||
}
|
||||
},
|
||||
Char: function Char(node) {
|
||||
if (node.kind !== 'simple') {
|
||||
throw new Error('NFA/DFA: Only simple chars are supported yet.');
|
||||
}
|
||||
|
||||
return char(node.value);
|
||||
},
|
||||
Group: function Group(node) {
|
||||
return gen(node.expression);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Builds an NFA from the passed regexp.
|
||||
*/
|
||||
build: function build(regexp) {
|
||||
var ast = regexp;
|
||||
|
||||
if (regexp instanceof RegExp) {
|
||||
regexp = '' + regexp;
|
||||
}
|
||||
|
||||
if (typeof regexp === 'string') {
|
||||
ast = parser.parse(regexp, {
|
||||
captureLocations: true
|
||||
});
|
||||
}
|
||||
|
||||
return gen(ast);
|
||||
}
|
||||
};
|
220
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa-state.js
generated
vendored
Normal file
220
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa-state.js
generated
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
var State = require('../state');
|
||||
|
||||
var _require = require('../special-symbols'),
|
||||
EPSILON = _require.EPSILON;
|
||||
|
||||
/**
|
||||
* NFA state.
|
||||
*
|
||||
* Allows nondeterministic transitions to several states on the
|
||||
* same symbol, and also epsilon-transitions.
|
||||
*/
|
||||
|
||||
|
||||
var NFAState = function (_State) {
|
||||
_inherits(NFAState, _State);
|
||||
|
||||
function NFAState() {
|
||||
_classCallCheck(this, NFAState);
|
||||
|
||||
return _possibleConstructorReturn(this, (NFAState.__proto__ || Object.getPrototypeOf(NFAState)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(NFAState, [{
|
||||
key: 'matches',
|
||||
|
||||
|
||||
/**
|
||||
* Whether this state matches a string.
|
||||
*
|
||||
* We maintain set of visited epsilon-states to avoid infinite loops
|
||||
* when an epsilon-transition goes eventually to itself.
|
||||
*
|
||||
* NOTE: this function is rather "educational", since we use DFA for strings
|
||||
* matching. DFA is built on top of NFA, and uses fast transition table.
|
||||
*/
|
||||
value: function matches(string) {
|
||||
var visited = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
|
||||
|
||||
// An epsilon-state has been visited, stop to avoid infinite loop.
|
||||
if (visited.has(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
visited.add(this);
|
||||
|
||||
// No symbols left..
|
||||
if (string.length === 0) {
|
||||
// .. and we're in the accepting state.
|
||||
if (this.accepting) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we can reach any accepting state from
|
||||
// on the epsilon transitions.
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = this.getTransitionsOnSymbol(EPSILON)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var nextState = _step.value;
|
||||
|
||||
if (nextState.matches('', visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Else, we get some symbols.
|
||||
var symbol = string[0];
|
||||
var rest = string.slice(1);
|
||||
|
||||
var symbolTransitions = this.getTransitionsOnSymbol(symbol);
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = symbolTransitions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var _nextState = _step2.value;
|
||||
|
||||
if (_nextState.matches(rest)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't match on symbol, check still epsilon-transitions
|
||||
// without consuming the symbol (i.e. continue from `string`, not `rest`).
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = this.getTransitionsOnSymbol(EPSILON)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var _nextState2 = _step3.value;
|
||||
|
||||
if (_nextState2.matches(string, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ε-closure for this state:
|
||||
* self + all states following ε-transitions.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getEpsilonClosure',
|
||||
value: function getEpsilonClosure() {
|
||||
var _this2 = this;
|
||||
|
||||
if (!this._epsilonClosure) {
|
||||
(function () {
|
||||
var epsilonTransitions = _this2.getTransitionsOnSymbol(EPSILON);
|
||||
var closure = _this2._epsilonClosure = new Set();
|
||||
closure.add(_this2);
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = epsilonTransitions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var nextState = _step4.value;
|
||||
|
||||
if (!closure.has(nextState)) {
|
||||
closure.add(nextState);
|
||||
var nextClosure = nextState.getEpsilonClosure();
|
||||
nextClosure.forEach(function (state) {
|
||||
return closure.add(state);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return this._epsilonClosure;
|
||||
}
|
||||
}]);
|
||||
|
||||
return NFAState;
|
||||
}(State);
|
||||
|
||||
module.exports = NFAState;
|
234
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa.js
generated
vendored
Normal file
234
node_modules/regexp-tree/dist/interpreter/finite-automaton/nfa/nfa.js
generated
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var _require = require('../special-symbols'),
|
||||
EPSILON = _require.EPSILON,
|
||||
EPSILON_CLOSURE = _require.EPSILON_CLOSURE;
|
||||
|
||||
/**
|
||||
* NFA fragment.
|
||||
*
|
||||
* NFA sub-fragments can be combined to a larger NFAs building
|
||||
* the resulting machine. Combining the fragments is done by patching
|
||||
* edges of the in- and out-states.
|
||||
*
|
||||
* 2-states implementation, `in`, and `out`. Eventually all transitions
|
||||
* go to the same `out`, which can further be connected via ε-transition
|
||||
* with other fragment.
|
||||
*/
|
||||
|
||||
|
||||
var NFA = function () {
|
||||
function NFA(inState, outState) {
|
||||
_classCallCheck(this, NFA);
|
||||
|
||||
this.in = inState;
|
||||
this.out = outState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to recognize a string based on this NFA fragment.
|
||||
*/
|
||||
|
||||
|
||||
_createClass(NFA, [{
|
||||
key: 'matches',
|
||||
value: function matches(string) {
|
||||
return this.in.matches(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an alphabet for this NFA.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getAlphabet',
|
||||
value: function getAlphabet() {
|
||||
if (!this._alphabet) {
|
||||
this._alphabet = new Set();
|
||||
var table = this.getTransitionTable();
|
||||
for (var state in table) {
|
||||
var transitions = table[state];
|
||||
for (var symbol in transitions) {
|
||||
if (symbol !== EPSILON_CLOSURE) {
|
||||
this._alphabet.add(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._alphabet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set of accepting states.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getAcceptingStates',
|
||||
value: function getAcceptingStates() {
|
||||
if (!this._acceptingStates) {
|
||||
// States are determined during table construction.
|
||||
this.getTransitionTable();
|
||||
}
|
||||
return this._acceptingStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns accepting state numbers.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getAcceptingStateNumbers',
|
||||
value: function getAcceptingStateNumbers() {
|
||||
if (!this._acceptingStateNumbers) {
|
||||
this._acceptingStateNumbers = new Set();
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = this.getAcceptingStates()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var acceptingState = _step.value;
|
||||
|
||||
this._acceptingStateNumbers.add(acceptingState.number);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._acceptingStateNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and returns transition table.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getTransitionTable',
|
||||
value: function getTransitionTable() {
|
||||
var _this = this;
|
||||
|
||||
if (!this._transitionTable) {
|
||||
this._transitionTable = {};
|
||||
this._acceptingStates = new Set();
|
||||
|
||||
var visited = new Set();
|
||||
var symbols = new Set();
|
||||
|
||||
var visitState = function visitState(state) {
|
||||
if (visited.has(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
visited.add(state);
|
||||
state.number = visited.size;
|
||||
_this._transitionTable[state.number] = {};
|
||||
|
||||
if (state.accepting) {
|
||||
_this._acceptingStates.add(state);
|
||||
}
|
||||
|
||||
var transitions = state.getTransitions();
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = transitions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var _ref = _step2.value;
|
||||
|
||||
var _ref2 = _slicedToArray(_ref, 2);
|
||||
|
||||
var symbol = _ref2[0];
|
||||
var symbolTransitions = _ref2[1];
|
||||
|
||||
var combinedState = [];
|
||||
symbols.add(symbol);
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = symbolTransitions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var nextState = _step3.value;
|
||||
|
||||
visitState(nextState);
|
||||
combinedState.push(nextState.number);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_this._transitionTable[state.number][symbol] = combinedState;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Traverse the graph starting from the `in`.
|
||||
visitState(this.in);
|
||||
|
||||
// Append epsilon-closure column.
|
||||
visited.forEach(function (state) {
|
||||
delete _this._transitionTable[state.number][EPSILON];
|
||||
_this._transitionTable[state.number][EPSILON_CLOSURE] = [].concat(_toConsumableArray(state.getEpsilonClosure())).map(function (s) {
|
||||
return s.number;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return this._transitionTable;
|
||||
}
|
||||
}]);
|
||||
|
||||
return NFA;
|
||||
}();
|
||||
|
||||
module.exports = NFA;
|
22
node_modules/regexp-tree/dist/interpreter/finite-automaton/special-symbols.js
generated
vendored
Normal file
22
node_modules/regexp-tree/dist/interpreter/finite-automaton/special-symbols.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Epsilon, the empty string.
|
||||
*/
|
||||
|
||||
var EPSILON = 'ε';
|
||||
|
||||
/**
|
||||
* Epsilon-closure.
|
||||
*/
|
||||
var EPSILON_CLOSURE = EPSILON + '*';
|
||||
|
||||
module.exports = {
|
||||
EPSILON: EPSILON,
|
||||
EPSILON_CLOSURE: EPSILON_CLOSURE
|
||||
};
|
81
node_modules/regexp-tree/dist/interpreter/finite-automaton/state.js
generated
vendored
Normal file
81
node_modules/regexp-tree/dist/interpreter/finite-automaton/state.js
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A generic FA State class (base for NFA and DFA).
|
||||
*
|
||||
* Maintains the transition map, and the flag whether
|
||||
* the state is accepting.
|
||||
*/
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var State = function () {
|
||||
function State() {
|
||||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
||||
_ref$accepting = _ref.accepting,
|
||||
accepting = _ref$accepting === undefined ? false : _ref$accepting;
|
||||
|
||||
_classCallCheck(this, State);
|
||||
|
||||
/**
|
||||
* Outgoing transitions to other states.
|
||||
*/
|
||||
this._transitions = new Map();
|
||||
|
||||
/**
|
||||
* Whether the state is accepting.
|
||||
*/
|
||||
this.accepting = accepting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns transitions for this state.
|
||||
*/
|
||||
|
||||
|
||||
_createClass(State, [{
|
||||
key: 'getTransitions',
|
||||
value: function getTransitions() {
|
||||
return this._transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transition on symbol.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'addTransition',
|
||||
value: function addTransition(symbol, toState) {
|
||||
this.getTransitionsOnSymbol(symbol).add(toState);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns transitions set on symbol.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getTransitionsOnSymbol',
|
||||
value: function getTransitionsOnSymbol(symbol) {
|
||||
var transitions = this._transitions.get(symbol);
|
||||
|
||||
if (!transitions) {
|
||||
transitions = new Set();
|
||||
this._transitions.set(symbol, transitions);
|
||||
}
|
||||
|
||||
return transitions;
|
||||
}
|
||||
}]);
|
||||
|
||||
return State;
|
||||
}();
|
||||
|
||||
module.exports = State;
|
27
node_modules/regexp-tree/dist/interpreter/finite-automaton/table-printer.js
generated
vendored
Normal file
27
node_modules/regexp-tree/dist/interpreter/finite-automaton/table-printer.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2015-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
var Table = require('cli-table3');
|
||||
|
||||
/**
|
||||
* Wrapper class over `cli-table3` with default options preset.
|
||||
*/
|
||||
|
||||
var TablePrinter = function TablePrinter(options) {
|
||||
_classCallCheck(this, TablePrinter);
|
||||
|
||||
return new Table(Object.assign({}, options, {
|
||||
style: {
|
||||
head: ['blue'],
|
||||
border: ['gray']
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
module.exports = TablePrinter;
|
35
node_modules/regexp-tree/dist/interpreter/finite-automaton/transforms/char-plus-to-star-transform.js
generated
vendored
Normal file
35
node_modules/regexp-tree/dist/interpreter/finite-automaton/transforms/char-plus-to-star-transform.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to replace `a+` to `aa*`, since NFA/DFA
|
||||
* handles Kleene-closure `a*`, and `a+` is just a syntactic sugar.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
Repetition: function Repetition(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
|
||||
if (node.quantifier.kind !== '+') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.type === 'Alternative') {
|
||||
path.getParent().insertChildAt(node.expression, path.index);
|
||||
} else {
|
||||
path.replace({
|
||||
type: 'Alternative',
|
||||
expressions: [node.expression, node]
|
||||
});
|
||||
}
|
||||
|
||||
// Change quantifier.
|
||||
node.quantifier.kind = '*';
|
||||
}
|
||||
};
|
10
node_modules/regexp-tree/dist/interpreter/finite-automaton/transforms/index.js
generated
vendored
Normal file
10
node_modules/regexp-tree/dist/interpreter/finite-automaton/transforms/index.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = [
|
||||
// a+ -> aa*
|
||||
require('./char-plus-to-star-transform')];
|
83
node_modules/regexp-tree/dist/optimizer/index.js
generated
vendored
Normal file
83
node_modules/regexp-tree/dist/optimizer/index.js
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var clone = require('../utils/clone');
|
||||
var parser = require('../parser');
|
||||
var transform = require('../transform');
|
||||
var optimizationTransforms = require('./transforms');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Optimizer transforms a regular expression into an optimized version,
|
||||
* replacing some sub-expressions with their idiomatic patterns.
|
||||
*
|
||||
* @param string | RegExp | AST - a regexp to optimize.
|
||||
*
|
||||
* @return TransformResult - an optimized regexp.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* /[a-zA-Z_0-9][a-zA-Z_0-9]*\e{1,}/
|
||||
*
|
||||
* Optimized to:
|
||||
*
|
||||
* /\w+e+/
|
||||
*/
|
||||
optimize: function optimize(regexp) {
|
||||
var transformsWhitelist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||||
|
||||
var transformToApply = transformsWhitelist.length > 0 ? transformsWhitelist : Object.keys(optimizationTransforms);
|
||||
|
||||
var ast = regexp;
|
||||
if (regexp instanceof RegExp) {
|
||||
regexp = '' + regexp;
|
||||
}
|
||||
|
||||
if (typeof regexp === 'string') {
|
||||
ast = parser.parse(regexp);
|
||||
}
|
||||
|
||||
var result = new transform.TransformResult(ast);
|
||||
var prevResultString = void 0;
|
||||
|
||||
do {
|
||||
// Get a copy of the current state here so
|
||||
// we can compare it with the state at the
|
||||
// end of the loop.
|
||||
prevResultString = result.toString();
|
||||
ast = clone(result.getAST());
|
||||
|
||||
transformToApply.forEach(function (transformName) {
|
||||
if (!optimizationTransforms.hasOwnProperty(transformName)) {
|
||||
throw new Error('Unknown optimization-transform: ' + transformName + '. ' + 'Available transforms are: ' + Object.keys(optimizationTransforms).join(', '));
|
||||
}
|
||||
|
||||
var transformer = optimizationTransforms[transformName];
|
||||
|
||||
// Don't override result just yet since we
|
||||
// might want to rollback the transform
|
||||
var newResult = transform.transform(ast, transformer);
|
||||
|
||||
if (newResult.toString() !== result.toString()) {
|
||||
if (newResult.toString().length <= result.toString().length) {
|
||||
result = newResult;
|
||||
} else {
|
||||
// Result has changed but is not shorter:
|
||||
// restore ast to its previous state.
|
||||
|
||||
ast = clone(result.getAST());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Keep running the optimizer until it stops
|
||||
// making any change to the regexp.
|
||||
} while (result.toString() !== prevResultString);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
110
node_modules/regexp-tree/dist/optimizer/transforms/char-case-insensitive-lowercase-transform.js
generated
vendored
Normal file
110
node_modules/regexp-tree/dist/optimizer/transforms/char-case-insensitive-lowercase-transform.js
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var UPPER_A_CP = 'A'.codePointAt(0);
|
||||
var UPPER_Z_CP = 'Z'.codePointAt(0);
|
||||
/**
|
||||
* Transforms case-insensitive regexp to lowercase
|
||||
*
|
||||
* /AaBbÏ/i -> /aabbï/i
|
||||
*/
|
||||
module.exports = {
|
||||
_AZClassRanges: null,
|
||||
_hasUFlag: false,
|
||||
init: function init(ast) {
|
||||
this._AZClassRanges = new Set();
|
||||
this._hasUFlag = ast.flags.includes('u');
|
||||
},
|
||||
shouldRun: function shouldRun(ast) {
|
||||
return ast.flags.includes('i');
|
||||
},
|
||||
Char: function Char(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
if (isNaN(node.codePoint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Engine support for case-insensitive matching without the u flag
|
||||
// for characters above \u1000 does not seem reliable.
|
||||
if (!this._hasUFlag && node.codePoint >= 0x1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.type === 'ClassRange') {
|
||||
// The only class ranges we handle must be inside A-Z.
|
||||
// After the `from` char is processed, the isAZClassRange test
|
||||
// will be false, so we use a Set to keep track of parents and
|
||||
// process the `to` char.
|
||||
if (!this._AZClassRanges.has(parent) && !isAZClassRange(parent)) {
|
||||
return;
|
||||
}
|
||||
this._AZClassRanges.add(parent);
|
||||
}
|
||||
|
||||
var lower = node.symbol.toLowerCase();
|
||||
if (lower !== node.symbol) {
|
||||
node.value = displaySymbolAsValue(lower, node);
|
||||
node.symbol = lower;
|
||||
node.codePoint = lower.codePointAt(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function isAZClassRange(classRange) {
|
||||
var from = classRange.from,
|
||||
to = classRange.to;
|
||||
// A-Z
|
||||
|
||||
return from.codePoint >= UPPER_A_CP && from.codePoint <= UPPER_Z_CP && to.codePoint >= UPPER_A_CP && to.codePoint <= UPPER_Z_CP;
|
||||
}
|
||||
|
||||
function displaySymbolAsValue(symbol, node) {
|
||||
var codePoint = symbol.codePointAt(0);
|
||||
if (node.kind === 'decimal') {
|
||||
return '\\' + codePoint;
|
||||
}
|
||||
if (node.kind === 'oct') {
|
||||
return '\\0' + codePoint.toString(8);
|
||||
}
|
||||
if (node.kind === 'hex') {
|
||||
return '\\x' + codePoint.toString(16);
|
||||
}
|
||||
if (node.kind === 'unicode') {
|
||||
if (node.isSurrogatePair) {
|
||||
var _getSurrogatePairFrom = getSurrogatePairFromCodePoint(codePoint),
|
||||
lead = _getSurrogatePairFrom.lead,
|
||||
trail = _getSurrogatePairFrom.trail;
|
||||
|
||||
return '\\u' + '0'.repeat(4 - lead.length) + lead + '\\u' + '0'.repeat(4 - trail.length) + trail;
|
||||
} else if (node.value.includes('{')) {
|
||||
return '\\u{' + codePoint.toString(16) + '}';
|
||||
} else {
|
||||
var code = codePoint.toString(16);
|
||||
return '\\u' + '0'.repeat(4 - code.length) + code;
|
||||
}
|
||||
}
|
||||
// simple
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a code point to a surrogate pair.
|
||||
* Conversion algorithm is taken from The Unicode Standard 3.0 Section 3.7
|
||||
* (https://www.unicode.org/versions/Unicode3.0.0/ch03.pdf)
|
||||
* @param {number} codePoint - Between 0x10000 and 0x10ffff
|
||||
* @returns {{lead: string, trail: string}}
|
||||
*/
|
||||
function getSurrogatePairFromCodePoint(codePoint) {
|
||||
var lead = Math.floor((codePoint - 0x10000) / 0x400) + 0xd800;
|
||||
var trail = (codePoint - 0x10000) % 0x400 + 0xdc00;
|
||||
return {
|
||||
lead: lead.toString(16),
|
||||
trail: trail.toString(16)
|
||||
};
|
||||
}
|
339
node_modules/regexp-tree/dist/optimizer/transforms/char-class-classranges-merge-transform.js
generated
vendored
Normal file
339
node_modules/regexp-tree/dist/optimizer/transforms/char-class-classranges-merge-transform.js
generated
vendored
Normal file
@ -0,0 +1,339 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to merge class ranges.
|
||||
*
|
||||
* [a-ec] -> [a-e]
|
||||
* [a-ec-e] -> [a-e]
|
||||
* [\w\da-f] -> [\w]
|
||||
* [abcdef] -> [a-f]
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
_hasIUFlags: false,
|
||||
init: function init(ast) {
|
||||
this._hasIUFlags = ast.flags.includes('i') && ast.flags.includes('u');
|
||||
},
|
||||
CharacterClass: function CharacterClass(path) {
|
||||
var node = path.node;
|
||||
|
||||
var expressions = node.expressions;
|
||||
|
||||
var metas = [];
|
||||
// Extract metas
|
||||
expressions.forEach(function (expression) {
|
||||
if (isMeta(expression)) {
|
||||
metas.push(expression.value);
|
||||
}
|
||||
});
|
||||
|
||||
expressions.sort(sortCharClass);
|
||||
|
||||
for (var i = 0; i < expressions.length; i++) {
|
||||
var expression = expressions[i];
|
||||
if (fitsInMetas(expression, metas, this._hasIUFlags) || combinesWithPrecedingClassRange(expression, expressions[i - 1]) || combinesWithFollowingClassRange(expression, expressions[i + 1])) {
|
||||
expressions.splice(i, 1);
|
||||
i--;
|
||||
} else {
|
||||
var nbMergedChars = charCombinesWithPrecedingChars(expression, i, expressions);
|
||||
expressions.splice(i - nbMergedChars + 1, nbMergedChars);
|
||||
i -= nbMergedChars;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts expressions in char class in the following order:
|
||||
* - meta chars, ordered alphabetically by value
|
||||
* - chars (except `control` kind) and class ranges, ordered alphabetically (`from` char is used for class ranges)
|
||||
* - if ambiguous, class range comes before char
|
||||
* - if ambiguous between two class ranges, orders alphabetically by `to` char
|
||||
* - control chars, ordered alphabetically by value
|
||||
* @param {Object} a - Left Char or ClassRange node
|
||||
* @param {Object} b - Right Char or ClassRange node
|
||||
* @returns {number}
|
||||
*/
|
||||
function sortCharClass(a, b) {
|
||||
var aValue = getSortValue(a);
|
||||
var bValue = getSortValue(b);
|
||||
|
||||
if (aValue === bValue) {
|
||||
// We want ClassRange before Char
|
||||
// [bb-d] -> [b-db]
|
||||
if (a.type === 'ClassRange' && b.type !== 'ClassRange') {
|
||||
return -1;
|
||||
}
|
||||
if (b.type === 'ClassRange' && a.type !== 'ClassRange') {
|
||||
return 1;
|
||||
}
|
||||
if (a.type === 'ClassRange' && b.type === 'ClassRange') {
|
||||
return getSortValue(a.to) - getSortValue(b.to);
|
||||
}
|
||||
if (isMeta(a) && isMeta(b) || isControl(a) && isControl(b)) {
|
||||
return a.value < b.value ? -1 : 1;
|
||||
}
|
||||
}
|
||||
return aValue - bValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @returns {number}
|
||||
*/
|
||||
function getSortValue(expression) {
|
||||
if (expression.type === 'Char') {
|
||||
if (expression.kind === 'control') {
|
||||
return Infinity;
|
||||
}
|
||||
if (expression.kind === 'meta' && isNaN(expression.codePoint)) {
|
||||
return -1;
|
||||
}
|
||||
return expression.codePoint;
|
||||
}
|
||||
// ClassRange
|
||||
return expression.from.codePoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a node is a meta char from the set \d\w\s\D\W\S
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {?string} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isMeta(expression) {
|
||||
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
|
||||
return expression.type === 'Char' && expression.kind === 'meta' && (value ? expression.value === value : /^\\[dws]$/i.test(expression.value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isControl(expression) {
|
||||
return expression.type === 'Char' && expression.kind === 'control';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {string[]} metas - Array of meta chars, e.g. ["\\w", "\\s"]
|
||||
* @param {boolean} hasIUFlags
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInMetas(expression, metas, hasIUFlags) {
|
||||
for (var i = 0; i < metas.length; i++) {
|
||||
if (fitsInMeta(expression, metas[i], hasIUFlags)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {string} meta - e.g. "\\w"
|
||||
* @param {boolean} hasIUFlags
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInMeta(expression, meta, hasIUFlags) {
|
||||
if (expression.type === 'ClassRange') {
|
||||
return fitsInMeta(expression.from, meta, hasIUFlags) && fitsInMeta(expression.to, meta, hasIUFlags);
|
||||
}
|
||||
|
||||
// Special cases:
|
||||
// \S contains \w and \d
|
||||
if (meta === '\\S' && (isMeta(expression, '\\w') || isMeta(expression, '\\d'))) {
|
||||
return true;
|
||||
}
|
||||
// \D contains \W and \s
|
||||
if (meta === '\\D' && (isMeta(expression, '\\W') || isMeta(expression, '\\s'))) {
|
||||
return true;
|
||||
}
|
||||
// \w contains \d
|
||||
if (meta === '\\w' && isMeta(expression, '\\d')) {
|
||||
return true;
|
||||
}
|
||||
// \W contains \s
|
||||
if (meta === '\\W' && isMeta(expression, '\\s')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expression.type !== 'Char' || isNaN(expression.codePoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (meta === '\\s') {
|
||||
return fitsInMetaS(expression);
|
||||
}
|
||||
if (meta === '\\S') {
|
||||
return !fitsInMetaS(expression);
|
||||
}
|
||||
if (meta === '\\d') {
|
||||
return fitsInMetaD(expression);
|
||||
}
|
||||
if (meta === '\\D') {
|
||||
return !fitsInMetaD(expression);
|
||||
}
|
||||
if (meta === '\\w') {
|
||||
return fitsInMetaW(expression, hasIUFlags);
|
||||
}
|
||||
if (meta === '\\W') {
|
||||
return !fitsInMetaW(expression, hasIUFlags);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char node with codePoint
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInMetaS(expression) {
|
||||
return expression.codePoint === 0x0009 || // \t
|
||||
expression.codePoint === 0x000a || // \n
|
||||
expression.codePoint === 0x000b || // \v
|
||||
expression.codePoint === 0x000c || // \f
|
||||
expression.codePoint === 0x000d || // \r
|
||||
expression.codePoint === 0x0020 || // space
|
||||
expression.codePoint === 0x00a0 || // nbsp
|
||||
expression.codePoint === 0x1680 || // part of Zs
|
||||
expression.codePoint >= 0x2000 && expression.codePoint <= 0x200a || // part of Zs
|
||||
expression.codePoint === 0x2028 || // line separator
|
||||
expression.codePoint === 0x2029 || // paragraph separator
|
||||
expression.codePoint === 0x202f || // part of Zs
|
||||
expression.codePoint === 0x205f || // part of Zs
|
||||
expression.codePoint === 0x3000 || // part of Zs
|
||||
expression.codePoint === 0xfeff; // zwnbsp
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char node with codePoint
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInMetaD(expression) {
|
||||
return expression.codePoint >= 0x30 && expression.codePoint <= 0x39; // 0-9
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char node with codePoint
|
||||
* @param {boolean} hasIUFlags
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInMetaW(expression, hasIUFlags) {
|
||||
return fitsInMetaD(expression) || expression.codePoint >= 0x41 && expression.codePoint <= 0x5a || // A-Z
|
||||
expression.codePoint >= 0x61 && expression.codePoint <= 0x7a || // a-z
|
||||
expression.value === '_' || hasIUFlags && (expression.codePoint === 0x017f || expression.codePoint === 0x212a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {Object} classRange - Char or ClassRange node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function combinesWithPrecedingClassRange(expression, classRange) {
|
||||
if (classRange && classRange.type === 'ClassRange') {
|
||||
|
||||
if (fitsInClassRange(expression, classRange)) {
|
||||
// [a-gc] -> [a-g]
|
||||
// [a-gc-e] -> [a-g]
|
||||
return true;
|
||||
} else if (
|
||||
// We only want \w chars or char codes to keep readability
|
||||
isMetaWCharOrCode(expression) && classRange.to.codePoint === expression.codePoint - 1) {
|
||||
// [a-de] -> [a-e]
|
||||
classRange.to = expression;
|
||||
return true;
|
||||
} else if (expression.type === 'ClassRange' && expression.from.codePoint <= classRange.to.codePoint + 1 && expression.to.codePoint >= classRange.from.codePoint - 1) {
|
||||
// [a-db-f] -> [a-f]
|
||||
// [b-fa-d] -> [a-f]
|
||||
// [a-cd-f] -> [a-f]
|
||||
if (expression.from.codePoint < classRange.from.codePoint) {
|
||||
classRange.from = expression.from;
|
||||
}
|
||||
if (expression.to.codePoint > classRange.to.codePoint) {
|
||||
classRange.to = expression.to;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {Object} classRange - Char or ClassRange node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function combinesWithFollowingClassRange(expression, classRange) {
|
||||
if (classRange && classRange.type === 'ClassRange') {
|
||||
// Considering the elements were ordered alphabetically,
|
||||
// there is only one case to handle
|
||||
// [ab-e] -> [a-e]
|
||||
if (
|
||||
// We only want \w chars or char codes to keep readability
|
||||
isMetaWCharOrCode(expression) && classRange.from.codePoint === expression.codePoint + 1) {
|
||||
classRange.from = expression;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {Object} classRange - ClassRange node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fitsInClassRange(expression, classRange) {
|
||||
if (expression.type === 'Char' && isNaN(expression.codePoint)) {
|
||||
return false;
|
||||
}
|
||||
if (expression.type === 'ClassRange') {
|
||||
return fitsInClassRange(expression.from, classRange) && fitsInClassRange(expression.to, classRange);
|
||||
}
|
||||
return expression.codePoint >= classRange.from.codePoint && expression.codePoint <= classRange.to.codePoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} expression - Char or ClassRange node
|
||||
* @param {Number} index
|
||||
* @param {Object[]} expressions - expressions in CharClass
|
||||
* @returns {number} - Number of characters combined with expression
|
||||
*/
|
||||
function charCombinesWithPrecedingChars(expression, index, expressions) {
|
||||
// We only want \w chars or char codes to keep readability
|
||||
if (!isMetaWCharOrCode(expression)) {
|
||||
return 0;
|
||||
}
|
||||
var nbMergedChars = 0;
|
||||
while (index > 0) {
|
||||
var currentExpression = expressions[index];
|
||||
var precedingExpresion = expressions[index - 1];
|
||||
if (isMetaWCharOrCode(precedingExpresion) && precedingExpresion.codePoint === currentExpression.codePoint - 1) {
|
||||
nbMergedChars++;
|
||||
index--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbMergedChars > 1) {
|
||||
expressions[index] = {
|
||||
type: 'ClassRange',
|
||||
from: expressions[index],
|
||||
to: expression
|
||||
};
|
||||
return nbMergedChars;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function isMetaWCharOrCode(expression) {
|
||||
return expression && expression.type === 'Char' && !isNaN(expression.codePoint) && (fitsInMetaW(expression, false) || expression.kind === 'unicode' || expression.kind === 'hex' || expression.kind === 'oct' || expression.kind === 'decimal');
|
||||
}
|
30
node_modules/regexp-tree/dist/optimizer/transforms/char-class-classranges-to-chars-transform.js
generated
vendored
Normal file
30
node_modules/regexp-tree/dist/optimizer/transforms/char-class-classranges-to-chars-transform.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to simplify character classes
|
||||
* spanning only one or two chars.
|
||||
*
|
||||
* [a-a] -> [a]
|
||||
* [a-b] -> [ab]
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
ClassRange: function ClassRange(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.from.codePoint === node.to.codePoint) {
|
||||
|
||||
path.replace(node.from);
|
||||
} else if (node.from.codePoint === node.to.codePoint - 1) {
|
||||
|
||||
path.getParent().insertChildAt(node.to, path.index + 1);
|
||||
path.replace(node.from);
|
||||
}
|
||||
}
|
||||
};
|
33
node_modules/regexp-tree/dist/optimizer/transforms/char-class-remove-duplicates-transform.js
generated
vendored
Normal file
33
node_modules/regexp-tree/dist/optimizer/transforms/char-class-remove-duplicates-transform.js
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to remove duplicates from character classes.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
CharacterClass: function CharacterClass(path) {
|
||||
var node = path.node;
|
||||
|
||||
var sources = {};
|
||||
|
||||
for (var i = 0; i < node.expressions.length; i++) {
|
||||
var childPath = path.getChild(i);
|
||||
var source = childPath.jsonEncode();
|
||||
|
||||
if (sources.hasOwnProperty(source)) {
|
||||
childPath.remove();
|
||||
|
||||
// Since we remove the current node.
|
||||
// TODO: make it simpler for users with a method.
|
||||
i--;
|
||||
}
|
||||
|
||||
sources[source] = true;
|
||||
}
|
||||
}
|
||||
};
|
211
node_modules/regexp-tree/dist/optimizer/transforms/char-class-to-meta-transform.js
generated
vendored
Normal file
211
node_modules/regexp-tree/dist/optimizer/transforms/char-class-to-meta-transform.js
generated
vendored
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to replace standard character classes with
|
||||
* their meta symbols equivalents.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
_hasIFlag: false,
|
||||
_hasUFlag: false,
|
||||
init: function init(ast) {
|
||||
this._hasIFlag = ast.flags.includes('i');
|
||||
this._hasUFlag = ast.flags.includes('u');
|
||||
},
|
||||
CharacterClass: function CharacterClass(path) {
|
||||
|
||||
// [0-9] -> \d
|
||||
rewriteNumberRanges(path);
|
||||
|
||||
// [a-zA-Z_0-9] -> \w
|
||||
rewriteWordRanges(path, this._hasIFlag, this._hasUFlag);
|
||||
|
||||
// [ \t\r\n\f] -> \s
|
||||
rewriteWhitespaceRanges(path);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrites number ranges: [0-9] -> \d
|
||||
*/
|
||||
function rewriteNumberRanges(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
node.expressions.forEach(function (expression, i) {
|
||||
if (isFullNumberRange(expression)) {
|
||||
path.getChild(i).replace({
|
||||
type: 'Char',
|
||||
value: '\\d',
|
||||
kind: 'meta'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites word ranges: [a-zA-Z_0-9] -> \w
|
||||
* Thus, the ranges may go in any order, and other symbols/ranges
|
||||
* are kept untouched, e.g. [a-z_\dA-Z$] -> [\w$]
|
||||
*/
|
||||
function rewriteWordRanges(path, hasIFlag, hasUFlag) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
var numberPath = null;
|
||||
var lowerCasePath = null;
|
||||
var upperCasePath = null;
|
||||
var underscorePath = null;
|
||||
var u017fPath = null;
|
||||
var u212aPath = null;
|
||||
|
||||
node.expressions.forEach(function (expression, i) {
|
||||
|
||||
// \d
|
||||
if (isMetaChar(expression, '\\d')) {
|
||||
numberPath = path.getChild(i);
|
||||
}
|
||||
|
||||
// a-z
|
||||
else if (isLowerCaseRange(expression)) {
|
||||
lowerCasePath = path.getChild(i);
|
||||
}
|
||||
|
||||
// A-Z
|
||||
else if (isUpperCaseRange(expression)) {
|
||||
upperCasePath = path.getChild(i);
|
||||
}
|
||||
|
||||
// _
|
||||
else if (isUnderscore(expression)) {
|
||||
underscorePath = path.getChild(i);
|
||||
} else if (hasIFlag && hasUFlag && isU017fPath(expression)) {
|
||||
u017fPath = path.getChild(i);
|
||||
} else if (hasIFlag && hasUFlag && isU212aPath(expression)) {
|
||||
u212aPath = path.getChild(i);
|
||||
}
|
||||
});
|
||||
|
||||
// If we found the whole pattern, replace it.
|
||||
if (numberPath && (lowerCasePath && upperCasePath || hasIFlag && (lowerCasePath || upperCasePath)) && underscorePath && (!hasUFlag || !hasIFlag || u017fPath && u212aPath)) {
|
||||
|
||||
// Put \w in place of \d.
|
||||
numberPath.replace({
|
||||
type: 'Char',
|
||||
value: '\\w',
|
||||
kind: 'meta'
|
||||
});
|
||||
|
||||
// Other paths are removed.
|
||||
if (lowerCasePath) {
|
||||
lowerCasePath.remove();
|
||||
}
|
||||
if (upperCasePath) {
|
||||
upperCasePath.remove();
|
||||
}
|
||||
underscorePath.remove();
|
||||
if (u017fPath) {
|
||||
u017fPath.remove();
|
||||
}
|
||||
if (u212aPath) {
|
||||
u212aPath.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites whitespace ranges: [ \t\r\n\f] -> \s.
|
||||
*/
|
||||
function rewriteWhitespaceRanges(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
var spacePath = null;
|
||||
var tPath = null;
|
||||
var nPath = null;
|
||||
var rPath = null;
|
||||
var fPath = null;
|
||||
|
||||
node.expressions.forEach(function (expression, i) {
|
||||
|
||||
// Space
|
||||
if (isChar(expression, ' ')) {
|
||||
spacePath = path.getChild(i);
|
||||
}
|
||||
|
||||
// \t
|
||||
else if (isMetaChar(expression, '\\t')) {
|
||||
tPath = path.getChild(i);
|
||||
}
|
||||
|
||||
// \n
|
||||
else if (isMetaChar(expression, '\\n')) {
|
||||
nPath = path.getChild(i);
|
||||
}
|
||||
|
||||
// \r
|
||||
else if (isMetaChar(expression, '\\r')) {
|
||||
rPath = path.getChild(i);
|
||||
}
|
||||
|
||||
// \f
|
||||
else if (isMetaChar(expression, '\\f')) {
|
||||
fPath = path.getChild(i);
|
||||
}
|
||||
});
|
||||
|
||||
// If we found the whole pattern, replace it.
|
||||
// Make \f optional.
|
||||
if (spacePath && tPath && nPath && rPath) {
|
||||
|
||||
// Put \s in place of \n.
|
||||
nPath.node.value = '\\s';
|
||||
|
||||
// Other paths are removed.
|
||||
spacePath.remove();
|
||||
tPath.remove();
|
||||
rPath.remove();
|
||||
|
||||
if (fPath) {
|
||||
fPath.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isFullNumberRange(node) {
|
||||
return node.type === 'ClassRange' && node.from.value === '0' && node.to.value === '9';
|
||||
}
|
||||
|
||||
function isChar(node, value) {
|
||||
var kind = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'simple';
|
||||
|
||||
return node.type === 'Char' && node.value === value && node.kind === kind;
|
||||
}
|
||||
|
||||
function isMetaChar(node, value) {
|
||||
return isChar(node, value, 'meta');
|
||||
}
|
||||
|
||||
function isLowerCaseRange(node) {
|
||||
return node.type === 'ClassRange' && node.from.value === 'a' && node.to.value === 'z';
|
||||
}
|
||||
|
||||
function isUpperCaseRange(node) {
|
||||
return node.type === 'ClassRange' && node.from.value === 'A' && node.to.value === 'Z';
|
||||
}
|
||||
|
||||
function isUnderscore(node) {
|
||||
return node.type === 'Char' && node.value === '_' && node.kind === 'simple';
|
||||
}
|
||||
|
||||
function isU017fPath(node) {
|
||||
return node.type === 'Char' && node.kind === 'unicode' && node.codePoint === 0x017f;
|
||||
}
|
||||
function isU212aPath(node) {
|
||||
return node.type === 'Char' && node.kind === 'unicode' && node.codePoint === 0x212a;
|
||||
}
|
71
node_modules/regexp-tree/dist/optimizer/transforms/char-class-to-single-char-transform.js
generated
vendored
Normal file
71
node_modules/regexp-tree/dist/optimizer/transforms/char-class-to-single-char-transform.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to replace single char character classes with
|
||||
* just that character.
|
||||
*
|
||||
* [\d] -> \d, [^\w] -> \W
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
CharacterClass: function CharacterClass(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.expressions.length !== 1 || !isAppropriateChar(node.expressions[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _node$expressions$ = node.expressions[0],
|
||||
value = _node$expressions$.value,
|
||||
kind = _node$expressions$.kind,
|
||||
escaped = _node$expressions$.escaped;
|
||||
|
||||
|
||||
if (node.negative) {
|
||||
// For negative can extract only meta chars like [^\w] -> \W
|
||||
// cannot do for [^a] -> a (wrong).
|
||||
if (!isMeta(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
value = getInverseMeta(value);
|
||||
}
|
||||
|
||||
path.replace({
|
||||
type: 'Char',
|
||||
value: value,
|
||||
kind: kind,
|
||||
escaped: escaped || shouldEscape(value)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function isAppropriateChar(node) {
|
||||
return node.type === 'Char' &&
|
||||
// We don't extract [\b] (backspace) since \b has different
|
||||
// semantics (word boundary).
|
||||
node.value !== '\\b';
|
||||
}
|
||||
|
||||
function isMeta(value) {
|
||||
return (/^\\[dwsDWS]$/.test(value)
|
||||
);
|
||||
}
|
||||
|
||||
function getInverseMeta(value) {
|
||||
return (/[dws]/.test(value) ? value.toUpperCase() : value.toLowerCase()
|
||||
);
|
||||
}
|
||||
|
||||
// Note: \{ and \} are always preserved to avoid `a[{]2[}]` turning
|
||||
// into `a{2}`.
|
||||
function shouldEscape(value) {
|
||||
return (/[*[()+?$./{}|]/.test(value)
|
||||
);
|
||||
}
|
84
node_modules/regexp-tree/dist/optimizer/transforms/char-code-to-simple-char-transform.js
generated
vendored
Normal file
84
node_modules/regexp-tree/dist/optimizer/transforms/char-code-to-simple-char-transform.js
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var UPPER_A_CP = 'A'.codePointAt(0);
|
||||
var UPPER_Z_CP = 'Z'.codePointAt(0);
|
||||
var LOWER_A_CP = 'a'.codePointAt(0);
|
||||
var LOWER_Z_CP = 'z'.codePointAt(0);
|
||||
var DIGIT_0_CP = '0'.codePointAt(0);
|
||||
var DIGIT_9_CP = '9'.codePointAt(0);
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to transform coded chars into simple chars.
|
||||
*
|
||||
* \u0061 -> a
|
||||
*/
|
||||
module.exports = {
|
||||
Char: function Char(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
if (isNaN(node.codePoint) || node.kind === 'simple') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.type === 'ClassRange') {
|
||||
if (!isSimpleRange(parent)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isPrintableASCIIChar(node.codePoint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var symbol = String.fromCodePoint(node.codePoint);
|
||||
var newChar = {
|
||||
type: 'Char',
|
||||
kind: 'simple',
|
||||
value: symbol,
|
||||
symbol: symbol,
|
||||
codePoint: node.codePoint
|
||||
};
|
||||
if (needsEscape(symbol, parent.type)) {
|
||||
newChar.escaped = true;
|
||||
}
|
||||
path.replace(newChar);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a range is included either in 0-9, a-z or A-Z
|
||||
* @param classRange
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isSimpleRange(classRange) {
|
||||
var from = classRange.from,
|
||||
to = classRange.to;
|
||||
|
||||
return from.codePoint >= DIGIT_0_CP && from.codePoint <= DIGIT_9_CP && to.codePoint >= DIGIT_0_CP && to.codePoint <= DIGIT_9_CP || from.codePoint >= UPPER_A_CP && from.codePoint <= UPPER_Z_CP && to.codePoint >= UPPER_A_CP && to.codePoint <= UPPER_Z_CP || from.codePoint >= LOWER_A_CP && from.codePoint <= LOWER_Z_CP && to.codePoint >= LOWER_A_CP && to.codePoint <= LOWER_Z_CP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a code point in the range of printable ASCII chars
|
||||
* (DEL char excluded)
|
||||
* @param codePoint
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isPrintableASCIIChar(codePoint) {
|
||||
return codePoint >= 0x20 && codePoint <= 0x7e;
|
||||
}
|
||||
|
||||
function needsEscape(symbol, parentType) {
|
||||
if (parentType === 'ClassRange' || parentType === 'CharacterClass') {
|
||||
return (/[\]\\^-]/.test(symbol)
|
||||
);
|
||||
}
|
||||
|
||||
return (/[*[()+?^$./\\|{}]/.test(symbol)
|
||||
);
|
||||
}
|
143
node_modules/regexp-tree/dist/optimizer/transforms/char-escape-unescape-transform.js
generated
vendored
Normal file
143
node_modules/regexp-tree/dist/optimizer/transforms/char-escape-unescape-transform.js
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to remove unnecessary escape.
|
||||
*
|
||||
* \e -> e
|
||||
*
|
||||
* [\(] -> [(]
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
_hasXFlag: false,
|
||||
init: function init(ast) {
|
||||
this._hasXFlag = ast.flags.includes('x');
|
||||
},
|
||||
Char: function Char(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (!node.escaped) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldUnescape(path, this._hasXFlag)) {
|
||||
delete node.escaped;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shouldUnescape(path, hasXFlag) {
|
||||
var value = path.node.value,
|
||||
index = path.index,
|
||||
parent = path.parent;
|
||||
|
||||
// In char class (, etc are allowed.
|
||||
|
||||
if (parent.type !== 'CharacterClass' && parent.type !== 'ClassRange') {
|
||||
return !preservesEscape(value, index, parent, hasXFlag);
|
||||
}
|
||||
|
||||
return !preservesInCharClass(value, index, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* \], \\, \^, \-
|
||||
*/
|
||||
function preservesInCharClass(value, index, parent) {
|
||||
if (value === '^') {
|
||||
// Avoid [\^a] turning into [^a]
|
||||
return index === 0 && !parent.negative;
|
||||
}
|
||||
if (value === '-') {
|
||||
// Avoid [a\-z] turning into [a-z]
|
||||
return index !== 0 && index !== parent.expressions.length - 1;
|
||||
}
|
||||
return (/[\]\\]/.test(value)
|
||||
);
|
||||
}
|
||||
|
||||
function preservesEscape(value, index, parent, hasXFlag) {
|
||||
if (value === '{') {
|
||||
return preservesOpeningCurlyBraceEscape(index, parent);
|
||||
}
|
||||
|
||||
if (value === '}') {
|
||||
return preservesClosingCurlyBraceEscape(index, parent);
|
||||
}
|
||||
|
||||
if (hasXFlag && /[ #]/.test(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (/[*[()+?^$./\\|]/.test(value)
|
||||
);
|
||||
}
|
||||
|
||||
function consumeNumbers(startIndex, parent, rtl) {
|
||||
var i = startIndex;
|
||||
var siblingNode = (rtl ? i >= 0 : i < parent.expressions.length) && parent.expressions[i];
|
||||
|
||||
while (siblingNode && siblingNode.type === 'Char' && siblingNode.kind === 'simple' && !siblingNode.escaped && /\d/.test(siblingNode.value)) {
|
||||
rtl ? i-- : i++;
|
||||
siblingNode = (rtl ? i >= 0 : i < parent.expressions.length) && parent.expressions[i];
|
||||
}
|
||||
|
||||
return Math.abs(startIndex - i);
|
||||
}
|
||||
|
||||
function isSimpleChar(node, value) {
|
||||
return node && node.type === 'Char' && node.kind === 'simple' && !node.escaped && node.value === value;
|
||||
}
|
||||
|
||||
function preservesOpeningCurlyBraceEscape(index, parent) {
|
||||
var nbFollowingNumbers = consumeNumbers(index + 1, parent);
|
||||
var i = index + nbFollowingNumbers + 1;
|
||||
var nextSiblingNode = i < parent.expressions.length && parent.expressions[i];
|
||||
|
||||
if (nbFollowingNumbers) {
|
||||
|
||||
// Avoid \{3} turning into {3}
|
||||
if (isSimpleChar(nextSiblingNode, '}')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isSimpleChar(nextSiblingNode, ',')) {
|
||||
|
||||
nbFollowingNumbers = consumeNumbers(i + 1, parent);
|
||||
i = i + nbFollowingNumbers + 1;
|
||||
nextSiblingNode = i < parent.expressions.length && parent.expressions[i];
|
||||
|
||||
// Avoid \{3,} turning into {3,}
|
||||
return isSimpleChar(nextSiblingNode, '}');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function preservesClosingCurlyBraceEscape(index, parent) {
|
||||
var nbPrecedingNumbers = consumeNumbers(index - 1, parent, true);
|
||||
var i = index - nbPrecedingNumbers - 1;
|
||||
var previousSiblingNode = i >= 0 && parent.expressions[i];
|
||||
|
||||
// Avoid {3\} turning into {3}
|
||||
if (nbPrecedingNumbers && isSimpleChar(previousSiblingNode, '{')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isSimpleChar(previousSiblingNode, ',')) {
|
||||
|
||||
nbPrecedingNumbers = consumeNumbers(i - 1, parent, true);
|
||||
i = i - nbPrecedingNumbers - 1;
|
||||
previousSiblingNode = i < parent.expressions.length && parent.expressions[i];
|
||||
|
||||
// Avoid {3,\} turning into {3,}
|
||||
return nbPrecedingNumbers && isSimpleChar(previousSiblingNode, '{');
|
||||
}
|
||||
return false;
|
||||
}
|
27
node_modules/regexp-tree/dist/optimizer/transforms/char-surrogate-pair-to-single-unicode-transform.js
generated
vendored
Normal file
27
node_modules/regexp-tree/dist/optimizer/transforms/char-surrogate-pair-to-single-unicode-transform.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to transform surrogate pairs into single unicode code point
|
||||
*
|
||||
* \ud83d\ude80 -> \u{1f680}
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
shouldRun: function shouldRun(ast) {
|
||||
return ast.flags.includes('u');
|
||||
},
|
||||
Char: function Char(path) {
|
||||
var node = path.node;
|
||||
|
||||
if (node.kind !== 'unicode' || !node.isSurrogatePair || isNaN(node.codePoint)) {
|
||||
return;
|
||||
}
|
||||
node.value = '\\u{' + node.codePoint.toString(16) + '}';
|
||||
delete node.isSurrogatePair;
|
||||
}
|
||||
};
|
195
node_modules/regexp-tree/dist/optimizer/transforms/combine-repeating-patterns-transform.js
generated
vendored
Normal file
195
node_modules/regexp-tree/dist/optimizer/transforms/combine-repeating-patterns-transform.js
generated
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
var NodePath = require('../../traverse/node-path');
|
||||
|
||||
var _require = require('../../transform/utils'),
|
||||
increaseQuantifierByOne = _require.increaseQuantifierByOne;
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to combine repeating patterns.
|
||||
*
|
||||
* /^abcabcabc/ -> /^abc{3}/
|
||||
* /^(?:abc){2}abc/ -> /^(?:abc){3}/
|
||||
* /^abc(?:abc){2}/ -> /^(?:abc){3}/
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
Alternative: function Alternative(path) {
|
||||
var node = path.node;
|
||||
|
||||
// We can skip the first child
|
||||
|
||||
var index = 1;
|
||||
while (index < node.expressions.length) {
|
||||
var child = path.getChild(index);
|
||||
index = Math.max(1, combineRepeatingPatternLeft(path, child, index));
|
||||
|
||||
if (index >= node.expressions.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
child = path.getChild(index);
|
||||
index = Math.max(1, combineWithPreviousRepetition(path, child, index));
|
||||
|
||||
if (index >= node.expressions.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
child = path.getChild(index);
|
||||
index = Math.max(1, combineRepetitionWithPrevious(path, child, index));
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// abcabc -> (?:abc){2}
|
||||
function combineRepeatingPatternLeft(alternative, child, index) {
|
||||
var node = alternative.node;
|
||||
|
||||
|
||||
var nbPossibleLengths = Math.ceil(index / 2);
|
||||
var i = 0;
|
||||
|
||||
while (i < nbPossibleLengths) {
|
||||
var startIndex = index - 2 * i - 1;
|
||||
var right = void 0,
|
||||
left = void 0;
|
||||
|
||||
if (i === 0) {
|
||||
right = child;
|
||||
left = alternative.getChild(startIndex);
|
||||
} else {
|
||||
right = NodePath.getForNode({
|
||||
type: 'Alternative',
|
||||
expressions: [].concat(_toConsumableArray(node.expressions.slice(index - i, index)), [child.node])
|
||||
});
|
||||
|
||||
left = NodePath.getForNode({
|
||||
type: 'Alternative',
|
||||
expressions: [].concat(_toConsumableArray(node.expressions.slice(startIndex, index - i)))
|
||||
});
|
||||
}
|
||||
|
||||
if (right.hasEqualSource(left)) {
|
||||
for (var j = 0; j < 2 * i + 1; j++) {
|
||||
alternative.getChild(startIndex).remove();
|
||||
}
|
||||
|
||||
child.replace({
|
||||
type: 'Repetition',
|
||||
expression: i === 0 ? right.node : {
|
||||
type: 'Group',
|
||||
capturing: false,
|
||||
expression: right.node
|
||||
},
|
||||
quantifier: {
|
||||
type: 'Quantifier',
|
||||
kind: 'Range',
|
||||
from: 2,
|
||||
to: 2,
|
||||
greedy: true
|
||||
}
|
||||
});
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// (?:abc){2}abc -> (?:abc){3}
|
||||
function combineWithPreviousRepetition(alternative, child, index) {
|
||||
var node = alternative.node;
|
||||
|
||||
|
||||
var i = 0;
|
||||
while (i < index) {
|
||||
var previousChild = alternative.getChild(i);
|
||||
|
||||
if (previousChild.node.type === 'Repetition' && previousChild.node.quantifier.greedy) {
|
||||
var left = previousChild.getChild();
|
||||
var right = void 0;
|
||||
|
||||
if (left.node.type === 'Group' && !left.node.capturing) {
|
||||
left = left.getChild();
|
||||
}
|
||||
|
||||
if (i + 1 === index) {
|
||||
right = child;
|
||||
if (right.node.type === 'Group' && !right.node.capturing) {
|
||||
right = right.getChild();
|
||||
}
|
||||
} else {
|
||||
right = NodePath.getForNode({
|
||||
type: 'Alternative',
|
||||
expressions: [].concat(_toConsumableArray(node.expressions.slice(i + 1, index + 1)))
|
||||
});
|
||||
}
|
||||
|
||||
if (left.hasEqualSource(right)) {
|
||||
|
||||
for (var j = i; j < index; j++) {
|
||||
alternative.getChild(i + 1).remove();
|
||||
}
|
||||
|
||||
increaseQuantifierByOne(previousChild.node.quantifier);
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// abc(?:abc){2} -> (?:abc){3}
|
||||
function combineRepetitionWithPrevious(alternative, child, index) {
|
||||
var node = alternative.node;
|
||||
|
||||
|
||||
if (child.node.type === 'Repetition' && child.node.quantifier.greedy) {
|
||||
var right = child.getChild();
|
||||
var left = void 0;
|
||||
|
||||
if (right.node.type === 'Group' && !right.node.capturing) {
|
||||
right = right.getChild();
|
||||
}
|
||||
|
||||
var rightLength = void 0;
|
||||
if (right.node.type === 'Alternative') {
|
||||
rightLength = right.node.expressions.length;
|
||||
left = NodePath.getForNode({
|
||||
type: 'Alternative',
|
||||
expressions: [].concat(_toConsumableArray(node.expressions.slice(index - rightLength, index)))
|
||||
});
|
||||
} else {
|
||||
rightLength = 1;
|
||||
left = alternative.getChild(index - 1);
|
||||
if (left.node.type === 'Group' && !left.node.capturing) {
|
||||
left = left.getChild();
|
||||
}
|
||||
}
|
||||
|
||||
if (left.hasEqualSource(right)) {
|
||||
for (var j = index - rightLength; j < index; j++) {
|
||||
alternative.getChild(index - rightLength).remove();
|
||||
}
|
||||
|
||||
increaseQuantifierByOne(child.node.quantifier);
|
||||
|
||||
return index - rightLength;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
44
node_modules/regexp-tree/dist/optimizer/transforms/disjunction-remove-duplicates-transform.js
generated
vendored
Normal file
44
node_modules/regexp-tree/dist/optimizer/transforms/disjunction-remove-duplicates-transform.js
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var NodePath = require('../../traverse/node-path');
|
||||
|
||||
var _require = require('../../transform/utils'),
|
||||
disjunctionToList = _require.disjunctionToList,
|
||||
listToDisjunction = _require.listToDisjunction;
|
||||
|
||||
/**
|
||||
* Removes duplicates from a disjunction sequence:
|
||||
*
|
||||
* /(ab|bc|ab)+(xy|xy)+/ -> /(ab|bc)+(xy)+/
|
||||
*/
|
||||
|
||||
|
||||
module.exports = {
|
||||
Disjunction: function Disjunction(path) {
|
||||
var node = path.node;
|
||||
|
||||
// Make unique nodes.
|
||||
|
||||
var uniqueNodesMap = {};
|
||||
|
||||
var parts = disjunctionToList(node).filter(function (part) {
|
||||
var encoded = part ? NodePath.getForNode(part).jsonEncode() : 'null';
|
||||
|
||||
// Already recorded this part, filter out.
|
||||
if (uniqueNodesMap.hasOwnProperty(encoded)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uniqueNodesMap[encoded] = part;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Replace with the optimized disjunction.
|
||||
path.replace(listToDisjunction(parts));
|
||||
}
|
||||
};
|
92
node_modules/regexp-tree/dist/optimizer/transforms/group-single-chars-to-char-class.js
generated
vendored
Normal file
92
node_modules/regexp-tree/dist/optimizer/transforms/group-single-chars-to-char-class.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to replace single char group disjunction to char group
|
||||
*
|
||||
* a|b|c -> [abc]
|
||||
* [12]|3|4 -> [1234]
|
||||
* (a|b|c) -> ([abc])
|
||||
* (?:a|b|c) -> [abc]
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
Disjunction: function Disjunction(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
|
||||
if (!handlers[parent.type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var charset = new Map();
|
||||
|
||||
if (!shouldProcess(node, charset) || !charset.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
var characterClass = {
|
||||
type: 'CharacterClass',
|
||||
expressions: Array.from(charset.keys()).sort().map(function (key) {
|
||||
return charset.get(key);
|
||||
})
|
||||
};
|
||||
|
||||
handlers[parent.type](path.getParent(), characterClass);
|
||||
}
|
||||
};
|
||||
|
||||
var handlers = {
|
||||
RegExp: function RegExp(path, characterClass) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
node.body = characterClass;
|
||||
},
|
||||
Group: function Group(path, characterClass) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.capturing) {
|
||||
node.expression = characterClass;
|
||||
} else {
|
||||
path.replace(characterClass);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shouldProcess(expression, charset) {
|
||||
if (!expression) {
|
||||
// Abort on empty disjunction part
|
||||
return false;
|
||||
}
|
||||
|
||||
var type = expression.type;
|
||||
|
||||
|
||||
if (type === 'Disjunction') {
|
||||
var left = expression.left,
|
||||
right = expression.right;
|
||||
|
||||
|
||||
return shouldProcess(left, charset) && shouldProcess(right, charset);
|
||||
} else if (type === 'Char') {
|
||||
var value = expression.value;
|
||||
|
||||
|
||||
charset.set(value, expression);
|
||||
|
||||
return true;
|
||||
} else if (type === 'CharacterClass') {
|
||||
return expression.expressions.every(function (expression) {
|
||||
return shouldProcess(expression, charset);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
56
node_modules/regexp-tree/dist/optimizer/transforms/index.js
generated
vendored
Normal file
56
node_modules/regexp-tree/dist/optimizer/transforms/index.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
// \ud83d\ude80 -> \u{1f680}
|
||||
'charSurrogatePairToSingleUnicode': require('./char-surrogate-pair-to-single-unicode-transform'),
|
||||
|
||||
// \u0061 -> a
|
||||
'charCodeToSimpleChar': require('./char-code-to-simple-char-transform'),
|
||||
|
||||
// /Aa/i -> /aa/i
|
||||
'charCaseInsensitiveLowerCaseTransform': require('./char-case-insensitive-lowercase-transform'),
|
||||
|
||||
// [\d\d] -> [\d]
|
||||
'charClassRemoveDuplicates': require('./char-class-remove-duplicates-transform'),
|
||||
|
||||
// a{1,2}a{2,3} -> a{3,5}
|
||||
'quantifiersMerge': require('./quantifiers-merge-transform'),
|
||||
|
||||
// a{1,} -> a+, a{3,3} -> a{3}, a{1} -> a
|
||||
'quantifierRangeToSymbol': require('./quantifier-range-to-symbol-transform'),
|
||||
|
||||
// [a-a] -> [a], [a-b] -> [ab]
|
||||
'charClassClassrangesToChars': require('./char-class-classranges-to-chars-transform'),
|
||||
|
||||
// [a-de-f] -> [a-f]
|
||||
'charClassClassrangesMerge': require('./char-class-classranges-merge-transform'),
|
||||
|
||||
// [0-9] -> [\d]
|
||||
'charClassToMeta': require('./char-class-to-meta-transform'),
|
||||
|
||||
// [\d] -> \d, [^\w] -> \W
|
||||
'charClassToSingleChar': require('./char-class-to-single-char-transform'),
|
||||
|
||||
// \e -> e
|
||||
'charEscapeUnescape': require('./char-escape-unescape-transform'),
|
||||
|
||||
// (ab|ab) -> (ab)
|
||||
'disjunctionRemoveDuplicates': require('./disjunction-remove-duplicates-transform'),
|
||||
|
||||
// (a|b|c) -> [abc]
|
||||
'groupSingleCharsToCharClass': require('./group-single-chars-to-char-class'),
|
||||
|
||||
// (?:)a -> a
|
||||
'removeEmptyGroup': require('./remove-empty-group-transform'),
|
||||
|
||||
// (?:a) -> a
|
||||
'ungroup': require('./ungroup-transform'),
|
||||
|
||||
// abcabcabc -> (?:abc){3}
|
||||
'combineRepeatingPatterns': require('./combine-repeating-patterns-transform')
|
||||
};
|
74
node_modules/regexp-tree/dist/optimizer/transforms/quantifier-range-to-symbol-transform.js
generated
vendored
Normal file
74
node_modules/regexp-tree/dist/optimizer/transforms/quantifier-range-to-symbol-transform.js
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to replace different range-based quantifiers
|
||||
* with their symbol equivalents.
|
||||
*
|
||||
* a{0,} -> a*
|
||||
* a{1,} -> a+
|
||||
* a{1} -> a
|
||||
*
|
||||
* NOTE: the following is automatically handled in the generator:
|
||||
*
|
||||
* a{3,3} -> a{3}
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
Quantifier: function Quantifier(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.kind !== 'Range') {
|
||||
return;
|
||||
}
|
||||
|
||||
// a{0,} -> a*
|
||||
rewriteOpenZero(path);
|
||||
|
||||
// a{1,} -> a+
|
||||
rewriteOpenOne(path);
|
||||
|
||||
// a{1} -> a
|
||||
rewriteExactOne(path);
|
||||
}
|
||||
};
|
||||
|
||||
function rewriteOpenZero(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.from !== 0 || node.to) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.kind = '*';
|
||||
delete node.from;
|
||||
}
|
||||
|
||||
function rewriteOpenOne(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.from !== 1 || node.to) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.kind = '+';
|
||||
delete node.from;
|
||||
}
|
||||
|
||||
function rewriteExactOne(path) {
|
||||
var node = path.node;
|
||||
|
||||
|
||||
if (node.from !== 1 || node.to !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
path.parentPath.replace(path.parentPath.node.expression);
|
||||
}
|
113
node_modules/regexp-tree/dist/optimizer/transforms/quantifiers-merge-transform.js
generated
vendored
Normal file
113
node_modules/regexp-tree/dist/optimizer/transforms/quantifiers-merge-transform.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _require = require('../../transform/utils'),
|
||||
increaseQuantifierByOne = _require.increaseQuantifierByOne;
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to merge quantifiers
|
||||
*
|
||||
* a+a+ -> a{2,}
|
||||
* a{2}a{3} -> a{5}
|
||||
* a{1,2}a{2,3} -> a{3,5}
|
||||
*/
|
||||
|
||||
|
||||
module.exports = {
|
||||
Repetition: function Repetition(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
|
||||
if (parent.type !== 'Alternative' || !path.index) {
|
||||
return;
|
||||
}
|
||||
|
||||
var previousSibling = path.getPreviousSibling();
|
||||
|
||||
if (!previousSibling) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousSibling.node.type === 'Repetition') {
|
||||
if (!previousSibling.getChild().hasEqualSource(path.getChild())) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _extractFromTo = extractFromTo(previousSibling.node.quantifier),
|
||||
previousSiblingFrom = _extractFromTo.from,
|
||||
previousSiblingTo = _extractFromTo.to;
|
||||
|
||||
var _extractFromTo2 = extractFromTo(node.quantifier),
|
||||
nodeFrom = _extractFromTo2.from,
|
||||
nodeTo = _extractFromTo2.to;
|
||||
|
||||
// It's does not seem reliable to merge quantifiers with different greediness
|
||||
// when none of both is a greedy open range
|
||||
|
||||
|
||||
if (previousSibling.node.quantifier.greedy !== node.quantifier.greedy && !isGreedyOpenRange(previousSibling.node.quantifier) && !isGreedyOpenRange(node.quantifier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a*a* -> a*
|
||||
// a*a+ -> a+
|
||||
// a+a+ -> a{2,}
|
||||
// a{2}a{4} -> a{6}
|
||||
// a{1,2}a{2,3} -> a{3,5}
|
||||
// a{1,}a{2,} -> a{3,}
|
||||
// a+a{2,} -> a{3,}
|
||||
|
||||
// a??a{2,} -> a{2,}
|
||||
// a*?a{2,} -> a{2,}
|
||||
// a+?a{2,} -> a{3,}
|
||||
|
||||
node.quantifier.kind = 'Range';
|
||||
node.quantifier.from = previousSiblingFrom + nodeFrom;
|
||||
if (previousSiblingTo && nodeTo) {
|
||||
node.quantifier.to = previousSiblingTo + nodeTo;
|
||||
} else {
|
||||
delete node.quantifier.to;
|
||||
}
|
||||
if (isGreedyOpenRange(previousSibling.node.quantifier) || isGreedyOpenRange(node.quantifier)) {
|
||||
node.quantifier.greedy = true;
|
||||
}
|
||||
|
||||
previousSibling.remove();
|
||||
} else {
|
||||
if (!previousSibling.hasEqualSource(path.getChild())) {
|
||||
return;
|
||||
}
|
||||
|
||||
increaseQuantifierByOne(node.quantifier);
|
||||
previousSibling.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function isGreedyOpenRange(quantifier) {
|
||||
return quantifier.greedy && (quantifier.kind === '+' || quantifier.kind === '*' || quantifier.kind === 'Range' && !quantifier.to);
|
||||
}
|
||||
|
||||
function extractFromTo(quantifier) {
|
||||
var from = void 0,
|
||||
to = void 0;
|
||||
if (quantifier.kind === '*') {
|
||||
from = 0;
|
||||
} else if (quantifier.kind === '+') {
|
||||
from = 1;
|
||||
} else if (quantifier.kind === '?') {
|
||||
from = 0;
|
||||
to = 1;
|
||||
} else {
|
||||
from = quantifier.from;
|
||||
if (quantifier.to) {
|
||||
to = quantifier.to;
|
||||
}
|
||||
}
|
||||
return { from: from, to: to };
|
||||
}
|
34
node_modules/regexp-tree/dist/optimizer/transforms/remove-empty-group-transform.js
generated
vendored
Normal file
34
node_modules/regexp-tree/dist/optimizer/transforms/remove-empty-group-transform.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to remove non-capturing empty groups.
|
||||
*
|
||||
* /(?:)a/ -> /a/
|
||||
* /a|(?:)/ -> /a|/
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
Group: function Group(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
var childPath = path.getChild();
|
||||
|
||||
if (node.capturing || childPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.type === 'Repetition') {
|
||||
|
||||
path.getParent().replace(node);
|
||||
} else if (parent.type !== 'RegExp') {
|
||||
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
};
|
55
node_modules/regexp-tree/dist/optimizer/transforms/ungroup-transform.js
generated
vendored
Normal file
55
node_modules/regexp-tree/dist/optimizer/transforms/ungroup-transform.js
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A regexp-tree plugin to remove unnecessary groups.
|
||||
*
|
||||
* /(?:a)/ -> /a/
|
||||
*/
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
module.exports = {
|
||||
Group: function Group(path) {
|
||||
var node = path.node,
|
||||
parent = path.parent;
|
||||
|
||||
var childPath = path.getChild();
|
||||
|
||||
if (node.capturing || !childPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't optimize /a(?:b|c)/ to /ab|c/
|
||||
// but /(?:b|c)/ to /b|c/ is ok
|
||||
if (childPath.node.type === 'Disjunction' && parent.type !== 'RegExp') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't optimize /(?:ab)+/ to /ab+/
|
||||
// but /(?:a)+/ to /a+/ is ok
|
||||
// and /(?:[a-d])+/ to /[a-d]+/ is ok too
|
||||
if (parent.type === 'Repetition' && childPath.node.type !== 'Char' && childPath.node.type !== 'CharacterClass') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (childPath.node.type === 'Alternative') {
|
||||
var parentPath = path.getParent();
|
||||
if (parentPath.node.type === 'Alternative') {
|
||||
|
||||
// /abc(?:def)ghi/ When (?:def) is ungrouped its content must be merged with parent alternative
|
||||
|
||||
parentPath.replace({
|
||||
type: 'Alternative',
|
||||
expressions: [].concat(_toConsumableArray(parent.expressions.slice(0, path.index)), _toConsumableArray(childPath.node.expressions), _toConsumableArray(parent.expressions.slice(path.index + 1)))
|
||||
});
|
||||
}
|
||||
} else {
|
||||
path.replace(childPath.node);
|
||||
}
|
||||
}
|
||||
};
|
1403
node_modules/regexp-tree/dist/parser/generated/regexp-tree.js
generated
vendored
Normal file
1403
node_modules/regexp-tree/dist/parser/generated/regexp-tree.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
28
node_modules/regexp-tree/dist/parser/index.js
generated
vendored
Normal file
28
node_modules/regexp-tree/dist/parser/index.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var regexpTreeParser = require('./generated/regexp-tree');
|
||||
|
||||
/**
|
||||
* Original parse function.
|
||||
*/
|
||||
var generatedParseFn = regexpTreeParser.parse.bind(regexpTreeParser);
|
||||
|
||||
/**
|
||||
* Parses a regular expression.
|
||||
*
|
||||
* Override original `regexpTreeParser.parse` to convert a value to a string,
|
||||
* since in regexp-tree we may pass strings, and RegExp instance.
|
||||
*/
|
||||
regexpTreeParser.parse = function (regexp, options) {
|
||||
return generatedParseFn('' + regexp, options);
|
||||
};
|
||||
|
||||
// By default do not capture locations; callers may override.
|
||||
regexpTreeParser.setOptions({ captureLocations: false });
|
||||
|
||||
module.exports = regexpTreeParser;
|
379
node_modules/regexp-tree/dist/parser/unicode/parser-unicode-properties.js
generated
vendored
Normal file
379
node_modules/regexp-tree/dist/parser/unicode/parser-unicode-properties.js
generated
vendored
Normal file
@ -0,0 +1,379 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
var NON_BINARY_PROP_NAMES_TO_ALIASES = {
|
||||
General_Category: 'gc',
|
||||
Script: 'sc',
|
||||
Script_Extensions: 'scx'
|
||||
};
|
||||
|
||||
var NON_BINARY_ALIASES_TO_PROP_NAMES = inverseMap(NON_BINARY_PROP_NAMES_TO_ALIASES);
|
||||
|
||||
var BINARY_PROP_NAMES_TO_ALIASES = {
|
||||
ASCII: 'ASCII',
|
||||
ASCII_Hex_Digit: 'AHex',
|
||||
Alphabetic: 'Alpha',
|
||||
Any: 'Any',
|
||||
Assigned: 'Assigned',
|
||||
Bidi_Control: 'Bidi_C',
|
||||
Bidi_Mirrored: 'Bidi_M',
|
||||
Case_Ignorable: 'CI',
|
||||
Cased: 'Cased',
|
||||
Changes_When_Casefolded: 'CWCF',
|
||||
Changes_When_Casemapped: 'CWCM',
|
||||
Changes_When_Lowercased: 'CWL',
|
||||
Changes_When_NFKC_Casefolded: 'CWKCF',
|
||||
Changes_When_Titlecased: 'CWT',
|
||||
Changes_When_Uppercased: 'CWU',
|
||||
Dash: 'Dash',
|
||||
Default_Ignorable_Code_Point: 'DI',
|
||||
Deprecated: 'Dep',
|
||||
Diacritic: 'Dia',
|
||||
Emoji: 'Emoji',
|
||||
Emoji_Component: 'Emoji_Component',
|
||||
Emoji_Modifier: 'Emoji_Modifier',
|
||||
Emoji_Modifier_Base: 'Emoji_Modifier_Base',
|
||||
Emoji_Presentation: 'Emoji_Presentation',
|
||||
Extended_Pictographic: 'Extended_Pictographic',
|
||||
Extender: 'Ext',
|
||||
Grapheme_Base: 'Gr_Base',
|
||||
Grapheme_Extend: 'Gr_Ext',
|
||||
Hex_Digit: 'Hex',
|
||||
IDS_Binary_Operator: 'IDSB',
|
||||
IDS_Trinary_Operator: 'IDST',
|
||||
ID_Continue: 'IDC',
|
||||
ID_Start: 'IDS',
|
||||
Ideographic: 'Ideo',
|
||||
Join_Control: 'Join_C',
|
||||
Logical_Order_Exception: 'LOE',
|
||||
Lowercase: 'Lower',
|
||||
Math: 'Math',
|
||||
Noncharacter_Code_Point: 'NChar',
|
||||
Pattern_Syntax: 'Pat_Syn',
|
||||
Pattern_White_Space: 'Pat_WS',
|
||||
Quotation_Mark: 'QMark',
|
||||
Radical: 'Radical',
|
||||
Regional_Indicator: 'RI',
|
||||
Sentence_Terminal: 'STerm',
|
||||
Soft_Dotted: 'SD',
|
||||
Terminal_Punctuation: 'Term',
|
||||
Unified_Ideograph: 'UIdeo',
|
||||
Uppercase: 'Upper',
|
||||
Variation_Selector: 'VS',
|
||||
White_Space: 'space',
|
||||
XID_Continue: 'XIDC',
|
||||
XID_Start: 'XIDS'
|
||||
};
|
||||
|
||||
var BINARY_ALIASES_TO_PROP_NAMES = inverseMap(BINARY_PROP_NAMES_TO_ALIASES);
|
||||
|
||||
var GENERAL_CATEGORY_VALUE_TO_ALIASES = {
|
||||
Cased_Letter: 'LC',
|
||||
Close_Punctuation: 'Pe',
|
||||
Connector_Punctuation: 'Pc',
|
||||
Control: ['Cc', 'cntrl'],
|
||||
Currency_Symbol: 'Sc',
|
||||
Dash_Punctuation: 'Pd',
|
||||
Decimal_Number: ['Nd', 'digit'],
|
||||
Enclosing_Mark: 'Me',
|
||||
Final_Punctuation: 'Pf',
|
||||
Format: 'Cf',
|
||||
Initial_Punctuation: 'Pi',
|
||||
Letter: 'L',
|
||||
Letter_Number: 'Nl',
|
||||
Line_Separator: 'Zl',
|
||||
Lowercase_Letter: 'Ll',
|
||||
Mark: ['M', 'Combining_Mark'],
|
||||
Math_Symbol: 'Sm',
|
||||
Modifier_Letter: 'Lm',
|
||||
Modifier_Symbol: 'Sk',
|
||||
Nonspacing_Mark: 'Mn',
|
||||
Number: 'N',
|
||||
Open_Punctuation: 'Ps',
|
||||
Other: 'C',
|
||||
Other_Letter: 'Lo',
|
||||
Other_Number: 'No',
|
||||
Other_Punctuation: 'Po',
|
||||
Other_Symbol: 'So',
|
||||
Paragraph_Separator: 'Zp',
|
||||
Private_Use: 'Co',
|
||||
Punctuation: ['P', 'punct'],
|
||||
Separator: 'Z',
|
||||
Space_Separator: 'Zs',
|
||||
Spacing_Mark: 'Mc',
|
||||
Surrogate: 'Cs',
|
||||
Symbol: 'S',
|
||||
Titlecase_Letter: 'Lt',
|
||||
Unassigned: 'Cn',
|
||||
Uppercase_Letter: 'Lu'
|
||||
};
|
||||
|
||||
var GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES = inverseMap(GENERAL_CATEGORY_VALUE_TO_ALIASES);
|
||||
|
||||
var SCRIPT_VALUE_TO_ALIASES = {
|
||||
Adlam: 'Adlm',
|
||||
Ahom: 'Ahom',
|
||||
Anatolian_Hieroglyphs: 'Hluw',
|
||||
Arabic: 'Arab',
|
||||
Armenian: 'Armn',
|
||||
Avestan: 'Avst',
|
||||
Balinese: 'Bali',
|
||||
Bamum: 'Bamu',
|
||||
Bassa_Vah: 'Bass',
|
||||
Batak: 'Batk',
|
||||
Bengali: 'Beng',
|
||||
Bhaiksuki: 'Bhks',
|
||||
Bopomofo: 'Bopo',
|
||||
Brahmi: 'Brah',
|
||||
Braille: 'Brai',
|
||||
Buginese: 'Bugi',
|
||||
Buhid: 'Buhd',
|
||||
Canadian_Aboriginal: 'Cans',
|
||||
Carian: 'Cari',
|
||||
Caucasian_Albanian: 'Aghb',
|
||||
Chakma: 'Cakm',
|
||||
Cham: 'Cham',
|
||||
Cherokee: 'Cher',
|
||||
Common: 'Zyyy',
|
||||
Coptic: ['Copt', 'Qaac'],
|
||||
Cuneiform: 'Xsux',
|
||||
Cypriot: 'Cprt',
|
||||
Cyrillic: 'Cyrl',
|
||||
Deseret: 'Dsrt',
|
||||
Devanagari: 'Deva',
|
||||
Dogra: 'Dogr',
|
||||
Duployan: 'Dupl',
|
||||
Egyptian_Hieroglyphs: 'Egyp',
|
||||
Elbasan: 'Elba',
|
||||
Ethiopic: 'Ethi',
|
||||
Georgian: 'Geor',
|
||||
Glagolitic: 'Glag',
|
||||
Gothic: 'Goth',
|
||||
Grantha: 'Gran',
|
||||
Greek: 'Grek',
|
||||
Gujarati: 'Gujr',
|
||||
Gunjala_Gondi: 'Gong',
|
||||
Gurmukhi: 'Guru',
|
||||
Han: 'Hani',
|
||||
Hangul: 'Hang',
|
||||
Hanifi_Rohingya: 'Rohg',
|
||||
Hanunoo: 'Hano',
|
||||
Hatran: 'Hatr',
|
||||
Hebrew: 'Hebr',
|
||||
Hiragana: 'Hira',
|
||||
Imperial_Aramaic: 'Armi',
|
||||
Inherited: ['Zinh', 'Qaai'],
|
||||
Inscriptional_Pahlavi: 'Phli',
|
||||
Inscriptional_Parthian: 'Prti',
|
||||
Javanese: 'Java',
|
||||
Kaithi: 'Kthi',
|
||||
Kannada: 'Knda',
|
||||
Katakana: 'Kana',
|
||||
Kayah_Li: 'Kali',
|
||||
Kharoshthi: 'Khar',
|
||||
Khmer: 'Khmr',
|
||||
Khojki: 'Khoj',
|
||||
Khudawadi: 'Sind',
|
||||
Lao: 'Laoo',
|
||||
Latin: 'Latn',
|
||||
Lepcha: 'Lepc',
|
||||
Limbu: 'Limb',
|
||||
Linear_A: 'Lina',
|
||||
Linear_B: 'Linb',
|
||||
Lisu: 'Lisu',
|
||||
Lycian: 'Lyci',
|
||||
Lydian: 'Lydi',
|
||||
Mahajani: 'Mahj',
|
||||
Makasar: 'Maka',
|
||||
Malayalam: 'Mlym',
|
||||
Mandaic: 'Mand',
|
||||
Manichaean: 'Mani',
|
||||
Marchen: 'Marc',
|
||||
Medefaidrin: 'Medf',
|
||||
Masaram_Gondi: 'Gonm',
|
||||
Meetei_Mayek: 'Mtei',
|
||||
Mende_Kikakui: 'Mend',
|
||||
Meroitic_Cursive: 'Merc',
|
||||
Meroitic_Hieroglyphs: 'Mero',
|
||||
Miao: 'Plrd',
|
||||
Modi: 'Modi',
|
||||
Mongolian: 'Mong',
|
||||
Mro: 'Mroo',
|
||||
Multani: 'Mult',
|
||||
Myanmar: 'Mymr',
|
||||
Nabataean: 'Nbat',
|
||||
New_Tai_Lue: 'Talu',
|
||||
Newa: 'Newa',
|
||||
Nko: 'Nkoo',
|
||||
Nushu: 'Nshu',
|
||||
Ogham: 'Ogam',
|
||||
Ol_Chiki: 'Olck',
|
||||
Old_Hungarian: 'Hung',
|
||||
Old_Italic: 'Ital',
|
||||
Old_North_Arabian: 'Narb',
|
||||
Old_Permic: 'Perm',
|
||||
Old_Persian: 'Xpeo',
|
||||
Old_Sogdian: 'Sogo',
|
||||
Old_South_Arabian: 'Sarb',
|
||||
Old_Turkic: 'Orkh',
|
||||
Oriya: 'Orya',
|
||||
Osage: 'Osge',
|
||||
Osmanya: 'Osma',
|
||||
Pahawh_Hmong: 'Hmng',
|
||||
Palmyrene: 'Palm',
|
||||
Pau_Cin_Hau: 'Pauc',
|
||||
Phags_Pa: 'Phag',
|
||||
Phoenician: 'Phnx',
|
||||
Psalter_Pahlavi: 'Phlp',
|
||||
Rejang: 'Rjng',
|
||||
Runic: 'Runr',
|
||||
Samaritan: 'Samr',
|
||||
Saurashtra: 'Saur',
|
||||
Sharada: 'Shrd',
|
||||
Shavian: 'Shaw',
|
||||
Siddham: 'Sidd',
|
||||
SignWriting: 'Sgnw',
|
||||
Sinhala: 'Sinh',
|
||||
Sogdian: 'Sogd',
|
||||
Sora_Sompeng: 'Sora',
|
||||
Soyombo: 'Soyo',
|
||||
Sundanese: 'Sund',
|
||||
Syloti_Nagri: 'Sylo',
|
||||
Syriac: 'Syrc',
|
||||
Tagalog: 'Tglg',
|
||||
Tagbanwa: 'Tagb',
|
||||
Tai_Le: 'Tale',
|
||||
Tai_Tham: 'Lana',
|
||||
Tai_Viet: 'Tavt',
|
||||
Takri: 'Takr',
|
||||
Tamil: 'Taml',
|
||||
Tangut: 'Tang',
|
||||
Telugu: 'Telu',
|
||||
Thaana: 'Thaa',
|
||||
Thai: 'Thai',
|
||||
Tibetan: 'Tibt',
|
||||
Tifinagh: 'Tfng',
|
||||
Tirhuta: 'Tirh',
|
||||
Ugaritic: 'Ugar',
|
||||
Vai: 'Vaii',
|
||||
Warang_Citi: 'Wara',
|
||||
Yi: 'Yiii',
|
||||
Zanabazar_Square: 'Zanb'
|
||||
};
|
||||
|
||||
var SCRIPT_VALUE_ALIASES_TO_VALUE = inverseMap(SCRIPT_VALUE_TO_ALIASES);
|
||||
|
||||
function inverseMap(data) {
|
||||
var inverse = {};
|
||||
|
||||
for (var name in data) {
|
||||
if (!data.hasOwnProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
var value = data[name];
|
||||
if (Array.isArray(value)) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
inverse[value[i]] = name;
|
||||
}
|
||||
} else {
|
||||
inverse[value] = name;
|
||||
}
|
||||
}
|
||||
|
||||
return inverse;
|
||||
}
|
||||
|
||||
function isValidName(name) {
|
||||
return NON_BINARY_PROP_NAMES_TO_ALIASES.hasOwnProperty(name) || NON_BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name) || BINARY_PROP_NAMES_TO_ALIASES.hasOwnProperty(name) || BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
function isValidValue(name, value) {
|
||||
if (isGeneralCategoryName(name)) {
|
||||
return isGeneralCategoryValue(value);
|
||||
}
|
||||
|
||||
if (isScriptCategoryName(name)) {
|
||||
return isScriptCategoryValue(value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAlias(name) {
|
||||
return NON_BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name) || BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
function isGeneralCategoryName(name) {
|
||||
return name === 'General_Category' || name == 'gc';
|
||||
}
|
||||
|
||||
function isScriptCategoryName(name) {
|
||||
return name === 'Script' || name === 'Script_Extensions' || name === 'sc' || name === 'scx';
|
||||
}
|
||||
|
||||
function isGeneralCategoryValue(value) {
|
||||
return GENERAL_CATEGORY_VALUE_TO_ALIASES.hasOwnProperty(value) || GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES.hasOwnProperty(value);
|
||||
}
|
||||
|
||||
function isScriptCategoryValue(value) {
|
||||
return SCRIPT_VALUE_TO_ALIASES.hasOwnProperty(value) || SCRIPT_VALUE_ALIASES_TO_VALUE.hasOwnProperty(value);
|
||||
}
|
||||
|
||||
function isBinaryPropertyName(name) {
|
||||
return BINARY_PROP_NAMES_TO_ALIASES.hasOwnProperty(name) || BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
function getCanonicalName(name) {
|
||||
if (NON_BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name)) {
|
||||
return NON_BINARY_ALIASES_TO_PROP_NAMES[name];
|
||||
}
|
||||
|
||||
if (BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(name)) {
|
||||
return BINARY_ALIASES_TO_PROP_NAMES[name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getCanonicalValue(value) {
|
||||
if (GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES.hasOwnProperty(value)) {
|
||||
return GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES[value];
|
||||
}
|
||||
|
||||
if (SCRIPT_VALUE_ALIASES_TO_VALUE.hasOwnProperty(value)) {
|
||||
return SCRIPT_VALUE_ALIASES_TO_VALUE[value];
|
||||
}
|
||||
|
||||
if (BINARY_ALIASES_TO_PROP_NAMES.hasOwnProperty(value)) {
|
||||
return BINARY_ALIASES_TO_PROP_NAMES[value];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isAlias: isAlias,
|
||||
isValidName: isValidName,
|
||||
isValidValue: isValidValue,
|
||||
isGeneralCategoryValue: isGeneralCategoryValue,
|
||||
isScriptCategoryValue: isScriptCategoryValue,
|
||||
isBinaryPropertyName: isBinaryPropertyName,
|
||||
getCanonicalName: getCanonicalName,
|
||||
getCanonicalValue: getCanonicalValue,
|
||||
|
||||
NON_BINARY_PROP_NAMES_TO_ALIASES: NON_BINARY_PROP_NAMES_TO_ALIASES,
|
||||
NON_BINARY_ALIASES_TO_PROP_NAMES: NON_BINARY_ALIASES_TO_PROP_NAMES,
|
||||
|
||||
BINARY_PROP_NAMES_TO_ALIASES: BINARY_PROP_NAMES_TO_ALIASES,
|
||||
BINARY_ALIASES_TO_PROP_NAMES: BINARY_ALIASES_TO_PROP_NAMES,
|
||||
|
||||
GENERAL_CATEGORY_VALUE_TO_ALIASES: GENERAL_CATEGORY_VALUE_TO_ALIASES,
|
||||
GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES: GENERAL_CATEGORY_VALUE_ALIASES_TO_VALUES,
|
||||
|
||||
SCRIPT_VALUE_TO_ALIASES: SCRIPT_VALUE_TO_ALIASES,
|
||||
SCRIPT_VALUE_ALIASES_TO_VALUE: SCRIPT_VALUE_ALIASES_TO_VALUE
|
||||
};
|
178
node_modules/regexp-tree/dist/regexp-tree.js
generated
vendored
Normal file
178
node_modules/regexp-tree/dist/regexp-tree.js
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var compatTranspiler = require('./compat-transpiler');
|
||||
var generator = require('./generator');
|
||||
var optimizer = require('./optimizer');
|
||||
var parser = require('./parser');
|
||||
var _transform = require('./transform');
|
||||
var _traverse = require('./traverse');
|
||||
var fa = require('./interpreter/finite-automaton');
|
||||
|
||||
var _require = require('./compat-transpiler/runtime'),
|
||||
RegExpTree = _require.RegExpTree;
|
||||
|
||||
/**
|
||||
* An API object for RegExp processing (parsing/transform/generation).
|
||||
*/
|
||||
|
||||
|
||||
var regexpTree = {
|
||||
/**
|
||||
* Parser module exposed.
|
||||
*/
|
||||
parser: parser,
|
||||
|
||||
/**
|
||||
* Expose finite-automaton module.
|
||||
*/
|
||||
fa: fa,
|
||||
|
||||
/**
|
||||
* `TransformResult` exposed.
|
||||
*/
|
||||
TransformResult: _transform.TransformResult,
|
||||
|
||||
/**
|
||||
* Parses a regexp string, producing an AST.
|
||||
*
|
||||
* @param string regexp
|
||||
*
|
||||
* a regular expression in different formats: string, AST, RegExp.
|
||||
*
|
||||
* @param Object options
|
||||
*
|
||||
* parsing options for this parse call. Default are:
|
||||
*
|
||||
* - captureLocations: boolean
|
||||
* - any other custom options
|
||||
*
|
||||
* @return Object AST
|
||||
*/
|
||||
parse: function parse(regexp, options) {
|
||||
return parser.parse('' + regexp, options);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Traverses a RegExp AST.
|
||||
*
|
||||
* @param Object ast
|
||||
* @param Object | Array<Object> handlers
|
||||
*
|
||||
* Each `handler` is an object containing handler function for needed
|
||||
* node types. Example:
|
||||
*
|
||||
* regexpTree.traverse(ast, {
|
||||
* onChar(node) {
|
||||
* ...
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* The value for a node type may also be an object with functions pre and post.
|
||||
* This enables more context-aware analyses, e.g. measuring star height.
|
||||
*/
|
||||
traverse: function traverse(ast, handlers, options) {
|
||||
return _traverse.traverse(ast, handlers, options);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a regular expression.
|
||||
*
|
||||
* A regexp can be passed in different formats (string, regexp or AST),
|
||||
* applying a set of transformations. It is a convenient wrapper
|
||||
* on top of "parse-traverse-generate" tool chain.
|
||||
*
|
||||
* @param string | AST | RegExp regexp - a regular expression;
|
||||
* @param Object | Array<Object> handlers - a list of handlers.
|
||||
*
|
||||
* @return TransformResult - a transformation result.
|
||||
*/
|
||||
transform: function transform(regexp, handlers) {
|
||||
return _transform.transform(regexp, handlers);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Generates a RegExp string from an AST.
|
||||
*
|
||||
* @param Object ast
|
||||
*
|
||||
* Invariant:
|
||||
*
|
||||
* regexpTree.generate(regexpTree.parse('/[a-z]+/i')); // '/[a-z]+/i'
|
||||
*/
|
||||
generate: function generate(ast) {
|
||||
return generator.generate(ast);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Creates a RegExp object from a regexp string.
|
||||
*
|
||||
* @param string regexp
|
||||
*/
|
||||
toRegExp: function toRegExp(regexp) {
|
||||
var compat = this.compatTranspile(regexp);
|
||||
return new RegExp(compat.getSource(), compat.getFlags());
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Optimizes a regular expression by replacing some
|
||||
* sub-expressions with their idiomatic patterns.
|
||||
*
|
||||
* @param string regexp
|
||||
*
|
||||
* @return TransformResult object
|
||||
*/
|
||||
optimize: function optimize(regexp, whitelist) {
|
||||
return optimizer.optimize(regexp, whitelist);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Translates a regular expression in new syntax or in new format
|
||||
* into equivalent expressions in old syntax.
|
||||
*
|
||||
* @param string regexp
|
||||
*
|
||||
* @return TransformResult object
|
||||
*/
|
||||
compatTranspile: function compatTranspile(regexp, whitelist) {
|
||||
return compatTranspiler.transform(regexp, whitelist);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Executes a regular expression on a string.
|
||||
*
|
||||
* @param RegExp|string re - a regular expression.
|
||||
* @param string string - a testing string.
|
||||
*/
|
||||
exec: function exec(re, string) {
|
||||
if (typeof re === 'string') {
|
||||
var compat = this.compatTranspile(re);
|
||||
var extra = compat.getExtra();
|
||||
|
||||
if (extra.namedCapturingGroups) {
|
||||
re = new RegExpTree(compat.toRegExp(), {
|
||||
flags: compat.getFlags(),
|
||||
source: compat.getSource(),
|
||||
groups: extra.namedCapturingGroups
|
||||
});
|
||||
} else {
|
||||
re = compat.toRegExp();
|
||||
}
|
||||
}
|
||||
|
||||
return re.exec(string);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = regexpTree;
|
138
node_modules/regexp-tree/dist/transform/index.js
generated
vendored
Normal file
138
node_modules/regexp-tree/dist/transform/index.js
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var generator = require('../generator');
|
||||
var parser = require('../parser');
|
||||
var traverse = require('../traverse');
|
||||
|
||||
/**
|
||||
* Transform result.
|
||||
*/
|
||||
|
||||
var TransformResult = function () {
|
||||
/**
|
||||
* Initializes a transform result for an AST.
|
||||
*
|
||||
* @param Object ast - an AST node
|
||||
* @param mixed extra - any extra data a transform may return
|
||||
*/
|
||||
function TransformResult(ast) {
|
||||
var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
|
||||
_classCallCheck(this, TransformResult);
|
||||
|
||||
this._ast = ast;
|
||||
this._source = null;
|
||||
this._string = null;
|
||||
this._regexp = null;
|
||||
this._extra = extra;
|
||||
}
|
||||
|
||||
_createClass(TransformResult, [{
|
||||
key: 'getAST',
|
||||
value: function getAST() {
|
||||
return this._ast;
|
||||
}
|
||||
}, {
|
||||
key: 'setExtra',
|
||||
value: function setExtra(extra) {
|
||||
this._extra = extra;
|
||||
}
|
||||
}, {
|
||||
key: 'getExtra',
|
||||
value: function getExtra() {
|
||||
return this._extra;
|
||||
}
|
||||
}, {
|
||||
key: 'toRegExp',
|
||||
value: function toRegExp() {
|
||||
if (!this._regexp) {
|
||||
this._regexp = new RegExp(this.getSource(), this._ast.flags);
|
||||
}
|
||||
return this._regexp;
|
||||
}
|
||||
}, {
|
||||
key: 'getSource',
|
||||
value: function getSource() {
|
||||
if (!this._source) {
|
||||
this._source = generator.generate(this._ast.body);
|
||||
}
|
||||
return this._source;
|
||||
}
|
||||
}, {
|
||||
key: 'getFlags',
|
||||
value: function getFlags() {
|
||||
return this._ast.flags;
|
||||
}
|
||||
}, {
|
||||
key: 'toString',
|
||||
value: function toString() {
|
||||
if (!this._string) {
|
||||
this._string = generator.generate(this._ast);
|
||||
}
|
||||
return this._string;
|
||||
}
|
||||
}]);
|
||||
|
||||
return TransformResult;
|
||||
}();
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Expose `TransformResult`.
|
||||
*/
|
||||
TransformResult: TransformResult,
|
||||
|
||||
/**
|
||||
* Transforms a regular expression applying a set of
|
||||
* transformation handlers.
|
||||
*
|
||||
* @param string | AST | RegExp:
|
||||
*
|
||||
* a regular expression in different representations: a string,
|
||||
* a RegExp object, or an AST.
|
||||
*
|
||||
* @param Object | Array<Object>:
|
||||
*
|
||||
* a handler (or a list of handlers) from `traverse` API.
|
||||
*
|
||||
* @return TransformResult instance.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* transform(/[a-z]/i, {
|
||||
* onChar(path) {
|
||||
* const {node} = path;
|
||||
*
|
||||
* if (...) {
|
||||
* path.remove();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
transform: function transform(regexp, handlers) {
|
||||
var ast = regexp;
|
||||
|
||||
if (regexp instanceof RegExp) {
|
||||
regexp = '' + regexp;
|
||||
}
|
||||
|
||||
if (typeof regexp === 'string') {
|
||||
ast = parser.parse(regexp, {
|
||||
captureLocations: true
|
||||
});
|
||||
}
|
||||
|
||||
traverse.traverse(ast, handlers);
|
||||
|
||||
return new TransformResult(ast);
|
||||
}
|
||||
};
|
88
node_modules/regexp-tree/dist/transform/utils.js
generated
vendored
Normal file
88
node_modules/regexp-tree/dist/transform/utils.js
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Flattens a nested disjunction node to a list.
|
||||
*
|
||||
* /a|b|c|d/
|
||||
*
|
||||
* {{{a, b}, c}, d} -> [a, b, c, d]
|
||||
*/
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
function disjunctionToList(node) {
|
||||
if (node.type !== 'Disjunction') {
|
||||
throw new TypeError('Expected "Disjunction" node, got "' + node.type + '"');
|
||||
}
|
||||
|
||||
var list = [];
|
||||
|
||||
if (node.left && node.left.type === 'Disjunction') {
|
||||
list.push.apply(list, _toConsumableArray(disjunctionToList(node.left)).concat([node.right]));
|
||||
} else {
|
||||
list.push(node.left, node.right);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a nested disjunction node from a list.
|
||||
*
|
||||
* /a|b|c|d/
|
||||
*
|
||||
* [a, b, c, d] -> {{{a, b}, c}, d}
|
||||
*/
|
||||
function listToDisjunction(list) {
|
||||
return list.reduce(function (left, right) {
|
||||
return {
|
||||
type: 'Disjunction',
|
||||
left: left,
|
||||
right: right
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases a quantifier by one.
|
||||
* Does not change greediness.
|
||||
* * -> +
|
||||
* + -> {2,}
|
||||
* ? -> {1,2}
|
||||
* {2} -> {3}
|
||||
* {2,} -> {3,}
|
||||
* {2,3} -> {3,4}
|
||||
*/
|
||||
function increaseQuantifierByOne(quantifier) {
|
||||
if (quantifier.kind === '*') {
|
||||
|
||||
quantifier.kind = '+';
|
||||
} else if (quantifier.kind === '+') {
|
||||
|
||||
quantifier.kind = 'Range';
|
||||
quantifier.from = 2;
|
||||
delete quantifier.to;
|
||||
} else if (quantifier.kind === '?') {
|
||||
|
||||
quantifier.kind = 'Range';
|
||||
quantifier.from = 1;
|
||||
quantifier.to = 2;
|
||||
} else if (quantifier.kind === 'Range') {
|
||||
|
||||
quantifier.from += 1;
|
||||
if (quantifier.to) {
|
||||
quantifier.to += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
disjunctionToList: disjunctionToList,
|
||||
listToDisjunction: listToDisjunction,
|
||||
increaseQuantifierByOne: increaseQuantifierByOne
|
||||
};
|
313
node_modules/regexp-tree/dist/traverse/index.js
generated
vendored
Normal file
313
node_modules/regexp-tree/dist/traverse/index.js
generated
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var NodePath = require('./node-path');
|
||||
|
||||
/**
|
||||
* Does an actual AST traversal, using visitor pattern,
|
||||
* and calling set of callbacks.
|
||||
*
|
||||
* Based on https://github.com/olov/ast-traverse
|
||||
*
|
||||
* Expects AST in Mozilla Parser API: nodes which are supposed to be
|
||||
* handled should have `type` property.
|
||||
*
|
||||
* @param Object root - a root node to start traversal from.
|
||||
*
|
||||
* @param Object options - an object with set of callbacks:
|
||||
*
|
||||
* - `pre(node, parent, prop, index)` - a hook called on node enter
|
||||
* - `post`(node, parent, prop, index) - a hook called on node exit
|
||||
* - `skipProperty(prop)` - a predicated whether a property should be skipped
|
||||
*/
|
||||
function astTraverse(root) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var pre = options.pre;
|
||||
var post = options.post;
|
||||
var skipProperty = options.skipProperty;
|
||||
|
||||
function visit(node, parent, prop, idx) {
|
||||
if (!node || typeof node.type !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var res = undefined;
|
||||
if (pre) {
|
||||
res = pre(node, parent, prop, idx);
|
||||
}
|
||||
|
||||
if (res !== false) {
|
||||
|
||||
// A node can be replaced during traversal, so we have to
|
||||
// recalculate it from the parent, to avoid traversing "dead" nodes.
|
||||
if (parent && parent[prop]) {
|
||||
if (!isNaN(idx)) {
|
||||
node = parent[prop][idx];
|
||||
} else {
|
||||
node = parent[prop];
|
||||
}
|
||||
}
|
||||
|
||||
for (var _prop in node) {
|
||||
if (node.hasOwnProperty(_prop)) {
|
||||
if (skipProperty ? skipProperty(_prop, node) : _prop[0] === '$') {
|
||||
continue;
|
||||
}
|
||||
|
||||
var child = node[_prop];
|
||||
|
||||
// Collection node.
|
||||
//
|
||||
// NOTE: a node (or several nodes) can be removed or inserted
|
||||
// during traversal.
|
||||
//
|
||||
// Current traversing index is stored on top of the
|
||||
// `NodePath.traversingIndexStack`. The stack is used to support
|
||||
// recursive nature of the traversal.
|
||||
//
|
||||
// In this case `NodePath.traversingIndex` (which we use here) is
|
||||
// updated in the NodePath remove/insert methods.
|
||||
//
|
||||
if (Array.isArray(child)) {
|
||||
var index = 0;
|
||||
NodePath.traversingIndexStack.push(index);
|
||||
while (index < child.length) {
|
||||
visit(child[index], node, _prop, index);
|
||||
index = NodePath.updateTraversingIndex(+1);
|
||||
}
|
||||
NodePath.traversingIndexStack.pop();
|
||||
}
|
||||
|
||||
// Simple node.
|
||||
else {
|
||||
visit(child, node, _prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (post) {
|
||||
post(node, parent, prop, idx);
|
||||
}
|
||||
}
|
||||
|
||||
visit(root, null);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Traverses an AST.
|
||||
*
|
||||
* @param Object ast - an AST node
|
||||
*
|
||||
* @param Object | Array<Object> handlers:
|
||||
*
|
||||
* an object (or an array of objects)
|
||||
*
|
||||
* Each such object contains a handler function per node.
|
||||
* In case of an array of handlers, they are applied in order.
|
||||
* A handler may return a transformed node (or a different type).
|
||||
*
|
||||
* The per-node function may instead be an object with functions pre and post.
|
||||
* pre is called before visiting the node, post after.
|
||||
* If a handler is a function, it is treated as the pre function, with an empty post.
|
||||
*
|
||||
* @param Object options:
|
||||
*
|
||||
* a config object, specifying traversal options:
|
||||
*
|
||||
* `asNodes`: boolean - whether handlers should receives raw AST nodes
|
||||
* (false by default), instead of a `NodePath` wrapper. Note, by default
|
||||
* `NodePath` wrapper provides a set of convenient method to manipulate
|
||||
* a traversing AST, and also has access to all parents list. A raw
|
||||
* nodes traversal should be used in rare cases, when no `NodePath`
|
||||
* features are needed.
|
||||
*
|
||||
* Special hooks:
|
||||
*
|
||||
* - `shouldRun(ast)` - a predicate determining whether the handler
|
||||
* should be applied.
|
||||
*
|
||||
* NOTE: Multiple handlers are used as an optimization of applying all of
|
||||
* them in one AST traversal pass.
|
||||
*/
|
||||
traverse: function traverse(ast, handlers) {
|
||||
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { asNodes: false };
|
||||
|
||||
|
||||
if (!Array.isArray(handlers)) {
|
||||
handlers = [handlers];
|
||||
}
|
||||
|
||||
// Filter out handlers by result of `shouldRun`, if the method is present.
|
||||
handlers = handlers.filter(function (handler) {
|
||||
if (typeof handler.shouldRun !== 'function') {
|
||||
return true;
|
||||
}
|
||||
return handler.shouldRun(ast);
|
||||
});
|
||||
|
||||
NodePath.initRegistry();
|
||||
|
||||
// Allow handlers to initializer themselves.
|
||||
handlers.forEach(function (handler) {
|
||||
if (typeof handler.init === 'function') {
|
||||
handler.init(ast);
|
||||
}
|
||||
});
|
||||
|
||||
function getPathFor(node, parent, prop, index) {
|
||||
var parentPath = NodePath.getForNode(parent);
|
||||
var nodePath = NodePath.getForNode(node, parentPath, prop, index);
|
||||
|
||||
return nodePath;
|
||||
}
|
||||
|
||||
// Handle actual nodes.
|
||||
astTraverse(ast, {
|
||||
/**
|
||||
* Handler on node enter.
|
||||
*/
|
||||
pre: function pre(node, parent, prop, index) {
|
||||
var nodePath = void 0;
|
||||
if (!options.asNodes) {
|
||||
nodePath = getPathFor(node, parent, prop, index);
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var handler = _step.value;
|
||||
|
||||
// "Catch-all" `*` handler.
|
||||
if (typeof handler['*'] === 'function') {
|
||||
if (nodePath) {
|
||||
// A path/node can be removed by some previous handler.
|
||||
if (!nodePath.isRemoved()) {
|
||||
var handlerResult = handler['*'](nodePath);
|
||||
// Explicitly stop traversal.
|
||||
if (handlerResult === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handler['*'](node, parent, prop, index);
|
||||
}
|
||||
}
|
||||
|
||||
// Per-node handler.
|
||||
var handlerFuncPre = void 0;
|
||||
if (typeof handler[node.type] === 'function') {
|
||||
handlerFuncPre = handler[node.type];
|
||||
} else if (typeof handler[node.type] === 'object' && typeof handler[node.type].pre === 'function') {
|
||||
handlerFuncPre = handler[node.type].pre;
|
||||
}
|
||||
|
||||
if (handlerFuncPre) {
|
||||
if (nodePath) {
|
||||
// A path/node can be removed by some previous handler.
|
||||
if (!nodePath.isRemoved()) {
|
||||
var _handlerResult = handlerFuncPre.call(handler, nodePath);
|
||||
// Explicitly stop traversal.
|
||||
if (_handlerResult === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handlerFuncPre.call(handler, node, parent, prop, index);
|
||||
}
|
||||
}
|
||||
} // Loop over handlers
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// pre func
|
||||
|
||||
/**
|
||||
* Handler on node exit.
|
||||
*/
|
||||
post: function post(node, parent, prop, index) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
var nodePath = void 0;
|
||||
if (!options.asNodes) {
|
||||
nodePath = getPathFor(node, parent, prop, index);
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = handlers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var handler = _step2.value;
|
||||
|
||||
// Per-node handler.
|
||||
var handlerFuncPost = void 0;
|
||||
if (typeof handler[node.type] === 'object' && typeof handler[node.type].post === 'function') {
|
||||
handlerFuncPost = handler[node.type].post;
|
||||
}
|
||||
|
||||
if (handlerFuncPost) {
|
||||
if (nodePath) {
|
||||
// A path/node can be removed by some previous handler.
|
||||
if (!nodePath.isRemoved()) {
|
||||
var handlerResult = handlerFuncPost.call(handler, nodePath);
|
||||
// Explicitly stop traversal.
|
||||
if (handlerResult === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handlerFuncPost.call(handler, node, parent, prop, index);
|
||||
}
|
||||
}
|
||||
} // Loop over handlers
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// post func
|
||||
|
||||
/**
|
||||
* Skip locations by default.
|
||||
*/
|
||||
skipProperty: function skipProperty(prop) {
|
||||
return prop === 'loc';
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
426
node_modules/regexp-tree/dist/traverse/node-path.js
generated
vendored
Normal file
426
node_modules/regexp-tree/dist/traverse/node-path.js
generated
vendored
Normal file
@ -0,0 +1,426 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var DEFAULT_COLLECTION_PROP = 'expressions';
|
||||
var DEFAULT_SINGLE_PROP = 'expression';
|
||||
|
||||
/**
|
||||
* NodePath class encapsulates a traversing node,
|
||||
* its parent node, property name in the parent node, and
|
||||
* an index (in case if a node is part of a collection).
|
||||
* It also provides set of methods for AST manipulation.
|
||||
*/
|
||||
|
||||
var NodePath = function () {
|
||||
/**
|
||||
* NodePath constructor.
|
||||
*
|
||||
* @param Object node - an AST node
|
||||
* @param NodePath parentPath - a nullable parent path
|
||||
* @param string property - property name of the node in the parent
|
||||
* @param number index - index of the node in a collection.
|
||||
*/
|
||||
function NodePath(node) {
|
||||
var parentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
var property = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
||||
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
||||
|
||||
_classCallCheck(this, NodePath);
|
||||
|
||||
this.node = node;
|
||||
this.parentPath = parentPath;
|
||||
this.parent = parentPath ? parentPath.node : null;
|
||||
this.property = property;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
_createClass(NodePath, [{
|
||||
key: '_enforceProp',
|
||||
value: function _enforceProp(property) {
|
||||
if (!this.node.hasOwnProperty(property)) {
|
||||
throw new Error('Node of type ' + this.node.type + ' doesn\'t have "' + property + '" collection.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a node into a children collection or the single child.
|
||||
* By default child nodes are supposed to be under `expressions` property.
|
||||
* An explicit property can be passed.
|
||||
*
|
||||
* @param Object node - a node to set into a collection or as single child
|
||||
* @param number index - index at which to set
|
||||
* @param string property - name of the collection or single property
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'setChild',
|
||||
value: function setChild(node) {
|
||||
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
var property = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
||||
|
||||
|
||||
var childPath = void 0;
|
||||
if (index != null) {
|
||||
if (!property) {
|
||||
property = DEFAULT_COLLECTION_PROP;
|
||||
}
|
||||
this._enforceProp(property);
|
||||
this.node[property][index] = node;
|
||||
childPath = NodePath.getForNode(node, this, property, index);
|
||||
} else {
|
||||
if (!property) {
|
||||
property = DEFAULT_SINGLE_PROP;
|
||||
}
|
||||
this._enforceProp(property);
|
||||
this.node[property] = node;
|
||||
childPath = NodePath.getForNode(node, this, property, null);
|
||||
}
|
||||
return childPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a node to a children collection.
|
||||
* By default child nodes are supposed to be under `expressions` property.
|
||||
* An explicit property can be passed.
|
||||
*
|
||||
* @param Object node - a node to set into a collection or as single child
|
||||
* @param string property - name of the collection or single property
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'appendChild',
|
||||
value: function appendChild(node) {
|
||||
var property = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
|
||||
|
||||
if (!property) {
|
||||
property = DEFAULT_COLLECTION_PROP;
|
||||
}
|
||||
this._enforceProp(property);
|
||||
var end = this.node[property].length;
|
||||
return this.setChild(node, end, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a node into a collection.
|
||||
* By default child nodes are supposed to be under `expressions` property.
|
||||
* An explicit property can be passed.
|
||||
*
|
||||
* @param Object node - a node to insert into a collection
|
||||
* @param number index - index at which to insert
|
||||
* @param string property - name of the collection property
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'insertChildAt',
|
||||
value: function insertChildAt(node, index) {
|
||||
var property = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COLLECTION_PROP;
|
||||
|
||||
this._enforceProp(property);
|
||||
|
||||
this.node[property].splice(index, 0, node);
|
||||
|
||||
// If we inserted a node before the traversing index,
|
||||
// we should increase the later.
|
||||
if (index <= NodePath.getTraversingIndex()) {
|
||||
NodePath.updateTraversingIndex(+1);
|
||||
}
|
||||
|
||||
this._rebuildIndex(this.node, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a node.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'remove',
|
||||
value: function remove() {
|
||||
if (this.isRemoved()) {
|
||||
return;
|
||||
}
|
||||
NodePath.registry.delete(this.node);
|
||||
|
||||
this.node = null;
|
||||
|
||||
if (!this.parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A node is in a collection.
|
||||
if (this.index !== null) {
|
||||
this.parent[this.property].splice(this.index, 1);
|
||||
|
||||
// If we remove a node before the traversing index,
|
||||
// we should increase the later.
|
||||
if (this.index <= NodePath.getTraversingIndex()) {
|
||||
NodePath.updateTraversingIndex(-1);
|
||||
}
|
||||
|
||||
// Rebuild index.
|
||||
this._rebuildIndex(this.parent, this.property);
|
||||
|
||||
this.index = null;
|
||||
this.property = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// A simple node.
|
||||
delete this.parent[this.property];
|
||||
this.property = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds child nodes index (used on remove/insert).
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: '_rebuildIndex',
|
||||
value: function _rebuildIndex(parent, property) {
|
||||
var parentPath = NodePath.getForNode(parent);
|
||||
|
||||
for (var i = 0; i < parent[property].length; i++) {
|
||||
var path = NodePath.getForNode(parent[property][i], parentPath, property, i);
|
||||
path.index = i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the path was removed.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'isRemoved',
|
||||
value: function isRemoved() {
|
||||
return this.node === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a node with the passed one.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'replace',
|
||||
value: function replace(newNode) {
|
||||
NodePath.registry.delete(this.node);
|
||||
|
||||
this.node = newNode;
|
||||
|
||||
if (!this.parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// A node is in a collection.
|
||||
if (this.index !== null) {
|
||||
this.parent[this.property][this.index] = newNode;
|
||||
}
|
||||
|
||||
// A simple node.
|
||||
else {
|
||||
this.parent[this.property] = newNode;
|
||||
}
|
||||
|
||||
// Rebuild the node path for the new node.
|
||||
return NodePath.getForNode(newNode, this.parentPath, this.property, this.index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a node inline.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'update',
|
||||
value: function update(nodeProps) {
|
||||
Object.assign(this.node, nodeProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns parent.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getParent',
|
||||
value: function getParent() {
|
||||
return this.parentPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns nth child.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getChild',
|
||||
value: function getChild() {
|
||||
var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||
|
||||
if (this.node.expressions) {
|
||||
return NodePath.getForNode(this.node.expressions[n], this, DEFAULT_COLLECTION_PROP, n);
|
||||
} else if (this.node.expression && n == 0) {
|
||||
return NodePath.getForNode(this.node.expression, this, DEFAULT_SINGLE_PROP);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a path node is syntactically equal to the passed one.
|
||||
*
|
||||
* NOTE: we don't rely on `source` property from the `loc` data
|
||||
* (which would be the fastest comparison), since it might be unsync
|
||||
* after several modifications. We use here simple `JSON.stringify`
|
||||
* excluding the `loc` data.
|
||||
*
|
||||
* @param NodePath other - path to compare to.
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'hasEqualSource',
|
||||
value: function hasEqualSource(path) {
|
||||
return JSON.stringify(this.node, jsonSkipLoc) === JSON.stringify(path.node, jsonSkipLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON-encodes a node skipping location.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'jsonEncode',
|
||||
value: function jsonEncode() {
|
||||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
||||
format = _ref.format,
|
||||
useLoc = _ref.useLoc;
|
||||
|
||||
return JSON.stringify(this.node, useLoc ? null : jsonSkipLoc, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns previous sibling.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getPreviousSibling',
|
||||
value: function getPreviousSibling() {
|
||||
if (!this.parent || this.index == null) {
|
||||
return null;
|
||||
}
|
||||
return NodePath.getForNode(this.parent[this.property][this.index - 1], NodePath.getForNode(this.parent), this.property, this.index - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next sibling.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getNextSibling',
|
||||
value: function getNextSibling() {
|
||||
if (!this.parent || this.index == null) {
|
||||
return null;
|
||||
}
|
||||
return NodePath.getForNode(this.parent[this.property][this.index + 1], NodePath.getForNode(this.parent), this.property, this.index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a NodePath instance for a node.
|
||||
*
|
||||
* The same NodePath can be reused in several places, e.g.
|
||||
* a parent node passed for all its children.
|
||||
*/
|
||||
|
||||
}], [{
|
||||
key: 'getForNode',
|
||||
value: function getForNode(node) {
|
||||
var parentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
var prop = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
||||
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;
|
||||
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!NodePath.registry.has(node)) {
|
||||
NodePath.registry.set(node, new NodePath(node, parentPath, prop, index == -1 ? null : index));
|
||||
}
|
||||
|
||||
var path = NodePath.registry.get(node);
|
||||
|
||||
if (parentPath !== null) {
|
||||
path.parentPath = parentPath;
|
||||
path.parent = path.parentPath.node;
|
||||
}
|
||||
|
||||
if (prop !== null) {
|
||||
path.property = prop;
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
path.index = index;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the NodePath registry. The registry is a map from
|
||||
* a node to its NodePath instance.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'initRegistry',
|
||||
value: function initRegistry() {
|
||||
if (!NodePath.registry) {
|
||||
NodePath.registry = new Map();
|
||||
}
|
||||
NodePath.registry.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates index of a currently traversing collection.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'updateTraversingIndex',
|
||||
value: function updateTraversingIndex(dx) {
|
||||
return NodePath.traversingIndexStack[NodePath.traversingIndexStack.length - 1] += dx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current traversing index.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'getTraversingIndex',
|
||||
value: function getTraversingIndex() {
|
||||
return NodePath.traversingIndexStack[NodePath.traversingIndexStack.length - 1];
|
||||
}
|
||||
}]);
|
||||
|
||||
return NodePath;
|
||||
}();
|
||||
|
||||
NodePath.initRegistry();
|
||||
|
||||
/**
|
||||
* Index of a currently traversing collection is stored on top of the
|
||||
* `NodePath.traversingIndexStack`. Remove/insert methods can adjust
|
||||
* this index.
|
||||
*/
|
||||
NodePath.traversingIndexStack = [];
|
||||
|
||||
// Helper function used to skip `loc` in JSON operations.
|
||||
function jsonSkipLoc(prop, value) {
|
||||
if (prop === 'loc') {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
module.exports = NodePath;
|
29
node_modules/regexp-tree/dist/utils/clone.js
generated
vendored
Normal file
29
node_modules/regexp-tree/dist/utils/clone.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Performs a deep copy of an simple object.
|
||||
* Only handles scalar values, arrays and objects.
|
||||
*
|
||||
* @param obj Object
|
||||
*/
|
||||
|
||||
module.exports = function clone(obj) {
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
return obj;
|
||||
}
|
||||
var res = void 0;
|
||||
if (Array.isArray(obj)) {
|
||||
res = [];
|
||||
} else {
|
||||
res = {};
|
||||
}
|
||||
for (var i in obj) {
|
||||
res[i] = clone(obj[i]);
|
||||
}
|
||||
return res;
|
||||
};
|
Reference in New Issue
Block a user