Skip to content

Commit

Permalink
allowUnhandledGAnchors -> ignoreUnsupportedGAnchors
Browse files Browse the repository at this point in the history
  • Loading branch information
slevithan committed Dec 27, 2024
1 parent fc39a08 commit 6a56d32
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 18 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ type OnigurumaToEsOptions = {
maxRecursionDepth?: number | null;
rules?: {
allowOrphanBackrefs?: boolean;
allowUnhandledGAnchors?: boolean;
asciiWordBoundaries?: boolean;
captureGroup?: boolean;
ignoreUnsupportedGAnchors?: boolean;
};
target?: 'auto' | 'ES2025' | 'ES2024' | 'ES2018';
verbose?: boolean;
Expand Down Expand Up @@ -217,10 +217,10 @@ Using a high limit has a small impact on performance. Generally, this is only a
Advanced pattern options that override standard error checking and flags when enabled.

- `allowOrphanBackrefs`: Useful with TextMate grammars that merge backreferences across patterns.
- `allowUnhandledGAnchors`: Removes unsupported uses of `\G`, rather than erroring.
- Oniguruma-To-ES uses a variety of strategies to accurately emulate many common uses of `\G`. When using this option, if a `\G` is found that doesn't have a known emulation strategy, the `\G` is simply removed. This might lead to some false positive matches, but is useful for non-critical matching (like syntax highlighting) when having some mismatches is better than not working.
- `asciiWordBoundaries`: Use ASCII-based `\b` and `\B`, which increases search performance of generated regexes.
- `captureGroup`: Oniguruma option `ONIG_OPTION_CAPTURE_GROUP`. Unnamed captures and numbered calls allowed when using named capture.
- `ignoreUnsupportedGAnchors`: Removes unsupported uses of `\G`, rather than erroring.
- Oniguruma-To-ES uses a variety of strategies to accurately emulate many common uses of `\G`. When using this option, if a `\G` is found that doesn't have a known emulation strategy, the `\G` is simply removed. This might lead to some false positive matches, but is useful for non-critical matching (like syntax highlighting) when having some mismatches is better than not working.

### `target`

Expand Down
2 changes: 1 addition & 1 deletion demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const state = {
maxRecursionDepth: getValue('option-maxRecursionDepth'),
rules: {
allowOrphanBackrefs: getValue('option-allowOrphanBackrefs'),
allowUnhandledGAnchors: getValue('option-allowUnhandledGAnchors'),
asciiWordBoundaries: getValue('option-asciiWordBoundaries'),
captureGroup: getValue('option-captureGroup'),
ignoreUnsupportedGAnchors: getValue('option-ignoreUnsupportedGAnchors'),
},
target: getValue('option-target'),
verbose: getValue('option-verbose'),
Expand Down
4 changes: 2 additions & 2 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ <h2>Try it</h2>
</p>
<p>
<label>
<input type="checkbox" id="option-allowUnhandledGAnchors" onchange="setRule('allowUnhandledGAnchors', this.checked)">
<code>allowUnhandledGAnchors</code>
<input type="checkbox" id="option-ignoreUnsupportedGAnchors" onchange="setRule('ignoreUnsupportedGAnchors', this.checked)">
<code>ignoreUnsupportedGAnchors</code>
<span class="tip tip-lg">Removes unsupported uses of <code>\G</code>, rather than erroring</span>
</label>
</p>
Expand Down
2 changes: 1 addition & 1 deletion spec/match-search-start.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe('Assertion: Search start', () => {
];
patterns.forEach(pattern => {
expect(() => toDetails(pattern)).toThrow();
expect(() => toDetails(pattern, {rules: {allowUnhandledGAnchors: true}})).not.toThrow();
expect(() => toDetails(pattern, {rules: {ignoreUnsupportedGAnchors: true}})).not.toThrow();
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import {recursion} from 'regex-recursion';
maxRecursionDepth?: number | null;
rules?: {
allowOrphanBackrefs?: boolean;
allowUnhandledGAnchors?: boolean;
asciiWordBoundaries?: boolean;
captureGroup?: boolean;
ignoreUnsupportedGAnchors?: boolean;
};
target?: keyof Target;
verbose?: boolean;
Expand All @@ -59,10 +59,10 @@ function toDetails(pattern, options) {
});
const regexAst = transform(onigurumaAst, {
accuracy: opts.accuracy,
allowUnhandledGAnchors: opts.rules.allowUnhandledGAnchors,
asciiWordBoundaries: opts.rules.asciiWordBoundaries,
avoidSubclass,
bestEffortTarget: opts.target,
ignoreUnsupportedGAnchors: opts.rules.ignoreUnsupportedGAnchors,
});
const generated = generate(regexAst, opts);
const pluginData = {useEmulationGroups: !avoidSubclass};
Expand Down
4 changes: 2 additions & 2 deletions src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ function getOptions(options) {
rules: {
// Useful with TextMate grammars that merge backreferences across patterns.
allowOrphanBackrefs: false,
// Removes unsupported uses of `\G`, rather than erroring.
allowUnhandledGAnchors: false,
// Use ASCII-based `\b` and `\B`, which increases search performance of generated regexes.
asciiWordBoundaries: false,
// Oniguruma option `ONIG_OPTION_CAPTURE_GROUP`. Unnamed captures and numbered calls allowed
// when using named capture.
captureGroup: false,
// Removes unsupported uses of `\G`, rather than erroring.
ignoreUnsupportedGAnchors: false,
...(options?.rules),
},
};
Expand Down
14 changes: 7 additions & 7 deletions src/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ AST represents what's needed to precisely reproduce Oniguruma behavior using Reg
@param {import('./parse.js').OnigurumaAst} ast
@param {{
accuracy?: keyof Accuracy;
allowUnhandledGAnchors?: boolean;
asciiWordBoundaries?: boolean;
avoidSubclass?: boolean;
bestEffortTarget?: keyof Target;
ignoreUnsupportedGAnchors?: boolean;
}} [options]
@returns {RegexAst}
*/
Expand All @@ -46,19 +46,19 @@ function transform(ast, options) {
// representations would be hard to change to ASCII-based after the fact in the generator
// based on `target`/`accuracy`, so produce the appropriate structure here.
accuracy: 'default',
allowUnhandledGAnchors: false,
asciiWordBoundaries: false,
avoidSubclass: false,
bestEffortTarget: 'ES2025',
ignoreUnsupportedGAnchors: false,
...options,
};
// AST transformations that work together with a `RegExp` subclass to add advanced emulation
const strategy = opts.avoidSubclass ? null : applySubclassStrategies(ast);
const firstPassState = {
accuracy: opts.accuracy,
allowUnhandledGAnchors: opts.allowUnhandledGAnchors,
asciiWordBoundaries: opts.asciiWordBoundaries,
flagDirectivesByAlt: new Map(),
ignoreUnsupportedGAnchors: opts.ignoreUnsupportedGAnchors,
minTargetEs2024: isMinTarget(opts.bestEffortTarget, 'ES2024'),
// Subroutines can appear before the groups they ref, so collect reffed nodes for a second pass
subroutineRefMap: new Map(),
Expand Down Expand Up @@ -130,7 +130,7 @@ const FirstPassVisitor = {
},
},

Assertion({node, ast, remove, replaceWith}, {allowUnhandledGAnchors, asciiWordBoundaries, supportedGNodes, wordIsAscii}) {
Assertion({node, ast, remove, replaceWith}, {asciiWordBoundaries, ignoreUnsupportedGAnchors, supportedGNodes, wordIsAscii}) {
const {kind, negate} = node;
if (kind === AstAssertionKinds.line_end) {
// Onig's only line break char is line feed, unlike JS
Expand All @@ -142,7 +142,7 @@ const FirstPassVisitor = {
} else if (kind === AstAssertionKinds.search_start) {
if (supportedGNodes.has(node)) {
ast.flags.sticky = true;
} else if (!allowUnhandledGAnchors) {
} else if (!ignoreUnsupportedGAnchors) {
throw new Error(r`Uses "\G" in a way that's unsupported`);
}
remove();
Expand Down Expand Up @@ -305,7 +305,7 @@ const FirstPassVisitor = {
!node.flags.enable && !node.flags.disable && delete node.flags;
},

Pattern({node}, {allowUnhandledGAnchors, supportedGNodes}) {
Pattern({node}, {ignoreUnsupportedGAnchors, supportedGNodes}) {
// For `\G` to be accurately emulatable using JS flag y, it must be at (and only at) the start
// of every top-level alternative (with complex rules for what determines being at the start).
// Additional `\G` error checking in `Assertion` visitor
Expand All @@ -327,7 +327,7 @@ const FirstPassVisitor = {
if (!hasAltWithoutLeadG) {
// Supported `\G` nodes will be removed (and add flag y) when traversed; others will error
leadingGs.forEach(g => supportedGNodes.add(g));
} else if (!allowUnhandledGAnchors) {
} else if (!ignoreUnsupportedGAnchors) {
throw new Error(r`Uses "\G" in a way that's unsupported`);
}
}
Expand Down

0 comments on commit 6a56d32

Please sign in to comment.