refactor: init cypress-cucumber-preprocessor install.

This commit is contained in:
2021-09-02 17:02:45 +02:00
parent 89ec2d42ac
commit 1aa57bbd0a
5000 changed files with 408119 additions and 231 deletions

42
node_modules/cucumber-expressions/dist/src/argument.js generated vendored Normal file
View File

@@ -0,0 +1,42 @@
"use strict";
const {
CucumberExpressionError
} = require('./errors');
class Argument {
static build(treeRegexp, text, parameterTypes) {
const group = treeRegexp.match(text);
if (!group) return null;
const argGroups = group.children;
if (argGroups.length !== parameterTypes.length) {
throw new CucumberExpressionError(`Expression ${treeRegexp.regexp} has ${argGroups.length} capture groups (${argGroups.map(g => g.value)}), but there were ${parameterTypes.length} parameter types (${parameterTypes.map(p => p.name)})`);
}
return parameterTypes.map((parameterType, i) => new Argument(argGroups[i], parameterType));
}
constructor(group, parameterType) {
this._group = group;
this._parameterType = parameterType;
}
get group() {
return this._group;
}
/**
* Get the value returned by the parameter type's transformer function.
*
* @param thisObj the object in which the transformer function is applied.
*/
getValue(thisObj) {
let groupValues = this._group ? this._group.values : null;
return this._parameterType.transform(thisObj, groupValues);
}
}
module.exports = Argument;

View File

@@ -0,0 +1,48 @@
"use strict";
const GeneratedExpression = require('./generated_expression'); // 256 generated expressions ought to be enough for anybody
const MAX_EXPRESSIONS = 256;
class CombinatorialGeneratedExpressionFactory {
constructor(expressionTemplate, parameterTypeCombinations) {
this._expressionTemplate = expressionTemplate;
this._parameterTypeCombinations = parameterTypeCombinations;
}
generateExpressions() {
const generatedExpressions = [];
this._generatePermutations(generatedExpressions, 0, []);
return generatedExpressions;
}
_generatePermutations(generatedExpressions, depth, currentParameterTypes) {
if (generatedExpressions.length >= MAX_EXPRESSIONS) {
return;
}
if (depth === this._parameterTypeCombinations.length) {
generatedExpressions.push(new GeneratedExpression(this._expressionTemplate, currentParameterTypes));
return;
}
for (let i = 0; i < this._parameterTypeCombinations[depth].length; ++i) {
// Avoid recursion if no elements can be added.
if (generatedExpressions.length >= MAX_EXPRESSIONS) {
return;
}
const newCurrentParameterTypes = currentParameterTypes.slice(); // clone
newCurrentParameterTypes.push(this._parameterTypeCombinations[depth][i]);
this._generatePermutations(generatedExpressions, depth + 1, newCurrentParameterTypes);
}
}
}
module.exports = CombinatorialGeneratedExpressionFactory;

View File

@@ -0,0 +1,125 @@
"use strict";
const Argument = require('./argument');
const TreeRegexp = require('./tree_regexp');
const ParameterType = require('./parameter_type');
const {
UndefinedParameterTypeError,
CucumberExpressionError
} = require('./errors'); // RegExps with the g flag are stateful in JavaScript. In order to be able
// to reuse them we have to wrap them in a function.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
// Does not include (){} characters because they have special meaning
const ESCAPE_REGEXP = () => /([\\^[$.|?*+])/g;
const PARAMETER_REGEXP = () => /(\\\\)?{([^}]*)}/g;
const OPTIONAL_REGEXP = () => /(\\\\)?\(([^)]+)\)/g;
const ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP = () => /([^\s^/]+)((\/[^\s^/]+)+)/g;
const DOUBLE_ESCAPE = '\\\\';
const PARAMETER_TYPES_CANNOT_BE_ALTERNATIVE = 'Parameter types cannot be alternative: ';
const PARAMETER_TYPES_CANNOT_BE_OPTIONAL = 'Parameter types cannot be optional: ';
class CucumberExpression {
/**
* @param expression
* @param parameterTypeRegistry
*/
constructor(expression, parameterTypeRegistry) {
this._expression = expression;
this._parameterTypes = [];
expression = this.processEscapes(expression);
expression = this.processOptional(expression);
expression = this.processAlternation(expression);
expression = this.processParameters(expression, parameterTypeRegistry);
expression = `^${expression}$`;
this._treeRegexp = new TreeRegexp(expression);
}
processEscapes(expression) {
return expression.replace(ESCAPE_REGEXP(), '\\$1');
}
processOptional(expression) {
return expression.replace(OPTIONAL_REGEXP(), (match, p1, p2) => {
if (p1 === DOUBLE_ESCAPE) {
return `\\(${p2}\\)`;
}
this._checkNoParameterType(p2, PARAMETER_TYPES_CANNOT_BE_OPTIONAL);
return `(?:${p2})?`;
});
}
processAlternation(expression) {
return expression.replace(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP(), match => {
// replace \/ with /
// replace / with |
const replacement = match.replace(/\//g, '|').replace(/\\\|/g, '/');
if (replacement.indexOf('|') !== -1) {
for (const part of replacement.split(/\|/)) {
this._checkNoParameterType(part, PARAMETER_TYPES_CANNOT_BE_ALTERNATIVE);
}
return `(?:${replacement})`;
} else {
return replacement;
}
});
}
processParameters(expression, parameterTypeRegistry) {
return expression.replace(PARAMETER_REGEXP(), (match, p1, p2) => {
if (p1 === DOUBLE_ESCAPE) return `\\{${p2}\\}`;
const typeName = p2;
ParameterType.checkParameterTypeName(typeName);
const parameterType = parameterTypeRegistry.lookupByTypeName(typeName);
if (!parameterType) throw new UndefinedParameterTypeError(typeName);
this._parameterTypes.push(parameterType);
return buildCaptureRegexp(parameterType.regexps);
});
}
match(text) {
return Argument.build(this._treeRegexp, text, this._parameterTypes);
}
get regexp() {
return this._treeRegexp.regexp;
}
get source() {
return this._expression;
}
_checkNoParameterType(s, message) {
if (s.match(PARAMETER_REGEXP())) {
throw new CucumberExpressionError(message + this.source);
}
}
}
function buildCaptureRegexp(regexps) {
if (regexps.length === 1) {
return `(${regexps[0]})`;
}
const captureGroups = regexps.map(group => {
return `(?:${group})`;
});
return `(${captureGroups.join('|')})`;
}
module.exports = CucumberExpression;

View File

@@ -0,0 +1,110 @@
"use strict";
const util = require('util');
const ParameterTypeMatcher = require('./parameter_type_matcher');
const ParameterType = require('./parameter_type');
const CombinatorialGeneratedExpressionFactory = require('./combinatorial_generated_expression_factory');
class CucumberExpressionGenerator {
constructor(parameterTypeRegistry) {
this._parameterTypeRegistry = parameterTypeRegistry;
}
generateExpressions(text) {
const parameterTypeCombinations = [];
const parameterTypeMatchers = this._createParameterTypeMatchers(text);
let expressionTemplate = '';
let pos = 0; // eslint-disable-next-line no-constant-condition
while (true) {
let matchingParameterTypeMatchers = [];
for (const parameterTypeMatcher of parameterTypeMatchers) {
const advancedParameterTypeMatcher = parameterTypeMatcher.advanceTo(pos);
if (advancedParameterTypeMatcher.find) {
matchingParameterTypeMatchers.push(advancedParameterTypeMatcher);
}
}
if (matchingParameterTypeMatchers.length > 0) {
matchingParameterTypeMatchers = matchingParameterTypeMatchers.sort(ParameterTypeMatcher.compare); // Find all the best parameter type matchers, they are all candidates.
const bestParameterTypeMatcher = matchingParameterTypeMatchers[0];
const bestParameterTypeMatchers = matchingParameterTypeMatchers.filter(m => ParameterTypeMatcher.compare(m, bestParameterTypeMatcher) === 0); // Build a list of parameter types without duplicates. The reason there
// might be duplicates is that some parameter types have more than one regexp,
// which means multiple ParameterTypeMatcher objects will have a reference to the
// same ParameterType.
// We're sorting the list so preferential parameter types are listed first.
// Users are most likely to want these, so they should be listed at the top.
let parameterTypes = [];
for (const parameterTypeMatcher of bestParameterTypeMatchers) {
if (parameterTypes.indexOf(parameterTypeMatcher.parameterType) === -1) {
parameterTypes.push(parameterTypeMatcher.parameterType);
}
}
parameterTypes = parameterTypes.sort(ParameterType.compare);
parameterTypeCombinations.push(parameterTypes);
expressionTemplate += escape(text.slice(pos, bestParameterTypeMatcher.start));
expressionTemplate += '{%s}';
pos = bestParameterTypeMatcher.start + bestParameterTypeMatcher.group.length;
} else {
break;
}
if (pos >= text.length) {
break;
}
}
expressionTemplate += escape(text.slice(pos));
return new CombinatorialGeneratedExpressionFactory(expressionTemplate, parameterTypeCombinations).generateExpressions();
}
/**
* @deprecated
*/
generateExpression(text) {
return util.deprecate(() => this.generateExpressions(text)[0], 'CucumberExpressionGenerator.generateExpression: Use CucumberExpressionGenerator.generateExpressions instead')();
}
_createParameterTypeMatchers(text) {
let parameterMatchers = [];
for (const parameterType of this._parameterTypeRegistry.parameterTypes) {
if (parameterType.useForSnippets) {
parameterMatchers = parameterMatchers.concat(this._createParameterTypeMatchers2(parameterType, text));
}
}
return parameterMatchers;
}
_createParameterTypeMatchers2(parameterType, text) {
// TODO: [].map
const result = [];
for (const regexp of parameterType.regexps) {
result.push(new ParameterTypeMatcher(parameterType, regexp, text));
}
return result;
}
}
function escape(s) {
return s.replace(/%/g, '%%') // for util.format
.replace(/\(/g, '\\(').replace(/{/g, '\\{').replace(/\//g, '\\/');
}
module.exports = CucumberExpressionGenerator;

45
node_modules/cucumber-expressions/dist/src/errors.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
"use strict";
class CucumberExpressionError extends Error {}
class AmbiguousParameterTypeError extends CucumberExpressionError {
static forConstructor(keyName, keyValue, parameterTypes, generatedExpressions) {
return new this(`parameter type with ${keyName}=${keyValue} is used by several parameter types: ${parameterTypes}, ${generatedExpressions}`);
}
static forRegExp(parameterTypeRegexp, expressionRegexp, parameterTypes, generatedExpressions) {
return new this(`Your Regular Expression ${expressionRegexp}
matches multiple parameter types with regexp ${parameterTypeRegexp}:
${this._parameterTypeNames(parameterTypes)}
I couldn't decide which one to use. You have two options:
1) Use a Cucumber Expression instead of a Regular Expression. Try one of these:
${this._expressions(generatedExpressions)}
2) Make one of the parameter types preferential and continue to use a Regular Expression.
`);
}
static _parameterTypeNames(parameterTypes) {
return parameterTypes.map(p => `{${p.name}}`).join('\n ');
}
static _expressions(generatedExpressions) {
return generatedExpressions.map(e => e.source).join('\n ');
}
}
class UndefinedParameterTypeError extends CucumberExpressionError {
constructor(typeName) {
super(`Undefined parameter type {${typeName}}`);
}
}
module.exports = {
AmbiguousParameterTypeError,
UndefinedParameterTypeError,
CucumberExpressionError
};

View File

@@ -0,0 +1,43 @@
"use strict";
const util = require('util');
class GeneratedExpression {
constructor(expressionTemplate, parameterTypes) {
this._expressionTemplate = expressionTemplate;
this._parameterTypes = parameterTypes;
}
get source() {
return util.format(this._expressionTemplate, ...this._parameterTypes.map(t => t.name));
}
/**
* Returns an array of parameter names to use in generated function/method signatures
*
* @returns {Array.<String>}
*/
get parameterNames() {
const usageByTypeName = {};
return this._parameterTypes.map(t => getParameterName(t.name, usageByTypeName));
}
/**
* @returns {Array.<ParameterType>}
*/
get parameterTypes() {
return this._parameterTypes;
}
}
function getParameterName(typeName, usageByTypeName) {
let count = usageByTypeName[typeName];
count = count ? count + 1 : 1;
usageByTypeName[typeName] = count;
return count === 1 ? typeName : `${typeName}${count}`;
}
module.exports = GeneratedExpression;

33
node_modules/cucumber-expressions/dist/src/group.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
"use strict";
class Group {
constructor(value, start, end, children) {
this._value = value;
this._start = start;
this._end = end;
this._children = children;
}
get value() {
return this._value;
}
get start() {
return this._start;
}
get end() {
return this._end;
}
get children() {
return this._children;
}
get values() {
return (this.children.length === 0 ? [this] : this.children).map(g => g.value).filter(v => v !== undefined);
}
}
module.exports = Group;

View File

@@ -0,0 +1,41 @@
"use strict";
const Group = require('./group');
class GroupBuilder {
constructor() {
this._groupBuilders = [];
this._capturing = true;
}
add(groupBuilder) {
this._groupBuilders.push(groupBuilder);
}
build(match, nextGroupIndex) {
const groupIndex = nextGroupIndex();
const children = this._groupBuilders.map(gb => gb.build(match, nextGroupIndex));
return new Group(match[groupIndex], match.index[groupIndex], match.index[groupIndex] + (match[groupIndex] || '').length, children);
}
setNonCapturing() {
this._capturing = false;
}
get capturing() {
return this._capturing;
}
get children() {
return this._groupBuilders;
}
moveChildrenTo(groupBuilder) {
this._groupBuilders.forEach(child => groupBuilder.add(child));
}
}
module.exports = GroupBuilder;

19
node_modules/cucumber-expressions/dist/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
"use strict";
const CucumberExpression = require('./cucumber_expression');
const RegularExpression = require('./regular_expression');
const CucumberExpressionGenerator = require('./cucumber_expression_generator');
const ParameterTypeRegistry = require('./parameter_type_registry');
const ParameterType = require('./parameter_type');
module.exports = {
CucumberExpression,
RegularExpression,
CucumberExpressionGenerator,
ParameterTypeRegistry,
ParameterType
};

View File

@@ -0,0 +1,106 @@
"use strict";
const {
CucumberExpressionError
} = require('./errors');
const ILLEGAL_PARAMETER_NAME_PATTERN = /([[\]()$.|?*+])/;
const UNESCAPE_PATTERN = () => /(\\([[$.|?*+\]]))/g;
class ParameterType {
static compare(pt1, pt2) {
if (pt1.preferForRegexpMatch && !pt2.preferForRegexpMatch) return -1;
if (pt2.preferForRegexpMatch && !pt1.preferForRegexpMatch) return 1;
return pt1.name.localeCompare(pt2.name);
}
static checkParameterTypeName(typeName) {
const unescapedTypeName = typeName.replace(UNESCAPE_PATTERN(), '$2');
const match = unescapedTypeName.match(ILLEGAL_PARAMETER_NAME_PATTERN);
if (match) throw new CucumberExpressionError(`Illegal character '${match[1]}' in parameter name {${unescapedTypeName}}`);
}
/**
* @param name {String} the name of the type
* @param regexps {Array.<RegExp>,RegExp,Array.<String>,String} that matches the type
* @param type {Function} the prototype (constructor) of the type. May be null.
* @param transform {Function} function transforming string to another type. May be null.
* @param useForSnippets {boolean} true if this should be used for snippets. Defaults to true.
* @param preferForRegexpMatch {boolean} true if this is a preferential type. Defaults to false.
*/
constructor(name, regexps, type, transform, useForSnippets, preferForRegexpMatch) {
if (transform === undefined) transform = s => s;
if (useForSnippets === undefined) useForSnippets = true;
if (preferForRegexpMatch === undefined) preferForRegexpMatch = false;
if (name) ParameterType.checkParameterTypeName(name);
this._name = name;
this._regexps = stringArray(regexps);
this._type = type;
this._transform = transform;
this._useForSnippets = useForSnippets;
this._preferForRegexpMatch = preferForRegexpMatch;
}
get name() {
return this._name;
}
get regexps() {
return this._regexps;
}
get type() {
return this._type;
}
get preferForRegexpMatch() {
return this._preferForRegexpMatch;
}
get useForSnippets() {
return this._useForSnippets;
}
transform(thisObj, groupValues) {
return this._transform.apply(thisObj, groupValues);
}
}
function stringArray(regexps) {
const array = Array.isArray(regexps) ? regexps : [regexps];
return array.map(r => typeof r === 'string' ? r : regexpSource(r));
}
function regexpSource(regexp) {
const flags = regexpFlags(regexp);
for (const flag of ['g', 'i', 'm', 'y']) {
if (flags.indexOf(flag) !== -1) throw new CucumberExpressionError(`ParameterType Regexps can't use flag '${flag}'`);
}
return regexp.source;
} // Backport RegExp.flags for Node 4.x
// https://github.com/nodejs/node/issues/8390
//
// For some strange reason this is not needed for
// `./mocha dist/test`, but it is needed for
// `./mocha dist/test/parameter_type_test.js`
function regexpFlags(regexp) {
let flags = regexp.flags;
if (flags === undefined) {
flags = '';
if (regexp.ignoreCase) flags += 'i';
if (regexp.global) flags += 'g';
if (regexp.multiline) flags += 'm';
}
return flags;
}
module.exports = ParameterType;

View File

@@ -0,0 +1,51 @@
"use strict";
class ParameterTypeMatcher {
constructor(parameter, regexp, text, matchPosition) {
this._parameterType = parameter;
this._treeRegexp = regexp;
this._text = text;
this._matchPosition = matchPosition || 0;
const captureGroupRegexp = new RegExp(`(${regexp})`);
this._match = captureGroupRegexp.exec(text.slice(this._matchPosition));
}
get parameterType() {
return this._parameterType;
}
advanceTo(newMatchPosition) {
for (let advancedPos = newMatchPosition; advancedPos < this._text.length; advancedPos++) {
let matcher = new ParameterTypeMatcher(this._parameterType, this._treeRegexp, this._text, advancedPos);
if (matcher.find) {
return matcher;
}
}
return new ParameterTypeMatcher(this._parameterType, this._treeRegexp, this._text, this._text.length);
}
get find() {
return this._match && this.group !== '';
}
get start() {
return this._matchPosition + this._match.index;
}
get group() {
return this._match[0];
}
static compare(a, b) {
const posComparison = a.start - b.start;
if (posComparison !== 0) return posComparison;
const lengthComparison = b.group.length - a.group.length;
if (lengthComparison !== 0) return lengthComparison;
return 0;
}
}
module.exports = ParameterTypeMatcher;

View File

@@ -0,0 +1,83 @@
"use strict";
const ParameterType = require('./parameter_type');
const CucumberExpressionGenerator = require('./cucumber_expression_generator.js');
const {
CucumberExpressionError,
AmbiguousParameterTypeError
} = require('./errors');
const INTEGER_REGEXPS = [/-?\d+/, /\d+/];
const FLOAT_REGEXP = /-?\d*\.\d+/;
const WORD_REGEXP = /[^\s]+/;
const STRING_REGEXP = /"([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'/;
const ANONYMOUS_REGEXP = /.*/;
class ParameterTypeRegistry {
constructor() {
this._parameterTypeByName = new Map();
this._parameterTypesByRegexp = new Map();
this.defineParameterType(new ParameterType('int', INTEGER_REGEXPS, Number, s => s && parseInt(s), true, true));
this.defineParameterType(new ParameterType('float', FLOAT_REGEXP, Number, s => s && parseFloat(s), true, false));
this.defineParameterType(new ParameterType('word', WORD_REGEXP, String, s => s, false, false));
this.defineParameterType(new ParameterType('string', STRING_REGEXP, String, s => s.replace(/\\"/g, '"').replace(/\\'/g, "'"), true, false));
this.defineParameterType(new ParameterType('', ANONYMOUS_REGEXP, String, s => s, false, true));
}
get parameterTypes() {
return this._parameterTypeByName.values();
}
lookupByTypeName(typeName) {
return this._parameterTypeByName.get(typeName);
}
lookupByRegexp(parameterTypeRegexp, expressionRegexp, text) {
const parameterTypes = this._parameterTypesByRegexp.get(parameterTypeRegexp);
if (!parameterTypes) return null;
if (parameterTypes.length > 1 && !parameterTypes[0].preferForRegexpMatch) {
// We don't do this check on insertion because we only want to restrict
// ambiguiuty when we look up by Regexp. Users of CucumberExpression should
// not be restricted.
const generatedExpressions = new CucumberExpressionGenerator(this).generateExpressions(text);
throw new AmbiguousParameterTypeError.forRegExp(parameterTypeRegexp, expressionRegexp, parameterTypes, generatedExpressions);
}
return parameterTypes[0];
}
defineParameterType(parameterType) {
if (parameterType.name !== undefined) {
if (this._parameterTypeByName.has(parameterType.name)) if (parameterType.name.length === 0) throw new Error(`The anonymous parameter type has already been defined`);else throw new Error(`There is already a parameter type with name ${parameterType.name}`);
this._parameterTypeByName.set(parameterType.name, parameterType);
}
for (const parameterTypeRegexp of parameterType.regexps) {
if (!this._parameterTypesByRegexp.has(parameterTypeRegexp)) {
this._parameterTypesByRegexp.set(parameterTypeRegexp, []);
}
const parameterTypes = this._parameterTypesByRegexp.get(parameterTypeRegexp);
const existingParameterType = parameterTypes[0];
if (parameterTypes.length > 0 && existingParameterType.preferForRegexpMatch && parameterType.preferForRegexpMatch) {
throw new CucumberExpressionError('There can only be one preferential parameter type per regexp. ' + `The regexp /${parameterTypeRegexp}/ is used for two preferential parameter types, {${existingParameterType.name}} and {${parameterType.name}}`);
}
if (parameterTypes.indexOf(parameterType) === -1) {
parameterTypes.push(parameterType);
this._parameterTypesByRegexp.set(parameterTypeRegexp, parameterTypes.sort(ParameterType.compare));
}
}
}
}
module.exports = ParameterTypeRegistry;

View File

@@ -0,0 +1,35 @@
"use strict";
const Argument = require('./argument');
const TreeRegexp = require('./tree_regexp');
const ParameterType = require('./parameter_type');
class RegularExpression {
constructor(expressionRegexp, parameterTypeRegistry) {
this._expressionRegexp = expressionRegexp;
this._parameterTypeRegistry = parameterTypeRegistry;
this._treeRegexp = new TreeRegexp(expressionRegexp);
}
match(text) {
const parameterTypes = this._treeRegexp.groupBuilder.children.map(groupBuilder => {
const parameterTypeRegexp = groupBuilder.source;
return this._parameterTypeRegistry.lookupByRegexp(parameterTypeRegexp, this._treeRegexp, text) || new ParameterType(null, parameterTypeRegexp, String, s => s, false, false);
});
return Argument.build(this._treeRegexp, text, parameterTypes);
}
get regexp() {
return this._expressionRegexp;
}
get source() {
return this._expressionRegexp.source;
}
}
module.exports = RegularExpression;

View File

@@ -0,0 +1,74 @@
"use strict";
const Regex = require('becke-ch--regex--s0-0-v1--base--pl--lib');
const GroupBuilder = require('./group_builder');
class TreeRegexp {
constructor(regexp) {
this._re = 'string' === typeof regexp ? new RegExp(regexp) : regexp;
this._regex = new Regex(this._re.source, this._re.flags);
const stack = [new GroupBuilder()];
const groupStartStack = [];
let last = null;
let escaping = false;
let nonCapturingMaybe = false;
let charClass = false;
this._re.source.split('').forEach((c, n) => {
if (c == '[' && !escaping) {
charClass = true;
} else if (c == ']' && !escaping) {
charClass = false;
} else if (c === '(' && !escaping && !charClass) {
stack.push(new GroupBuilder());
groupStartStack.push(n + 1);
nonCapturingMaybe = false;
} else if (c === ')' && !escaping && !charClass) {
const gb = stack.pop();
const groupStart = groupStartStack.pop();
if (gb.capturing) {
gb.source = this._re.source.substring(groupStart, n);
stack[stack.length - 1].add(gb);
} else {
gb.moveChildrenTo(stack[stack.length - 1]);
}
nonCapturingMaybe = false;
} else if (c === '?' && last === '(') {
nonCapturingMaybe = true;
} else if (c === ':' && nonCapturingMaybe) {
stack[stack.length - 1].setNonCapturing();
nonCapturingMaybe = false;
}
escaping = c === '\\' && !escaping;
last = c;
});
this._groupBuilder = stack.pop();
}
get regexp() {
return this._re;
}
get groupBuilder() {
return this._groupBuilder;
}
match(s) {
const match = this._regex.exec(s);
if (!match) return null;
let groupIndex = 0;
const nextGroupIndex = () => groupIndex++;
return this._groupBuilder.build(match, nextGroupIndex);
}
}
module.exports = TreeRegexp;