From 1c8c5b619bc65de69df9502d51cbdfb4ca70a242 Mon Sep 17 00:00:00 2001 From: Steven Levithan Date: Wed, 13 Nov 2024 12:43:48 +0100 Subject: [PATCH] Remove \G handling case that adds complexity and trades against other supported cases --- spec/match-search-start.spec.js | 54 +-------------------------------- src/transform.js | 22 +------------- 2 files changed, 2 insertions(+), 74 deletions(-) diff --git a/spec/match-search-start.spec.js b/spec/match-search-start.spec.js index 6a97a63..bb85b13 100644 --- a/spec/match-search-start.spec.js +++ b/spec/match-search-start.spec.js @@ -82,59 +82,7 @@ describe('Assertion: Search start', () => { expect(() => toDetails(r`(\Ga)+\G`)).toThrow(); }); - it('should allow if leading in a leading positive lookahead', () => { - expect('a').toExactlyMatch(r`(?=\G)a`); - expect('a').toExactlyMatch(r`(?=\Ga)a`); - expect('aaba'.match(toRegExp(r`(?=\Ga)a`, {global: true}))).toEqual(['a', 'a']); - expect(['a', 'b']).toExactlyMatch(r`(?=\G)a|\Gb`); - expect('a').toExactlyMatch(r`((?=\G)a)`); - expect(['a', 'A']).toExactlyMatch({ - pattern: r`(?i)(?=\G)a`, - maxTestTarget: maxTestTargetForPatternMods, - }); - // Similar but not covered - [ r`(?=\G|)a`, - r`(?:(?=\G))?a`, - r`(?=\G)a|b`, - ].forEach(pattern => { - expect(() => toDetails(pattern, {avoidSubclass: true})).toThrow(); - }); - }); - - it('should allow if trailing in a leading positive lookbehind', () => { - expect('a').toExactlyMatch(r`(?<=\G)a`); - expect(['aa', 'abaa']).not.toFindMatch(r`(?<=a\G)a`); - let re = toRegExp(r`(?<=a\G)a`); - re.lastIndex = 3; - expect(re.exec('abaa')?.index).toBe(3); - expect(['a', 'b']).toExactlyMatch(r`(?<=\G)a|\Gb`); - expect('a').toExactlyMatch(r`((?<=\G)a)`); - expect(['a', 'A']).toExactlyMatch({ - pattern: r`(?i)(?<=\G)a`, - maxTestTarget: maxTestTargetForPatternMods, - }); - // Similar but not covered - [ r`(?<=\G|)a`, - r`(?:(?<=\G))?a`, - r`(?<=\G)a|b`, - ].forEach(pattern => { - expect(() => toDetails(pattern, {avoidSubclass: true})).toThrow(); - }); - }); - - it('should throw if leading in a leading positive lookbehind', () => { - // [Oniguruma] Matches at index 3 within `abc`, but doesn't match within `aabc` - // [TODO] Emulatable by replacing `\G` with `^`, slicing the string to `lastIndex`, and doing - // a non-sticky search - expect(() => toDetails(r`(?<=\Gabc)`)).toThrow(); - }); - - it('should throw if leading in a leading negative lookaround', () => { - expect(() => toDetails(r`(?!\G)a`, {avoidSubclass: true})).toThrow(); - expect(() => toDetails(r`(? { expect(() => toDetails(r`\G\Ga`)).toThrow(); expect(() => toDetails(r`\Ga|\G\Gb`)).toThrow(); diff --git a/src/transform.js b/src/transform.js index 22913c3..8586feb 100644 --- a/src/transform.js +++ b/src/transform.js @@ -705,27 +705,7 @@ function getKids(node) { } function getLeadingG(els) { - let firstToConsider = els.find(el => el.type !== AstTypes.Directive); - if (!firstToConsider) { - return null; - } - // Special case for leading positive lookaround with leading `\G`; else all leading assertions - // are ignored when looking for `\G`; can be nested within a wrapper group via subsequent - // recursion into groups - if ( - isLookaround(firstToConsider) && - !firstToConsider.negate && - firstToConsider.alternatives.length === 1 && - firstToConsider.alternatives[0].elements.length - ) { - const els = firstToConsider.alternatives[0].elements; - const index = firstToConsider.kind === AstAssertionKinds.lookahead ? 0 : els.length - 1; - // `\G` is first in lookahead or last in lookbehind - if (els[index].kind === AstAssertionKinds.search_start) { - return els[index]; - } - } - firstToConsider = els.find(el => { + const firstToConsider = els.find(el => { return el.kind === AstAssertionKinds.search_start ? true : ( el.type !== AstTypes.Assertion &&