diff --git a/cucumber-expressions/CHANGELOG.md b/cucumber-expressions/CHANGELOG.md index bcb3e7dbd6..9c83490168 100644 --- a/cucumber-expressions/CHANGELOG.md +++ b/cucumber-expressions/CHANGELOG.md @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +* Use native RegExp Match indices (currently relying on a polyfill) + ([#1652](https://github.com/cucumber/common/pull/1652) + [aslakhellesoy]) + ## [12.1.1] - 2021-04-06 ### Fixed diff --git a/cucumber-expressions/javascript/package.json b/cucumber-expressions/javascript/package.json index f303381d3b..bdcdd1e8d3 100644 --- a/cucumber-expressions/javascript/package.json +++ b/cucumber-expressions/javascript/package.json @@ -34,7 +34,7 @@ "typescript": "4.3.5" }, "dependencies": { - "becke-ch--regex--s0-0-v1--base--pl--lib": "1.4.0" + "regexp-match-indices": "1.0.2" }, "directories": { "test": "test" diff --git a/cucumber-expressions/javascript/src/Group.ts b/cucumber-expressions/javascript/src/Group.ts index 41787768c8..a128607b82 100644 --- a/cucumber-expressions/javascript/src/Group.ts +++ b/cucumber-expressions/javascript/src/Group.ts @@ -1,8 +1,8 @@ export default class Group { constructor( public readonly value: string | undefined, - public readonly start: number, - public readonly end: number, + public readonly start: number | undefined, + public readonly end: number | undefined, public readonly children: readonly Group[] ) {} diff --git a/cucumber-expressions/javascript/src/GroupBuilder.ts b/cucumber-expressions/javascript/src/GroupBuilder.ts index 75df6617be..f8e1779dad 100644 --- a/cucumber-expressions/javascript/src/GroupBuilder.ts +++ b/cucumber-expressions/javascript/src/GroupBuilder.ts @@ -1,5 +1,5 @@ import Group from './Group' -import RegexExecArray from './RegexExecArray' +import { RegExpExecArray } from 'regexp-match-indices' export default class GroupBuilder { public source: string @@ -10,15 +10,14 @@ export default class GroupBuilder { this.groupBuilders.push(groupBuilder) } - public build(match: RegexExecArray, nextGroupIndex: () => number): Group { + public build(match: RegExpExecArray, nextGroupIndex: () => number): Group { const groupIndex = nextGroupIndex() const children = this.groupBuilders.map((gb) => gb.build(match, nextGroupIndex)) - return new Group( - match[groupIndex] || undefined, - match.index[groupIndex], - match.index[groupIndex] + (match[groupIndex] || '').length, - children - ) + const value = match[groupIndex] || undefined + const index = match.indices[groupIndex] + const start = index ? index[0] : undefined + const end = index ? index[1] : undefined + return new Group(value, start, end, children) } public setNonCapturing() { diff --git a/cucumber-expressions/javascript/src/RegexExecArray.ts b/cucumber-expressions/javascript/src/RegexExecArray.ts deleted file mode 100644 index 968885fbac..0000000000 --- a/cucumber-expressions/javascript/src/RegexExecArray.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default interface RegexExecArray extends ReadonlyArray { - index: ReadonlyArray - input: string -} diff --git a/cucumber-expressions/javascript/src/TreeRegexp.ts b/cucumber-expressions/javascript/src/TreeRegexp.ts index 2cb0c9d60b..46dda9f9c2 100644 --- a/cucumber-expressions/javascript/src/TreeRegexp.ts +++ b/cucumber-expressions/javascript/src/TreeRegexp.ts @@ -1,18 +1,18 @@ import GroupBuilder from './GroupBuilder' -// @ts-ignore -import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib' -import RegexExecArray from './RegexExecArray' import Group from './Group' +import execWithIndices from 'regexp-match-indices' export default class TreeRegexp { - public regexp: RegExp - private regex: any - public groupBuilder: GroupBuilder + public readonly regexp: RegExp + public readonly groupBuilder: GroupBuilder constructor(regexp: RegExp | string) { - this.regexp = 'string' === typeof regexp ? new RegExp(regexp) : regexp - this.regex = new Regex(this.regexp.source, this.regexp.flags) - this.groupBuilder = TreeRegexp.createGroupBuilder(this.regex) + if (regexp instanceof RegExp) { + this.regexp = regexp + } else { + this.regexp = new RegExp(regexp) + } + this.groupBuilder = TreeRegexp.createGroupBuilder(this.regexp) } private static createGroupBuilder(regexp: RegExp) { @@ -53,22 +53,22 @@ export default class TreeRegexp { private static isNonCapturing(source: string, i: number): boolean { // Regex is valid. Bounds check not required. - if (source[i + 1] != '?') { + if (source[i + 1] !== '?') { // (X) return false } - if (source[i + 2] != '<') { + if (source[i + 2] !== '<') { // (?:X) // (?=X) // (?!X) return true } // (?<=X) or (?X) - return source[i + 3] == '=' || source[i + 3] == '!' + return source[i + 3] === '=' || source[i + 3] === '!' } public match(s: string): Group | null { - const match: RegexExecArray = this.regex.exec(s) + const match = execWithIndices(this.regexp, s) if (!match) { return null } diff --git a/cucumber-expressions/javascript/test/TreeRegexpTest.ts b/cucumber-expressions/javascript/test/TreeRegexpTest.ts index 5993b866a3..4d452b3e40 100644 --- a/cucumber-expressions/javascript/test/TreeRegexpTest.ts +++ b/cucumber-expressions/javascript/test/TreeRegexpTest.ts @@ -120,7 +120,7 @@ describe('TreeRegexp', () => { assert.strictEqual(group.children.length, 1) }) - it('works with flags', () => { + it('works with case insensitive flag', () => { const tr = new TreeRegexp(/HELLO/i) const group = tr.match('hello') assert.strictEqual(group.value, 'hello') diff --git a/package-lock.json b/package-lock.json index 17887f5737..ef0cb7ed0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,7 +79,7 @@ "version": "12.1.1", "license": "MIT", "dependencies": { - "becke-ch--regex--s0-0-v1--base--pl--lib": "1.4.0" + "regexp-match-indices": "1.0.2" }, "devDependencies": { "@types/js-yaml": "4.0.2", @@ -25351,6 +25351,22 @@ "node": ">=0.10.0" } }, + "node_modules/regexp-match-indices": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", + "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "dependencies": { + "regexp-tree": "^0.1.11" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", @@ -31785,9 +31801,9 @@ "@types/js-yaml": "4.0.2", "@types/mocha": "8.2.3", "@types/node": "14.17.5", - "becke-ch--regex--s0-0-v1--base--pl--lib": "1.4.0", "js-yaml": "4.1.0", "mocha": "9.0.2", + "regexp-match-indices": "1.0.2", "ts-node": "10.1.0", "typescript": "4.3.5" }, @@ -50156,6 +50172,19 @@ "safe-regex": "^1.1.0" } }, + "regexp-match-indices": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", + "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "requires": { + "regexp-tree": "^0.1.11" + } + }, + "regexp-tree": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==" + }, "regexp.prototype.flags": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz",