full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

21
node_modules/oniguruma-parser/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Steven Levithan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

264
node_modules/oniguruma-parser/README.md generated vendored Normal file
View File

@@ -0,0 +1,264 @@
# oniguruma-parser 🌿
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
A TypeScript library for parsing, validating, traversing, transforming, and optimizing [Oniguruma](https://github.com/kkos/oniguruma) regular expressions.
> [!NOTE]
> Oniguruma is a regular expression engine written in C that's used in Ruby (via a fork named Onigmo), PHP (`mb_ereg`, etc.), TextMate grammars (used by VS Code, [Shiki](https://shiki.style/), etc.), and many other tools.
This library has been battle-tested by [Oniguruma-To-ES](https://github.com/slevithan/oniguruma-to-es) and [tm-grammars](https://github.com/shikijs/textmate-grammars-themes), which are used by Shiki to process tens of thousands of real-world Oniguruma regexes.
## 📜 Contents
- [Install and use](#-install-and-use)
- [Convert a pattern to an AST](#-convert-a-pattern-to-an-ast)
- [Traverse and transform an AST](#-traverse-and-transform-an-ast)
- [Convert an AST to a pattern](#-convert-an-ast-to-a-pattern)
- [Optimize regexes](#-optimize-regexes)
- [Known differences](#-known-differences)
- [Oniguruma version](#-oniguruma-version)
## 🕹️ Install and use
```sh
npm install oniguruma-parser
```
```js
import {toOnigurumaAst} from 'oniguruma-parser';
```
The following modules are available in addition to the root `'oniguruma-parser'` export:
- [Parser module](https://github.com/slevithan/oniguruma-parser/blob/main/src/parser/README.md): Includes numerous functions and types for constructing and working with `OnigurumaAst` nodes. Also includes the `parse` function, wrapped by `toOnigurumaAst`.
- [Traverser module](https://github.com/slevithan/oniguruma-parser/blob/main/src/traverser/README.md): Traverse and transform an `OnigurumaAst`.
- [Generator module](https://github.com/slevithan/oniguruma-parser/blob/main/src/generator/README.md): Convert an `OnigurumaAst` to pattern and flags strings.
- [Optimizer module](https://github.com/slevithan/oniguruma-parser/blob/main/src/optimizer/README.md): Minify and improve the performance of Oniguruma regexes.
## 🌿 Convert a pattern to an AST
To parse an Oniguruma pattern (with optional flags and compile-time options) and return an AST, call `toOnigurumaAst`, which uses the following type definition:
```ts
function toOnigurumaAst(
pattern: string,
options?: {
flags?: string;
rules?: {
captureGroup?: boolean;
singleline?: boolean;
};
}
): OnigurumaAst;
```
For example:
```js
import {toOnigurumaAst} from 'oniguruma-parser';
const ast = toOnigurumaAst('A.*');
console.log(ast);
/* →
{ type: 'Regex',
body: [
{ type: 'Alternative',
body: [
{ type: 'Character',
value: 65,
},
{ type: 'Quantifier',
kind: 'greedy',
min: 0,
max: Infinity,
body: {
type: 'CharacterSet',
kind: 'dot',
},
},
],
},
],
flags: {
type: 'Flags',
ignoreCase: false,
dotAll: false,
extended: false,
digitIsAscii: false,
posixIsAscii: false,
spaceIsAscii: false,
wordIsAscii: false,
textSegmentMode: null,
},
}
*/
```
An error is thrown if the provided pattern or flags aren't valid in Oniguruma.
> **Note:** `toOnigurumaAst` is a wrapper around the [parser module](https://github.com/slevithan/oniguruma-parser/blob/main/src/parser/README.md)'s `parse` function that makes it easier to use by automatically providing the appropriate Unicode property validation data.
## 🌀 Traverse and transform an AST
See details and examples in the [traverser module's readme](https://github.com/slevithan/oniguruma-parser/blob/main/src/traverser/README.md).
## ↩️ Convert an AST to a pattern
See details and examples in the [generator module's readme](https://github.com/slevithan/oniguruma-parser/blob/main/src/generator/README.md).
## 🪄 Optimize regexes
This library includes one of the few implementations (for any regex flavor) of a "regex optimizer" that can minify and improve the performance and readability of regexes prior to use.
Example:
```
(?x) (?:\!{1,}) (\b(?:ark|arm|art)\b) [[^0-9A-Fa-f]\P{^Nd}\p{ Letter }]
```
Becomes:
```
!+\b(ar[kmt])\b[\H\d\p{L}]
```
Optimized regexes always match exactly the same strings.
See more details and examples in the [optimizer module's readme](https://github.com/slevithan/oniguruma-parser/blob/main/src/optimizer/README.md).
> [!TIP]
> 🧪 Try the [optimizer demo](https://slevithan.github.io/oniguruma-parser/demo/).
## 🆚 Known differences
Known differences will be resolved in future versions.
### Unsupported features
The following rarely-used features throw errors since they aren't yet supported:
- Rarely-used character specifiers: Non-A-Za-z with `\cx` `\C-x`, meta `\M-x` `\M-\C-x`, octal code points `\o{…}`, and octal encoded bytes ≥ `\200`.
- Code point sequences: `\x{H H …}` `\o{O O …}`.
- Absence expressions `(?~|…|…)`, stoppers `(?~|…)`, and clearers `(?~|)`.
- Conditionals: `(?(…)…)`, etc.
- Non-built-in callouts: `(?{…})`, etc.
- Numbered *forward* backreferences (incl. relative `\k<+N>`) and backreferences with recursion level (`\k<N+N>`, etc.).
- Flags `D` `P` `S` `W` `y{g}` `y{w}` within pattern modifiers, and whole-pattern modifiers `C` `I` `L`.
Despite these gaps, more than 99.99% of real-world Oniguruma regexes are supported, based on a sample of ~55k regexes used in TextMate grammars (conditionals were used in three regexes, and other unsupported features weren't used at all). Some of the Oniguruma features above are so exotic that they aren't used in *any* public code on GitHub.
<details>
<summary>More details about numbered forward backreferences</summary>
This library currently treats it as an error if a numbered backreference comes before its referenced group. This is a rare issue because:
- Most such placements are mistakes and can never match, due to Oniguruma's behavior for backreferences to nonparticipating groups.
- Erroring matches the correct behavior of named backreferences.
- For unenclosed backreferences, this only affects `\1``\9` since it's not a backreference in the first place if using `\10` or higher and not as many capturing groups are defined to the left (it's an octal or identity escape).
</details>
<details>
<summary>Unsupported validation errors</summary>
The following don't yet throw errors, but should:
- Special characters that are invalid in backreference names even when referencing a valid group with that name.
- Named backreferences should use a more limited set of allowed characters than named groups and subroutines.
- Note that an error is already correctly thrown for any backreference name that includes `-` or `+` (which is separate from how these symbols are used in relative *numbered* backreferences).
- Subroutines used in ways that resemble infinite recursion ([#5](https://github.com/slevithan/oniguruma-parser/issues/5)).
- Such subroutines error at compile time in Oniguruma.
</details>
### Behavior differences
#### Unenclosed four-digit backreferences
Although any number of digits are supported for enclosed `\k<…>`/`\k'…'` backreferences (assuming the backreference refers to a valid capturing group), unenclosed backreferences currently support only up to three digits (`\999`). In other words, `\1000` is handled as `\100` followed by `0` even if 1,000+ captures appear to the left.
> **Note:** An apparent bug in vscode-oniguruma (v2.0.1 tested) prevents any regex with more than 999 captures from working. They fail to match anything, with no error.
#### Erroring on patterns that trigger Oniguruma bugs
This library intentionally doesn't reproduce bugs, and it currently throws errors for several edge cases that trigger Oniguruma bugs and undefined behavior.
<details>
<summary>Nested absence functions</summary>
Although nested absence functions like `(?~(?~…))` don't throw an error in Oniguruma, they produce self-described "strange" results, and Oniguruma's docs state that "nested absent functions are not supported and the behavior is undefined".
In this library, nested absence functions throw an error. In future versions, parsing of nested absence functions will follow Oniguruma and no longer error.
</details>
<details>
<summary>Bare <code>\x</code> as a <code>NUL</code> character</summary>
In Oniguruma, `\x` is an escape for the `NUL` character (equivalent to `\0`, `\x00`, etc.) if it's not followed by `{` or a hexadecimal digit.
In this library, bare `\x` throws an error.
Additional behavior details for `\x` in Oniguruma:
- `\x` is an error if followed by a `{` that's followed by a hexadecimal digit but doesn't form a valid `\x{…}` code point escape. Ex: `\x{F` and `\x{0,2}` are errors.
- `\x` matches a literal `x` if followed by a `{` that isn't followed by a hexadecimal digit. Ex: `\x{` matches `x{`, `\x{G` matches `x{G`, and `\x{,2}` matches 02 `x` characters, since `{,2}` is a quantifier with an implicit 0 min.
- In Oniguruma 6.9.10 and earlier ([report](https://github.com/kkos/oniguruma/issues/343)), `\x` matches a literal `x` if it appears at the very end of a pattern. *This is a bug.*
In future versions, parsing of `\x` will follow the Oniguruma rules above (excluding bugs), removing some cases where it currently errors.
</details>
<details>
<summary>Pattern-terminating bare <code>\u</code></summary>
Normally, any incomplete `\uHHHH` (including bare `\u`) throws an error. However, in Oniguruma 6.9.10 and earlier ([report](https://github.com/kkos/oniguruma/issues/343)), bare `\u` matches a literal `u` if it appears at the very end of a pattern. *This is a bug.*
In this library, incomplete `\u` is always an error.
</details>
<details>
<summary>Invalid standalone encoded bytes <code>\x80</code> to <code>\xFF</code></summary>
> **Context:** Unlike `\uHHHH` and enclosed `\x{H…}` (which match code points), Oniguruma's unenclosed `\xHH` represents an encoded byte, which means that, unlike in other regex flavors, `\x80` to `\xFF` are treated as fragments of a code unit. Ex: `[\0-\xE2\x82\xAC]` is equivalent to `[\0-\u20AC]`.
Invalid standalone encoded bytes should throw an error, but several related bugs are present in Oniguruma 6.9.10 and earlier ([report](https://github.com/kkos/oniguruma/issues/345)).
In this library, they always throw an error.
Behavior details in Oniguruma:
- Standalone `\x80` to `\xF4` throw an error.
- Standalone `\xF5` to `\xFF` fail to match anything, but don't throw. *This is a bug.*
- When used as the end value of a character class range:
- Standalone `\x80` to `\xBF` and `\xF5` to `\xFF` are treated as `\x7F`. *This is a bug.*
- If the range is within a negated, non-nested character class (ex: `[^\0-\xFF]`), `\xF5` to `\xFF` are treated as `\x{10FFFF}`. *This is a bug.*
</details>
## 🔢 Oniguruma version
All versions of this library to date have followed the rules of Oniguruma 6.9.10 (released 2025-01-01), which uses Unicode 16.0.0.
At least since Oniguruma 6.0.0 (released 2016-05-09), regex syntax changes in [new versions](https://github.com/kkos/oniguruma/blob/master/HISTORY) have been backward compatible. Some versions added new syntax that was previously an error (such as new Unicode property names), and in a few cases, edge case parsing bugs were fixed.
> Oniguruma 6.9.8 (released 2022-04-29) is an important baseline for JavaScript projects, since that's the version used by [vscode-oniguruma](https://github.com/microsoft/vscode-oniguruma) 1.7.0 to the latest 2.0.1. It's therefore used in recent versions of various projects, including VS Code and Shiki. However, the regex syntax differences between Oniguruma 6.9.8 and 6.9.10 are so minor that this is a non-issue.
## 🧩 Contributing
Contributions are welcome. See the [guide](https://github.com/slevithan/oniguruma-parser/blob/main/CONTRIBUTING.md) to help you get started.
## 🏷️ About
Created by [Steven Levithan](https://github.com/slevithan) and [contributors](https://github.com/slevithan/oniguruma-parser/graphs/contributors).
If you want to support this project, I'd love your help by contributing improvements ([guide](https://github.com/slevithan/oniguruma-parser/blob/main/CONTRIBUTING.md)), sharing it with others, or [sponsoring](https://github.com/sponsors/slevithan) ongoing development.
MIT License.
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/oniguruma-parser?color=78C372
[npm-version-href]: https://npmjs.com/package/oniguruma-parser
[npm-downloads-src]: https://img.shields.io/npm/dm/oniguruma-parser?color=78C372
[npm-downloads-href]: https://npmjs.com/package/oniguruma-parser
[bundle-src]: https://img.shields.io/bundlejs/size/oniguruma-parser?color=78C372&label=minzip
[bundle-href]: https://bundlejs.com/?q=oniguruma-parser&treeshake=[*]

7
node_modules/oniguruma-parser/dist/bundle.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
export { generate } from './generator/generate.js';
export { toOnigurumaAst } from './index.js';
export { getOptionalOptimizations, optimize } from './optimizer/optimize.js';
export { parse } from './parser/parse.js';
export { traverse } from './traverser/traverse.js';
export { OnigUnicodePropertyMap } from './unicode.js';
//# sourceMappingURL=bundle.d.ts.map

1
node_modules/oniguruma-parser/dist/bundle.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAC,wBAAwB,EAAE,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAC,sBAAsB,EAAC,MAAM,cAAc,CAAC"}

2
node_modules/oniguruma-parser/dist/bundle.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
"use strict";export{generate}from"./generator/generate.js";export{toOnigurumaAst}from"./index.js";export{getOptionalOptimizations,optimize}from"./optimizer/optimize.js";export{parse}from"./parser/parse.js";export{traverse}from"./traverser/traverse.js";export{OnigUnicodePropertyMap}from"./unicode.js";
//# sourceMappingURL=bundle.js.map

7
node_modules/oniguruma-parser/dist/bundle.js.map generated vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/bundle.ts"],
"sourcesContent": ["export {generate} from './generator/generate.js';\nexport {toOnigurumaAst} from './index.js';\nexport {getOptionalOptimizations, optimize} from './optimizer/optimize.js';\nexport {parse} from './parser/parse.js';\nexport {traverse} from './traverser/traverse.js';\nexport {OnigUnicodePropertyMap} from './unicode.js';\n"],
"mappings": "aAAA,OAAQ,aAAe,0BACvB,OAAQ,mBAAqB,aAC7B,OAAQ,yBAA0B,aAAe,0BACjD,OAAQ,UAAY,oBACpB,OAAQ,aAAe,0BACvB,OAAQ,2BAA6B",
"names": []
}

View File

@@ -0,0 +1,11 @@
import type { OnigurumaAst } from '../parser/parse.js';
type OnigurumaRegex = {
pattern: string;
flags: string;
};
/**
Generates an Oniguruma `pattern` and `flags` from an `OnigurumaAst`.
*/
declare function generate(ast: OnigurumaAst): OnigurumaRegex;
export { type OnigurumaRegex, generate, };
//# sourceMappingURL=generate.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/generator/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAwC,MAAM,oBAAoB,CAAC;AAI7G,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;EAEE;AACF,iBAAS,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,cAAc,CA6BnD;AAgZD,OAAO,EACL,KAAK,cAAc,EACnB,QAAQ,GACT,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{r as n,throwIfNullish as d}from"../utils.js";function h(e){const r=[];let a=e;const t={inCharClass:!1,lastNode:a,parent:e},i=s=>{t.lastNode=a,a=s,b(t.lastNode)===s&&(t.parent=t.lastNode,r.push(t.parent));const u=d(C[s.type],`Unexpected node type "${s.type}"`)(s,t,i);return w(t.parent)===s&&(r.pop(),t.parent=r.at(-1)??e),u};return{pattern:e.body.map(i).join("|"),flags:i(e.flags)}}const C={AbsenceFunction({body:e,kind:r},a,t){if(r!=="repeater")throw new Error(`Unexpected absence function kind "${r}"`);return`(?~${e.map(t).join("|")})`},Alternative({body:e},r,a){return e.map(a).join("")},Assertion({kind:e,negate:r}){return e==="text_segment_boundary"?r?n`\Y`:n`\y`:e==="word_boundary"?r?n`\B`:n`\b`:d({line_end:"$",line_start:"^",search_start:n`\G`,string_end:n`\z`,string_end_newline:n`\Z`,string_start:n`\A`}[e],`Unexpected assertion kind "${e}"`)},Backreference({ref:e}){return typeof e=="number"?"\\"+e:`\\k<${e}>`},CapturingGroup({body:e,name:r},a,t){return`(${r?`?${r.includes(">")?`'${r}'`:`<${r}>`}`:""}${e.map(t).join("|")})`},Character(e,{inCharClass:r,lastNode:a,parent:t}){const{value:i}=e;if(y.has(i))return y.get(i);const s=a.type==="Backreference";if(i<32||i>126&&i<160||i>262143||s&&S(i))return i>127?`\\x{${i.toString(16).toUpperCase()}}`:`\\x${i.toString(16).toUpperCase().padStart(2,"0")}`;const o=String.fromCodePoint(i);let u=!1;if(r){const f=t.type==="CharacterClass",l=f&&t.body[0]===e,c=f&&t.body.at(-1)===e;o==="^"?u=l&&!t.negate:o==="]"?u=!l:o==="-"?u=!l&&!c:u=x.has(o)}else u=N.has(o);return`${u?"\\":""}${o}`},CharacterClass({body:e,kind:r,negate:a},t,i){function s(){return t.parent.type==="CharacterClass"&&t.parent.kind==="intersection"&&r==="union"&&!e.length?"":`[${a?"^":""}${e.map(i).join(r==="intersection"?"&&":"")}]`}if(!t.inCharClass){t.inCharClass=!0;const o=s();return t.inCharClass=!1,o}return s()},CharacterClassRange({min:e,max:r},a,t){return`${t(e)}-${t(r)}`},CharacterSet({kind:e,negate:r,value:a},{inCharClass:t}){switch(e){case"any":return n`\O`;case"digit":return r?n`\D`:n`\d`;case"dot":return".";case"hex":return r?n`\H`:n`\h`;case"newline":return r?n`\N`:n`\R`;case"posix":return t?`[:${r?"^":""}${a}:]`:`${r?n`\P`:n`\p`}{${a}}`;case"property":return`${r?n`\P`:n`\p`}{${a}}`;case"space":return r?n`\S`:n`\s`;case"text_segment":return n`\X`;case"word":return r?n`\W`:n`\w`;default:throw new Error(`Unexpected character set kind "${e}"`)}},Directive({kind:e,flags:r}){if(e==="flags"){const{enable:a={},disable:t={}}=r,i=p(a),s=p(t);return i||s?`(?${i}${s?`-${s}`:""})`:""}if(e==="keep")return n`\K`;throw new Error(`Unexpected directive kind "${e}"`)},Flags(e){return p(e)},Group({atomic:e,body:r,flags:a},t,i){const s=r.map(i).join("|");return`(?${F(e,a)}${s})`},LookaroundAssertion({body:e,kind:r,negate:a},t,i){return`(?${`${r==="lookahead"?"":"<"}${a?"!":"="}`}${e.map(i).join("|")})`},NamedCallout({kind:e,tag:r,arguments:a}){if(e==="custom")throw new Error(`Unexpected named callout kind "${e}"`);return`(*${e.toUpperCase()}${r?`[${r}]`:""}${a?`{${a.join(",")}}`:""})`},Quantifier(e,{parent:r},a){const{body:t,kind:i,max:s,min:o}=e;if(o===1/0)throw new Error("Invalid quantifier: infinite min");if(o>s)throw new Error(`Invalid quantifier: min "${o}" > max "${s}"`);const u=t.type==="Quantifier"&&t.kind==="greedy",f=r.type==="Quantifier"&&r.kind==="possessive"&&r.min===1&&r.max===1/0,l=i==="greedy"&&f;let c;g(e)&&!l&&(!o&&s===1&&!u?c="?":!o&&s===1/0?c="*":o===1&&s===1/0&&(!(u&&g(t))||i==="possessive")&&(c="+"));const $=!c;if($)if(i==="possessive"){if(o===s)throw new Error(`Invalid possessive quantifier: min and max are equal "${o}"`);if(s===1/0)throw new Error(`Invalid possessive quantifier: min "${o}" with infinite max"`);c=`{${s},${o}}`}else o===s?c=`{${o}}`:c=`{${o},${s===1/0?"":s}}`;const m={greedy:"",lazy:"?",possessive:$?"":"+"}[i];return`${a(t)}${c}${m}`},Subroutine({ref:e}){return typeof e=="string"&&e.includes(">")?n`\g'${e}'`:n`\g<${e}>`}},N=new Set(["$","(",")","*","+",".","?","[","\\","^","{","|"]),x=new Set(["&","-","[","\\","]","^"]),y=new Map([[7,n`\a`],[9,n`\t`],[10,n`\n`],[11,n`\v`],[12,n`\f`],[13,n`\r`],[27,n`\e`],[8232,n`\u2028`],[8233,n`\u2029`],[65279,n`\uFEFF`]]);function b(e){return"body"in e?Array.isArray(e.body)?e.body[0]??null:e.body:"min"in e&&e.min.type?e.min:null}function w(e){return"body"in e?Array.isArray(e.body)?e.body.at(-1)??null:e.body:"max"in e&&e.max.type?e.max:null}function p({ignoreCase:e,dotAll:r,extended:a,digitIsAscii:t,posixIsAscii:i,spaceIsAscii:s,wordIsAscii:o,textSegmentMode:u}){return`${e?"i":""}${r?"m":""}${a?"x":""}${t?"D":""}${i?"P":""}${s?"S":""}${o?"W":""}${u?d({grapheme:"y{g}",word:"y{w}"}[u],`Unexpected text segment mode "${u}"`):""}`}function F(e,r){if(e)return">";let a="";if(r){const{enable:t={},disable:i={}}=r,s=p(t),o=p(i);a=`${s}${o?`-${o}`:""}`}return`${a}:`}function S(e){return e>47&&e<58}function g({min:e,max:r}){return!e&&r===1||!e&&r===1/0||e===1&&r===1/0}export{h as generate};
//# sourceMappingURL=generate.js.map

File diff suppressed because one or more lines are too long

14
node_modules/oniguruma-parser/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
import type { OnigurumaAst } from './parser/parse.js';
type ToOnigurumaAstOptions = {
flags?: string;
rules?: {
captureGroup?: boolean;
singleline?: boolean;
};
};
/**
Returns an Oniguruma AST generated from an Oniguruma pattern.
*/
declare function toOnigurumaAst(pattern: string, options?: ToOnigurumaAstOptions): OnigurumaAst;
export { type ToOnigurumaAstOptions, toOnigurumaAst, };
//# sourceMappingURL=index.d.ts.map

1
node_modules/oniguruma-parser/dist/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAIpD,KAAK,qBAAqB,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;CACH,CAAC;AAEF;;EAEE;AACF,iBAAS,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,YAAY,CAc1F;AAED,OAAO,EACL,KAAK,qBAAqB,EAC1B,cAAc,GACf,CAAC"}

2
node_modules/oniguruma-parser/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
"use strict";import{parse as t}from"./parser/parse.js";import{OnigUnicodePropertyMap as n}from"./unicode.js";function o(e,r={}){if({}.toString.call(r)!=="[object Object]")throw new Error("Unexpected options");return t(e,{flags:r.flags??"",rules:{captureGroup:r.rules?.captureGroup??!1,singleline:r.rules?.singleline??!1},unicodePropertyMap:n})}export{o as toOnigurumaAst};
//# sourceMappingURL=index.js.map

7
node_modules/oniguruma-parser/dist/index.js.map generated vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["import type {OnigurumaAst} from './parser/parse.js';\nimport {parse} from './parser/parse.js';\nimport {OnigUnicodePropertyMap} from './unicode.js';\n\ntype ToOnigurumaAstOptions = {\n flags?: string;\n rules?: {\n captureGroup?: boolean;\n singleline?: boolean;\n };\n};\n\n/**\nReturns an Oniguruma AST generated from an Oniguruma pattern.\n*/\nfunction toOnigurumaAst(pattern: string, options: ToOnigurumaAstOptions = {}): OnigurumaAst {\n // If `options` provided, it must be a plain object (excluding `null`, arrays, etc.)\n if ({}.toString.call(options) !== '[object Object]') {\n throw new Error('Unexpected options');\n }\n return parse(pattern, {\n // The parser includes additional options; limit the options that can be passed\n flags: options.flags ?? '',\n rules: {\n captureGroup: options.rules?.captureGroup ?? false,\n singleline: options.rules?.singleline ?? false,\n },\n unicodePropertyMap: OnigUnicodePropertyMap,\n });\n}\n\nexport {\n type ToOnigurumaAstOptions,\n toOnigurumaAst,\n};\n"],
"mappings": "aACA,OAAQ,SAAAA,MAAY,oBACpB,OAAQ,0BAAAC,MAA6B,eAarC,SAASC,EAAeC,EAAiBC,EAAiC,CAAC,EAAiB,CAE1F,GAAI,CAAC,EAAE,SAAS,KAAKA,CAAO,IAAM,kBAChC,MAAM,IAAI,MAAM,oBAAoB,EAEtC,OAAOJ,EAAMG,EAAS,CAEpB,MAAOC,EAAQ,OAAS,GACxB,MAAO,CACL,aAAcA,EAAQ,OAAO,cAAgB,GAC7C,WAAYA,EAAQ,OAAO,YAAc,EAC3C,EACA,mBAAoBH,CACtB,CAAC,CACH,CAEA,OAEEC,KAAA",
"names": ["parse", "OnigUnicodePropertyMap", "toOnigurumaAst", "pattern", "options"]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
import type { Visitor } from '../traverser/traverse.js';
type OptimizationName = 'alternationToClass' | 'exposeAnchors' | 'extractPrefix' | 'extractPrefix2' | 'extractSuffix' | 'mergeRanges' | 'optionalize' | 'preventReDoS' | 'removeEmptyGroups' | 'removeUselessFlags' | 'simplifyCallouts' | 'unnestUselessClasses' | 'unwrapNegationWrappers' | 'unwrapUselessClasses' | 'unwrapUselessGroups' | 'useShorthands' | 'useUnicodeAliases' | 'useUnicodeProps';
declare const optimizations: Map<OptimizationName, Visitor>;
export { type OptimizationName, optimizations, };
//# sourceMappingURL=optimizations.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"optimizations.d.ts","sourceRoot":"","sources":["../../src/optimizer/optimizations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,0BAA0B,CAAC;AAoBtD,KAAK,gBAAgB,GACnB,oBAAoB,GACpB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,aAAa,GACb,cAAc,GACd,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,sBAAsB,GACtB,wBAAwB,GACxB,sBAAsB,GACtB,qBAAqB,GACrB,eAAe,GACf,mBAAmB,GACnB,iBAAiB,CAAC;AAEpB,QAAA,MAAM,aAAa,gCAoBjB,CAAC;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,aAAa,GACd,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{alternationToClass as e}from"./transforms/alternation-to-class.js";import{exposeAnchors as s}from"./transforms/expose-anchors.js";import{extractPrefix as r}from"./transforms/extract-prefix.js";import{extractPrefix2 as o}from"./transforms/extract-prefix-2.js";import{extractSuffix as t}from"./transforms/extract-suffix.js";import{mergeRanges as i}from"./transforms/merge-ranges.js";import{optionalize as a}from"./transforms/optionalize.js";import{preventReDoS as p}from"./transforms/prevent-redos.js";import{removeEmptyGroups as m}from"./transforms/remove-empty-groups.js";import{removeUselessFlags as n}from"./transforms/remove-useless-flags.js";import{simplifyCallouts as l}from"./transforms/simplify-callouts.js";import{unnestUselessClasses as f}from"./transforms/unnest-useless-classes.js";import{unwrapNegationWrappers as u}from"./transforms/unwrap-negation-wrappers.js";import{unwrapUselessClasses as x}from"./transforms/unwrap-useless-classes.js";import{unwrapUselessGroups as c}from"./transforms/unwrap-useless-groups.js";import{useShorthands as U}from"./transforms/use-shorthands.js";import{useUnicodeAliases as g}from"./transforms/use-unicode-aliases.js";import{useUnicodeProps as C}from"./transforms/use-unicode-props.js";const v=new Map([["alternationToClass",e],["exposeAnchors",s],["extractPrefix",r],["extractPrefix2",o],["extractSuffix",t],["optionalize",a],["preventReDoS",p],["removeEmptyGroups",m],["removeUselessFlags",n],["simplifyCallouts",l],["unnestUselessClasses",f],["unwrapNegationWrappers",u],["unwrapUselessClasses",x],["unwrapUselessGroups",c],["useShorthands",U],["useUnicodeAliases",g],["useUnicodeProps",C],["mergeRanges",i]]);export{v as optimizations};
//# sourceMappingURL=optimizations.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/optimizer/optimizations.ts"],
"sourcesContent": ["import type {Visitor} from '../traverser/traverse.js';\nimport {alternationToClass} from './transforms/alternation-to-class.js';\nimport {exposeAnchors} from './transforms/expose-anchors.js';\nimport {extractPrefix} from './transforms/extract-prefix.js';\nimport {extractPrefix2} from './transforms/extract-prefix-2.js';\nimport {extractSuffix} from './transforms/extract-suffix.js';\nimport {mergeRanges} from './transforms/merge-ranges.js';\nimport {optionalize} from './transforms/optionalize.js';\nimport {preventReDoS} from './transforms/prevent-redos.js';\nimport {removeEmptyGroups} from './transforms/remove-empty-groups.js';\nimport {removeUselessFlags} from './transforms/remove-useless-flags.js';\nimport {simplifyCallouts} from './transforms/simplify-callouts.js';\nimport {unnestUselessClasses} from './transforms/unnest-useless-classes.js';\nimport {unwrapNegationWrappers} from './transforms/unwrap-negation-wrappers.js';\nimport {unwrapUselessClasses} from './transforms/unwrap-useless-classes.js';\nimport {unwrapUselessGroups} from './transforms/unwrap-useless-groups.js';\nimport {useShorthands} from './transforms/use-shorthands.js';\nimport {useUnicodeAliases} from './transforms/use-unicode-aliases.js';\nimport {useUnicodeProps} from './transforms/use-unicode-props.js';\n\ntype OptimizationName =\n 'alternationToClass' |\n 'exposeAnchors' |\n 'extractPrefix' |\n 'extractPrefix2' |\n 'extractSuffix' |\n 'mergeRanges' |\n 'optionalize' |\n 'preventReDoS' |\n 'removeEmptyGroups' |\n 'removeUselessFlags' |\n 'simplifyCallouts' |\n 'unnestUselessClasses' |\n 'unwrapNegationWrappers' |\n 'unwrapUselessClasses' |\n 'unwrapUselessGroups' |\n 'useShorthands' |\n 'useUnicodeAliases' |\n 'useUnicodeProps';\n\nconst optimizations = new Map<OptimizationName, Visitor>([\n ['alternationToClass', alternationToClass],\n ['exposeAnchors', exposeAnchors],\n ['extractPrefix', extractPrefix],\n ['extractPrefix2', extractPrefix2],\n ['extractSuffix', extractSuffix],\n ['optionalize', optionalize],\n ['preventReDoS', preventReDoS],\n ['removeEmptyGroups', removeEmptyGroups],\n ['removeUselessFlags', removeUselessFlags],\n ['simplifyCallouts', simplifyCallouts],\n ['unnestUselessClasses', unnestUselessClasses],\n ['unwrapNegationWrappers', unwrapNegationWrappers],\n ['unwrapUselessClasses', unwrapUselessClasses],\n ['unwrapUselessGroups', unwrapUselessGroups],\n ['useShorthands', useShorthands],\n ['useUnicodeAliases', useUnicodeAliases],\n ['useUnicodeProps', useUnicodeProps],\n // Run last to let shorthands, etc. be found from ranges first\n ['mergeRanges', mergeRanges],\n]);\n\nexport {\n type OptimizationName,\n optimizations,\n};\n"],
"mappings": "aACA,OAAQ,sBAAAA,MAAyB,uCACjC,OAAQ,iBAAAC,MAAoB,iCAC5B,OAAQ,iBAAAC,MAAoB,iCAC5B,OAAQ,kBAAAC,MAAqB,mCAC7B,OAAQ,iBAAAC,MAAoB,iCAC5B,OAAQ,eAAAC,MAAkB,+BAC1B,OAAQ,eAAAC,MAAkB,8BAC1B,OAAQ,gBAAAC,MAAmB,gCAC3B,OAAQ,qBAAAC,MAAwB,sCAChC,OAAQ,sBAAAC,MAAyB,uCACjC,OAAQ,oBAAAC,MAAuB,oCAC/B,OAAQ,wBAAAC,MAA2B,yCACnC,OAAQ,0BAAAC,MAA6B,2CACrC,OAAQ,wBAAAC,MAA2B,yCACnC,OAAQ,uBAAAC,MAA0B,wCAClC,OAAQ,iBAAAC,MAAoB,iCAC5B,OAAQ,qBAAAC,MAAwB,sCAChC,OAAQ,mBAAAC,MAAsB,oCAsB9B,MAAMC,EAAgB,IAAI,IAA+B,CACvD,CAAC,qBAAsBlB,CAAkB,EACzC,CAAC,gBAAiBC,CAAa,EAC/B,CAAC,gBAAiBC,CAAa,EAC/B,CAAC,iBAAkBC,CAAc,EACjC,CAAC,gBAAiBC,CAAa,EAC/B,CAAC,cAAeE,CAAW,EAC3B,CAAC,eAAgBC,CAAY,EAC7B,CAAC,oBAAqBC,CAAiB,EACvC,CAAC,qBAAsBC,CAAkB,EACzC,CAAC,mBAAoBC,CAAgB,EACrC,CAAC,uBAAwBC,CAAoB,EAC7C,CAAC,yBAA0BC,CAAsB,EACjD,CAAC,uBAAwBC,CAAoB,EAC7C,CAAC,sBAAuBC,CAAmB,EAC3C,CAAC,gBAAiBC,CAAa,EAC/B,CAAC,oBAAqBC,CAAiB,EACvC,CAAC,kBAAmBC,CAAe,EAEnC,CAAC,cAAeZ,CAAW,CAC7B,CAAC,EAED,OAEEa,KAAA",
"names": ["alternationToClass", "exposeAnchors", "extractPrefix", "extractPrefix2", "extractSuffix", "mergeRanges", "optionalize", "preventReDoS", "removeEmptyGroups", "removeUselessFlags", "simplifyCallouts", "unnestUselessClasses", "unwrapNegationWrappers", "unwrapUselessClasses", "unwrapUselessGroups", "useShorthands", "useUnicodeAliases", "useUnicodeProps", "optimizations"]
}

View File

@@ -0,0 +1,23 @@
import type { OnigurumaRegex } from '../generator/generate.js';
import type { OptimizationName } from './optimizations.js';
type OptimizationStates = {
[key in OptimizationName]: boolean;
};
type OptimizeOptions = {
flags?: string;
override?: Partial<OptimizationStates>;
rules?: {
allowOrphanBackrefs?: boolean;
captureGroup?: boolean;
singleline?: boolean;
};
};
/**
Returns an optimized Oniguruma pattern and flags.
*/
declare function optimize(pattern: string, options?: OptimizeOptions): OnigurumaRegex;
declare function getOptionalOptimizations(options?: {
disable?: boolean;
}): OptimizationStates;
export { type OptimizeOptions, getOptionalOptimizations, optimize, };
//# sourceMappingURL=optimize.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"optimize.d.ts","sourceRoot":"","sources":["../../src/optimizer/optimize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAOzD,KAAK,kBAAkB,GAAG;KAAE,GAAG,IAAI,gBAAgB,GAAG,OAAO;CAAC,CAAC;AAE/D,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE;QACN,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;CACH,CAAC;AAEF;;EAEE;AACF,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,CAkC5E;AA0BD,iBAAS,wBAAwB,CAAC,OAAO,GAAE;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAM,GAAG,kBAAkB,CAMvF;AAED,OAAO,EACL,KAAK,eAAe,EACpB,wBAAwB,EACxB,QAAQ,GACT,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{generate as f}from"../generator/generate.js";import{parse as u}from"../parser/parse.js";import{traverse as O}from"../traverser/traverse.js";import{OnigUnicodePropertyMap as c}from"../unicode.js";import{optimizations as n}from"./optimizations.js";function g(e,t){const i=z(t),s=u(e,{flags:i.flags,rules:{captureGroup:i.rules.captureGroup,singleline:i.rules.singleline},skipBackrefValidation:i.rules.allowOrphanBackrefs,unicodePropertyMap:c}),a=Object.assign(p(),i.override);for(const r of n.keys())a[r]||delete a[r];const l=Object.keys(a);let o={pattern:e,flags:i.flags},m=0;do{if(++m>200)throw new Error("Optimization exceeded maximum iterations; possible infinite loop");e=o.pattern;for(const r of l)O(s,n.get(r));o=f(s)}while(e!==o.pattern);return o}function z(e={}){return{flags:"",override:{},...e,rules:{allowOrphanBackrefs:!1,captureGroup:!1,singleline:!1,...e.rules}}}function p(e={}){const t={};for(const i of n.keys())t[i]=!e.disable;return t}export{p as getOptionalOptimizations,g as optimize};
//# sourceMappingURL=optimize.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/optimizer/optimize.ts"],
"sourcesContent": ["import type {OnigurumaRegex} from '../generator/generate.js';\nimport type {OptimizationName} from './optimizations.js';\nimport {generate} from '../generator/generate.js';\nimport {parse} from '../parser/parse.js';\nimport {traverse} from '../traverser/traverse.js';\nimport {OnigUnicodePropertyMap} from '../unicode.js';\nimport {optimizations} from './optimizations.js';\n\ntype OptimizationStates = {[key in OptimizationName]: boolean};\n\ntype OptimizeOptions = {\n flags?: string;\n override?: Partial<OptimizationStates>;\n rules?: {\n allowOrphanBackrefs?: boolean;\n captureGroup?: boolean;\n singleline?: boolean;\n };\n};\n\n/**\nReturns an optimized Oniguruma pattern and flags.\n*/\nfunction optimize(pattern: string, options?: OptimizeOptions): OnigurumaRegex {\n const opts = getOptions(options);\n const ast = parse(pattern, {\n flags: opts.flags,\n rules: {\n captureGroup: opts.rules.captureGroup,\n singleline: opts.rules.singleline,\n },\n skipBackrefValidation: opts.rules.allowOrphanBackrefs,\n unicodePropertyMap: OnigUnicodePropertyMap,\n });\n const active = Object.assign(getOptionalOptimizations(), opts.override);\n for (const key of optimizations.keys()) {\n if (!active[key]) {\n delete active[key];\n }\n }\n const names = Object.keys(active) as Array<OptimizationName>;\n let optimized: OnigurumaRegex = {pattern, flags: opts.flags};\n let counter = 0;\n do {\n if (++counter > 200) {\n throw new Error('Optimization exceeded maximum iterations; possible infinite loop');\n }\n pattern = optimized.pattern;\n for (const name of names) {\n traverse(ast, optimizations.get(name)!);\n }\n optimized = generate(ast);\n } while (\n // Continue until no further optimization progress is made\n pattern !== optimized.pattern\n );\n return optimized;\n}\n\nfunction getOptions(options: OptimizeOptions = {}): Required<OptimizeOptions> {\n return {\n // Oniguruma flags; a string with `imxDPSW` in any order (all optional). Oniguruma's `m` is\n // equivalent to JavaScript's `s` (`dotAll`).\n flags: '',\n // Enable or disable individual, optional optimizations to change their default state.\n override: {},\n ...options,\n rules: {\n // Useful with TextMate grammars that merge backreferences across patterns. Maps to the\n // parser's `skipBackrefValidation` option, but placed/named differently to match its use\n // in `oniguruma-to-es`, which offers it for the same purpose that the optimizer does.\n allowOrphanBackrefs: false,\n // Allow unnamed captures and numbered calls (backreferences and subroutines) when using\n // named capture. This is Oniguruma option `ONIG_OPTION_CAPTURE_GROUP`; on by default in\n // `vscode-oniguruma`.\n captureGroup: false,\n // `^` as `\\A`; `$` as`\\Z`. This is Oniguruma option `ONIG_OPTION_SINGLELINE`.\n singleline: false,\n ...options.rules,\n },\n };\n}\n\nfunction getOptionalOptimizations(options: {disable?: boolean} = {}): OptimizationStates {\n const obj = {} as OptimizationStates;\n for (const key of optimizations.keys()) {\n obj[key] = !options.disable;\n }\n return obj;\n}\n\nexport {\n type OptimizeOptions,\n getOptionalOptimizations,\n optimize,\n};\n"],
"mappings": "aAEA,OAAQ,YAAAA,MAAe,2BACvB,OAAQ,SAAAC,MAAY,qBACpB,OAAQ,YAAAC,MAAe,2BACvB,OAAQ,0BAAAC,MAA6B,gBACrC,OAAQ,iBAAAC,MAAoB,qBAiB5B,SAASC,EAASC,EAAiBC,EAA2C,CAC5E,MAAMC,EAAOC,EAAWF,CAAO,EACzBG,EAAMT,EAAMK,EAAS,CACzB,MAAOE,EAAK,MACZ,MAAO,CACL,aAAcA,EAAK,MAAM,aACzB,WAAYA,EAAK,MAAM,UACzB,EACA,sBAAuBA,EAAK,MAAM,oBAClC,mBAAoBL,CACtB,CAAC,EACKQ,EAAS,OAAO,OAAOC,EAAyB,EAAGJ,EAAK,QAAQ,EACtE,UAAWK,KAAOT,EAAc,KAAK,EAC9BO,EAAOE,CAAG,GACb,OAAOF,EAAOE,CAAG,EAGrB,MAAMC,EAAQ,OAAO,KAAKH,CAAM,EAChC,IAAII,EAA4B,CAAC,QAAAT,EAAS,MAAOE,EAAK,KAAK,EACvDQ,EAAU,EACd,EAAG,CACD,GAAI,EAAEA,EAAU,IACd,MAAM,IAAI,MAAM,kEAAkE,EAEpFV,EAAUS,EAAU,QACpB,UAAWE,KAAQH,EACjBZ,EAASQ,EAAKN,EAAc,IAAIa,CAAI,CAAE,EAExCF,EAAYf,EAASU,CAAG,CAC1B,OAEEJ,IAAYS,EAAU,SAExB,OAAOA,CACT,CAEA,SAASN,EAAWF,EAA2B,CAAC,EAA8B,CAC5E,MAAO,CAGL,MAAO,GAEP,SAAU,CAAC,EACX,GAAGA,EACH,MAAO,CAIL,oBAAqB,GAIrB,aAAc,GAEd,WAAY,GACZ,GAAGA,EAAQ,KACb,CACF,CACF,CAEA,SAASK,EAAyBL,EAA+B,CAAC,EAAuB,CACvF,MAAMW,EAAM,CAAC,EACb,UAAWL,KAAOT,EAAc,KAAK,EACnCc,EAAIL,CAAG,EAAI,CAACN,EAAQ,QAEtB,OAAOW,CACT,CAEA,OAEEN,KAAA,yBACAP,KAAA",
"names": ["generate", "parse", "traverse", "OnigUnicodePropertyMap", "optimizations", "optimize", "pattern", "options", "opts", "getOptions", "ast", "active", "getOptionalOptimizations", "key", "names", "optimized", "counter", "name", "obj"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Use character classes for adjacent alternatives with single-length values.
*/
declare const alternationToClass: Visitor;
export { alternationToClass, };
//# sourceMappingURL=alternation-to-class.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"alternation-to-class.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/alternation-to-class.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAIzD;;EAEE;AACF,QAAA,MAAM,kBAAkB,EAAE,OA8BzB,CAAC;AAsBF,OAAO,EACL,kBAAkB,GACnB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as i}from"../../parser/node-utils.js";import{createAlternative as n,createCharacterClass as c}from"../../parser/parse.js";const h={"*"({node:t}){if(!i(t)||t.body.length<2)return;const r=[];let e=[];for(const o of t.body){const a=o.body[0];o.body.length===1&&(a.type==="Character"||a.type==="CharacterClass"||a.type==="CharacterSet"&&d.has(a.kind))?e.push(a):(e.length&&(r.push(s(e)),e=[]),r.push(o))}e.length&&r.push(s(e)),t.body=r}};function s(t){const r=n(),e=t.length>1?c({body:t}):t[0];return e&&r.body.push(e),r}const d=new Set(["digit","hex","posix","property","space","word"]);export{h as alternationToClass};
//# sourceMappingURL=alternation-to-class.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/alternation-to-class.ts"],
"sourcesContent": ["import type {AlternativeNode, CharacterClassNode, CharacterNode, CharacterSetNode, NodeCharacterSetKind} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer} from '../../parser/node-utils.js';\nimport {createAlternative, createCharacterClass} from '../../parser/parse.js';\n\n/**\nUse character classes for adjacent alternatives with single-length values.\n*/\nconst alternationToClass: Visitor = {\n '*'({node}) {\n if (!isAlternativeContainer(node) || node.body.length < 2) {\n return;\n }\n const newAlts = [];\n let ccNodes = [];\n for (const alt of node.body) {\n const kid = alt.body[0];\n if (\n alt.body.length === 1 &&\n ( kid.type === 'Character' ||\n kid.type === 'CharacterClass' ||\n (kid.type === 'CharacterSet' && universalCharacterSetKinds.has(kid.kind))\n )\n ) {\n ccNodes.push(kid);\n } else {\n if (ccNodes.length) {\n newAlts.push(createAlternativeWithCombinedNodes(ccNodes));\n ccNodes = [];\n }\n newAlts.push(alt);\n }\n }\n if (ccNodes.length) {\n newAlts.push(createAlternativeWithCombinedNodes(ccNodes));\n }\n node.body = newAlts;\n },\n};\n\nfunction createAlternativeWithCombinedNodes(nodes: Array<CharacterNode | CharacterClassNode | CharacterSetNode>): AlternativeNode {\n const alt = createAlternative();\n const node = nodes.length > 1 ? createCharacterClass({body: nodes}) : nodes[0];\n if (node) {\n alt.body.push(node);\n }\n return alt;\n}\n\n// Character set kinds that can appear inside and outside of character classes, and can be inverted\n// by setting `negate`. Some but not all of those excluded use `variableLength: true`\nconst universalCharacterSetKinds = new Set<NodeCharacterSetKind>([\n 'digit',\n 'hex',\n 'posix',\n 'property',\n 'space',\n 'word',\n]);\n\nexport {\n alternationToClass,\n};\n"],
"mappings": "aAEA,OAAQ,0BAAAA,MAA6B,6BACrC,OAAQ,qBAAAC,EAAmB,wBAAAC,MAA2B,wBAKtD,MAAMC,EAA8B,CAClC,IAAI,CAAC,KAAAC,CAAI,EAAG,CACV,GAAI,CAACJ,EAAuBI,CAAI,GAAKA,EAAK,KAAK,OAAS,EACtD,OAEF,MAAMC,EAAU,CAAC,EACjB,IAAIC,EAAU,CAAC,EACf,UAAWC,KAAOH,EAAK,KAAM,CAC3B,MAAMI,EAAMD,EAAI,KAAK,CAAC,EAEpBA,EAAI,KAAK,SAAW,IAClBC,EAAI,OAAS,aACbA,EAAI,OAAS,kBACZA,EAAI,OAAS,gBAAkBC,EAA2B,IAAID,EAAI,IAAI,GAGzEF,EAAQ,KAAKE,CAAG,GAEZF,EAAQ,SACVD,EAAQ,KAAKK,EAAmCJ,CAAO,CAAC,EACxDA,EAAU,CAAC,GAEbD,EAAQ,KAAKE,CAAG,EAEpB,CACID,EAAQ,QACVD,EAAQ,KAAKK,EAAmCJ,CAAO,CAAC,EAE1DF,EAAK,KAAOC,CACd,CACF,EAEA,SAASK,EAAmCC,EAAsF,CAChI,MAAMJ,EAAMN,EAAkB,EACxBG,EAAOO,EAAM,OAAS,EAAIT,EAAqB,CAAC,KAAMS,CAAK,CAAC,EAAIA,EAAM,CAAC,EAC7E,OAAIP,GACFG,EAAI,KAAK,KAAKH,CAAI,EAEbG,CACT,CAIA,MAAME,EAA6B,IAAI,IAA0B,CAC/D,QACA,MACA,QACA,WACA,QACA,MACF,CAAC,EAED,OACEN,KAAA",
"names": ["isAlternativeContainer", "createAlternative", "createCharacterClass", "alternationToClass", "node", "newAlts", "ccNodes", "alt", "kid", "universalCharacterSetKinds", "createAlternativeWithCombinedNodes", "nodes"]
}

View File

@@ -0,0 +1,9 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Pull leading and trailing assertions out of capturing groups when possible; helps group unwrapping.
Ex: `(^abc$)` -> `^(abc)$`.
Ex: `(\b(?:a|bc)\b)` -> `\b((?:a|bc))\b`. The inner group can subsequently be unwrapped.
*/
declare const exposeAnchors: Visitor;
export { exposeAnchors, };
//# sourceMappingURL=expose-anchors.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"expose-anchors.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/expose-anchors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAEzD;;;;EAIE;AACF,QAAA,MAAM,aAAa,EAAE,OAwCpB,CAAC;AAEF,OAAO,EACL,aAAa,GACd,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";const d={CapturingGroup({node:s,parent:a,replaceWithMultiple:c}){if(a.type==="Quantifier"||s.body.length>1||s.isSubroutined)return;const p=s.body[0],t=p.body,e=t[0],i=t.length>1?t.at(-1):null,o=e&&e.type==="Assertion",n=i&&i.type==="Assertion",l=o?1:0,u=t.length-(n?1:0);if(o||n){p.body=t.slice(l,u);const r=[];o&&r.push(e),r.push(s),n&&r.push(i),c(r,{traverse:!0})}}};export{d as exposeAnchors};
//# sourceMappingURL=expose-anchors.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/expose-anchors.ts"],
"sourcesContent": ["import type {Node} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\n\n/**\nPull leading and trailing assertions out of capturing groups when possible; helps group unwrapping.\nEx: `(^abc$)` -> `^(abc)$`.\nEx: `(\\b(?:a|bc)\\b)` -> `\\b((?:a|bc))\\b`. The inner group can subsequently be unwrapped.\n*/\nconst exposeAnchors: Visitor = {\n // Done for capturing groups only because they can't be unwrapped like noncapturing groups (done\n // via `unwrapUselessGroups` combined with `removeUselessFlags`; the latter also avoids hazards\n // from flags that modify word boundary and text segment boundary assertions that would need to\n // be handled here since noncapturing groups can specify flags to change). Pulling anchors out\n // can subsequently enable unwrapping multi-alternative noncapturing groups within the capturing\n // group, and has the side benefit that exposed anchors also improve readability\n CapturingGroup({node, parent, replaceWithMultiple}) {\n if (\n parent.type === 'Quantifier' ||\n node.body.length > 1 || // Multiple alts\n node.isSubroutined\n ) {\n return;\n }\n const firstAlt = node.body[0];\n const firstAltEls = firstAlt.body;\n // Despite only pulling one assertion at a time, multiple can be extracted through multiple\n // rounds of running this optimization\n const leading = firstAltEls[0];\n const trailing = firstAltEls.length > 1 ? firstAltEls.at(-1)! : null;\n const hasLeadingAssertion = leading && leading.type === 'Assertion';\n const hasTrailingAssertion = trailing && trailing.type === 'Assertion';\n const clippedStart = hasLeadingAssertion ? 1 : 0;\n const clippedEnd = firstAltEls.length - (hasTrailingAssertion ? 1 : 0);\n if (hasLeadingAssertion || hasTrailingAssertion) {\n firstAlt.body = firstAltEls.slice(clippedStart, clippedEnd);\n const nodes: Array<Node> = [];\n if (hasLeadingAssertion) {\n // Could use `insertBefore` if the traverser supported it\n nodes.push(leading);\n }\n nodes.push(node);\n if (hasTrailingAssertion) {\n // Could use `insertAfter` if the traverser supported it\n nodes.push(trailing);\n }\n replaceWithMultiple(nodes, {traverse: true});\n }\n },\n};\n\nexport {\n exposeAnchors,\n};\n"],
"mappings": "aAQA,MAAMA,EAAyB,CAO7B,eAAe,CAAC,KAAAC,EAAM,OAAAC,EAAQ,oBAAAC,CAAmB,EAAG,CAClD,GACED,EAAO,OAAS,cAChBD,EAAK,KAAK,OAAS,GACnBA,EAAK,cAEL,OAEF,MAAMG,EAAWH,EAAK,KAAK,CAAC,EACtBI,EAAcD,EAAS,KAGvBE,EAAUD,EAAY,CAAC,EACvBE,EAAWF,EAAY,OAAS,EAAIA,EAAY,GAAG,EAAE,EAAK,KAC1DG,EAAsBF,GAAWA,EAAQ,OAAS,YAClDG,EAAuBF,GAAYA,EAAS,OAAS,YACrDG,EAAeF,EAAsB,EAAI,EACzCG,EAAaN,EAAY,QAAUI,EAAuB,EAAI,GACpE,GAAID,GAAuBC,EAAsB,CAC/CL,EAAS,KAAOC,EAAY,MAAMK,EAAcC,CAAU,EAC1D,MAAMC,EAAqB,CAAC,EACxBJ,GAEFI,EAAM,KAAKN,CAAO,EAEpBM,EAAM,KAAKX,CAAI,EACXQ,GAEFG,EAAM,KAAKL,CAAQ,EAErBJ,EAAoBS,EAAO,CAAC,SAAU,EAAI,CAAC,CAC7C,CACF,CACF,EAEA,OACEZ,KAAA",
"names": ["exposeAnchors", "node", "parent", "replaceWithMultiple", "firstAlt", "firstAltEls", "leading", "trailing", "hasLeadingAssertion", "hasTrailingAssertion", "clippedStart", "clippedEnd", "nodes"]
}

View File

@@ -0,0 +1,9 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Extract alternating prefixes if patterns are repeated for each prefix.
Ex: `^a|!a|^bb|!bb|^c|!c` -> `(?:^|!)(?:a|bb|c)`.
Also works within groups.
*/
declare const extractPrefix2: Visitor;
export { extractPrefix2, };
//# sourceMappingURL=extract-prefix-2.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extract-prefix-2.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/extract-prefix-2.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAKzD;;;;EAIE;AACF,QAAA,MAAM,cAAc,EAAE,OAwErB,CAAC;AAmBF,OAAO,EACL,cAAc,GACf,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as I}from"../../parser/node-utils.js";import{createAlternative as d,createGroup as x}from"../../parser/parse.js";import{isAllowedSimpleNode as g,isNodeEqual as v}from"./extract-prefix.js";const E={"*"({node:o}){if(!I(o))return;const t=2,i=o.body.length;if(i<t*2||i%t)return;const y=[...o.body.slice(0,t).map(e=>e.body)],s=Array.from({length:t},()=>[]),l=Array(t).fill(!1),p=Math.max(...y.map(e=>e.length));for(let e=0;e<p;e++)for(let r=0;r<t;r++)if(!l[r]){const n=y[r][e];!n||!g(n)||!j(n,o.body,r,e,t)?l[r]=!0:s[r].push(n)}if(!s.some(e=>e.length))return;const f=[];let a=0;for(let e=0;e<i;e++)f.push(d({body:o.body[e].body.slice(s[a].length)})),a=a<t-1?a+1:0;for(let e=0;e<i/t;e++){const r=f.slice(e*t,e*t+t);for(let n=1;n<r.length;n++){const h=r[n].body;if(h.length!==r[0].body.length||!h.every((A,N)=>g(A)&&v(A,r[0].body[N])))return}}const b=[];for(let e=0;e<t;e++)b.push(d({body:s[e]}));const c=x({body:b}),m=d({body:[c]}),u=x({body:f.filter((e,r)=>r%t)});u.body.every(e=>!e.body.length)?o.body=c.body:(m.body.push(u),o.body=[m])}};function j(o,t,i,y,s){for(let l=i;l<t.length;l+=s){const f=t[l].body[y];if(!f||!v(f,o))return!1}return!0}export{E as extractPrefix2};
//# sourceMappingURL=extract-prefix-2.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/extract-prefix-2.ts"],
"sourcesContent": ["import type {AlternativeElementNode, AlternativeNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer} from '../../parser/node-utils.js';\nimport {createAlternative, createGroup} from '../../parser/parse.js';\nimport {isAllowedSimpleNode, isNodeEqual} from './extract-prefix.js';\n\n/**\nExtract alternating prefixes if patterns are repeated for each prefix.\nEx: `^a|!a|^bb|!bb|^c|!c` -> `(?:^|!)(?:a|bb|c)`.\nAlso works within groups.\n*/\nconst extractPrefix2: Visitor = {\n '*'({node}) {\n if (!isAlternativeContainer(node)) {\n return;\n }\n const numDiffPrefixes = 2;\n const numAlts = node.body.length;\n if (numAlts < (numDiffPrefixes * 2) || numAlts % numDiffPrefixes) {\n return;\n }\n const prefixAltElsByI = [...node.body.slice(0, numDiffPrefixes).map(alt => alt.body)];\n const prefixNodesByI = Array.from({length: numDiffPrefixes}, (): Array<AlternativeElementNode> => []);\n const prefixIsFinishedByI = Array(numDiffPrefixes).fill(false);\n const longestOf = Math.max(...prefixAltElsByI.map(els => els.length));\n for (let nodeI = 0; nodeI < longestOf; nodeI++) {\n for (let prefixI = 0; prefixI < numDiffPrefixes; prefixI++) {\n if (!prefixIsFinishedByI[prefixI]) {\n const nextNode = prefixAltElsByI[prefixI][nodeI];\n if (\n !nextNode ||\n !isAllowedSimpleNode(nextNode) ||\n !isPrefixNodeShared(nextNode, node.body, prefixI, nodeI, numDiffPrefixes)\n ) {\n prefixIsFinishedByI[prefixI] = true;\n } else {\n prefixNodesByI[prefixI].push(nextNode);\n }\n }\n }\n }\n if (!prefixNodesByI.some(nodes => nodes.length)) {\n return;\n }\n const strippedAlts = [];\n let counter = 0;\n for (let i = 0; i < numAlts; i++) {\n strippedAlts.push(createAlternative({\n body: node.body[i].body.slice(prefixNodesByI[counter].length),\n }));\n counter = counter < (numDiffPrefixes - 1) ? counter + 1 : 0;\n }\n // Check that each set of alts now use the same value after having had their prefixes removed\n for (let i = 0; i < (numAlts / numDiffPrefixes); i++) {\n const altComparisonSet = strippedAlts.slice(i * numDiffPrefixes, (i * numDiffPrefixes) + numDiffPrefixes);\n for (let j = 1; j < altComparisonSet.length; j++) {\n const els = altComparisonSet[j].body;\n if (els.length !== altComparisonSet[0].body.length) {\n return;\n }\n if (!els.every((el, k) => (\n isAllowedSimpleNode(el) &&\n isNodeEqual(el, altComparisonSet[0].body[k])\n ))) {\n return;\n }\n }\n }\n const prefixAlts = [];\n for (let i = 0; i < numDiffPrefixes; i++) {\n prefixAlts.push(createAlternative({body: prefixNodesByI[i]}));\n }\n const prefixGroup = createGroup({body: prefixAlts});\n const newContentsAlt = createAlternative({body: [prefixGroup]});\n // Only take one (unique) alt from each set of stripped alts\n const suffixGroup = createGroup({body: strippedAlts.filter((_, i) => i % numDiffPrefixes)});\n if (suffixGroup.body.every(alt => !alt.body.length)) {\n node.body = prefixGroup.body;\n } else {\n newContentsAlt.body.push(suffixGroup);\n node.body = [newContentsAlt];\n }\n },\n};\n\nfunction isPrefixNodeShared(\n node: AlternativeElementNode,\n alts: Array<AlternativeNode>,\n prefixI: number,\n nodeI: number,\n numDiffPrefixes: number\n): boolean {\n for (let i = prefixI; i < alts.length; i += numDiffPrefixes) {\n const alt = alts[i];\n const bNode = alt.body[nodeI];\n if (!bNode || !isNodeEqual(bNode, node)) {\n return false;\n }\n }\n return true;\n}\n\nexport {\n extractPrefix2,\n};\n"],
"mappings": "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",
"names": ["isAlternativeContainer", "createAlternative", "createGroup", "isAllowedSimpleNode", "isNodeEqual", "extractPrefix2", "node", "numDiffPrefixes", "numAlts", "prefixAltElsByI", "alt", "prefixNodesByI", "prefixIsFinishedByI", "longestOf", "els", "nodeI", "prefixI", "nextNode", "isPrefixNodeShared", "nodes", "strippedAlts", "counter", "i", "altComparisonSet", "j", "el", "k", "prefixAlts", "prefixGroup", "newContentsAlt", "suffixGroup", "_", "alts", "bNode"]
}

View File

@@ -0,0 +1,24 @@
import type { AssertionNode, CharacterNode, Node } from '../../parser/parse.js';
import type { Visitor } from '../../traverser/traverse.js';
/**
Extract nodes at the start of every alternative into a prefix.
Ex: `^aa|^abb|^ac` -> `^a(?:a|bb|c)`.
Also works within groups.
*/
declare const extractPrefix: Visitor;
declare function isAllowedSimpleNode(node: Node): node is AssertionNode | CharacterNode | {
type: "CharacterSet";
kind: "posix" | "property";
value: string;
negate: boolean;
variableLength?: never;
} | {
type: "CharacterSet";
kind: Exclude<import("../../parser/parse.js").NodeCharacterSetKind, "posix" | "property">;
value?: never;
negate?: boolean;
variableLength?: boolean;
};
declare function isNodeEqual(a: Node, b: Node): boolean;
export { extractPrefix, isAllowedSimpleNode, isNodeEqual, };
//# sourceMappingURL=extract-prefix.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extract-prefix.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/extract-prefix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAE,aAAa,EAAoB,IAAI,EAAC,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAIzD;;;;EAIE;AACF,QAAA,MAAM,aAAa,EAAE,OAkCpB,CAAC;AAEF,iBAAS,mBAAmB,CAAC,IAAI,EAAE,IAAI;;;;;;;;;;;;EAMtC;AAGD,iBAAS,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAiB9C;AAED,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,WAAW,GACZ,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as y}from"../../parser/node-utils.js";import{createAlternative as f,createGroup as c}from"../../parser/parse.js";const l={"*"({node:e}){if(!y(e)||e.body.length<2)return;const t=[];let i=!1,o=0;for(;!i;){t.push(e.body[0].body[o]);for(const r of e.body){const s=r.body[o];if(!s||!d(s)||!p(s,t[o])){i=!0;break}}o++}if(t.pop(),!t.length)return;for(const r of e.body)r.body=r.body.slice(t.length);const a=f({body:t}),n=c({body:e.body});n.body.every(r=>!r.body.length)||a.body.push(n),e.body=[a]}};function d(e){return e.type==="Assertion"||e.type==="Character"||e.type==="CharacterSet"}function p(e,t){if(e.type!==t.type)return!1;if(e.type==="Assertion"||e.type==="CharacterSet")return e.kind===t.kind&&e.negate===t.negate;if(e.type==="Character")return e.value===t.value;throw new Error(`Unexpected node type "${e.type}"`)}export{l as extractPrefix,d as isAllowedSimpleNode,p as isNodeEqual};
//# sourceMappingURL=extract-prefix.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/extract-prefix.ts"],
"sourcesContent": ["import type {AssertionNode, CharacterNode, CharacterSetNode, Node} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer} from '../../parser/node-utils.js';\nimport {createAlternative, createGroup} from '../../parser/parse.js';\n\n/**\nExtract nodes at the start of every alternative into a prefix.\nEx: `^aa|^abb|^ac` -> `^a(?:a|bb|c)`.\nAlso works within groups.\n*/\nconst extractPrefix: Visitor = {\n '*'({node}) {\n if (!isAlternativeContainer(node) || node.body.length < 2) {\n return;\n }\n const prefixNodes = [];\n let passedSharedPrefix = false;\n let i = 0;\n while (!passedSharedPrefix) {\n prefixNodes.push(node.body[0].body[i]);\n for (const alt of node.body) {\n const kid = alt.body[i];\n if (!kid || !isAllowedSimpleNode(kid) || !isNodeEqual(kid, prefixNodes[i])) {\n passedSharedPrefix = true;\n break;\n }\n }\n i++;\n }\n prefixNodes.pop();\n if (!prefixNodes.length) {\n return;\n }\n\n for (const alt of node.body) {\n alt.body = alt.body.slice(prefixNodes.length);\n }\n const newContentsAlt = createAlternative({body: prefixNodes});\n const suffixGroup = createGroup({body: node.body});\n if (!suffixGroup.body.every(alt => !alt.body.length)) {\n newContentsAlt.body.push(suffixGroup);\n }\n node.body = [newContentsAlt];\n },\n};\n\nfunction isAllowedSimpleNode(node: Node) {\n return (\n node.type === 'Assertion' ||\n node.type === 'Character' ||\n node.type === 'CharacterSet'\n );\n}\n\n// TODO: Add support for more node types and move to `src/parser/node-utils.ts`\nfunction isNodeEqual(a: Node, b: Node): boolean {\n if (a.type !== b.type) {\n // TS doesn't understand that this makes `a` and `b` always have the same type, so we'll still\n // need to cast, later\n return false;\n }\n if (a.type === 'Assertion' || a.type === 'CharacterSet') {\n return (\n a.kind === (b as AssertionNode | CharacterSetNode).kind &&\n a.negate === (b as AssertionNode | CharacterSetNode).negate\n );\n }\n if (a.type === 'Character') {\n return a.value === (b as CharacterNode).value;\n }\n // Only supports types from `isAllowedSimpleNode`\n throw new Error(`Unexpected node type \"${a.type}\"`);\n}\n\nexport {\n extractPrefix,\n isAllowedSimpleNode,\n isNodeEqual,\n};\n"],
"mappings": "aAEA,OAAQ,0BAAAA,MAA6B,6BACrC,OAAQ,qBAAAC,EAAmB,eAAAC,MAAkB,wBAO7C,MAAMC,EAAyB,CAC7B,IAAI,CAAC,KAAAC,CAAI,EAAG,CACV,GAAI,CAACJ,EAAuBI,CAAI,GAAKA,EAAK,KAAK,OAAS,EACtD,OAEF,MAAMC,EAAc,CAAC,EACrB,IAAIC,EAAqB,GACrBC,EAAI,EACR,KAAO,CAACD,GAAoB,CAC1BD,EAAY,KAAKD,EAAK,KAAK,CAAC,EAAE,KAAKG,CAAC,CAAC,EACrC,UAAWC,KAAOJ,EAAK,KAAM,CAC3B,MAAMK,EAAMD,EAAI,KAAKD,CAAC,EACtB,GAAI,CAACE,GAAO,CAACC,EAAoBD,CAAG,GAAK,CAACE,EAAYF,EAAKJ,EAAYE,CAAC,CAAC,EAAG,CAC1ED,EAAqB,GACrB,KACF,CACF,CACAC,GACF,CAEA,GADAF,EAAY,IAAI,EACZ,CAACA,EAAY,OACf,OAGF,UAAWG,KAAOJ,EAAK,KACrBI,EAAI,KAAOA,EAAI,KAAK,MAAMH,EAAY,MAAM,EAE9C,MAAMO,EAAiBX,EAAkB,CAAC,KAAMI,CAAW,CAAC,EACtDQ,EAAcX,EAAY,CAAC,KAAME,EAAK,IAAI,CAAC,EAC5CS,EAAY,KAAK,MAAML,GAAO,CAACA,EAAI,KAAK,MAAM,GACjDI,EAAe,KAAK,KAAKC,CAAW,EAEtCT,EAAK,KAAO,CAACQ,CAAc,CAC7B,CACF,EAEA,SAASF,EAAoBN,EAAY,CACvC,OACEA,EAAK,OAAS,aACdA,EAAK,OAAS,aACdA,EAAK,OAAS,cAElB,CAGA,SAASO,EAAYG,EAASC,EAAkB,CAC9C,GAAID,EAAE,OAASC,EAAE,KAGf,MAAO,GAET,GAAID,EAAE,OAAS,aAAeA,EAAE,OAAS,eACvC,OACEA,EAAE,OAAUC,EAAuC,MACnDD,EAAE,SAAYC,EAAuC,OAGzD,GAAID,EAAE,OAAS,YACb,OAAOA,EAAE,QAAWC,EAAoB,MAG1C,MAAM,IAAI,MAAM,yBAAyBD,EAAE,IAAI,GAAG,CACpD,CAEA,OACEX,KAAA,cACAO,KAAA,oBACAC,KAAA",
"names": ["isAlternativeContainer", "createAlternative", "createGroup", "extractPrefix", "node", "prefixNodes", "passedSharedPrefix", "i", "alt", "kid", "isAllowedSimpleNode", "isNodeEqual", "newContentsAlt", "suffixGroup", "a", "b"]
}

View File

@@ -0,0 +1,9 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Extract nodes at the end of every alternative into a suffix.
Ex: `aa$|bba$|ca$` -> `(?:a|bb|c)a$`.
Also works within groups.
*/
declare const extractSuffix: Visitor;
export { extractSuffix, };
//# sourceMappingURL=extract-suffix.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extract-suffix.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/extract-suffix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAKzD;;;;EAIE;AACF,QAAA,MAAM,aAAa,EAAE,OA2DpB,CAAC;AAEF,OAAO,EACL,aAAa,GACd,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as h}from"../../parser/node-utils.js";import{createAlternative as p,createGroup as a}from"../../parser/parse.js";import{isAllowedSimpleNode as c,isNodeEqual as u}from"./extract-prefix.js";const g={"*"({node:e}){if(!h(e)||e.body.length<2)return;const y=e.body[0].body,t=[];let f=!1,s=0;for(;!f;){const o=y.length-1-s;t.push(y[o]);for(const i of e.body){const n=i.body.length-1-s,r=i.body[n];if(!r||!c(r)||!u(r,t[s])){f=!0;break}}s++}if(t.pop(),!t.length||t.length<3&&t[0].type!=="Assertion"&&t.length*(e.body.length-1)<4&&!e.body.some((o,i,n)=>{const r=n[i-1],d=t.length;return o.body.length-d<2&&r&&r.body.length-d<2}))return;t.reverse();for(const o of e.body)o.body=o.body.slice(0,-t.length);const l=p(),b=a({body:e.body});b.body.every(o=>!o.body.length)||l.body.push(b),l.body.push(...t),e.body=[l]}};export{g as extractSuffix};
//# sourceMappingURL=extract-suffix.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/extract-suffix.ts"],
"sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer} from '../../parser/node-utils.js';\nimport {createAlternative, createGroup} from '../../parser/parse.js';\nimport {isAllowedSimpleNode, isNodeEqual} from './extract-prefix.js';\n\n/**\nExtract nodes at the end of every alternative into a suffix.\nEx: `aa$|bba$|ca$` -> `(?:a|bb|c)a$`.\nAlso works within groups.\n*/\nconst extractSuffix: Visitor = {\n '*'({node}) {\n if (!isAlternativeContainer(node) || node.body.length < 2) {\n return;\n }\n const firstAltEls = node.body[0].body;\n const suffixNodes = [];\n let passedSharedSuffix = false;\n let i = 0;\n while (!passedSharedSuffix) {\n const inverseI = firstAltEls.length - 1 - i;\n suffixNodes.push(firstAltEls[inverseI]);\n for (const alt of node.body) {\n const inverseIOfAlt = alt.body.length - 1 - i;\n const kid = alt.body[inverseIOfAlt];\n if (!kid || !isAllowedSimpleNode(kid) || !isNodeEqual(kid, suffixNodes[i])) {\n passedSharedSuffix = true;\n break;\n }\n }\n i++;\n }\n suffixNodes.pop();\n if (\n !suffixNodes.length ||\n // Avoid applying in cases when it would lengthen the pattern without any benefit; ex:\n // `true|false` -> `(?:tru|fals)e`, or `if|elseif` -> `(?:|else)if`\n ( suffixNodes.length < 3 &&\n // Always extract the suffix if it ends with an assertion, since that provides a\n // readability benefit and is more likely to trigger follow-on optimizations\n suffixNodes[0].type !== 'Assertion' &&\n // Four chars are added by the `(?:)` wrapper and one instance of the suffix is added back\n // at the end, so avoid if the result could be longer\n (suffixNodes.length * (node.body.length - 1)) < 4 &&\n // Adjacent alts reduced to 0 or 1 node after extracting the suffix can possibly be\n // collapsed in follow-on optimizations, providing a performance and/or minification\n // benefit\n !node.body.some((alt, i, arr) => {\n const lastAlt = arr[i - 1];\n const removed = suffixNodes.length;\n return alt.body.length - removed < 2 && lastAlt && lastAlt.body.length - removed < 2;\n })\n )\n ) {\n return;\n }\n suffixNodes.reverse();\n\n for (const alt of node.body) {\n alt.body = alt.body.slice(0, -suffixNodes.length);\n }\n const newContentsAlt = createAlternative();\n const prefixGroup = createGroup({body: node.body});\n if (!prefixGroup.body.every(alt => !alt.body.length)) {\n newContentsAlt.body.push(prefixGroup);\n }\n newContentsAlt.body.push(...suffixNodes);\n node.body = [newContentsAlt];\n },\n};\n\nexport {\n extractSuffix,\n};\n"],
"mappings": "aACA,OAAQ,0BAAAA,MAA6B,6BACrC,OAAQ,qBAAAC,EAAmB,eAAAC,MAAkB,wBAC7C,OAAQ,uBAAAC,EAAqB,eAAAC,MAAkB,sBAO/C,MAAMC,EAAyB,CAC7B,IAAI,CAAC,KAAAC,CAAI,EAAG,CACV,GAAI,CAACN,EAAuBM,CAAI,GAAKA,EAAK,KAAK,OAAS,EACtD,OAEF,MAAMC,EAAcD,EAAK,KAAK,CAAC,EAAE,KAC3BE,EAAc,CAAC,EACrB,IAAIC,EAAqB,GACrBC,EAAI,EACR,KAAO,CAACD,GAAoB,CAC1B,MAAME,EAAWJ,EAAY,OAAS,EAAIG,EAC1CF,EAAY,KAAKD,EAAYI,CAAQ,CAAC,EACtC,UAAWC,KAAON,EAAK,KAAM,CAC3B,MAAMO,EAAgBD,EAAI,KAAK,OAAS,EAAIF,EACtCI,EAAMF,EAAI,KAAKC,CAAa,EAClC,GAAI,CAACC,GAAO,CAACX,EAAoBW,CAAG,GAAK,CAACV,EAAYU,EAAKN,EAAYE,CAAC,CAAC,EAAG,CAC1ED,EAAqB,GACrB,KACF,CACF,CACAC,GACF,CAEA,GADAF,EAAY,IAAI,EAEd,CAACA,EAAY,QAGXA,EAAY,OAAS,GAGrBA,EAAY,CAAC,EAAE,OAAS,aAGvBA,EAAY,QAAUF,EAAK,KAAK,OAAS,GAAM,GAIhD,CAACA,EAAK,KAAK,KAAK,CAACM,EAAK,EAAGG,IAAQ,CAC/B,MAAMC,EAAUD,EAAI,EAAI,CAAC,EACnBE,EAAUT,EAAY,OAC5B,OAAOI,EAAI,KAAK,OAASK,EAAU,GAAKD,GAAWA,EAAQ,KAAK,OAASC,EAAU,CACrF,CAAC,EAGH,OAEFT,EAAY,QAAQ,EAEpB,UAAWI,KAAON,EAAK,KACrBM,EAAI,KAAOA,EAAI,KAAK,MAAM,EAAG,CAACJ,EAAY,MAAM,EAElD,MAAMU,EAAiBjB,EAAkB,EACnCkB,EAAcjB,EAAY,CAAC,KAAMI,EAAK,IAAI,CAAC,EAC5Ca,EAAY,KAAK,MAAMP,GAAO,CAACA,EAAI,KAAK,MAAM,GACjDM,EAAe,KAAK,KAAKC,CAAW,EAEtCD,EAAe,KAAK,KAAK,GAAGV,CAAW,EACvCF,EAAK,KAAO,CAACY,CAAc,CAC7B,CACF,EAEA,OACEb,KAAA",
"names": ["isAlternativeContainer", "createAlternative", "createGroup", "isAllowedSimpleNode", "isNodeEqual", "extractSuffix", "node", "firstAltEls", "suffixNodes", "passedSharedSuffix", "i", "inverseI", "alt", "inverseIOfAlt", "kid", "arr", "lastAlt", "removed", "newContentsAlt", "prefixGroup"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Merge, dedupe, and sort ranges and characters in character classes.
*/
declare const mergeRanges: Visitor;
export { mergeRanges, };
//# sourceMappingURL=merge-ranges.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"merge-ranges.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/merge-ranges.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;EAEE;AACF,QAAA,MAAM,WAAW,EAAE,OAgGlB,CAAC;AASF,OAAO,EACL,WAAW,GACZ,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{createCharacter as u,createCharacterClassRange as h}from"../../parser/parse.js";const m={CharacterClass({node:t}){if(t.kind!=="union"||!t.body.length)return;const l=[];for(const e of t.body)e.type==="CharacterSet"&&l.some(a=>a.type===e.type&&a.kind===e.kind&&a.negate===e.negate&&a.value===e.value)||l.push(e);t.body=l;const o=[],n=[];for(const e of t.body)e.type==="Character"||e.type==="CharacterClassRange"?n.push(e):o.push(e);if(!n.length)return;n.sort((e,a)=>{const r=e.type==="Character"?e.value:e.min.value,c=a.type==="Character"?a.value:a.min.value;return r-c});const s=[n[0]];for(let e=1;e<n.length;e++){const a=n[e],r=s.at(-1),c=a.type==="Character"?a.value:a.min.value,p=r.type==="Character"?r.value:r.max.value;if(c<=p+1)if(r.type==="Character"&&a.type==="Character")r.value!==a.value&&(s[s.length-1]=h(r,a));else if(r.type==="Character"&&a.type==="CharacterClassRange")s[s.length-1]=h(u(r.value),a.max);else if(r.type==="CharacterClassRange"&&a.type==="Character")r.max.value=Math.max(a.value,r.max.value);else if(r.type==="CharacterClassRange"&&a.type==="CharacterClassRange")r.max.value=Math.max(a.max.value,r.max.value);else throw new Error("Unexpected merge case");else s.push(a)}const i=s.flatMap(e=>{if(e.type==="CharacterClassRange"){const a=e.max.value-e.min.value;if(e.min.value>262143&&a>1)return e;if(a){if(a===1)return[e.min,e.max];if(a===2)return[e.min,u(e.min.value+1),e.max]}else return e.min}return e});t.body=[...i.filter(e=>C(e)),...i.filter(e=>!C(e)),...o]}};function C(t){return t.type==="Character"&&(t.value===45||t.value===93)}export{m as mergeRanges};
//# sourceMappingURL=merge-ranges.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/merge-ranges.ts"],
"sourcesContent": ["import type {CharacterClassElementNode, CharacterClassRangeNode, CharacterNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {createCharacter, createCharacterClassRange} from '../../parser/parse.js';\n\n/**\nMerge, dedupe, and sort ranges and characters in character classes.\n*/\nconst mergeRanges: Visitor = {\n CharacterClass({node}) {\n if (node.kind !== 'union' || !node.body.length) {\n return;\n }\n\n // ## Since characters and ranges will be deduped by merging, might as well dedupe sets too\n const withoutDupeSets: Array<CharacterClassElementNode> = [];\n for (const el of node.body) {\n if (\n el.type === 'CharacterSet' &&\n withoutDupeSets.some(k => (\n k.type === el.type &&\n k.kind === el.kind &&\n k.negate === el.negate &&\n k.value === el.value\n ))\n ) {\n continue;\n }\n // Keep non-duplicate sets (first instance) and any non-set nodes\n withoutDupeSets.push(el);\n }\n node.body = withoutDupeSets;\n\n // ## Now merge characters and ranges\n const keep: Array<Exclude<CharacterClassElementNode, HandledNode>> = [];\n const candidates: Array<HandledNode> = [];\n for (const el of node.body) {\n if (el.type === 'Character' || el.type === 'CharacterClassRange') {\n candidates.push(el);\n } else {\n keep.push(el);\n }\n }\n if (!candidates.length) {\n return;\n }\n candidates.sort((a, b) => {\n const aValue = a.type === 'Character' ? a.value : a.min.value;\n const bValue = b.type === 'Character' ? b.value : b.min.value;\n return aValue - bValue;\n });\n const merged: Array<HandledNode> = [candidates[0]];\n for (let i = 1; i < candidates.length; i++) {\n const el = candidates[i];\n const last = merged.at(-1)!;\n const elMin = el.type === 'Character' ? el.value : el.min.value;\n const lastMax = last.type === 'Character' ? last.value : last.max.value;\n if (elMin <= lastMax + 1) {\n if (last.type === 'Character' && el.type === 'Character') {\n if (last.value !== el.value) {\n merged[merged.length - 1] = createCharacterClassRange(last, el);\n }\n } else if (last.type === 'Character' && el.type === 'CharacterClassRange') {\n merged[merged.length - 1] = createCharacterClassRange(createCharacter(last.value), el.max);\n } else if (last.type === 'CharacterClassRange' && el.type === 'Character') {\n last.max.value = Math.max(el.value, last.max.value);\n } else if (last.type === 'CharacterClassRange' && el.type === 'CharacterClassRange') {\n last.max.value = Math.max(el.max.value, last.max.value);\n } else {\n throw new Error('Unexpected merge case');\n }\n } else {\n merged.push(el);\n }\n }\n // Replace any ranges with fewer than four (sometimes three) chars with character nodes\n const final = merged.flatMap(el => {\n if (el.type === 'CharacterClassRange') {\n const diff = el.max.value - el.min.value;\n // More aggressively use ranges for U+40000+, since they're rendered in long form like\n // `\\x{40000}` rather than as single-length characters\n if (el.min.value > 0x3FFFF && diff > 1) {\n return el;\n } else if (!diff) {\n return el.min;\n } else if (diff === 1) {\n return [el.min, el.max];\n } else if (diff === 2) {\n // Ex: `a-c` -> `abc`\n return [el.min, createCharacter(el.min.value + 1), el.max];\n }\n // `diff > 2`\n }\n return el;\n });\n // Always replace `body` to avoid skipping things like `[a-a]` -> `[a]` where both classes\n // contain the same number of nodes; means we always sort characters/ranges by their values\n node.body = [\n // Pull chars to the front that don't need to be escaped in first position\n ...final.filter(el => firstPosChar(el)),\n ...final.filter(el => !firstPosChar(el)),\n ...keep\n ];\n },\n};\n\ntype HandledNode = CharacterNode | CharacterClassRangeNode;\n\nfunction firstPosChar(node: HandledNode): boolean {\n // Is `-` or `]`\n return node.type === 'Character' && (node.value === 45 || node.value === 93);\n}\n\nexport {\n mergeRanges,\n};\n"],
"mappings": "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",
"names": ["createCharacter", "createCharacterClassRange", "mergeRanges", "node", "withoutDupeSets", "el", "k", "keep", "candidates", "a", "b", "aValue", "bValue", "merged", "i", "last", "elMin", "lastMax", "final", "diff", "firstPosChar"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Combine adjacent alternatives with only an added last node as the difference.
*/
declare const optionalize: Visitor;
export { optionalize, };
//# sourceMappingURL=optionalize.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"optionalize.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/optionalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAMzD;;EAEE;AACF,QAAA,MAAM,WAAW,EAAE,OA4ElB,CAAC;AAmBF,OAAO,EACL,WAAW,GACZ,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as A,isQuantifiable as u}from"../../parser/node-utils.js";import{createQuantifier as m}from"../../parser/parse.js";import{throwIfNullish as c}from"../../utils.js";import{isAllowedSimpleNode as d,isNodeEqual as v}from"./extract-prefix.js";const K={"*"({node:i}){if(!A(i)||i.body.length<2)return;const{body:n}=i,r=[n[0]];let f=n[0];for(let o=1;o<n.length;o++){const s=n[o],l=s.body,t=f.body,p=Math.abs(l.length-t.length);if(p){if(p===1){const a=t.length>l.length,y=a?l:l.slice(0,-1),g=a?t.slice(0,-1):t;if(h(y,g)){if(a){const e=c(t.at(-1));if(u(e))if(e.type==="Quantifier")if(e.min){if(e.min===1&&e.kind!=="lazy"){e.min=0;continue}}else continue;else{t.pop(),t.push(m("greedy",0,1,e));continue}}else if(t.length>0||n.length===2){const e=c(l.at(-1));if(u(e))if(e.type==="Quantifier"){if(e.kind!=="possessive"){if(e.min<=1&&e.kind==="lazy"){e.min=0,t.push(e);continue}else if(!e.min&&e.max===1){e.kind="lazy",t.push(e);continue}}}else{t.push(m("lazy",0,1,e));continue}}}}}else if(h(l,t))continue;r.push(s),f=s}i.body=r}};function h(i,n){if(i.length!==n.length)return!1;for(let r=0;r<i.length;r++)if(!d(i[r])||!d(n[r])||!v(i[r],n[r]))return!1;return!0}export{K as optionalize};
//# sourceMappingURL=optionalize.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/optionalize.ts"],
"sourcesContent": ["import type {AlternativeElementNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer, isQuantifiable} from '../../parser/node-utils.js';\nimport {createQuantifier} from '../../parser/parse.js';\nimport {throwIfNullish} from '../../utils.js';\nimport {isAllowedSimpleNode, isNodeEqual} from './extract-prefix.js';\n\n/**\nCombine adjacent alternatives with only an added last node as the difference.\n*/\nconst optionalize: Visitor = {\n '*'({node}) {\n if (!isAlternativeContainer(node) || node.body.length < 2) {\n return;\n }\n const {body} = node;\n const newAlts = [body[0]];\n let lastAltKept = body[0];\n for (let i = 1; i < body.length; i++) {\n // NOTE: Anytime we `continue` we don't keep this alt\n const alt = body[i];\n const altKids = alt.body;\n const prevAltKids = lastAltKept.body;\n const lengthDiff = Math.abs(altKids.length - prevAltKids.length);\n if (!lengthDiff) {\n if (isNodeArrayEqual(altKids, prevAltKids)) {\n continue;\n }\n } else if (lengthDiff === 1) {\n const isPrevAltLonger = !!(prevAltKids.length > altKids.length);\n const altKidsToCompare = isPrevAltLonger ? altKids : altKids.slice(0, -1);\n const prevAltKidsToCompare = isPrevAltLonger ? prevAltKids.slice(0, -1) : prevAltKids;\n if (isNodeArrayEqual(altKidsToCompare, prevAltKidsToCompare)) {\n if (isPrevAltLonger) {\n const prevAltLastKid = throwIfNullish(prevAltKids.at(-1));\n if (isQuantifiable(prevAltLastKid)) {\n // Avoid chaining quantifiers since e.g. chained greedy `?` is `?{0,1}` and can\n // lengthen the pattern\n if (prevAltLastKid.type === 'Quantifier') {\n if (!prevAltLastKid.min) {\n continue;\n } else if (prevAltLastKid.min === 1 && prevAltLastKid.kind !== 'lazy') {\n prevAltLastKid.min = 0;\n continue;\n }\n } else {\n // Put the prev alt's extra last node in a greedy `?`\n prevAltKids.pop();\n prevAltKids.push(createQuantifier('greedy', 0, 1, prevAltLastKid));\n continue;\n }\n }\n } else if (\n // Don't apply if last alt empty since that would lengthen e.g. `(|a|b)` to `(a??|b)`\n prevAltKids.length > 0 ||\n // Unless there are two alts since e.g. `(?:|a)` to `(?:a??)` enables group unwrapping\n body.length === 2\n ) {\n const altLastKid = throwIfNullish(altKids.at(-1));\n if (isQuantifiable(altLastKid)) {\n if (altLastKid.type === 'Quantifier') {\n if (altLastKid.kind === 'possessive') {\n // No-op since possessive quantifiers can't also be lazy\n } else if (altLastKid.min <= 1 && altLastKid.kind === 'lazy') {\n altLastKid.min = 0;\n prevAltKids.push(altLastKid);\n continue;\n } else if (!altLastKid.min && altLastKid.max === 1) {\n altLastKid.kind = 'lazy';\n prevAltKids.push(altLastKid);\n continue;\n }\n } else {\n // Put this alt's extra last node in a lazy `??` then add it to the prev alt\n prevAltKids.push(createQuantifier('lazy', 0, 1, altLastKid));\n continue;\n }\n }\n }\n }\n }\n newAlts.push(alt);\n lastAltKept = alt;\n }\n node.body = newAlts;\n },\n};\n\n// Returns `false` if the arrays contain a node type it doesn't know how to compare, or doesn't\n// want to compare (e.g. with capturing groups, which can't be removed)\nfunction isNodeArrayEqual(a: Array<AlternativeElementNode>, b: Array<AlternativeElementNode>) {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!isAllowedSimpleNode(a[i]) || !isAllowedSimpleNode(b[i])) {\n return false;\n }\n if (!isNodeEqual(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport {\n optionalize,\n};\n"],
"mappings": "aAEA,OAAQ,0BAAAA,EAAwB,kBAAAC,MAAqB,6BACrD,OAAQ,oBAAAC,MAAuB,wBAC/B,OAAQ,kBAAAC,MAAqB,iBAC7B,OAAQ,uBAAAC,EAAqB,eAAAC,MAAkB,sBAK/C,MAAMC,EAAuB,CAC3B,IAAI,CAAC,KAAAC,CAAI,EAAG,CACV,GAAI,CAACP,EAAuBO,CAAI,GAAKA,EAAK,KAAK,OAAS,EACtD,OAEF,KAAM,CAAC,KAAAC,CAAI,EAAID,EACTE,EAAU,CAACD,EAAK,CAAC,CAAC,EACxB,IAAIE,EAAcF,EAAK,CAAC,EACxB,QAASG,EAAI,EAAGA,EAAIH,EAAK,OAAQG,IAAK,CAEpC,MAAMC,EAAMJ,EAAKG,CAAC,EACZE,EAAUD,EAAI,KACdE,EAAcJ,EAAY,KAC1BK,EAAa,KAAK,IAAIF,EAAQ,OAASC,EAAY,MAAM,EAC/D,GAAKC,GAIE,GAAIA,IAAe,EAAG,CAC3B,MAAMC,EAAqBF,EAAY,OAASD,EAAQ,OAClDI,EAAmBD,EAAkBH,EAAUA,EAAQ,MAAM,EAAG,EAAE,EAClEK,EAAuBF,EAAkBF,EAAY,MAAM,EAAG,EAAE,EAAIA,EAC1E,GAAIK,EAAiBF,EAAkBC,CAAoB,GACzD,GAAIF,EAAiB,CACnB,MAAMI,EAAiBjB,EAAeW,EAAY,GAAG,EAAE,CAAC,EACxD,GAAIb,EAAemB,CAAc,EAG/B,GAAIA,EAAe,OAAS,aAC1B,GAAKA,EAAe,KAEb,GAAIA,EAAe,MAAQ,GAAKA,EAAe,OAAS,OAAQ,CACrEA,EAAe,IAAM,EACrB,QACF,MAJE,cAKG,CAELN,EAAY,IAAI,EAChBA,EAAY,KAAKZ,EAAiB,SAAU,EAAG,EAAGkB,CAAc,CAAC,EACjE,QACF,CAEJ,SAEEN,EAAY,OAAS,GAErBN,EAAK,SAAW,EAChB,CACA,MAAMa,EAAalB,EAAeU,EAAQ,GAAG,EAAE,CAAC,EAChD,GAAIZ,EAAeoB,CAAU,EAC3B,GAAIA,EAAW,OAAS,cACtB,GAAIA,EAAW,OAAS,cAEjB,GAAIA,EAAW,KAAO,GAAKA,EAAW,OAAS,OAAQ,CAC5DA,EAAW,IAAM,EACjBP,EAAY,KAAKO,CAAU,EAC3B,QACF,SAAW,CAACA,EAAW,KAAOA,EAAW,MAAQ,EAAG,CAClDA,EAAW,KAAO,OAClBP,EAAY,KAAKO,CAAU,EAC3B,QACF,OACK,CAELP,EAAY,KAAKZ,EAAiB,OAAQ,EAAG,EAAGmB,CAAU,CAAC,EAC3D,QACF,CAEJ,EAEJ,UAvDMF,EAAiBN,EAASC,CAAW,EACvC,SAuDJL,EAAQ,KAAKG,CAAG,EAChBF,EAAcE,CAChB,CACAL,EAAK,KAAOE,CACd,CACF,EAIA,SAASU,EAAiBG,EAAkCC,EAAkC,CAC5F,GAAID,EAAE,SAAWC,EAAE,OACjB,MAAO,GAET,QAASZ,EAAI,EAAGA,EAAIW,EAAE,OAAQX,IAI5B,GAHI,CAACP,EAAoBkB,EAAEX,CAAC,CAAC,GAAK,CAACP,EAAoBmB,EAAEZ,CAAC,CAAC,GAGvD,CAACN,EAAYiB,EAAEX,CAAC,EAAGY,EAAEZ,CAAC,CAAC,EACzB,MAAO,GAGX,MAAO,EACT,CAEA,OACEL,KAAA",
"names": ["isAlternativeContainer", "isQuantifiable", "createQuantifier", "throwIfNullish", "isAllowedSimpleNode", "isNodeEqual", "optionalize", "node", "body", "newAlts", "lastAltKept", "i", "alt", "altKids", "prevAltKids", "lengthDiff", "isPrevAltLonger", "altKidsToCompare", "prevAltKidsToCompare", "isNodeArrayEqual", "prevAltLastKid", "altLastKid", "a", "b"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Remove identified ReDoS vulnerabilities without changing matches.
*/
declare const preventReDoS: Visitor;
export { preventReDoS, };
//# sourceMappingURL=prevent-redos.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"prevent-redos.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/prevent-redos.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;EAEE;AACF,QAAA,MAAM,YAAY,EAAE,OAuCnB,CAAC;AAEF,OAAO,EACL,YAAY,GACb,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{hasOnlyChild as n}from"../../parser/node-utils.js";const s={Quantifier({node:t}){const{body:r,max:o}=t;if(o!==1/0||r.type!=="Group"||r.atomic)return;const e=r.body[0];if(!n(e,{type:"Quantifier"}))return;const i=e.body[0];i.kind==="possessive"||i.min>1||i.max<2||(i.min?i.min===1&&(e.body[0]=i.body):i.max=1)}};export{s as preventReDoS};
//# sourceMappingURL=prevent-redos.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/prevent-redos.ts"],
"sourcesContent": ["import type {QuantifierNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {hasOnlyChild} from '../../parser/node-utils.js';\n\n/**\nRemove identified ReDoS vulnerabilities without changing matches.\n*/\nconst preventReDoS: Visitor = {\n Quantifier({node}) {\n // Prevent a common cause of catastrophic backtracking by removing an unneeded nested\n // quantifier from the first alternative of infinitely-quantified groups. Can't remove nested\n // quantifiers from other alternatives or when the first alternative contains more than one\n // node, because that might change the match\n // TODO: It's safe to skip this transform if the quantified group is the last node in the\n // pattern, since there's no backtracking trigger if there's no following node\n const {body, max} = node;\n if (\n max !== Infinity ||\n // Can't operate on capturing groups because that could change the captured value\n body.type !== 'Group' ||\n // No benefit with atomic groups\n body.atomic\n ) {\n return;\n }\n const firstAlt = body.body[0];\n if (!hasOnlyChild(firstAlt, {type: 'Quantifier'})) {\n return;\n }\n const nestedQuantifier = firstAlt.body[0] as QuantifierNode;\n if (\n // No benefit with possessive quantifiers\n nestedQuantifier.kind === 'possessive' ||\n nestedQuantifier.min > 1 ||\n nestedQuantifier.max < 2\n ) {\n return;\n }\n if (!nestedQuantifier.min) {\n // Ex: Change `*` or `{0,2}` to `?`; preserve laziness\n nestedQuantifier.max = 1;\n } else if (nestedQuantifier.min === 1) {\n // Ex: Remove `+` or `{1,2}`\n firstAlt.body[0] = nestedQuantifier.body;\n }\n },\n};\n\nexport {\n preventReDoS,\n};\n"],
"mappings": "aAEA,OAAQ,gBAAAA,MAAmB,6BAK3B,MAAMC,EAAwB,CAC5B,WAAW,CAAC,KAAAC,CAAI,EAAG,CAOjB,KAAM,CAAC,KAAAC,EAAM,IAAAC,CAAG,EAAIF,EACpB,GACEE,IAAQ,KAERD,EAAK,OAAS,SAEdA,EAAK,OAEL,OAEF,MAAME,EAAWF,EAAK,KAAK,CAAC,EAC5B,GAAI,CAACH,EAAaK,EAAU,CAAC,KAAM,YAAY,CAAC,EAC9C,OAEF,MAAMC,EAAmBD,EAAS,KAAK,CAAC,EAGtCC,EAAiB,OAAS,cAC1BA,EAAiB,IAAM,GACvBA,EAAiB,IAAM,IAIpBA,EAAiB,IAGXA,EAAiB,MAAQ,IAElCD,EAAS,KAAK,CAAC,EAAIC,EAAiB,MAHpCA,EAAiB,IAAM,EAK3B,CACF,EAEA,OACEL,KAAA",
"names": ["hasOnlyChild", "preventReDoS", "node", "body", "max", "firstAlt", "nestedQuantifier"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Remove empty noncapturing, atomic, and flag groups, even if quantified.
*/
declare const removeEmptyGroups: Visitor;
export { removeEmptyGroups, };
//# sourceMappingURL=remove-empty-groups.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"remove-empty-groups.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/remove-empty-groups.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAEzD;;EAEE;AACF,QAAA,MAAM,iBAAiB,EAAE,OA4BxB,CAAC;AAmBF,OAAO,EACL,iBAAiB,GAClB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";const n={AbsenceFunction({node:e,remove:r}){o(e)&&r()},Group({node:e,remove:r}){o(e)&&r()},LookaroundAssertion({node:e,remove:r}){o(e)&&r()},Quantifier({node:e,remove:r}){let t=e.body;for(;t.type==="Quantifier";)t=t.body;o(t)&&r()}};function i(e){return e.body.every(r=>!r.body.length)}function o(e){switch(e.type){case"AbsenceFunction":return e.kind==="repeater"&&i(e);case"Group":return i(e);case"LookaroundAssertion":return!e.negate&&i(e);default:return!1}}export{n as removeEmptyGroups};
//# sourceMappingURL=remove-empty-groups.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/remove-empty-groups.ts"],
"sourcesContent": ["import type {AlternativeContainerNode, Node} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\n\n/**\nRemove empty noncapturing, atomic, and flag groups, even if quantified.\n*/\nconst removeEmptyGroups: Visitor = {\n AbsenceFunction({node, remove}) {\n if (isQualifiedAndEmpty(node)) {\n remove();\n }\n },\n\n Group({node, remove}) {\n if (isQualifiedAndEmpty(node)) {\n remove();\n }\n },\n\n LookaroundAssertion({node, remove}) {\n if (isQualifiedAndEmpty(node)) {\n remove();\n }\n },\n\n Quantifier({node, remove}) {\n let kid = node.body;\n while (kid.type === 'Quantifier') {\n kid = kid.body;\n }\n if (isQualifiedAndEmpty(kid)) {\n remove();\n }\n },\n};\n\nfunction hasOnlyEmptyAlts(node: AlternativeContainerNode): boolean {\n return node.body.every(alt => !alt.body.length);\n}\n\nfunction isQualifiedAndEmpty(node: Node): boolean {\n switch (node.type) {\n case 'AbsenceFunction':\n return node.kind === 'repeater' && hasOnlyEmptyAlts(node);\n case 'Group':\n return hasOnlyEmptyAlts(node);\n case 'LookaroundAssertion':\n return !node.negate && hasOnlyEmptyAlts(node);\n default:\n return false;\n }\n}\n\nexport {\n removeEmptyGroups,\n};\n"],
"mappings": "aAMA,MAAMA,EAA6B,CACjC,gBAAgB,CAAC,KAAAC,EAAM,OAAAC,CAAM,EAAG,CAC1BC,EAAoBF,CAAI,GAC1BC,EAAO,CAEX,EAEA,MAAM,CAAC,KAAAD,EAAM,OAAAC,CAAM,EAAG,CAChBC,EAAoBF,CAAI,GAC1BC,EAAO,CAEX,EAEA,oBAAoB,CAAC,KAAAD,EAAM,OAAAC,CAAM,EAAG,CAC9BC,EAAoBF,CAAI,GAC1BC,EAAO,CAEX,EAEA,WAAW,CAAC,KAAAD,EAAM,OAAAC,CAAM,EAAG,CACzB,IAAIE,EAAMH,EAAK,KACf,KAAOG,EAAI,OAAS,cAClBA,EAAMA,EAAI,KAERD,EAAoBC,CAAG,GACzBF,EAAO,CAEX,CACF,EAEA,SAASG,EAAiBJ,EAAyC,CACjE,OAAOA,EAAK,KAAK,MAAMK,GAAO,CAACA,EAAI,KAAK,MAAM,CAChD,CAEA,SAASH,EAAoBF,EAAqB,CAChD,OAAQA,EAAK,KAAM,CACjB,IAAK,kBACH,OAAOA,EAAK,OAAS,YAAcI,EAAiBJ,CAAI,EAC1D,IAAK,QACH,OAAOI,EAAiBJ,CAAI,EAC9B,IAAK,sBACH,MAAO,CAACA,EAAK,QAAUI,EAAiBJ,CAAI,EAC9C,QACE,MAAO,EACX,CACF,CAEA,OACED,KAAA",
"names": ["removeEmptyGroups", "node", "remove", "isQualifiedAndEmpty", "kid", "hasOnlyEmptyAlts", "alt"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Remove flags (from top-level and modifiers) that have no effect.
*/
declare const removeUselessFlags: Visitor;
export { removeUselessFlags, };
//# sourceMappingURL=remove-useless-flags.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"remove-useless-flags.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/remove-useless-flags.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAEzD;;EAEE;AACF,QAAA,MAAM,kBAAkB,EAAE,OA6BzB,CAAC;AAyBF,OAAO,EACL,kBAAkB,GACnB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";const o={Flags({node:e}){e.extended=!1,e.textSegmentMode==="grapheme"&&(e.textSegmentMode=null)},Directive({node:e,remove:t}){e.kind==="flags"&&(i(e),r(e)&&t())},Group({node:e}){e.flags&&(i(e),r(e))}};function r(e){const{flags:t}=e;return t&&!t.enable&&!t.disable?(delete e.flags,!0):!1}function i({flags:e}){if(!e)throw new Error("Expected flags");e.enable&&delete e.enable.extended,e.disable&&delete e.disable.extended,l(e)}function l(e){e.enable&&!Object.keys(e.enable).length&&delete e.enable,e.disable&&!Object.keys(e.disable).length&&delete e.disable}export{o as removeUselessFlags};
//# sourceMappingURL=remove-useless-flags.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/remove-useless-flags.ts"],
"sourcesContent": ["import type {DirectiveNode, GroupNode} from '../../parser/parse.js';\nimport type {FlagGroupModifiers} from '../../tokenizer/tokenize.js';\nimport type {Visitor} from '../../traverser/traverse.js';\n\n/**\nRemove flags (from top-level and modifiers) that have no effect.\n*/\nconst removeUselessFlags: Visitor = {\n // TODO: Support removing additional flags\n\n Flags({node}) {\n // Effects of flag x are already applied during parsing\n node.extended = false;\n // Text segment handling uses grapheme mode by default, so it doesn't need to be set\n if (node.textSegmentMode === 'grapheme') {\n node.textSegmentMode = null;\n }\n },\n\n Directive({node, remove}) {\n if (node.kind !== 'flags') {\n return;\n }\n removeFlagX(node);\n if (removeEmptyFlagsObj(node)) {\n remove();\n }\n },\n\n Group({node}) {\n if (!node.flags) {\n return;\n }\n removeFlagX(node);\n removeEmptyFlagsObj(node);\n },\n};\n\nfunction removeEmptyFlagsObj(node: DirectiveNode | GroupNode): boolean {\n const {flags} = node;\n if (flags && !flags.enable && !flags.disable) {\n delete node.flags;\n return true;\n }\n return false;\n}\n\nfunction removeFlagX({flags}: DirectiveNode | GroupNode) {\n if (!flags) {\n throw new Error('Expected flags');\n }\n flags.enable && delete flags.enable.extended;\n flags.disable && delete flags.disable.extended;\n cleanupFlagsObj(flags);\n}\n\nfunction cleanupFlagsObj(flags: FlagGroupModifiers) {\n flags.enable && !Object.keys(flags.enable).length && delete flags.enable;\n flags.disable && !Object.keys(flags.disable).length && delete flags.disable;\n}\n\nexport {\n removeUselessFlags,\n};\n"],
"mappings": "aAOA,MAAMA,EAA8B,CAGlC,MAAM,CAAC,KAAAC,CAAI,EAAG,CAEZA,EAAK,SAAW,GAEZA,EAAK,kBAAoB,aAC3BA,EAAK,gBAAkB,KAE3B,EAEA,UAAU,CAAC,KAAAA,EAAM,OAAAC,CAAM,EAAG,CACpBD,EAAK,OAAS,UAGlBE,EAAYF,CAAI,EACZG,EAAoBH,CAAI,GAC1BC,EAAO,EAEX,EAEA,MAAM,CAAC,KAAAD,CAAI,EAAG,CACPA,EAAK,QAGVE,EAAYF,CAAI,EAChBG,EAAoBH,CAAI,EAC1B,CACF,EAEA,SAASG,EAAoBH,EAA0C,CACrE,KAAM,CAAC,MAAAI,CAAK,EAAIJ,EAChB,OAAII,GAAS,CAACA,EAAM,QAAU,CAACA,EAAM,SACnC,OAAOJ,EAAK,MACL,IAEF,EACT,CAEA,SAASE,EAAY,CAAC,MAAAE,CAAK,EAA8B,CACvD,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,gBAAgB,EAElCA,EAAM,QAAU,OAAOA,EAAM,OAAO,SACpCA,EAAM,SAAW,OAAOA,EAAM,QAAQ,SACtCC,EAAgBD,CAAK,CACvB,CAEA,SAASC,EAAgBD,EAA2B,CAClDA,EAAM,QAAU,CAAC,OAAO,KAAKA,EAAM,MAAM,EAAE,QAAU,OAAOA,EAAM,OAClEA,EAAM,SAAW,CAAC,OAAO,KAAKA,EAAM,OAAO,EAAE,QAAU,OAAOA,EAAM,OACtE,CAEA,OACEL,KAAA",
"names": ["removeUselessFlags", "node", "remove", "removeFlagX", "removeEmptyFlagsObj", "flags", "cleanupFlagsObj"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Cleanup callout arguments, removing redundant commas, leading zeros, and empty braces.
*/
declare const simplifyCallouts: Visitor;
export { simplifyCallouts, };
//# sourceMappingURL=simplify-callouts.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"simplify-callouts.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/simplify-callouts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;EAEE;AACF,QAAA,MAAM,gBAAgB,EAAE,OAoBvB,CAAC;AAEF,OAAO,EACL,gBAAgB,GACjB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{createLookaroundAssertion as o}from"../../parser/parse.js";const a={NamedCallout({node:r,replaceWith:i}){const{arguments:e,kind:n}=r;if(n==="fail"){i(o({negate:!0}));return}if(!e)return;const s=e.filter(t=>t!=="").map(t=>typeof t=="string"&&/^[+-]?\d+$/.test(t)?+t:t);r.arguments=s.length?s:null}};export{a as simplifyCallouts};
//# sourceMappingURL=simplify-callouts.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/simplify-callouts.ts"],
"sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\nimport {createLookaroundAssertion} from '../../parser/parse.js';\n\n/**\nCleanup callout arguments, removing redundant commas, leading zeros, and empty braces.\n*/\nconst simplifyCallouts: Visitor = {\n NamedCallout({node, replaceWith}) {\n const {arguments: args, kind} = node;\n\n // Special case: `(*FAIL)` -> `(?!)`\n if (kind === 'fail') {\n replaceWith(createLookaroundAssertion({negate: true}));\n return;\n }\n\n if (!args) {\n return;\n }\n const newArgs: Array<string | number> = args.\n filter(arg => arg !== '').\n // TODO: If supporting custom callout names in the future, add `kind !== 'custom'` to this\n // condition, since custom named callouts might treat e.g. `+05` as a string\n map(arg => (typeof arg === 'string' && /^[+-]?\\d+$/.test(arg)) ? +arg : arg);\n node.arguments = newArgs.length ? newArgs : null;\n },\n};\n\nexport {\n simplifyCallouts,\n};\n"],
"mappings": "aACA,OAAQ,6BAAAA,MAAgC,wBAKxC,MAAMC,EAA4B,CAChC,aAAa,CAAC,KAAAC,EAAM,YAAAC,CAAW,EAAG,CAChC,KAAM,CAAC,UAAWC,EAAM,KAAAC,CAAI,EAAIH,EAGhC,GAAIG,IAAS,OAAQ,CACnBF,EAAYH,EAA0B,CAAC,OAAQ,EAAI,CAAC,CAAC,EACrD,MACF,CAEA,GAAI,CAACI,EACH,OAEF,MAAME,EAAkCF,EACtC,OAAOG,GAAOA,IAAQ,EAAE,EAGxB,IAAIA,GAAQ,OAAOA,GAAQ,UAAY,aAAa,KAAKA,CAAG,EAAK,CAACA,EAAMA,CAAG,EAC7EL,EAAK,UAAYI,EAAQ,OAASA,EAAU,IAC9C,CACF,EAEA,OACEL,KAAA",
"names": ["createLookaroundAssertion", "simplifyCallouts", "node", "replaceWith", "args", "kind", "newArgs", "arg"]
}

View File

@@ -0,0 +1,8 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Unnest character classes when possible.
See also `unwrapNegationWrappers`.
*/
declare const unnestUselessClasses: Visitor;
export { unnestUselessClasses, };
//# sourceMappingURL=unnest-useless-classes.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unnest-useless-classes.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/unnest-useless-classes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;;EAGE;AACF,QAAA,MAAM,oBAAoB,EAAE,OAsC3B,CAAC;AAEF,OAAO,EACL,oBAAoB,GACrB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{hasOnlyChild as i}from"../../parser/node-utils.js";const f={CharacterClass({node:s,parent:r,replaceWith:n,replaceWithMultiple:t}){const{body:e,kind:o,negate:a}=s;if(r.type!=="CharacterClass"||o!=="union"||!e.length)return;const C=e[0];if(i(r,{type:"CharacterClass",kind:"union"})){r.negate=r.negate!==a,t(e,{traverse:!0});return}a||(r.kind==="union"?t(e,{traverse:!0}):i(s)&&n(C,{traverse:!0}))}};export{f as unnestUselessClasses};
//# sourceMappingURL=unnest-useless-classes.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/unnest-useless-classes.ts"],
"sourcesContent": ["import type {CharacterClassNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {hasOnlyChild} from '../../parser/node-utils.js';\n\n/**\nUnnest character classes when possible.\nSee also `unwrapNegationWrappers`.\n*/\nconst unnestUselessClasses: Visitor = {\n CharacterClass({node, parent, replaceWith, replaceWithMultiple}) {\n const {body, kind, negate} = node;\n if (\n // Don't use this to unwrap outermost classes; see `unwrapUselessClasses` for that\n parent.type !== 'CharacterClass' ||\n kind !== 'union' ||\n !body.length\n ) {\n return;\n }\n const firstEl = body[0];\n // Special case to unnest classes that are an only-kid of their parent, since it might flip\n // `negate` on the parent; ex:\n // `[[a]]` -> `[a]`; `[[^a]]` -> `[^a]`; `[^[a]]` -> `[^a]`; `[^[^a]]` -> `[a]`\n if (hasOnlyChild(parent, {\n type: 'CharacterClass',\n kind: 'union',\n })) {\n parent.negate = parent.negate !== negate;\n replaceWithMultiple(body, {traverse: true});\n return;\n }\n // Remainder of options apply only if the class is non-negated\n if (negate) {\n return;\n }\n // Unnest all kids into a union class\n if (parent.kind === 'union') {\n replaceWithMultiple(body, {traverse: true});\n // Can unnest any one kid into an intersection class\n // TODO: After supporting `format` for classes (see <github.com/slevithan/oniguruma-parser/issues/1>),\n // can visually unnest any number of kids into intersection by flipping this class's `format`\n // from `'explicit'` to `'implicit'`, rather than replacing it\n } else if (hasOnlyChild(node)) {\n replaceWith(firstEl, {traverse: true});\n }\n },\n};\n\nexport {\n unnestUselessClasses,\n};\n"],
"mappings": "aAEA,OAAQ,gBAAAA,MAAmB,6BAM3B,MAAMC,EAAgC,CACpC,eAAe,CAAC,KAAAC,EAAM,OAAAC,EAAQ,YAAAC,EAAa,oBAAAC,CAAmB,EAAG,CAC/D,KAAM,CAAC,KAAAC,EAAM,KAAAC,EAAM,OAAAC,CAAM,EAAIN,EAC7B,GAEEC,EAAO,OAAS,kBAChBI,IAAS,SACT,CAACD,EAAK,OAEN,OAEF,MAAMG,EAAUH,EAAK,CAAC,EAItB,GAAIN,EAAaG,EAAQ,CACvB,KAAM,iBACN,KAAM,OACR,CAAC,EAAG,CACFA,EAAO,OAASA,EAAO,SAAWK,EAClCH,EAAoBC,EAAM,CAAC,SAAU,EAAI,CAAC,EAC1C,MACF,CAEIE,IAIAL,EAAO,OAAS,QAClBE,EAAoBC,EAAM,CAAC,SAAU,EAAI,CAAC,EAKjCN,EAAaE,CAAI,GAC1BE,EAAYK,EAAS,CAAC,SAAU,EAAI,CAAC,EAEzC,CACF,EAEA,OACER,KAAA",
"names": ["hasOnlyChild", "unnestUselessClasses", "node", "parent", "replaceWith", "replaceWithMultiple", "body", "kind", "negate", "firstEl"]
}

View File

@@ -0,0 +1,9 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Unwrap negated classes used to negate an individual character set.
Allows independently controlling this behavior, and avoids logic duplication in
`unwrapUselessClasses` and `unnestUselessClasses`.
*/
declare const unwrapNegationWrappers: Visitor;
export { unwrapNegationWrappers, };
//# sourceMappingURL=unwrap-negation-wrappers.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unwrap-negation-wrappers.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/unwrap-negation-wrappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;;;EAIE;AACF,QAAA,MAAM,sBAAsB,EAAE,OA0B7B,CAAC;AAEF,OAAO,EACL,sBAAsB,GACvB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{createCharacterSet as o}from"../../parser/parse.js";const c={CharacterClass({node:i,parent:t,replaceWith:r}){const{body:a,kind:n,negate:s}=i;if(!s||n!=="union"||a.length!==1)return;const e=a[0];if(e.type==="CharacterSet")e.negate=!e.negate,r(e);else if(t.type!=="CharacterClass"&&e.type==="Character"&&e.value===10){if(t.type==="Quantifier"&&t.kind!=="lazy")return;r(o("newline",{negate:!0}))}}};export{c as unwrapNegationWrappers};
//# sourceMappingURL=unwrap-negation-wrappers.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/unwrap-negation-wrappers.ts"],
"sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\nimport {createCharacterSet} from '../../parser/parse.js';\n\n/**\nUnwrap negated classes used to negate an individual character set.\nAllows independently controlling this behavior, and avoids logic duplication in\n`unwrapUselessClasses` and `unnestUselessClasses`.\n*/\nconst unwrapNegationWrappers: Visitor = {\n CharacterClass({node, parent, replaceWith}) {\n const {body, kind, negate} = node;\n if (!negate || kind !== 'union' || body.length !== 1) {\n return;\n }\n const kid = body[0];\n if (kid.type === 'CharacterSet') {\n kid.negate = !kid.negate;\n // Might unnest into a class or unwrap into a non-class. All character set kinds valid in a\n // class are also valid outside of a class, though the inverse isn't true\n replaceWith(kid);\n } else if (\n parent.type !== 'CharacterClass' &&\n kid.type === 'Character' &&\n kid.value === 10 // '\\n'\n ) {\n if (parent.type === 'Quantifier' && parent.kind !== 'lazy') {\n // Avoid introducing a trigger for a `vscode-oniguruma` bug (v2.0.1 tested); see\n // <github.com/kkos/oniguruma/issues/347>\n return;\n }\n // `[^\\n]` -> `\\N`; can only use `\\N` if not in a class\n replaceWith(createCharacterSet('newline', {negate: true}));\n }\n },\n};\n\nexport {\n unwrapNegationWrappers,\n};\n"],
"mappings": "aACA,OAAQ,sBAAAA,MAAyB,wBAOjC,MAAMC,EAAkC,CACtC,eAAe,CAAC,KAAAC,EAAM,OAAAC,EAAQ,YAAAC,CAAW,EAAG,CAC1C,KAAM,CAAC,KAAAC,EAAM,KAAAC,EAAM,OAAAC,CAAM,EAAIL,EAC7B,GAAI,CAACK,GAAUD,IAAS,SAAWD,EAAK,SAAW,EACjD,OAEF,MAAMG,EAAMH,EAAK,CAAC,EAClB,GAAIG,EAAI,OAAS,eACfA,EAAI,OAAS,CAACA,EAAI,OAGlBJ,EAAYI,CAAG,UAEfL,EAAO,OAAS,kBAChBK,EAAI,OAAS,aACbA,EAAI,QAAU,GACd,CACA,GAAIL,EAAO,OAAS,cAAgBA,EAAO,OAAS,OAGlD,OAGFC,EAAYJ,EAAmB,UAAW,CAAC,OAAQ,EAAI,CAAC,CAAC,CAC3D,CACF,CACF,EAEA,OACEC,KAAA",
"names": ["createCharacterSet", "unwrapNegationWrappers", "node", "parent", "replaceWith", "body", "kind", "negate", "kid"]
}

View File

@@ -0,0 +1,8 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Unwrap outermost non-negated character classes containing a single character or character set.
See also `unwrapNegationWrappers`.
*/
declare const unwrapUselessClasses: Visitor;
export { unwrapUselessClasses, };
//# sourceMappingURL=unwrap-useless-classes.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unwrap-useless-classes.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/unwrap-useless-classes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAEzD;;;EAGE;AACF,QAAA,MAAM,oBAAoB,EAAE,OAe3B,CAAC;AAEF,OAAO,EACL,oBAAoB,GACrB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";const i={CharacterClass({node:t,parent:s,replaceWith:a}){const{body:r,kind:n,negate:o}=t,e=r[0];s.type==="CharacterClass"||o||n!=="union"||r.length!==1||e.type!=="Character"&&e.type!=="CharacterSet"||a(e,{traverse:!0})}};export{i as unwrapUselessClasses};
//# sourceMappingURL=unwrap-useless-classes.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/unwrap-useless-classes.ts"],
"sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\n\n/**\nUnwrap outermost non-negated character classes containing a single character or character set.\nSee also `unwrapNegationWrappers`.\n*/\nconst unwrapUselessClasses: Visitor = {\n CharacterClass({node, parent, replaceWith}) {\n const {body, kind, negate} = node;\n const kid = body[0];\n if (\n parent.type === 'CharacterClass' ||\n negate ||\n kind !== 'union' ||\n body.length !== 1 ||\n (kid.type !== 'Character' && kid.type !== 'CharacterSet')\n ) {\n return;\n }\n replaceWith(kid, {traverse: true});\n },\n};\n\nexport {\n unwrapUselessClasses,\n};\n"],
"mappings": "aAMA,MAAMA,EAAgC,CACpC,eAAe,CAAC,KAAAC,EAAM,OAAAC,EAAQ,YAAAC,CAAW,EAAG,CAC1C,KAAM,CAAC,KAAAC,EAAM,KAAAC,EAAM,OAAAC,CAAM,EAAIL,EACvBM,EAAMH,EAAK,CAAC,EAEhBF,EAAO,OAAS,kBAChBI,GACAD,IAAS,SACTD,EAAK,SAAW,GACfG,EAAI,OAAS,aAAeA,EAAI,OAAS,gBAI5CJ,EAAYI,EAAK,CAAC,SAAU,EAAI,CAAC,CACnC,CACF,EAEA,OACEP,KAAA",
"names": ["unwrapUselessClasses", "node", "parent", "replaceWith", "body", "kind", "negate", "kid"]
}

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Unwrap nonbeneficial noncapturing and atomic groups.
*/
declare const unwrapUselessGroups: Visitor;
export { unwrapUselessGroups, };
//# sourceMappingURL=unwrap-useless-groups.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unwrap-useless-groups.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/unwrap-useless-groups.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAGzD;;EAEE;AACF,QAAA,MAAM,mBAAmB,EAAE,OA4D1B,CAAC;AAwBF,OAAO,EACL,mBAAmB,GACpB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{isAlternativeContainer as f,isQuantifiable as p}from"../../parser/node-utils.js";const d={"*"({node:e}){f(e)&&y(e)&&(e.body=e.body[0].body[0].body)},Group({node:e,parent:t,replaceWithMultiple:o}){const{atomic:r,body:a,flags:l}=e,n=a[0].body;if(a.length>1||t.type==="Quantifier")return;let i=!1;r?n.every(({type:u})=>s.has(u))&&(i=!0):l||(i=!0),i&&o(n,{traverse:!0})},Quantifier({node:e}){if(e.body.type!=="Group")return;const t=e.body;if(t.body.length>1)return;const o=t.body[0].body;if(o.length!==1)return;const r=o[0];!p(r)||t.atomic&&!s.has(r.type)||t.flags||(e.body=r)}},s=new Set(["Assertion","Backreference","Character","CharacterClass","CharacterSet","Directive","NamedCallout"]);function y({body:e}){const t=e[0].body;return e.length===1&&t.length===1&&t[0].type==="Group"&&!t[0].atomic&&!t[0].flags&&t[0].body.length>1}export{d as unwrapUselessGroups};
//# sourceMappingURL=unwrap-useless-groups.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/unwrap-useless-groups.ts"],
"sourcesContent": ["import type {AlternativeContainerNode, AlternativeElementNode, GroupNode, Node, QuantifiableNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer, isQuantifiable} from '../../parser/node-utils.js';\n\n/**\nUnwrap nonbeneficial noncapturing and atomic groups.\n*/\nconst unwrapUselessGroups: Visitor = {\n // Unwrap kid from the outside in, since the traverser doesn't support stepping multiple levels\n // up the tree\n '*'({node}) {\n if (!isAlternativeContainer(node)) {\n return;\n }\n if (hasMultiAltNoncapturingGroupOnlyChild(node)) {\n // Isn't needed in some cases like if `node` is itself a basic noncapturing group (since\n // there's already handling in `Group`), but it doesn't hurt to handle it here instead\n node.body = (node.body[0].body[0] as GroupNode).body;\n }\n },\n\n Group({node, parent, replaceWithMultiple}) {\n const {atomic, body, flags} = node;\n const firstAltEls = body[0].body;\n if (body.length > 1 || parent.type === 'Quantifier') {\n return;\n }\n let unwrap = false;\n if (atomic) {\n if (firstAltEls.every(({type}: AlternativeElementNode) => atomicTypes.has(type))) {\n unwrap = true;\n }\n // For flag groups, rely on `removeUselessFlags`, after which the group can be unwrapped in a\n // subsequent pass\n } else if (!flags) {\n unwrap = true;\n }\n if (unwrap) {\n replaceWithMultiple(firstAltEls, {traverse: true});\n }\n },\n\n // Unwrap quantified groups that contain a single quantifiable node\n Quantifier({node}) {\n if (node.body.type !== 'Group') {\n return;\n }\n const quantifiedGroup = node.body;\n if (quantifiedGroup.body.length > 1) {\n return;\n }\n const groupKids = quantifiedGroup.body[0].body;\n if (groupKids.length !== 1) {\n return;\n }\n const candidate = groupKids[0];\n if (\n !isQuantifiable(candidate) ||\n // Some atomic types have already been ruled out as not quantifiable\n (quantifiedGroup.atomic && !atomicTypes.has(candidate.type)) ||\n quantifiedGroup.flags\n ) {\n return;\n }\n // Make the only child of the group the new `body` of the quantifier\n node.body = candidate;\n },\n};\n\nconst atomicTypes = new Set<Node['type']>([\n 'Assertion',\n 'Backreference',\n 'Character',\n 'CharacterClass',\n 'CharacterSet',\n 'Directive',\n 'NamedCallout',\n]);\n\nfunction hasMultiAltNoncapturingGroupOnlyChild({body}: AlternativeContainerNode): boolean {\n const firstAltEls = body[0].body;\n return (\n body.length === 1 &&\n firstAltEls.length === 1 &&\n firstAltEls[0].type === 'Group' &&\n !firstAltEls[0].atomic &&\n !firstAltEls[0].flags &&\n firstAltEls[0].body.length > 1\n );\n}\n\nexport {\n unwrapUselessGroups,\n};\n"],
"mappings": "aAEA,OAAQ,0BAAAA,EAAwB,kBAAAC,MAAqB,6BAKrD,MAAMC,EAA+B,CAGnC,IAAI,CAAC,KAAAC,CAAI,EAAG,CACLH,EAAuBG,CAAI,GAG5BC,EAAsCD,CAAI,IAG5CA,EAAK,KAAQA,EAAK,KAAK,CAAC,EAAE,KAAK,CAAC,EAAgB,KAEpD,EAEA,MAAM,CAAC,KAAAA,EAAM,OAAAE,EAAQ,oBAAAC,CAAmB,EAAG,CACzC,KAAM,CAAC,OAAAC,EAAQ,KAAAC,EAAM,MAAAC,CAAK,EAAIN,EACxBO,EAAcF,EAAK,CAAC,EAAE,KAC5B,GAAIA,EAAK,OAAS,GAAKH,EAAO,OAAS,aACrC,OAEF,IAAIM,EAAS,GACTJ,EACEG,EAAY,MAAM,CAAC,CAAC,KAAAE,CAAI,IAA8BC,EAAY,IAAID,CAAI,CAAC,IAC7ED,EAAS,IAIDF,IACVE,EAAS,IAEPA,GACFL,EAAoBI,EAAa,CAAC,SAAU,EAAI,CAAC,CAErD,EAGA,WAAW,CAAC,KAAAP,CAAI,EAAG,CACjB,GAAIA,EAAK,KAAK,OAAS,QACrB,OAEF,MAAMW,EAAkBX,EAAK,KAC7B,GAAIW,EAAgB,KAAK,OAAS,EAChC,OAEF,MAAMC,EAAYD,EAAgB,KAAK,CAAC,EAAE,KAC1C,GAAIC,EAAU,SAAW,EACvB,OAEF,MAAMC,EAAYD,EAAU,CAAC,EAE3B,CAACd,EAAee,CAAS,GAExBF,EAAgB,QAAU,CAACD,EAAY,IAAIG,EAAU,IAAI,GAC1DF,EAAgB,QAKlBX,EAAK,KAAOa,EACd,CACF,EAEMH,EAAc,IAAI,IAAkB,CACxC,YACA,gBACA,YACA,iBACA,eACA,YACA,cACF,CAAC,EAED,SAAST,EAAsC,CAAC,KAAAI,CAAI,EAAsC,CACxF,MAAME,EAAcF,EAAK,CAAC,EAAE,KAC5B,OACEA,EAAK,SAAW,GAChBE,EAAY,SAAW,GACvBA,EAAY,CAAC,EAAE,OAAS,SACxB,CAACA,EAAY,CAAC,EAAE,QAChB,CAACA,EAAY,CAAC,EAAE,OAChBA,EAAY,CAAC,EAAE,KAAK,OAAS,CAEjC,CAEA,OACER,KAAA",
"names": ["isAlternativeContainer", "isQuantifiable", "unwrapUselessGroups", "node", "hasMultiAltNoncapturingGroupOnlyChild", "parent", "replaceWithMultiple", "atomic", "body", "flags", "firstAltEls", "unwrap", "type", "atomicTypes", "quantifiedGroup", "groupKids", "candidate"]
}

View File

@@ -0,0 +1,15 @@
import type { Node } from '../../parser/parse.js';
import type { Visitor } from '../../traverser/traverse.js';
/**
Use shorthands (`\d`, `\h`, `\s`, etc.) when possible.
- `\d` from `\p{Decimal_Number}`, `\p{Nd}`, `\p{digit}`, `[[:digit:]]`
- `\h` from `\p{ASCII_Hex_Digit}`, `\p{AHex}`, `\p{xdigit}`, `[[:xdigit:]]`, `[0-9A-Fa-f]`
- `\s` from `\p{White_Space}`, `\p{WSpace}`, `\p{space}`, `[[:space:]]`
- `\w` from `[\p{L}\p{M}\p{N}\p{Pc}]` - Not the same as POSIX `\p{word}`, `[[:word:]]`!
- `\O` from `\p{Any}` if not in class
See also `useUnicodeProps`.
*/
declare const useShorthands: Visitor;
declare function isRange(node: Node, min: number, max: number): boolean;
export { isRange, useShorthands, };
//# sourceMappingURL=use-shorthands.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-shorthands.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/use-shorthands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,IAAI,EAAC,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAIzD;;;;;;;;EAQE;AACF,QAAA,MAAM,aAAa,EAAE,OA+FpB,CAAC;AAWF,iBAAS,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAM9D;AAsDD,OAAO,EACL,OAAO,EACP,aAAa,GACd,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{createCharacterSet as p}from"../../parser/parse.js";import{cpOf as l}from"../../utils.js";const S={CharacterSet({node:r,parent:o,root:e,replaceWith:s}){const{kind:a,negate:u,value:t}=r;let c=null;a==="property"&&(t==="Decimal_Number"||t==="Nd")&&!e.flags.digitIsAscii&&!e.flags.posixIsAscii||a==="posix"&&t==="digit"?c=p("digit",{negate:u}):a==="property"&&(t==="ASCII_Hex_Digit"||t==="AHex")||a==="posix"&&t==="xdigit"?c=p("hex",{negate:u}):a==="property"&&(t==="White_Space"||t==="WSpace")&&!e.flags.spaceIsAscii&&!e.flags.posixIsAscii||a==="posix"&&t==="space"?c=p("space",{negate:u}):o.type!=="CharacterClass"&&a==="property"&&!u&&t==="Any"&&(c=p("any")),c&&s(c)},CharacterClass({node:r,root:o}){if(r.kind!=="union")return;const e={rangeDigit0To9:!1,rangeAToFLower:!1,rangeAToFUpper:!1,unicodeL:!1,unicodeM:!1,unicodeN:!1,unicodePc:!1};for(const s of r.body)s.type==="CharacterClassRange"?(e.rangeDigit0To9||=n(s,i.n0,i.n9),e.rangeAToFLower||=n(s,i.a,i.f),e.rangeAToFUpper||=n(s,i.A,i.F)):s.type==="CharacterSet"&&(e.unicodeL||=f(s,"L"),e.unicodeM||=f(s,"M"),e.unicodeN||=f(s,"N"),e.unicodePc||=f(s,"Pc",{includeSupercategories:!0}));e.rangeDigit0To9&&e.rangeAToFUpper&&e.rangeAToFLower&&(r.body=r.body.filter(s=>!(n(s,i.n0,i.n9)||n(s,i.a,i.f)||n(s,i.A,i.F))),r.body.push(p("hex"))),e.unicodeL&&e.unicodeM&&e.unicodeN&&e.unicodePc&&!o.flags.wordIsAscii&&!o.flags.posixIsAscii&&(r.body=r.body.filter(s=>!f(s,["L","M","N","Pc"],{includeSubcategories:!0})),r.body.push(p("word")))}},i={n0:l("0"),n9:l("9"),A:l("A"),F:l("F"),a:l("a"),f:l("f")};function n(r,o,e){return r.type==="CharacterClassRange"&&r.min.value===o&&r.max.value===e}function f(r,o,e={}){if(r.type!=="CharacterSet"||r.kind!=="property"||r.negate)return!1;const s=Array.isArray(o)?o:[o],a=[];for(const u of s){a.push(u);const t=g[u]?.full,c=b[u],y=g[u]?.sub;t&&a.push(t),e.includeSupercategories&&c&&(a.push(c),a.push(g[c].full)),e.includeSubcategories&&y&&a.push(...y)}return a.includes(r.value)}const d=["Ll","Lm","Lo","Lt","Lu"],h=["Mc","Me","Mn"],m=["Nd","Nl","No"],N=["Pc","Pd","Pe","Pf","Pi","Po","Ps"],g={L:{full:"Letter",sub:d},M:{full:"Mark",sub:h},N:{full:"Number",sub:m},P:{full:"Punctuation",sub:N}},b={};for(const r of Object.keys(g))for(const o of g[r].sub)b[o]=r;export{n as isRange,S as useShorthands};
//# sourceMappingURL=use-shorthands.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Use Unicode property aliases.
*/
declare const useUnicodeAliases: Visitor;
export { useUnicodeAliases, };
//# sourceMappingURL=use-unicode-aliases.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-unicode-aliases.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/use-unicode-aliases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAEzD;;EAEE;AACF,QAAA,MAAM,iBAAiB,EAAE,OAUxB,CAAC;AA0GF,OAAO,EACL,iBAAiB,GAClB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";const r={CharacterSet({node:e}){if(e.kind!=="property")return;const t=a.get(e.value);t&&(e.value=t)}},a=new Map([["Other","C"],["Control","Cc"],["Format","Cf"],["Unassigned","Cn"],["Private_Use","Co"],["Surrogate","Cs"],["Letter","L"],["Cased_Letter","LC"],["Lowercase_Letter","Ll"],["Modifier_Letter","Lm"],["Other_Letter","Lo"],["Titlecase_Letter","Lt"],["Uppercase_Letter","Lu"],["Mark","M"],["Combining_Mark","M"],["Spacing_Mark","Mc"],["Enclosing_Mark","Me"],["Nonspacing_Mark","Mn"],["Number","N"],["Decimal_Number","Nd"],["Letter_Number","Nl"],["Other_Number","No"],["Punctuation","P"],["punct","P"],["Connector_Punctuation","Pc"],["Dash_Punctuation","Pd"],["Close_Punctuation","Pe"],["Final_Punctuation","Pf"],["Initial_Punctuation","Pi"],["Other_Punctuation","Po"],["Open_Punctuation","Ps"],["Symbol","S"],["Currency_Symbol","Sc"],["Modifier_Symbol","Sk"],["Math_Symbol","Sm"],["Other_Symbol","So"],["Separator","Z"],["Line_Separator","Zl"],["Paragraph_Separator","Zp"],["Space_Separator","Zs"],["ASCII_Hex_Digit","AHex"],["Bidi_Control","Bidi_C"],["Case_Ignorable","CI"],["Changes_When_Casefolded","CWCF"],["Changes_When_Casemapped","CWCM"],["Changes_When_Lowercased","CWL"],["Changes_When_Titlecased","CWT"],["Changes_When_Uppercased","CWU"],["Default_Ignorable_Code_Point","DI"],["Deprecated","Dep"],["Diacritic","Dia"],["Emoji_Component","EComp"],["Emoji_Modifier","EMod"],["Emoji_Modifier_Base","EBase"],["Emoji_Presentation","EPres"],["Extended_Pictographic","ExtPict"],["Extender","Ext"],["Grapheme_Base","Gr_Base"],["Grapheme_Extend","Gr_Ext"],["Grapheme_Link","Gr_Link"],["Hex_Digit","Hex"],["IDS_Binary_Operator","IDSB"],["IDS_Trinary_Operator","IDST"],["IDS_Unary_Operator","IDSU"],["ID_Continue","IDC"],["ID_Start","IDS"],["Ideographic","Ideo"],["Join_Control","Join_C"],["Logical_Order_Exception","LOE"],["Noncharacter_Code_Point","NChar"],["Other_Alphabetic","OAlpha"],["Other_Default_Ignorable_Code_Point","ODI"],["Other_Grapheme_Extend","OGr_Ext"],["Other_ID_Continue","OIDC"],["Other_ID_Start","OIDS"],["Other_Lowercase","OLower"],["Other_Math","OMath"],["Other_Uppercase","OUpper"],["Pattern_Syntax","Pat_Syn"],["Pattern_White_Space","Pat_WS"],["Prepended_Concatenation_Mark","PCM"],["Quotation_Mark","QMark"],["Regional_Indicator","RI"],["Sentence_Terminal","STerm"],["Soft_Dotted","SD"],["Terminal_Punctuation","Term"],["Unified_Ideograph","UIdeo"],["Variation_Selector","VS"],["White_Space","WSpace"],["XID_Continue","XIDC"],["XID_Start","XIDS"]]);export{r as useUnicodeAliases};
//# sourceMappingURL=use-unicode-aliases.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/use-unicode-aliases.ts"],
"sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\n\n/**\nUse Unicode property aliases.\n*/\nconst useUnicodeAliases: Visitor = {\n CharacterSet({node}) {\n if (node.kind !== 'property') {\n return;\n }\n const alias = OnigUnicodeAliasMap.get(node.value);\n if (alias) {\n node.value = alias;\n }\n },\n};\n\n// Oniguruma doesn't include all Unicode property aliases; some are treated as POSIX class names\n// and are excluded (see `PosixClassNames`)\nconst OnigUnicodeAliasMap = /* @__PURE__ */ new Map([\n // ## General category aliases\n ['Other', 'C'],\n ['Control', 'Cc'],\n ['Format', 'Cf'],\n ['Unassigned', 'Cn'],\n ['Private_Use', 'Co'],\n ['Surrogate', 'Cs'],\n ['Letter', 'L'],\n ['Cased_Letter', 'LC'],\n ['Lowercase_Letter', 'Ll'],\n ['Modifier_Letter', 'Lm'],\n ['Other_Letter', 'Lo'],\n ['Titlecase_Letter', 'Lt'],\n ['Uppercase_Letter', 'Lu'],\n ['Mark', 'M'],\n ['Combining_Mark', 'M'],\n ['Spacing_Mark', 'Mc'],\n ['Enclosing_Mark', 'Me'],\n ['Nonspacing_Mark', 'Mn'],\n ['Number', 'N'],\n ['Decimal_Number', 'Nd'],\n ['Letter_Number', 'Nl'],\n ['Other_Number', 'No'],\n ['Punctuation', 'P'],\n // `punct` is also a POSIX class name, but it's included in the Oniguruma property list since the\n // POSIX class version uses a different value starting with Oniguruma 6.9.9\n ['punct', 'P'],\n ['Connector_Punctuation', 'Pc'],\n ['Dash_Punctuation', 'Pd'],\n ['Close_Punctuation', 'Pe'],\n ['Final_Punctuation', 'Pf'],\n ['Initial_Punctuation', 'Pi'],\n ['Other_Punctuation', 'Po'],\n ['Open_Punctuation', 'Ps'],\n ['Symbol', 'S'],\n ['Currency_Symbol', 'Sc'],\n ['Modifier_Symbol', 'Sk'],\n ['Math_Symbol', 'Sm'],\n ['Other_Symbol', 'So'],\n ['Separator', 'Z'],\n ['Line_Separator', 'Zl'],\n ['Paragraph_Separator', 'Zp'],\n ['Space_Separator', 'Zs'],\n\n // ## Binary property aliases\n ['ASCII_Hex_Digit', 'AHex'],\n ['Bidi_Control', 'Bidi_C'],\n ['Case_Ignorable', 'CI'],\n ['Changes_When_Casefolded', 'CWCF'],\n ['Changes_When_Casemapped', 'CWCM'],\n ['Changes_When_Lowercased', 'CWL'],\n ['Changes_When_Titlecased', 'CWT'],\n ['Changes_When_Uppercased', 'CWU'],\n ['Default_Ignorable_Code_Point', 'DI'],\n ['Deprecated', 'Dep'],\n ['Diacritic', 'Dia'],\n ['Emoji_Component', 'EComp'],\n ['Emoji_Modifier', 'EMod'],\n ['Emoji_Modifier_Base', 'EBase'],\n ['Emoji_Presentation', 'EPres'],\n ['Extended_Pictographic', 'ExtPict'],\n ['Extender', 'Ext'],\n ['Grapheme_Base', 'Gr_Base'],\n ['Grapheme_Extend', 'Gr_Ext'],\n ['Grapheme_Link', 'Gr_Link'],\n ['Hex_Digit', 'Hex'],\n ['IDS_Binary_Operator', 'IDSB'],\n ['IDS_Trinary_Operator', 'IDST'],\n ['IDS_Unary_Operator', 'IDSU'],\n ['ID_Continue', 'IDC'],\n ['ID_Start', 'IDS'],\n ['Ideographic', 'Ideo'],\n ['Join_Control', 'Join_C'],\n ['Logical_Order_Exception', 'LOE'],\n ['Noncharacter_Code_Point', 'NChar'],\n ['Other_Alphabetic', 'OAlpha'],\n ['Other_Default_Ignorable_Code_Point', 'ODI'],\n ['Other_Grapheme_Extend', 'OGr_Ext'],\n ['Other_ID_Continue', 'OIDC'],\n ['Other_ID_Start', 'OIDS'],\n ['Other_Lowercase', 'OLower'],\n ['Other_Math', 'OMath'],\n ['Other_Uppercase', 'OUpper'],\n ['Pattern_Syntax', 'Pat_Syn'],\n ['Pattern_White_Space', 'Pat_WS'],\n ['Prepended_Concatenation_Mark', 'PCM'],\n ['Quotation_Mark', 'QMark'],\n ['Regional_Indicator', 'RI'],\n ['Sentence_Terminal', 'STerm'],\n ['Soft_Dotted', 'SD'],\n ['Terminal_Punctuation', 'Term'],\n ['Unified_Ideograph', 'UIdeo'],\n ['Variation_Selector', 'VS'],\n ['White_Space', 'WSpace'],\n ['XID_Continue', 'XIDC'],\n ['XID_Start', 'XIDS'],\n\n // ## Script aliases\n // TODO: Add script aliases\n]);\n\nexport {\n useUnicodeAliases,\n};\n"],
"mappings": "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",
"names": ["useUnicodeAliases", "node", "alias", "OnigUnicodeAliasMap"]
}

View File

@@ -0,0 +1,10 @@
import type { Visitor } from '../../traverser/traverse.js';
/**
Use Unicode properties when possible.
- `\p{Any}` from `[\0-\x{10FFFF}]`
- `\p{Cc}` from POSIX `\p{cntrl}`, `[[:cntrl:]]`
See also `useShorthands`.
*/
declare const useUnicodeProps: Visitor;
export { useUnicodeProps, };
//# sourceMappingURL=use-unicode-props.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"use-unicode-props.d.ts","sourceRoot":"","sources":["../../../src/optimizer/transforms/use-unicode-props.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,6BAA6B,CAAC;AAIzD;;;;;EAKE;AACF,QAAA,MAAM,eAAe,EAAE,OAsBtB,CAAC;AAEF,OAAO,EACL,eAAe,GAChB,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";import{createUnicodeProperty as o}from"../../parser/parse.js";import{isRange as p}from"./use-shorthands.js";const c={CharacterSet({node:e,root:r,replaceWith:s}){const{kind:a,negate:i,value:n}=e;let t=null;a==="posix"&&n==="cntrl"&&!r.flags.posixIsAscii&&(t=o("Cc",{negate:i})),t&&s(t)},CharacterClassRange({node:e,replaceWith:r}){p(e,0,1114111)&&r(o("Any"))}};export{c as useUnicodeProps};
//# sourceMappingURL=use-unicode-props.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/optimizer/transforms/use-unicode-props.ts"],
"sourcesContent": ["import type {CharacterSetNode} from '../../parser/parse.js';\nimport type {Visitor} from '../../traverser/traverse.js';\nimport {createUnicodeProperty} from '../../parser/parse.js';\nimport {isRange} from './use-shorthands.js';\n\n/**\nUse Unicode properties when possible.\n- `\\p{Any}` from `[\\0-\\x{10FFFF}]`\n- `\\p{Cc}` from POSIX `\\p{cntrl}`, `[[:cntrl:]]`\nSee also `useShorthands`.\n*/\nconst useUnicodeProps: Visitor = {\n CharacterSet({node, root, replaceWith}) {\n const {kind, negate, value} = node;\n let newNode: CharacterSetNode | null = null;\n if (\n kind === 'posix' &&\n value === 'cntrl' &&\n // TODO: Also check local context when the parser supports this flag on pattern modifiers\n !root.flags.posixIsAscii\n ) {\n newNode = createUnicodeProperty('Cc', {negate});\n }\n if (newNode) {\n replaceWith(newNode);\n }\n },\n\n CharacterClassRange({node, replaceWith}) {\n if (isRange(node, 0, 0x10FFFF)) {\n replaceWith(createUnicodeProperty('Any'));\n }\n },\n};\n\nexport {\n useUnicodeProps,\n};\n"],
"mappings": "aAEA,OAAQ,yBAAAA,MAA4B,wBACpC,OAAQ,WAAAC,MAAc,sBAQtB,MAAMC,EAA2B,CAC/B,aAAa,CAAC,KAAAC,EAAM,KAAAC,EAAM,YAAAC,CAAW,EAAG,CACtC,KAAM,CAAC,KAAAC,EAAM,OAAAC,EAAQ,MAAAC,CAAK,EAAIL,EAC9B,IAAIM,EAAmC,KAErCH,IAAS,SACTE,IAAU,SAEV,CAACJ,EAAK,MAAM,eAEZK,EAAUT,EAAsB,KAAM,CAAC,OAAAO,CAAM,CAAC,GAE5CE,GACFJ,EAAYI,CAAO,CAEvB,EAEA,oBAAoB,CAAC,KAAAN,EAAM,YAAAE,CAAW,EAAG,CACnCJ,EAAQE,EAAM,EAAG,OAAQ,GAC3BE,EAAYL,EAAsB,KAAK,CAAC,CAE5C,CACF,EAEA,OACEE,KAAA",
"names": ["createUnicodeProperty", "isRange", "useUnicodeProps", "node", "root", "replaceWith", "kind", "negate", "value", "newNode"]
}

View File

@@ -0,0 +1,14 @@
import type { AlternativeContainerNode, Node, ParentNode, QuantifiableNode } from './parse.js';
type KeysOfUnion<T> = T extends T ? keyof T : never;
type Props = {
[key in KeysOfUnion<Node>]?: any;
} & {
type?: Node['type'];
};
declare function hasOnlyChild(node: ParentNode & {
body: Array<Node>;
}, props?: Props): boolean;
declare function isAlternativeContainer(node: Node): node is AlternativeContainerNode;
declare function isQuantifiable(node: Node): node is QuantifiableNode;
export { hasOnlyChild, isAlternativeContainer, isQuantifiable, };
//# sourceMappingURL=node-utils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../../src/parser/node-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAC,MAAM,YAAY,CAAC;AAE7F,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,GAAE,KAAK,CAAC;AACnD,KAAK,KAAK,GAAG;KAAE,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG;CAAC,GAAG;IAAC,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;CAAC,CAAC;AAExE,iBAAS,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG;IAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CASpF;AAED,iBAAS,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,wBAAwB,CAQ5E;AASD,iBAAS,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,gBAAgB,CAE5D;AAaD,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,CAAC"}

View File

@@ -0,0 +1,2 @@
"use strict";function o(e,t){if(!Array.isArray(e.body))throw new Error("Expected node with body array");if(e.body.length!==1)return!1;const r=e.body[0];return!t||Object.keys(t).every(n=>t[n]===r[n])}function a(e){return!(!i.has(e.type)||e.type==="AbsenceFunction"&&e.kind!=="repeater")}const i=new Set(["AbsenceFunction","CapturingGroup","Group","LookaroundAssertion","Regex"]);function s(e){return y.has(e.type)}const y=new Set(["AbsenceFunction","Backreference","CapturingGroup","Character","CharacterClass","CharacterSet","Group","Quantifier","Subroutine"]);export{o as hasOnlyChild,a as isAlternativeContainer,s as isQuantifiable};
//# sourceMappingURL=node-utils.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/parser/node-utils.ts"],
"sourcesContent": ["import type {AlternativeContainerNode, Node, ParentNode, QuantifiableNode} from './parse.js';\n\ntype KeysOfUnion<T> = T extends T ? keyof T: never;\ntype Props = {[key in KeysOfUnion<Node>]?: any} & {type?: Node['type']};\n\nfunction hasOnlyChild(node: ParentNode & {body: Array<Node>}, props?: Props): boolean {\n if (!Array.isArray(node.body)) {\n throw new Error('Expected node with body array');\n }\n if (node.body.length !== 1) {\n return false;\n }\n const kid = node.body[0] as Props;\n return !props || Object.keys(props).every(key => props[key as keyof Props] === kid[key as keyof Props]);\n}\n\nfunction isAlternativeContainer(node: Node): node is AlternativeContainerNode {\n if (\n !alternativeContainerTypes.has(node.type) ||\n (node.type === 'AbsenceFunction' && node.kind !== 'repeater')\n ) {\n return false;\n }\n return true;\n}\nconst alternativeContainerTypes = new Set<Node['type']>([\n 'AbsenceFunction',\n 'CapturingGroup',\n 'Group',\n 'LookaroundAssertion',\n 'Regex',\n]);\n\nfunction isQuantifiable(node: Node): node is QuantifiableNode {\n return quantifiableTypes.has(node.type);\n}\nconst quantifiableTypes = new Set<Node['type']>([\n 'AbsenceFunction',\n 'Backreference',\n 'CapturingGroup',\n 'Character',\n 'CharacterClass',\n 'CharacterSet',\n 'Group',\n 'Quantifier',\n 'Subroutine',\n]);\n\nexport {\n hasOnlyChild,\n isAlternativeContainer,\n isQuantifiable,\n};\n"],
"mappings": "aAKA,SAASA,EAAaC,EAAwCC,EAAwB,CACpF,GAAI,CAAC,MAAM,QAAQD,EAAK,IAAI,EAC1B,MAAM,IAAI,MAAM,+BAA+B,EAEjD,GAAIA,EAAK,KAAK,SAAW,EACvB,MAAO,GAET,MAAME,EAAMF,EAAK,KAAK,CAAC,EACvB,MAAO,CAACC,GAAS,OAAO,KAAKA,CAAK,EAAE,MAAME,GAAOF,EAAME,CAAkB,IAAMD,EAAIC,CAAkB,CAAC,CACxG,CAEA,SAASC,EAAuBJ,EAA8C,CAC5E,MACE,GAACK,EAA0B,IAAIL,EAAK,IAAI,GACvCA,EAAK,OAAS,mBAAqBA,EAAK,OAAS,WAKtD,CACA,MAAMK,EAA4B,IAAI,IAAkB,CACtD,kBACA,iBACA,QACA,sBACA,OACF,CAAC,EAED,SAASC,EAAeN,EAAsC,CAC5D,OAAOO,EAAkB,IAAIP,EAAK,IAAI,CACxC,CACA,MAAMO,EAAoB,IAAI,IAAkB,CAC9C,kBACA,gBACA,iBACA,YACA,iBACA,eACA,QACA,aACA,YACF,CAAC,EAED,OACER,KAAA,aACAK,KAAA,uBACAE,KAAA",
"names": ["hasOnlyChild", "node", "props", "kid", "key", "isAlternativeContainer", "alternativeContainerTypes", "isQuantifiable", "quantifiableTypes"]
}

Some files were not shown because too many files have changed in this diff Show More