Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
21
Frontend-Learner/node_modules/eslint-plugin-regexp/LICENSE
generated
vendored
Normal file
21
Frontend-Learner/node_modules/eslint-plugin-regexp/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Yosuke Ota
|
||||
|
||||
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.
|
||||
283
Frontend-Learner/node_modules/eslint-plugin-regexp/README.md
generated
vendored
Normal file
283
Frontend-Learner/node_modules/eslint-plugin-regexp/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
# Introduction
|
||||
|
||||
[eslint-plugin-regexp](https://www.npmjs.com/package/eslint-plugin-regexp) is ESLint plugin for finding RegExp mistakes and RegExp style guide violations.
|
||||
|
||||
<!--PACKAGE_STATUS_START-->
|
||||
|
||||
[](https://www.npmjs.com/package/eslint-plugin-regexp)
|
||||
[](https://www.npmjs.com/package/eslint-plugin-regexp)
|
||||
[](http://www.npmtrends.com/eslint-plugin-regexp)
|
||||
[](http://www.npmtrends.com/eslint-plugin-regexp)
|
||||
[](http://www.npmtrends.com/eslint-plugin-regexp)
|
||||
[](http://www.npmtrends.com/eslint-plugin-regexp)
|
||||
[](http://www.npmtrends.com/eslint-plugin-regexp)
|
||||
[](https://github.com/ota-meshi/eslint-plugin-regexp/actions?query=workflow%3ACI)
|
||||
[](https://coveralls.io/github/ota-meshi/eslint-plugin-regexp?branch=master)
|
||||
|
||||
<!--PACKAGE_STATUS_END-->
|
||||
|
||||
## :name_badge: Features
|
||||
|
||||
This ESLint plugin provides linting rules relate to better ways to help you avoid problems when using RegExp.
|
||||
|
||||
- Find the wrong usage of regular expressions, and their hints.
|
||||
- Enforces a consistent style of regular expressions.
|
||||
- Find hints for writing optimized regular expressions.
|
||||
- 80 plugin rules for regular expression syntax and features.
|
||||
|
||||
You can check on the [Online DEMO](https://ota-meshi.github.io/eslint-plugin-regexp/playground/).
|
||||
|
||||
<!--DOCS_IGNORE_START-->
|
||||
|
||||
## :book: Documentation
|
||||
|
||||
See [documents](https://ota-meshi.github.io/eslint-plugin-regexp/).
|
||||
|
||||
## :cd: Installation
|
||||
|
||||
```bash
|
||||
npm install --save-dev eslint eslint-plugin-regexp
|
||||
```
|
||||
|
||||
> **Requirements**
|
||||
>
|
||||
> - ESLint v8.44.0 and above
|
||||
> - Node.js v18.x, v20.x and above
|
||||
|
||||
<!--DOCS_IGNORE_END-->
|
||||
|
||||
## :book: Usage
|
||||
|
||||
<!--USAGE_SECTION_START-->
|
||||
|
||||
Add `regexp` to the plugins section of your `eslint.config.js` or `.eslintrc` configuration file (you can omit the `eslint-plugin-` prefix)
|
||||
and either use one of the two configurations available (`recommended` or `all`) or configure the rules you want:
|
||||
|
||||
### The recommended configuration (New Config)
|
||||
|
||||
The `plugin.configs["flat/recommended"]` config enables a subset of [the rules](#white_check_mark-rules) that should be most useful to most users.
|
||||
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/lib/configs/rules/recommended.ts) for more details.*
|
||||
|
||||
```js
|
||||
// eslint.config.js
|
||||
import * as regexpPlugin from "eslint-plugin-regexp"
|
||||
|
||||
export default [
|
||||
regexpPlugin.configs["flat/recommended"],
|
||||
];
|
||||
```
|
||||
|
||||
### The recommended configuration (Legacy Config)
|
||||
|
||||
The `plugin:regexp/recommended` config enables a subset of [the rules](#white_check_mark-rules) that should be most useful to most users.
|
||||
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/lib/configs/rules/recommended.ts) for more details.*
|
||||
|
||||
```js
|
||||
// .eslintrc.js
|
||||
module.exports = {
|
||||
"plugins": [
|
||||
"regexp"
|
||||
],
|
||||
"extends": [
|
||||
// add more generic rulesets here, such as:
|
||||
// 'eslint:recommended',
|
||||
"plugin:regexp/recommended"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
Override/add specific rules configurations. *See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring)*.
|
||||
|
||||
```js
|
||||
// eslint.config.js
|
||||
import * as regexpPlugin from "eslint-plugin-regexp"
|
||||
|
||||
export default [
|
||||
{
|
||||
plugins: { regexp: regexpPlugin },
|
||||
rules: {
|
||||
// Override/add rules settings here, such as:
|
||||
"regexp/rule-name": "error"
|
||||
}
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
```js
|
||||
// .eslintrc.js
|
||||
module.exports = {
|
||||
"plugins": [
|
||||
"regexp"
|
||||
],
|
||||
"rules": {
|
||||
// Override/add rules settings here, such as:
|
||||
"regexp/rule-name": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using the all configuration
|
||||
|
||||
The `plugin.configs["flat/all"]` / `plugin:regexp/all` config enables all rules. It's meant for testing, not for production use because it changes with every minor and major version of the plugin. Use it at your own risk.
|
||||
*See [lib/configs/rules/all.ts](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/lib/configs/rules/all.ts) for more details.*
|
||||
|
||||
<!--USAGE_SECTION_END-->
|
||||
|
||||
## :white_check_mark: Rules
|
||||
|
||||
<!-- begin auto-generated rules list -->
|
||||
|
||||
💼 Configurations enabled in.\
|
||||
⚠️ Configurations set to warn in.\
|
||||
🟢 Set in the `flat/recommended` configuration.\
|
||||
🔵 Set in the `recommended` configuration.\
|
||||
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
||||
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
### Possible Errors
|
||||
|
||||
| Name | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
||||
| :--------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :---- | :---- | :- | :- |
|
||||
| [no-contradiction-with-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-contradiction-with-assertion.html) | disallow elements that contradict assertions | 🟢 🔵 | | | 💡 |
|
||||
| [no-control-character](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-control-character.html) | disallow control characters | | | | 💡 |
|
||||
| [no-dupe-disjunctions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-disjunctions.html) | disallow duplicate disjunctions | 🟢 🔵 | | | 💡 |
|
||||
| [no-empty-alternative](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-alternative.html) | disallow alternatives without elements | | 🟢 🔵 | | 💡 |
|
||||
| [no-empty-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-capturing-group.html) | disallow capturing group that captures empty. | 🟢 🔵 | | | |
|
||||
| [no-empty-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-character-class.html) | disallow character classes that match no characters | 🟢 🔵 | | | |
|
||||
| [no-empty-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-group.html) | disallow empty group | 🟢 🔵 | | | |
|
||||
| [no-empty-lookarounds-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-lookarounds-assertion.html) | disallow empty lookahead assertion or empty lookbehind assertion | 🟢 🔵 | | | |
|
||||
| [no-escape-backspace](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-escape-backspace.html) | disallow escape backspace (`[\b]`) | 🟢 🔵 | | | 💡 |
|
||||
| [no-invalid-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invalid-regexp.html) | disallow invalid regular expression strings in `RegExp` constructors | 🟢 🔵 | | | |
|
||||
| [no-lazy-ends](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-lazy-ends.html) | disallow lazy quantifiers at the end of an expression | | 🟢 🔵 | | 💡 |
|
||||
| [no-misleading-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-capturing-group.html) | disallow capturing groups that do not behave as one would expect | 🟢 🔵 | | | 💡 |
|
||||
| [no-misleading-unicode-character](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-unicode-character.html) | disallow multi-code-point characters in character classes and quantifiers | 🟢 🔵 | | 🔧 | 💡 |
|
||||
| [no-missing-g-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-missing-g-flag.html) | disallow missing `g` flag in patterns used in `String#matchAll` and `String#replaceAll` | 🟢 🔵 | | 🔧 | |
|
||||
| [no-optional-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-optional-assertion.html) | disallow optional assertions | 🟢 🔵 | | | |
|
||||
| [no-potentially-useless-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-potentially-useless-backreference.html) | disallow backreferences that reference a group that might not be matched | | 🟢 🔵 | | |
|
||||
| [no-super-linear-backtracking](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-backtracking.html) | disallow exponential and polynomial backtracking | 🟢 🔵 | | 🔧 | |
|
||||
| [no-super-linear-move](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-move.html) | disallow quantifiers that cause quadratic moves | | | | |
|
||||
| [no-useless-assertions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-assertions.html) | disallow assertions that are known to always accept (or reject) | 🟢 🔵 | | | 💡 |
|
||||
| [no-useless-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-backreference.html) | disallow useless backreferences in regular expressions | 🟢 🔵 | | | |
|
||||
| [no-useless-dollar-replacements](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-dollar-replacements.html) | disallow useless `$` replacements in replacement string | 🟢 🔵 | | | |
|
||||
| [strict](https://ota-meshi.github.io/eslint-plugin-regexp/rules/strict.html) | disallow not strictly valid regular expressions | 🟢 🔵 | | 🔧 | 💡 |
|
||||
|
||||
### Best Practices
|
||||
|
||||
| Name | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
||||
| :----------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------- | :---- | :---- | :- | :- |
|
||||
| [confusing-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/confusing-quantifier.html) | disallow confusing quantifiers | | 🟢 🔵 | | |
|
||||
| [control-character-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/control-character-escape.html) | enforce consistent escaping of control characters | 🟢 🔵 | | 🔧 | |
|
||||
| [negation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/negation.html) | enforce use of escapes on negation | 🟢 🔵 | | 🔧 | |
|
||||
| [no-dupe-characters-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-characters-character-class.html) | disallow duplicate characters in the RegExp character class | 🟢 🔵 | | 🔧 | |
|
||||
| [no-empty-string-literal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-string-literal.html) | disallow empty string literals in character classes | 🟢 🔵 | | | |
|
||||
| [no-extra-lookaround-assertions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-extra-lookaround-assertions.html) | disallow unnecessary nested lookaround assertions | 🟢 🔵 | | 🔧 | |
|
||||
| [no-invisible-character](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invisible-character.html) | disallow invisible raw character | 🟢 🔵 | | 🔧 | |
|
||||
| [no-legacy-features](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-legacy-features.html) | disallow legacy RegExp features | 🟢 🔵 | | | |
|
||||
| [no-non-standard-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-non-standard-flag.html) | disallow non-standard flags | 🟢 🔵 | | | |
|
||||
| [no-obscure-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-obscure-range.html) | disallow obscure character ranges | 🟢 🔵 | | | |
|
||||
| [no-octal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-octal.html) | disallow octal escape sequence | | | | 💡 |
|
||||
| [no-standalone-backslash](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-standalone-backslash.html) | disallow standalone backslashes (`\`) | | | | |
|
||||
| [no-trivially-nested-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-assertion.html) | disallow trivially nested assertions | 🟢 🔵 | | 🔧 | |
|
||||
| [no-trivially-nested-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-quantifier.html) | disallow nested quantifiers that can be rewritten as one quantifier | 🟢 🔵 | | 🔧 | |
|
||||
| [no-unused-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-unused-capturing-group.html) | disallow unused capturing group | 🟢 🔵 | | 🔧 | 💡 |
|
||||
| [no-useless-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-character-class.html) | disallow character class with one character | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-flag.html) | disallow unnecessary regex flags | | 🟢 🔵 | 🔧 | |
|
||||
| [no-useless-lazy](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-lazy.html) | disallow unnecessarily non-greedy quantifiers | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-quantifier.html) | disallow quantifiers that can be removed | 🟢 🔵 | | 🔧 | 💡 |
|
||||
| [no-useless-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-range.html) | disallow unnecessary character ranges | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-set-operand](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-set-operand.html) | disallow unnecessary elements in expression character classes | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-string-literal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-string-literal.html) | disallow string disjunction of single characters in `\q{...}` | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-two-nums-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-two-nums-quantifier.html) | disallow unnecessary `{n,m}` quantifier | 🟢 🔵 | | 🔧 | |
|
||||
| [no-zero-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-zero-quantifier.html) | disallow quantifiers with a maximum of zero | 🟢 🔵 | | | 💡 |
|
||||
| [optimal-lookaround-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html) | disallow the alternatives of lookarounds that end with a non-constant quantifier | | 🟢 🔵 | | 💡 |
|
||||
| [optimal-quantifier-concatenation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-quantifier-concatenation.html) | require optimal quantifiers for concatenated quantifiers | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-escape-replacement-dollar-char](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-escape-replacement-dollar-char.html) | enforces escape of replacement `$` character (`$$`). | | | | |
|
||||
| [prefer-predefined-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-predefined-assertion.html) | prefer predefined assertion over equivalent lookarounds | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-quantifier.html) | enforce using quantifier | | | 🔧 | |
|
||||
| [prefer-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-range.html) | enforce using character class range | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-regexp-exec](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-regexp-exec.html) | enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided | | | | |
|
||||
| [prefer-regexp-test](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-regexp-test.html) | enforce that `RegExp#test` is used instead of `String#match` and `RegExp#exec` | | | 🔧 | |
|
||||
| [prefer-set-operation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-set-operation.html) | prefer character class set operations instead of lookarounds | 🟢 🔵 | | 🔧 | |
|
||||
| [require-unicode-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/require-unicode-regexp.html) | enforce the use of the `u` flag | | | 🔧 | |
|
||||
| [require-unicode-sets-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/require-unicode-sets-regexp.html) | enforce the use of the `v` flag | | | 🔧 | |
|
||||
| [simplify-set-operations](https://ota-meshi.github.io/eslint-plugin-regexp/rules/simplify-set-operations.html) | require simplify set operations | 🟢 🔵 | | 🔧 | |
|
||||
| [sort-alternatives](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-alternatives.html) | sort alternatives if order doesn't matter | | | 🔧 | |
|
||||
| [use-ignore-case](https://ota-meshi.github.io/eslint-plugin-regexp/rules/use-ignore-case.html) | use the `i` flag if it simplifies the pattern | 🟢 🔵 | | 🔧 | |
|
||||
|
||||
### Stylistic Issues
|
||||
|
||||
| Name | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------- | :---- | :- | :- | :- |
|
||||
| [grapheme-string-literal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/grapheme-string-literal.html) | enforce single grapheme in string literal | | | | |
|
||||
| [hexadecimal-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/hexadecimal-escape.html) | enforce consistent usage of hexadecimal escape | | | 🔧 | |
|
||||
| [letter-case](https://ota-meshi.github.io/eslint-plugin-regexp/rules/letter-case.html) | enforce into your favorite case | | | 🔧 | |
|
||||
| [match-any](https://ota-meshi.github.io/eslint-plugin-regexp/rules/match-any.html) | enforce match any character style | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-escape.html) | disallow unnecessary escape characters in RegExp | 🟢 🔵 | | 🔧 | |
|
||||
| [no-useless-non-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-non-capturing-group.html) | disallow unnecessary non-capturing group | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-character-class.html) | enforce using character class | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-d](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-d.html) | enforce using `\d` | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-lookaround](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-lookaround.html) | prefer lookarounds over capturing group that do not replace | | | 🔧 | |
|
||||
| [prefer-named-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-backreference.html) | enforce using named backreferences | | | 🔧 | |
|
||||
| [prefer-named-capture-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-capture-group.html) | enforce using named capture groups | | | | |
|
||||
| [prefer-named-replacement](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-replacement.html) | enforce using named replacement | | | 🔧 | |
|
||||
| [prefer-plus-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-plus-quantifier.html) | enforce using `+` quantifier | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-question-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-question-quantifier.html) | enforce using `?` quantifier | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-result-array-groups](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-result-array-groups.html) | enforce using result array `groups` | | | 🔧 | |
|
||||
| [prefer-star-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-star-quantifier.html) | enforce using `*` quantifier | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-unicode-codepoint-escapes](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-unicode-codepoint-escapes.html) | enforce use of unicode codepoint escapes | 🟢 🔵 | | 🔧 | |
|
||||
| [prefer-w](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-w.html) | enforce using `\w` | 🟢 🔵 | | 🔧 | |
|
||||
| [sort-character-class-elements](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-character-class-elements.html) | enforces elements order in character class | | | 🔧 | |
|
||||
| [sort-flags](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-flags.html) | require regex flags to be sorted | 🟢 🔵 | | 🔧 | |
|
||||
| [unicode-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/unicode-escape.html) | enforce consistent usage of unicode escape or unicode codepoint escape | | | 🔧 | |
|
||||
| [unicode-property](https://ota-meshi.github.io/eslint-plugin-regexp/rules/unicode-property.html) | enforce consistent naming of unicode properties | | | 🔧 | |
|
||||
|
||||
<!-- end auto-generated rules list -->
|
||||
|
||||
<!--REMOVED_RULES_START-->
|
||||
|
||||
### Removed
|
||||
|
||||
- :no_entry: These rules have been removed in a previous major release, after they have been deprecated for a while.
|
||||
|
||||
| Rule ID | Replaced by | Removed in version |
|
||||
|:--------|:------------|:-------------------|
|
||||
| [no-assertion-capturing-group](https://github.com/ota-meshi/eslint-plugin-regexp/blob/v1.15.0/docs/rules/no-assertion-capturing-group.md) | [regexp/no-empty-capturing-group](./no-empty-capturing-group.md) | v2.0.0 |
|
||||
| [no-useless-exactly-quantifier](https://github.com/ota-meshi/eslint-plugin-regexp/blob/v1.15.0/docs/rules/no-useless-exactly-quantifier.md) | [regexp/no-useless-quantifier](./no-useless-quantifier.md), [regexp/no-zero-quantifier](./no-zero-quantifier.md) | v2.0.0 |
|
||||
| [no-useless-non-greedy](https://github.com/ota-meshi/eslint-plugin-regexp/blob/v1.15.0/docs/rules/no-useless-non-greedy.md) | [regexp/no-useless-lazy](./no-useless-lazy.md) | v2.0.0 |
|
||||
| [order-in-character-class](https://github.com/ota-meshi/eslint-plugin-regexp/blob/v1.15.0/docs/rules/order-in-character-class.md) | [regexp/sort-character-class-elements](./sort-character-class-elements.md) | v2.0.0 |
|
||||
| [prefer-t](https://github.com/ota-meshi/eslint-plugin-regexp/blob/v1.15.0/docs/rules/prefer-t.md) | [regexp/control-character-escape](./control-character-escape.md) | v2.0.0 |
|
||||
|
||||
<!--REMOVED_RULES_END-->
|
||||
|
||||
## :gear: Settings
|
||||
|
||||
See [Settings](https://ota-meshi.github.io/eslint-plugin-regexp/settings/).
|
||||
|
||||
<!--DOCS_IGNORE_START-->
|
||||
|
||||
## :traffic_light: Semantic Versioning Policy
|
||||
|
||||
**eslint-plugin-regexp** follows [Semantic Versioning](http://semver.org/) and [ESLint's Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy).
|
||||
|
||||
## :beers: Contributing
|
||||
|
||||
Welcome contributing!
|
||||
|
||||
Please use GitHub's Issues/PRs.
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
### Development Tools
|
||||
|
||||
- `npm test` runs tests and measures coverage.
|
||||
- `npm run update` runs in order to update readme and recommended configuration.
|
||||
- `npm run new [new rule name]` runs to create the files needed for the new rule.
|
||||
- `npm run docs:watch` starts the website locally.
|
||||
|
||||
<!--DOCS_IGNORE_END-->
|
||||
|
||||
## :lock: License
|
||||
|
||||
See the [LICENSE](LICENSE) file for license rights and limitations (MIT).
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/all-rules.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/all-rules.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import type { RuleModule } from "./types";
|
||||
export declare const rules: RuleModule[];
|
||||
172
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/all-rules.js
generated
vendored
Normal file
172
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/all-rules.js
generated
vendored
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.rules = void 0;
|
||||
const confusing_quantifier_1 = __importDefault(require("./rules/confusing-quantifier"));
|
||||
const control_character_escape_1 = __importDefault(require("./rules/control-character-escape"));
|
||||
const grapheme_string_literal_1 = __importDefault(require("./rules/grapheme-string-literal"));
|
||||
const hexadecimal_escape_1 = __importDefault(require("./rules/hexadecimal-escape"));
|
||||
const letter_case_1 = __importDefault(require("./rules/letter-case"));
|
||||
const match_any_1 = __importDefault(require("./rules/match-any"));
|
||||
const negation_1 = __importDefault(require("./rules/negation"));
|
||||
const no_contradiction_with_assertion_1 = __importDefault(require("./rules/no-contradiction-with-assertion"));
|
||||
const no_control_character_1 = __importDefault(require("./rules/no-control-character"));
|
||||
const no_dupe_characters_character_class_1 = __importDefault(require("./rules/no-dupe-characters-character-class"));
|
||||
const no_dupe_disjunctions_1 = __importDefault(require("./rules/no-dupe-disjunctions"));
|
||||
const no_empty_alternative_1 = __importDefault(require("./rules/no-empty-alternative"));
|
||||
const no_empty_capturing_group_1 = __importDefault(require("./rules/no-empty-capturing-group"));
|
||||
const no_empty_character_class_1 = __importDefault(require("./rules/no-empty-character-class"));
|
||||
const no_empty_group_1 = __importDefault(require("./rules/no-empty-group"));
|
||||
const no_empty_lookarounds_assertion_1 = __importDefault(require("./rules/no-empty-lookarounds-assertion"));
|
||||
const no_empty_string_literal_1 = __importDefault(require("./rules/no-empty-string-literal"));
|
||||
const no_escape_backspace_1 = __importDefault(require("./rules/no-escape-backspace"));
|
||||
const no_extra_lookaround_assertions_1 = __importDefault(require("./rules/no-extra-lookaround-assertions"));
|
||||
const no_invalid_regexp_1 = __importDefault(require("./rules/no-invalid-regexp"));
|
||||
const no_invisible_character_1 = __importDefault(require("./rules/no-invisible-character"));
|
||||
const no_lazy_ends_1 = __importDefault(require("./rules/no-lazy-ends"));
|
||||
const no_legacy_features_1 = __importDefault(require("./rules/no-legacy-features"));
|
||||
const no_misleading_capturing_group_1 = __importDefault(require("./rules/no-misleading-capturing-group"));
|
||||
const no_misleading_unicode_character_1 = __importDefault(require("./rules/no-misleading-unicode-character"));
|
||||
const no_missing_g_flag_1 = __importDefault(require("./rules/no-missing-g-flag"));
|
||||
const no_non_standard_flag_1 = __importDefault(require("./rules/no-non-standard-flag"));
|
||||
const no_obscure_range_1 = __importDefault(require("./rules/no-obscure-range"));
|
||||
const no_octal_1 = __importDefault(require("./rules/no-octal"));
|
||||
const no_optional_assertion_1 = __importDefault(require("./rules/no-optional-assertion"));
|
||||
const no_potentially_useless_backreference_1 = __importDefault(require("./rules/no-potentially-useless-backreference"));
|
||||
const no_standalone_backslash_1 = __importDefault(require("./rules/no-standalone-backslash"));
|
||||
const no_super_linear_backtracking_1 = __importDefault(require("./rules/no-super-linear-backtracking"));
|
||||
const no_super_linear_move_1 = __importDefault(require("./rules/no-super-linear-move"));
|
||||
const no_trivially_nested_assertion_1 = __importDefault(require("./rules/no-trivially-nested-assertion"));
|
||||
const no_trivially_nested_quantifier_1 = __importDefault(require("./rules/no-trivially-nested-quantifier"));
|
||||
const no_unused_capturing_group_1 = __importDefault(require("./rules/no-unused-capturing-group"));
|
||||
const no_useless_assertions_1 = __importDefault(require("./rules/no-useless-assertions"));
|
||||
const no_useless_backreference_1 = __importDefault(require("./rules/no-useless-backreference"));
|
||||
const no_useless_character_class_1 = __importDefault(require("./rules/no-useless-character-class"));
|
||||
const no_useless_dollar_replacements_1 = __importDefault(require("./rules/no-useless-dollar-replacements"));
|
||||
const no_useless_escape_1 = __importDefault(require("./rules/no-useless-escape"));
|
||||
const no_useless_flag_1 = __importDefault(require("./rules/no-useless-flag"));
|
||||
const no_useless_lazy_1 = __importDefault(require("./rules/no-useless-lazy"));
|
||||
const no_useless_non_capturing_group_1 = __importDefault(require("./rules/no-useless-non-capturing-group"));
|
||||
const no_useless_quantifier_1 = __importDefault(require("./rules/no-useless-quantifier"));
|
||||
const no_useless_range_1 = __importDefault(require("./rules/no-useless-range"));
|
||||
const no_useless_set_operand_1 = __importDefault(require("./rules/no-useless-set-operand"));
|
||||
const no_useless_string_literal_1 = __importDefault(require("./rules/no-useless-string-literal"));
|
||||
const no_useless_two_nums_quantifier_1 = __importDefault(require("./rules/no-useless-two-nums-quantifier"));
|
||||
const no_zero_quantifier_1 = __importDefault(require("./rules/no-zero-quantifier"));
|
||||
const optimal_lookaround_quantifier_1 = __importDefault(require("./rules/optimal-lookaround-quantifier"));
|
||||
const optimal_quantifier_concatenation_1 = __importDefault(require("./rules/optimal-quantifier-concatenation"));
|
||||
const prefer_character_class_1 = __importDefault(require("./rules/prefer-character-class"));
|
||||
const prefer_d_1 = __importDefault(require("./rules/prefer-d"));
|
||||
const prefer_escape_replacement_dollar_char_1 = __importDefault(require("./rules/prefer-escape-replacement-dollar-char"));
|
||||
const prefer_lookaround_1 = __importDefault(require("./rules/prefer-lookaround"));
|
||||
const prefer_named_backreference_1 = __importDefault(require("./rules/prefer-named-backreference"));
|
||||
const prefer_named_capture_group_1 = __importDefault(require("./rules/prefer-named-capture-group"));
|
||||
const prefer_named_replacement_1 = __importDefault(require("./rules/prefer-named-replacement"));
|
||||
const prefer_plus_quantifier_1 = __importDefault(require("./rules/prefer-plus-quantifier"));
|
||||
const prefer_predefined_assertion_1 = __importDefault(require("./rules/prefer-predefined-assertion"));
|
||||
const prefer_quantifier_1 = __importDefault(require("./rules/prefer-quantifier"));
|
||||
const prefer_question_quantifier_1 = __importDefault(require("./rules/prefer-question-quantifier"));
|
||||
const prefer_range_1 = __importDefault(require("./rules/prefer-range"));
|
||||
const prefer_regexp_exec_1 = __importDefault(require("./rules/prefer-regexp-exec"));
|
||||
const prefer_regexp_test_1 = __importDefault(require("./rules/prefer-regexp-test"));
|
||||
const prefer_result_array_groups_1 = __importDefault(require("./rules/prefer-result-array-groups"));
|
||||
const prefer_set_operation_1 = __importDefault(require("./rules/prefer-set-operation"));
|
||||
const prefer_star_quantifier_1 = __importDefault(require("./rules/prefer-star-quantifier"));
|
||||
const prefer_unicode_codepoint_escapes_1 = __importDefault(require("./rules/prefer-unicode-codepoint-escapes"));
|
||||
const prefer_w_1 = __importDefault(require("./rules/prefer-w"));
|
||||
const require_unicode_regexp_1 = __importDefault(require("./rules/require-unicode-regexp"));
|
||||
const require_unicode_sets_regexp_1 = __importDefault(require("./rules/require-unicode-sets-regexp"));
|
||||
const simplify_set_operations_1 = __importDefault(require("./rules/simplify-set-operations"));
|
||||
const sort_alternatives_1 = __importDefault(require("./rules/sort-alternatives"));
|
||||
const sort_character_class_elements_1 = __importDefault(require("./rules/sort-character-class-elements"));
|
||||
const sort_flags_1 = __importDefault(require("./rules/sort-flags"));
|
||||
const strict_1 = __importDefault(require("./rules/strict"));
|
||||
const unicode_escape_1 = __importDefault(require("./rules/unicode-escape"));
|
||||
const unicode_property_1 = __importDefault(require("./rules/unicode-property"));
|
||||
const use_ignore_case_1 = __importDefault(require("./rules/use-ignore-case"));
|
||||
exports.rules = [
|
||||
confusing_quantifier_1.default,
|
||||
control_character_escape_1.default,
|
||||
grapheme_string_literal_1.default,
|
||||
hexadecimal_escape_1.default,
|
||||
letter_case_1.default,
|
||||
match_any_1.default,
|
||||
negation_1.default,
|
||||
no_contradiction_with_assertion_1.default,
|
||||
no_control_character_1.default,
|
||||
no_dupe_characters_character_class_1.default,
|
||||
no_dupe_disjunctions_1.default,
|
||||
no_empty_alternative_1.default,
|
||||
no_empty_capturing_group_1.default,
|
||||
no_empty_character_class_1.default,
|
||||
no_empty_group_1.default,
|
||||
no_empty_lookarounds_assertion_1.default,
|
||||
no_empty_string_literal_1.default,
|
||||
no_escape_backspace_1.default,
|
||||
no_extra_lookaround_assertions_1.default,
|
||||
no_invalid_regexp_1.default,
|
||||
no_invisible_character_1.default,
|
||||
no_lazy_ends_1.default,
|
||||
no_legacy_features_1.default,
|
||||
no_misleading_capturing_group_1.default,
|
||||
no_misleading_unicode_character_1.default,
|
||||
no_missing_g_flag_1.default,
|
||||
no_non_standard_flag_1.default,
|
||||
no_obscure_range_1.default,
|
||||
no_octal_1.default,
|
||||
no_optional_assertion_1.default,
|
||||
no_potentially_useless_backreference_1.default,
|
||||
no_standalone_backslash_1.default,
|
||||
no_super_linear_backtracking_1.default,
|
||||
no_super_linear_move_1.default,
|
||||
no_trivially_nested_assertion_1.default,
|
||||
no_trivially_nested_quantifier_1.default,
|
||||
no_unused_capturing_group_1.default,
|
||||
no_useless_assertions_1.default,
|
||||
no_useless_backreference_1.default,
|
||||
no_useless_character_class_1.default,
|
||||
no_useless_dollar_replacements_1.default,
|
||||
no_useless_escape_1.default,
|
||||
no_useless_flag_1.default,
|
||||
no_useless_lazy_1.default,
|
||||
no_useless_non_capturing_group_1.default,
|
||||
no_useless_quantifier_1.default,
|
||||
no_useless_range_1.default,
|
||||
no_useless_set_operand_1.default,
|
||||
no_useless_string_literal_1.default,
|
||||
no_useless_two_nums_quantifier_1.default,
|
||||
no_zero_quantifier_1.default,
|
||||
optimal_lookaround_quantifier_1.default,
|
||||
optimal_quantifier_concatenation_1.default,
|
||||
prefer_character_class_1.default,
|
||||
prefer_d_1.default,
|
||||
prefer_escape_replacement_dollar_char_1.default,
|
||||
prefer_lookaround_1.default,
|
||||
prefer_named_backreference_1.default,
|
||||
prefer_named_capture_group_1.default,
|
||||
prefer_named_replacement_1.default,
|
||||
prefer_plus_quantifier_1.default,
|
||||
prefer_predefined_assertion_1.default,
|
||||
prefer_quantifier_1.default,
|
||||
prefer_question_quantifier_1.default,
|
||||
prefer_range_1.default,
|
||||
prefer_regexp_exec_1.default,
|
||||
prefer_regexp_test_1.default,
|
||||
prefer_result_array_groups_1.default,
|
||||
prefer_set_operation_1.default,
|
||||
prefer_star_quantifier_1.default,
|
||||
prefer_unicode_codepoint_escapes_1.default,
|
||||
prefer_w_1.default,
|
||||
require_unicode_regexp_1.default,
|
||||
require_unicode_sets_regexp_1.default,
|
||||
simplify_set_operations_1.default,
|
||||
sort_alternatives_1.default,
|
||||
sort_character_class_elements_1.default,
|
||||
sort_flags_1.default,
|
||||
strict_1.default,
|
||||
unicode_escape_1.default,
|
||||
unicode_property_1.default,
|
||||
use_ignore_case_1.default,
|
||||
];
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/all.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/all.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { rules } from "./rules/all";
|
||||
export declare const plugins: string[];
|
||||
6
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/all.js
generated
vendored
Normal file
6
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/all.js
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.plugins = exports.rules = void 0;
|
||||
var all_1 = require("./rules/all");
|
||||
Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return all_1.rules; } });
|
||||
exports.plugins = ["regexp"];
|
||||
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/all.d.ts
generated
vendored
Normal file
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/all.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import * as plugin from "../../index";
|
||||
export { rules } from "../rules/all";
|
||||
export declare const plugins: {
|
||||
regexp: typeof plugin;
|
||||
};
|
||||
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/all.js
generated
vendored
Normal file
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/all.js
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.plugins = exports.rules = void 0;
|
||||
const plugin = __importStar(require("../../index"));
|
||||
var all_1 = require("../rules/all");
|
||||
Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return all_1.rules; } });
|
||||
exports.plugins = { regexp: plugin };
|
||||
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/recommended.d.ts
generated
vendored
Normal file
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/recommended.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import * as plugin from "../../index";
|
||||
export { rules } from "../rules/recommended";
|
||||
export declare const plugins: {
|
||||
regexp: typeof plugin;
|
||||
};
|
||||
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/recommended.js
generated
vendored
Normal file
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/flat/recommended.js
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.plugins = exports.rules = void 0;
|
||||
const plugin = __importStar(require("../../index"));
|
||||
var recommended_1 = require("../rules/recommended");
|
||||
Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return recommended_1.rules; } });
|
||||
exports.plugins = { regexp: plugin };
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/recommended.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/recommended.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { rules } from "./rules/recommended";
|
||||
export declare const plugins: string[];
|
||||
6
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/recommended.js
generated
vendored
Normal file
6
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/recommended.js
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.plugins = exports.rules = void 0;
|
||||
var recommended_1 = require("./rules/recommended");
|
||||
Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return recommended_1.rules; } });
|
||||
exports.plugins = ["regexp"];
|
||||
4
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/all.d.ts
generated
vendored
Normal file
4
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/all.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import type { SeverityString } from "../../types";
|
||||
export declare const rules: {
|
||||
[x: string]: SeverityString;
|
||||
};
|
||||
13
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/all.js
generated
vendored
Normal file
13
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/all.js
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.rules = void 0;
|
||||
const all_rules_1 = require("../../all-rules");
|
||||
const recommended_1 = require("./recommended");
|
||||
const all = {};
|
||||
for (const rule of all_rules_1.rules) {
|
||||
all[rule.meta.docs.ruleId] = "error";
|
||||
}
|
||||
exports.rules = {
|
||||
...all,
|
||||
...recommended_1.rules,
|
||||
};
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/recommended.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/recommended.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import type { SeverityString } from "../../types";
|
||||
export declare const rules: Record<string, SeverityString>;
|
||||
72
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/recommended.js
generated
vendored
Normal file
72
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/configs/rules/recommended.js
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.rules = void 0;
|
||||
exports.rules = {
|
||||
"no-control-regex": "error",
|
||||
"no-misleading-character-class": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"prefer-regex-literals": "error",
|
||||
"no-invalid-regexp": "off",
|
||||
"no-useless-backreference": "off",
|
||||
"no-empty-character-class": "off",
|
||||
"regexp/confusing-quantifier": "warn",
|
||||
"regexp/control-character-escape": "error",
|
||||
"regexp/match-any": "error",
|
||||
"regexp/negation": "error",
|
||||
"regexp/no-contradiction-with-assertion": "error",
|
||||
"regexp/no-dupe-characters-character-class": "error",
|
||||
"regexp/no-dupe-disjunctions": "error",
|
||||
"regexp/no-empty-alternative": "warn",
|
||||
"regexp/no-empty-capturing-group": "error",
|
||||
"regexp/no-empty-character-class": "error",
|
||||
"regexp/no-empty-group": "error",
|
||||
"regexp/no-empty-lookarounds-assertion": "error",
|
||||
"regexp/no-empty-string-literal": "error",
|
||||
"regexp/no-escape-backspace": "error",
|
||||
"regexp/no-extra-lookaround-assertions": "error",
|
||||
"regexp/no-invalid-regexp": "error",
|
||||
"regexp/no-invisible-character": "error",
|
||||
"regexp/no-lazy-ends": "warn",
|
||||
"regexp/no-legacy-features": "error",
|
||||
"regexp/no-misleading-capturing-group": "error",
|
||||
"regexp/no-misleading-unicode-character": "error",
|
||||
"regexp/no-missing-g-flag": "error",
|
||||
"regexp/no-non-standard-flag": "error",
|
||||
"regexp/no-obscure-range": "error",
|
||||
"regexp/no-optional-assertion": "error",
|
||||
"regexp/no-potentially-useless-backreference": "warn",
|
||||
"regexp/no-super-linear-backtracking": "error",
|
||||
"regexp/no-trivially-nested-assertion": "error",
|
||||
"regexp/no-trivially-nested-quantifier": "error",
|
||||
"regexp/no-unused-capturing-group": "error",
|
||||
"regexp/no-useless-assertions": "error",
|
||||
"regexp/no-useless-backreference": "error",
|
||||
"regexp/no-useless-character-class": "error",
|
||||
"regexp/no-useless-dollar-replacements": "error",
|
||||
"regexp/no-useless-escape": "error",
|
||||
"regexp/no-useless-flag": "warn",
|
||||
"regexp/no-useless-lazy": "error",
|
||||
"regexp/no-useless-non-capturing-group": "error",
|
||||
"regexp/no-useless-quantifier": "error",
|
||||
"regexp/no-useless-range": "error",
|
||||
"regexp/no-useless-set-operand": "error",
|
||||
"regexp/no-useless-string-literal": "error",
|
||||
"regexp/no-useless-two-nums-quantifier": "error",
|
||||
"regexp/no-zero-quantifier": "error",
|
||||
"regexp/optimal-lookaround-quantifier": "warn",
|
||||
"regexp/optimal-quantifier-concatenation": "error",
|
||||
"regexp/prefer-character-class": "error",
|
||||
"regexp/prefer-d": "error",
|
||||
"regexp/prefer-plus-quantifier": "error",
|
||||
"regexp/prefer-predefined-assertion": "error",
|
||||
"regexp/prefer-question-quantifier": "error",
|
||||
"regexp/prefer-range": "error",
|
||||
"regexp/prefer-set-operation": "error",
|
||||
"regexp/prefer-star-quantifier": "error",
|
||||
"regexp/prefer-unicode-codepoint-escapes": "error",
|
||||
"regexp/prefer-w": "error",
|
||||
"regexp/simplify-set-operations": "error",
|
||||
"regexp/sort-flags": "error",
|
||||
"regexp/strict": "error",
|
||||
"regexp/use-ignore-case": "error",
|
||||
};
|
||||
15
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/index.d.ts
generated
vendored
Normal file
15
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import * as all from "./configs/all";
|
||||
import * as flatAll from "./configs/flat/all";
|
||||
import * as flatRecommended from "./configs/flat/recommended";
|
||||
import * as recommended from "./configs/recommended";
|
||||
import type { RuleModule } from "./types";
|
||||
export * as meta from "./meta";
|
||||
export declare const configs: {
|
||||
recommended: typeof recommended;
|
||||
all: typeof all;
|
||||
"flat/all": typeof flatAll;
|
||||
"flat/recommended": typeof flatRecommended;
|
||||
};
|
||||
export declare const rules: {
|
||||
[key: string]: RuleModule;
|
||||
};
|
||||
52
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/index.js
generated
vendored
Normal file
52
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.rules = exports.configs = exports.meta = void 0;
|
||||
const all_rules_1 = require("./all-rules");
|
||||
const all = __importStar(require("./configs/all"));
|
||||
const flatAll = __importStar(require("./configs/flat/all"));
|
||||
const flatRecommended = __importStar(require("./configs/flat/recommended"));
|
||||
const recommended = __importStar(require("./configs/recommended"));
|
||||
exports.meta = __importStar(require("./meta"));
|
||||
exports.configs = {
|
||||
recommended,
|
||||
all,
|
||||
"flat/all": flatAll,
|
||||
"flat/recommended": flatRecommended,
|
||||
};
|
||||
exports.rules = all_rules_1.rules.reduce((obj, r) => {
|
||||
obj[r.meta.docs.ruleName] = r;
|
||||
return obj;
|
||||
}, {});
|
||||
1
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/meta.d.ts
generated
vendored
Normal file
1
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/meta.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export declare const name: any, version: any;
|
||||
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/meta.js
generated
vendored
Normal file
5
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/meta.js
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.version = exports.name = void 0;
|
||||
_a = require("../package.json"), exports.name = _a.name, exports.version = _a.version;
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/confusing-quantifier.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/confusing-quantifier.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
44
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/confusing-quantifier.js
generated
vendored
Normal file
44
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/confusing-quantifier.js
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const regexp_ast_1 = require("../utils/regexp-ast");
|
||||
exports.default = (0, utils_1.createRule)("confusing-quantifier", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow confusing quantifiers",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
default: "warn",
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
confusing: "This quantifier is confusing because its minimum is {{min}} but it can match the empty string. Maybe replace it with `{{proposal}}` to reflect that it can match the empty string?",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
return {
|
||||
onQuantifierEnter(qNode) {
|
||||
if (qNode.min > 0 &&
|
||||
(0, regexp_ast_analysis_1.isPotentiallyEmpty)(qNode.element, flags)) {
|
||||
const proposal = (0, regexp_ast_1.quantToString)({ ...qNode, min: 0 });
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(qNode, (0, regexp_ast_1.getQuantifierOffsets)(qNode)),
|
||||
messageId: "confusing",
|
||||
data: {
|
||||
min: String(qNode.min),
|
||||
proposal,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/control-character-escape.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/control-character-escape.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
74
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/control-character-escape.js
generated
vendored
Normal file
74
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/control-character-escape.js
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const utils_2 = require("../utils/ast-utils/utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const CONTROL_CHARS = new Map([
|
||||
[0, "\\0"],
|
||||
[utils_1.CP_TAB, "\\t"],
|
||||
[utils_1.CP_LF, "\\n"],
|
||||
[utils_1.CP_VT, "\\v"],
|
||||
[utils_1.CP_FF, "\\f"],
|
||||
[utils_1.CP_CR, "\\r"],
|
||||
]);
|
||||
function isRegExpLiteralAt({ node, patternSource }, at) {
|
||||
if ((0, utils_2.isRegexpLiteral)(node)) {
|
||||
return true;
|
||||
}
|
||||
const replaceRange = patternSource.getReplaceRange(at);
|
||||
if (replaceRange && replaceRange.type === "RegExp") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("control-character-escape", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce consistent escaping of control characters",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected control character escape {{actual}}. Use '{{expected}}' instead.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, getRegexpLocation, fixReplaceNode } = regexpContext;
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.parent.type === "CharacterClassRange") {
|
||||
return;
|
||||
}
|
||||
const expectedRaw = CONTROL_CHARS.get(cNode.value);
|
||||
if (expectedRaw === undefined) {
|
||||
return;
|
||||
}
|
||||
if (cNode.raw === expectedRaw) {
|
||||
return;
|
||||
}
|
||||
if (!isRegExpLiteralAt(regexpContext, cNode) &&
|
||||
cNode.raw === String.fromCodePoint(cNode.value)) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
actual: (0, mention_1.mentionChar)(cNode),
|
||||
expected: expectedRaw,
|
||||
},
|
||||
fix: fixReplaceNode(cNode, expectedRaw),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/grapheme-string-literal.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/grapheme-string-literal.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
53
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/grapheme-string-literal.js
generated
vendored
Normal file
53
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/grapheme-string-literal.js
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const segmenter = new Intl.Segmenter();
|
||||
exports.default = (0, utils_1.createRule)("grapheme-string-literal", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce single grapheme in string literal",
|
||||
category: "Stylistic Issues",
|
||||
recommended: false,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
onlySingleCharacters: "Only single characters and graphemes are allowed inside character classes. Use regular alternatives (e.g. `{{alternatives}}`) for strings instead.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, getRegexpLocation } = regexpContext;
|
||||
function isMultipleGraphemes(saNode) {
|
||||
if (saNode.elements.length <= 1)
|
||||
return false;
|
||||
const string = String.fromCodePoint(...saNode.elements.map((element) => element.value));
|
||||
const segments = [...segmenter.segment(string)];
|
||||
return segments.length > 1;
|
||||
}
|
||||
function buildAlternativeExample(saNode) {
|
||||
const alternativeRaws = saNode.parent.alternatives
|
||||
.filter(isMultipleGraphemes)
|
||||
.map((alt) => alt.raw);
|
||||
return `(?:${alternativeRaws.join("|")}|[...])`;
|
||||
}
|
||||
return {
|
||||
onStringAlternativeEnter(saNode) {
|
||||
if (!isMultipleGraphemes(saNode))
|
||||
return;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(saNode),
|
||||
messageId: "onlySingleCharacters",
|
||||
data: {
|
||||
alternatives: buildAlternativeExample(saNode),
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/hexadecimal-escape.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/hexadecimal-escape.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
77
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/hexadecimal-escape.js
generated
vendored
Normal file
77
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/hexadecimal-escape.js
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
exports.default = (0, utils_1.createRule)("hexadecimal-escape", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce consistent usage of hexadecimal escape",
|
||||
category: "Stylistic Issues",
|
||||
recommended: false,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
enum: ["always", "never"],
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
expectedHexEscape: "Expected hexadecimal escape ('{{hexEscape}}'), but {{unexpectedKind}} escape ('{{rejectEscape}}') is used.",
|
||||
unexpectedHexEscape: "Unexpected hexadecimal escape ('{{hexEscape}}').",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
const always = context.options[0] !== "never";
|
||||
function verifyForAlways({ node, getRegexpLocation, fixReplaceNode }, kind, cNode) {
|
||||
if (kind !== regex_syntax_1.EscapeSequenceKind.unicode &&
|
||||
kind !== regex_syntax_1.EscapeSequenceKind.unicodeCodePoint) {
|
||||
return;
|
||||
}
|
||||
const hexEscape = `\\x${cNode.value.toString(16).padStart(2, "0")}`;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "expectedHexEscape",
|
||||
data: {
|
||||
hexEscape,
|
||||
unexpectedKind: kind,
|
||||
rejectEscape: cNode.raw,
|
||||
},
|
||||
fix: fixReplaceNode(cNode, hexEscape),
|
||||
});
|
||||
}
|
||||
function verifyForNever({ node, getRegexpLocation, fixReplaceNode }, kind, cNode) {
|
||||
if (kind !== regex_syntax_1.EscapeSequenceKind.hexadecimal) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpectedHexEscape",
|
||||
data: {
|
||||
hexEscape: cNode.raw,
|
||||
},
|
||||
fix: fixReplaceNode(cNode, () => `\\u00${cNode.raw.slice(2)}`),
|
||||
});
|
||||
}
|
||||
const verify = always ? verifyForAlways : verifyForNever;
|
||||
function createVisitor(regexpContext) {
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.value > 0xff) {
|
||||
return;
|
||||
}
|
||||
const kind = (0, regex_syntax_1.getEscapeSequenceKind)(cNode.raw);
|
||||
if (!kind) {
|
||||
return;
|
||||
}
|
||||
verify(regexpContext, kind, cNode);
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/letter-case.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/letter-case.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
159
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/letter-case.js
generated
vendored
Normal file
159
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/letter-case.js
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
const CASE_SCHEMA = ["lowercase", "uppercase", "ignore"];
|
||||
const DEFAULTS = {
|
||||
caseInsensitive: "lowercase",
|
||||
unicodeEscape: "lowercase",
|
||||
hexadecimalEscape: "lowercase",
|
||||
controlEscape: "uppercase",
|
||||
};
|
||||
function parseOptions(option) {
|
||||
if (!option) {
|
||||
return DEFAULTS;
|
||||
}
|
||||
return {
|
||||
caseInsensitive: option.caseInsensitive || DEFAULTS.caseInsensitive,
|
||||
unicodeEscape: option.unicodeEscape || DEFAULTS.unicodeEscape,
|
||||
hexadecimalEscape: option.hexadecimalEscape || DEFAULTS.hexadecimalEscape,
|
||||
controlEscape: option.controlEscape || DEFAULTS.controlEscape,
|
||||
};
|
||||
}
|
||||
const CODE_POINT_CASE_CHECKER = {
|
||||
lowercase: utils_1.isLowercaseLetter,
|
||||
uppercase: utils_1.isUppercaseLetter,
|
||||
};
|
||||
const STRING_CASE_CHECKER = {
|
||||
lowercase: (s) => s.toLowerCase() === s,
|
||||
uppercase: (s) => s.toUpperCase() === s,
|
||||
};
|
||||
const CONVERTER = {
|
||||
lowercase: (s) => s.toLowerCase(),
|
||||
uppercase: (s) => s.toUpperCase(),
|
||||
};
|
||||
exports.default = (0, utils_1.createRule)("letter-case", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce into your favorite case",
|
||||
category: "Stylistic Issues",
|
||||
recommended: false,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
caseInsensitive: { enum: CASE_SCHEMA },
|
||||
unicodeEscape: { enum: CASE_SCHEMA },
|
||||
hexadecimalEscape: { enum: CASE_SCHEMA },
|
||||
controlEscape: { enum: CASE_SCHEMA },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpected: "'{{char}}' is not in {{case}}",
|
||||
},
|
||||
type: "layout",
|
||||
},
|
||||
create(context) {
|
||||
const options = parseOptions(context.options[0]);
|
||||
function report({ node, getRegexpLocation, fixReplaceNode }, reportNode, letterCase, convertText) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(reportNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
char: reportNode.raw,
|
||||
case: letterCase,
|
||||
},
|
||||
fix: fixReplaceNode(reportNode, () => convertText(CONVERTER[letterCase])),
|
||||
});
|
||||
}
|
||||
function verifyCharacterInCaseInsensitive(regexpContext, cNode) {
|
||||
if (cNode.parent.type === "CharacterClassRange" ||
|
||||
options.caseInsensitive === "ignore") {
|
||||
return;
|
||||
}
|
||||
if (CODE_POINT_CASE_CHECKER[options.caseInsensitive](cNode.value) ||
|
||||
!(0, utils_1.isLetter)(cNode.value)) {
|
||||
return;
|
||||
}
|
||||
report(regexpContext, cNode, options.caseInsensitive, (converter) => converter(String.fromCodePoint(cNode.value)));
|
||||
}
|
||||
function verifyCharacterClassRangeInCaseInsensitive(regexpContext, ccrNode) {
|
||||
if (options.caseInsensitive === "ignore") {
|
||||
return;
|
||||
}
|
||||
if (CODE_POINT_CASE_CHECKER[options.caseInsensitive](ccrNode.min.value) ||
|
||||
!(0, utils_1.isLetter)(ccrNode.min.value) ||
|
||||
CODE_POINT_CASE_CHECKER[options.caseInsensitive](ccrNode.max.value) ||
|
||||
!(0, utils_1.isLetter)(ccrNode.max.value)) {
|
||||
return;
|
||||
}
|
||||
report(regexpContext, ccrNode, options.caseInsensitive, (converter) => `${converter(String.fromCodePoint(ccrNode.min.value))}-${converter(String.fromCodePoint(ccrNode.max.value))}`);
|
||||
}
|
||||
function verifyCharacterInUnicodeEscape(regexpContext, cNode) {
|
||||
if (options.unicodeEscape === "ignore") {
|
||||
return;
|
||||
}
|
||||
const parts = /^(?<prefix>\\u\{?)(?<code>.*?)(?<suffix>\}?)$/u.exec(cNode.raw);
|
||||
if (STRING_CASE_CHECKER[options.unicodeEscape](parts.groups.code)) {
|
||||
return;
|
||||
}
|
||||
report(regexpContext, cNode, options.unicodeEscape, (converter) => `${parts.groups.prefix}${converter(parts.groups.code)}${parts.groups.suffix}`);
|
||||
}
|
||||
function verifyCharacterInHexadecimalEscape(regexpContext, cNode) {
|
||||
if (options.hexadecimalEscape === "ignore") {
|
||||
return;
|
||||
}
|
||||
const parts = /^\\x(?<code>.*)$/u.exec(cNode.raw);
|
||||
if (STRING_CASE_CHECKER[options.hexadecimalEscape](parts.groups.code)) {
|
||||
return;
|
||||
}
|
||||
report(regexpContext, cNode, options.hexadecimalEscape, (converter) => `\\x${converter(parts.groups.code)}`);
|
||||
}
|
||||
function verifyCharacterInControl(regexpContext, cNode) {
|
||||
if (options.controlEscape === "ignore") {
|
||||
return;
|
||||
}
|
||||
const parts = /^\\c(?<code>.*)$/u.exec(cNode.raw);
|
||||
if (STRING_CASE_CHECKER[options.controlEscape](parts.groups.code)) {
|
||||
return;
|
||||
}
|
||||
report(regexpContext, cNode, options.controlEscape, (converter) => `\\c${converter(parts.groups.code)}`);
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { flags } = regexpContext;
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (flags.ignoreCase) {
|
||||
verifyCharacterInCaseInsensitive(regexpContext, cNode);
|
||||
}
|
||||
const escapeKind = (0, regex_syntax_1.getEscapeSequenceKind)(cNode.raw);
|
||||
if (escapeKind === regex_syntax_1.EscapeSequenceKind.unicode ||
|
||||
escapeKind === regex_syntax_1.EscapeSequenceKind.unicodeCodePoint) {
|
||||
verifyCharacterInUnicodeEscape(regexpContext, cNode);
|
||||
}
|
||||
if (escapeKind === regex_syntax_1.EscapeSequenceKind.hexadecimal) {
|
||||
verifyCharacterInHexadecimalEscape(regexpContext, cNode);
|
||||
}
|
||||
if (escapeKind === regex_syntax_1.EscapeSequenceKind.control) {
|
||||
verifyCharacterInControl(regexpContext, cNode);
|
||||
}
|
||||
},
|
||||
...(flags.ignoreCase
|
||||
? {
|
||||
onCharacterClassRangeEnter(ccrNode) {
|
||||
verifyCharacterClassRangeInCaseInsensitive(regexpContext, ccrNode);
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/match-any.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/match-any.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
134
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/match-any.js
generated
vendored
Normal file
134
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/match-any.js
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const utils_2 = require("../utils/ast-utils/utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const OPTION_SS1 = "[\\s\\S]";
|
||||
const OPTION_SS2 = "[\\S\\s]";
|
||||
const OPTION_CARET = "[^]";
|
||||
const OPTION_DOTALL = "dotAll";
|
||||
exports.default = (0, utils_1.createRule)("match-any", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce match any character style",
|
||||
category: "Stylistic Issues",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allows: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
enum: [
|
||||
OPTION_SS1,
|
||||
OPTION_SS2,
|
||||
OPTION_CARET,
|
||||
OPTION_DOTALL,
|
||||
],
|
||||
},
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpected: "Unexpected using {{expr}} to match any character.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const sourceCode = context.sourceCode;
|
||||
const allowList = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allows) !== null && _b !== void 0 ? _b : [OPTION_SS1, OPTION_DOTALL];
|
||||
const allows = new Set(allowList);
|
||||
const preference = allowList[0] || null;
|
||||
function fix(fixer, { node, flags, patternSource }, regexpNode) {
|
||||
var _a, _b;
|
||||
if (!preference) {
|
||||
return null;
|
||||
}
|
||||
if (preference === OPTION_DOTALL) {
|
||||
if (!flags.dotAll) {
|
||||
return null;
|
||||
}
|
||||
if (!(0, utils_2.isRegexpLiteral)(node)) {
|
||||
return null;
|
||||
}
|
||||
const range = patternSource.getReplaceRange(regexpNode);
|
||||
if (range == null) {
|
||||
return null;
|
||||
}
|
||||
const afterRange = [
|
||||
range.range[1],
|
||||
node.range[1],
|
||||
];
|
||||
return [
|
||||
range.replace(fixer, "."),
|
||||
fixer.replaceTextRange(afterRange, sourceCode.text.slice(...afterRange)),
|
||||
];
|
||||
}
|
||||
if (regexpNode.type === "CharacterClass" &&
|
||||
preference.startsWith("[") &&
|
||||
preference.endsWith("]")) {
|
||||
const range = patternSource.getReplaceRange({
|
||||
start: regexpNode.start + 1,
|
||||
end: regexpNode.end - 1,
|
||||
});
|
||||
return (_a = range === null || range === void 0 ? void 0 : range.replace(fixer, preference.slice(1, -1))) !== null && _a !== void 0 ? _a : null;
|
||||
}
|
||||
const range = patternSource.getReplaceRange(regexpNode);
|
||||
return (_b = range === null || range === void 0 ? void 0 : range.replace(fixer, preference)) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, flags, getRegexpLocation } = regexpContext;
|
||||
function onClass(ccNode) {
|
||||
if ((0, regexp_ast_analysis_1.matchesAllCharacters)(ccNode, flags) &&
|
||||
!(0, regexp_ast_analysis_1.hasStrings)(ccNode, flags) &&
|
||||
!allows.has(ccNode.raw)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(ccNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
expr: (0, mention_1.mention)(ccNode),
|
||||
},
|
||||
fix(fixer) {
|
||||
return fix(fixer, regexpContext, ccNode);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
onCharacterSetEnter(csNode) {
|
||||
if (csNode.kind === "any" &&
|
||||
flags.dotAll &&
|
||||
!allows.has(OPTION_DOTALL)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(csNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
expr: (0, mention_1.mention)(csNode),
|
||||
},
|
||||
fix(fixer) {
|
||||
return fix(fixer, regexpContext, csNode);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
onCharacterClassEnter: onClass,
|
||||
onExpressionCharacterClassEnter: onClass,
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/negation.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/negation.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
87
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/negation.js
generated
vendored
Normal file
87
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/negation.js
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const util_1 = require("../utils/util");
|
||||
function isNegatableCharacterClassElement(node) {
|
||||
return (node.type === "CharacterClass" ||
|
||||
node.type === "ExpressionCharacterClass" ||
|
||||
(node.type === "CharacterSet" &&
|
||||
(node.kind !== "property" || !node.strings)));
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("negation", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "enforce use of escapes on negation",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected negated character class. Use '{{negatedCharSet}}' instead.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, getRegexpLocation, fixReplaceNode, flags, }) {
|
||||
return {
|
||||
onCharacterClassEnter(ccNode) {
|
||||
if (!ccNode.negate || ccNode.elements.length !== 1) {
|
||||
return;
|
||||
}
|
||||
const element = ccNode.elements[0];
|
||||
if (!isNegatableCharacterClassElement(element)) {
|
||||
return;
|
||||
}
|
||||
if (element.type !== "CharacterSet" && !element.negate) {
|
||||
return;
|
||||
}
|
||||
if (flags.ignoreCase &&
|
||||
!flags.unicodeSets &&
|
||||
element.type === "CharacterSet" &&
|
||||
element.kind === "property") {
|
||||
const ccSet = (0, regexp_ast_analysis_1.toUnicodeSet)(ccNode, flags);
|
||||
const negatedElementSet = (0, regexp_ast_analysis_1.toUnicodeSet)({
|
||||
...element,
|
||||
negate: !element.negate,
|
||||
}, flags);
|
||||
if (!ccSet.equals(negatedElementSet)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const negatedCharSet = getNegationText(element);
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(ccNode),
|
||||
messageId: "unexpected",
|
||||
data: { negatedCharSet },
|
||||
fix: fixReplaceNode(ccNode, negatedCharSet),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
function getNegationText(node) {
|
||||
if (node.type === "CharacterSet") {
|
||||
let kind = node.raw[1];
|
||||
if (kind.toLowerCase() === kind) {
|
||||
kind = kind.toUpperCase();
|
||||
}
|
||||
else {
|
||||
kind = kind.toLowerCase();
|
||||
}
|
||||
return `\\${kind}${node.raw.slice(2)}`;
|
||||
}
|
||||
if (node.type === "CharacterClass") {
|
||||
return `[${node.elements.map((e) => e.raw).join("")}]`;
|
||||
}
|
||||
if (node.type === "ExpressionCharacterClass") {
|
||||
return `[${node.raw.slice(2, -1)}]`;
|
||||
}
|
||||
return (0, util_1.assertNever)(node);
|
||||
}
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-contradiction-with-assertion.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-contradiction-with-assertion.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
252
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-contradiction-with-assertion.js
generated
vendored
Normal file
252
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-contradiction-with-assertion.js
generated
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const regexp_ast_1 = require("../utils/regexp-ast");
|
||||
function isTrivialAssertion(assertion, dir, flags) {
|
||||
if (assertion.kind !== "word") {
|
||||
if ((0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(assertion.kind) !== dir) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (assertion.kind === "lookahead" || assertion.kind === "lookbehind") {
|
||||
if ((0, regexp_ast_analysis_1.isPotentiallyEmpty)(assertion.alternatives, flags)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const look = regexp_ast_analysis_1.FirstConsumedChars.toLook((0, regexp_ast_analysis_1.getFirstConsumedChar)(assertion, dir, flags));
|
||||
if (look.char.isEmpty || look.char.isAll) {
|
||||
return true;
|
||||
}
|
||||
const after = (0, regexp_ast_analysis_1.getFirstCharAfter)(assertion, dir, flags);
|
||||
if (!after.edge) {
|
||||
if (look.exact && look.char.isSupersetOf(after.char)) {
|
||||
return true;
|
||||
}
|
||||
if (look.char.isDisjointWith(after.char)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function* getNextElements(start, dir, flags) {
|
||||
let element = start;
|
||||
for (;;) {
|
||||
const parent = element.parent;
|
||||
if (parent.type === "CharacterClass" ||
|
||||
parent.type === "CharacterClassRange" ||
|
||||
parent.type === "ClassIntersection" ||
|
||||
parent.type === "ClassSubtraction" ||
|
||||
parent.type === "StringAlternative") {
|
||||
return;
|
||||
}
|
||||
if (parent.type === "Quantifier") {
|
||||
if (parent.max === 1) {
|
||||
element = parent;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const elements = parent.elements;
|
||||
const index = elements.indexOf(element);
|
||||
const inc = dir === "ltr" ? 1 : -1;
|
||||
for (let i = index + inc; i >= 0 && i < elements.length; i += inc) {
|
||||
const e = elements[i];
|
||||
yield e;
|
||||
if (!(0, regexp_ast_analysis_1.isZeroLength)(e, flags)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const grandParent = parent.parent;
|
||||
if ((grandParent.type === "Group" ||
|
||||
grandParent.type === "CapturingGroup" ||
|
||||
(grandParent.type === "Assertion" &&
|
||||
(0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(grandParent.kind) !==
|
||||
dir)) &&
|
||||
grandParent.alternatives.length === 1) {
|
||||
element = grandParent;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
function tryFindContradictionIn(element, dir, condition, flags) {
|
||||
if (condition(element)) {
|
||||
return true;
|
||||
}
|
||||
if (element.type === "CapturingGroup" || element.type === "Group") {
|
||||
let some = false;
|
||||
element.alternatives.forEach((a) => {
|
||||
if (tryFindContradictionInAlternative(a, dir, condition, flags)) {
|
||||
some = true;
|
||||
}
|
||||
});
|
||||
return some;
|
||||
}
|
||||
if (element.type === "Quantifier" && element.max === 1) {
|
||||
return tryFindContradictionIn(element.element, dir, condition, flags);
|
||||
}
|
||||
if (element.type === "Assertion" &&
|
||||
(element.kind === "lookahead" || element.kind === "lookbehind") &&
|
||||
(0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(element.kind) === dir) {
|
||||
element.alternatives.forEach((a) => tryFindContradictionInAlternative(a, dir, condition, flags));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function tryFindContradictionInAlternative(alternative, dir, condition, flags) {
|
||||
if (condition(alternative)) {
|
||||
return true;
|
||||
}
|
||||
const { elements } = alternative;
|
||||
const first = dir === "ltr" ? 0 : elements.length;
|
||||
const inc = dir === "ltr" ? 1 : -1;
|
||||
for (let i = first; i >= 0 && i < elements.length; i += inc) {
|
||||
const e = elements[i];
|
||||
if (tryFindContradictionIn(e, dir, condition, flags)) {
|
||||
return true;
|
||||
}
|
||||
if (!(0, regexp_ast_analysis_1.isZeroLength)(e, flags)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function disjoint(a, b) {
|
||||
if (a.edge && b.edge) {
|
||||
return false;
|
||||
}
|
||||
return a.char.isDisjointWith(b.char);
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-contradiction-with-assertion", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow elements that contradict assertions",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
alternative: "The alternative {{ alt }} can never be entered because it contradicts with the assertion {{ assertion }}. Either change the alternative or assertion to resolve the contradiction.",
|
||||
cannotEnterQuantifier: "The quantifier {{ quant }} can never be entered because its element contradicts with the assertion {{ assertion }}. Change or remove the quantifier or change the assertion to resolve the contradiction.",
|
||||
alwaysEnterQuantifier: "The quantifier {{ quant }} is always entered despite having a minimum of 0. This is because the assertion {{ assertion }} contradicts with the element(s) after the quantifier. Either set the minimum to 1 ({{ newQuant }}) or change the assertion.",
|
||||
removeQuantifier: "Remove the quantifier.",
|
||||
changeQuantifier: "Change the quantifier to {{ newQuant }}.",
|
||||
},
|
||||
hasSuggestions: true,
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, flags, getRegexpLocation, fixReplaceQuant, fixReplaceNode, } = regexpContext;
|
||||
function analyseAssertion(assertion, dir) {
|
||||
if (isTrivialAssertion(assertion, dir, flags)) {
|
||||
return;
|
||||
}
|
||||
const assertionLook = regexp_ast_analysis_1.FirstConsumedChars.toLook((0, regexp_ast_analysis_1.getFirstConsumedChar)(assertion, dir, flags));
|
||||
for (const element of getNextElements(assertion, dir, flags)) {
|
||||
if (tryFindContradictionIn(element, dir, contradicts, flags)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
function contradictsAlternative(alternative) {
|
||||
let consumed = (0, regexp_ast_analysis_1.getFirstConsumedChar)(alternative, dir, flags);
|
||||
if (consumed.empty) {
|
||||
consumed = regexp_ast_analysis_1.FirstConsumedChars.concat([
|
||||
consumed,
|
||||
(0, regexp_ast_analysis_1.getFirstConsumedCharAfter)(alternative, dir, flags),
|
||||
], flags);
|
||||
}
|
||||
const look = regexp_ast_analysis_1.FirstConsumedChars.toLook(consumed);
|
||||
if (disjoint(assertionLook, look)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(alternative),
|
||||
messageId: "alternative",
|
||||
data: {
|
||||
assertion: (0, mention_1.mention)(assertion),
|
||||
alt: (0, mention_1.mention)(alternative),
|
||||
},
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function contradictsQuantifier(quant) {
|
||||
if (quant.max === 0) {
|
||||
return false;
|
||||
}
|
||||
if (quant.min !== 0) {
|
||||
return false;
|
||||
}
|
||||
const consumed = (0, regexp_ast_analysis_1.getFirstConsumedChar)(quant.element, dir, flags);
|
||||
const look = regexp_ast_analysis_1.FirstConsumedChars.toLook(consumed);
|
||||
if (disjoint(assertionLook, look)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(quant),
|
||||
messageId: "cannotEnterQuantifier",
|
||||
data: {
|
||||
assertion: (0, mention_1.mention)(assertion),
|
||||
quant: (0, mention_1.mention)(quant),
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "removeQuantifier",
|
||||
fix: fixReplaceNode(quant, ""),
|
||||
},
|
||||
],
|
||||
});
|
||||
return true;
|
||||
}
|
||||
const after = (0, regexp_ast_analysis_1.getFirstCharAfter)(quant, dir, flags);
|
||||
if (disjoint(assertionLook, after)) {
|
||||
const newQuant = (0, regexp_ast_1.quantToString)({ ...quant, min: 1 });
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(quant),
|
||||
messageId: "alwaysEnterQuantifier",
|
||||
data: {
|
||||
assertion: (0, mention_1.mention)(assertion),
|
||||
quant: (0, mention_1.mention)(quant),
|
||||
newQuant,
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "changeQuantifier",
|
||||
data: { newQuant },
|
||||
fix: fixReplaceQuant(quant, {
|
||||
min: 1,
|
||||
max: quant.max,
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function contradicts(element) {
|
||||
if (element.type === "Alternative") {
|
||||
return contradictsAlternative(element);
|
||||
}
|
||||
else if (element.type === "Quantifier") {
|
||||
return contradictsQuantifier(element);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return {
|
||||
onAssertionEnter(assertion) {
|
||||
analyseAssertion(assertion, "ltr");
|
||||
analyseAssertion(assertion, "rtl");
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-control-character.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-control-character.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
84
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-control-character.js
generated
vendored
Normal file
84
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-control-character.js
generated
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const unicode_1 = require("../utils/unicode");
|
||||
const CONTROL_CHARS = new Map([
|
||||
[0, "\\0"],
|
||||
[unicode_1.CP_TAB, "\\t"],
|
||||
[unicode_1.CP_LF, "\\n"],
|
||||
[unicode_1.CP_VT, "\\v"],
|
||||
[unicode_1.CP_FF, "\\f"],
|
||||
[unicode_1.CP_CR, "\\r"],
|
||||
]);
|
||||
const ALLOWED_CONTROL_CHARS = /^\\[0fnrtv]$/u;
|
||||
exports.default = (0, utils_1.createRule)("no-control-character", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow control characters",
|
||||
category: "Possible Errors",
|
||||
recommended: false,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected control character {{ char }}.",
|
||||
escape: "Use {{ escape }} instead.",
|
||||
},
|
||||
type: "suggestion",
|
||||
hasSuggestions: true,
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, patternSource, getRegexpLocation, fixReplaceNode } = regexpContext;
|
||||
function isBadEscapeRaw(raw, cp) {
|
||||
return (raw.codePointAt(0) === cp ||
|
||||
raw.startsWith("\\x") ||
|
||||
raw.startsWith("\\u"));
|
||||
}
|
||||
function isAllowedEscapeRaw(raw) {
|
||||
return (ALLOWED_CONTROL_CHARS.test(raw) ||
|
||||
(raw.startsWith("\\") &&
|
||||
ALLOWED_CONTROL_CHARS.test(raw.slice(1))));
|
||||
}
|
||||
function isBadEscape(char) {
|
||||
var _a;
|
||||
const range = (_a = patternSource.getReplaceRange(char)) === null || _a === void 0 ? void 0 : _a.range;
|
||||
const sourceRaw = range
|
||||
? context.sourceCode.text.slice(...range)
|
||||
: char.raw;
|
||||
if (isAllowedEscapeRaw(char.raw) ||
|
||||
isAllowedEscapeRaw(sourceRaw)) {
|
||||
return false;
|
||||
}
|
||||
return (isBadEscapeRaw(char.raw, char.value) ||
|
||||
(char.raw.startsWith("\\") &&
|
||||
isBadEscapeRaw(char.raw.slice(1), char.value)));
|
||||
}
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.value <= 0x1f && isBadEscape(cNode)) {
|
||||
const suggest = [];
|
||||
const allowedEscape = CONTROL_CHARS.get(cNode.value);
|
||||
if (allowedEscape !== undefined) {
|
||||
suggest.push({
|
||||
messageId: "escape",
|
||||
data: { escape: (0, mention_1.mention)(allowedEscape) },
|
||||
fix: fixReplaceNode(cNode, allowedEscape),
|
||||
});
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
data: { char: (0, mention_1.mentionChar)(cNode) },
|
||||
suggest,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-characters-character-class.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-characters-character-class.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
228
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-characters-character-class.js
generated
vendored
Normal file
228
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-characters-character-class.js
generated
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const refa_1 = require("refa");
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const refa_2 = require("../utils/refa");
|
||||
const util_1 = require("../utils/util");
|
||||
function groupElements(elements, flags) {
|
||||
const duplicates = [];
|
||||
const characters = new Map();
|
||||
const characterRanges = new Map();
|
||||
const characterSetAndClasses = new Map();
|
||||
function addToGroup(group, key, element) {
|
||||
const current = group.get(key);
|
||||
if (current !== undefined) {
|
||||
duplicates.push({ element: current, duplicate: element });
|
||||
}
|
||||
else {
|
||||
group.set(key, element);
|
||||
}
|
||||
}
|
||||
for (const e of elements) {
|
||||
if (e.type === "Character") {
|
||||
const charSet = (0, regexp_ast_analysis_1.toCharSet)(e, flags);
|
||||
const key = charSet.ranges[0].min;
|
||||
addToGroup(characters, key, e);
|
||||
}
|
||||
else if (e.type === "CharacterClassRange") {
|
||||
const charSet = (0, regexp_ast_analysis_1.toCharSet)(e, flags);
|
||||
const key = buildRangeKey(charSet);
|
||||
addToGroup(characterRanges, key, e);
|
||||
}
|
||||
else if (e.type === "CharacterSet" ||
|
||||
e.type === "CharacterClass" ||
|
||||
e.type === "ClassStringDisjunction" ||
|
||||
e.type === "ExpressionCharacterClass") {
|
||||
const key = e.raw;
|
||||
addToGroup(characterSetAndClasses, key, e);
|
||||
}
|
||||
else {
|
||||
(0, util_1.assertNever)(e);
|
||||
}
|
||||
}
|
||||
return {
|
||||
duplicates,
|
||||
characters: [...characters.values()],
|
||||
characterRanges: [...characterRanges.values()],
|
||||
characterSetAndClasses: [...characterSetAndClasses.values()],
|
||||
};
|
||||
function buildRangeKey(rangeCharSet) {
|
||||
return rangeCharSet.ranges
|
||||
.map((r) => String.fromCodePoint(r.min, r.max))
|
||||
.join(",");
|
||||
}
|
||||
}
|
||||
function inRange({ min, max }, char) {
|
||||
return min <= char && char <= max;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-dupe-characters-character-class", {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
docs: {
|
||||
description: "disallow duplicate characters in the RegExp character class",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
duplicate: "Unexpected duplicate {{duplicate}}.",
|
||||
duplicateNonObvious: "Unexpected duplicate. {{duplicate}} is a duplicate of {{element}}.",
|
||||
subset: "{{subsetElement}} is already included in {{element}}.",
|
||||
subsetOfMany: "{{subsetElement}} is already included by the elements {{elements}}.",
|
||||
overlap: "Unexpected overlap of {{elementA}} and {{elementB}} was found '{{overlap}}'.",
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
function reportDuplicate(regexpContext, duplicate, element) {
|
||||
const { node, getRegexpLocation } = regexpContext;
|
||||
if (duplicate.raw === element.raw) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(duplicate),
|
||||
messageId: "duplicate",
|
||||
data: {
|
||||
duplicate: (0, mention_1.mentionChar)(duplicate),
|
||||
},
|
||||
fix: (0, utils_1.fixRemoveCharacterClassElement)(regexpContext, duplicate),
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(duplicate),
|
||||
messageId: "duplicateNonObvious",
|
||||
data: {
|
||||
duplicate: (0, mention_1.mentionChar)(duplicate),
|
||||
element: (0, mention_1.mentionChar)(element),
|
||||
},
|
||||
fix: (0, utils_1.fixRemoveCharacterClassElement)(regexpContext, duplicate),
|
||||
});
|
||||
}
|
||||
}
|
||||
function reportOverlap({ node, getRegexpLocation }, element, intersectElement, overlap) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(element),
|
||||
messageId: "overlap",
|
||||
data: {
|
||||
elementA: (0, mention_1.mentionChar)(element),
|
||||
elementB: (0, mention_1.mentionChar)(intersectElement),
|
||||
overlap,
|
||||
},
|
||||
});
|
||||
}
|
||||
function reportSubset(regexpContext, subsetElement, element) {
|
||||
const { node, getRegexpLocation } = regexpContext;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(subsetElement),
|
||||
messageId: "subset",
|
||||
data: {
|
||||
subsetElement: (0, mention_1.mentionChar)(subsetElement),
|
||||
element: (0, mention_1.mentionChar)(element),
|
||||
},
|
||||
fix: (0, utils_1.fixRemoveCharacterClassElement)(regexpContext, subsetElement),
|
||||
});
|
||||
}
|
||||
function reportSubsetOfMany(regexpContext, subsetElement, elements) {
|
||||
const { node, getRegexpLocation } = regexpContext;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(subsetElement),
|
||||
messageId: "subsetOfMany",
|
||||
data: {
|
||||
subsetElement: (0, mention_1.mentionChar)(subsetElement),
|
||||
elements: `'${elements
|
||||
.map((e) => e.raw)
|
||||
.join("")}' (${elements.map(mention_1.mentionChar).join(", ")})`,
|
||||
},
|
||||
fix: (0, utils_1.fixRemoveCharacterClassElement)(regexpContext, subsetElement),
|
||||
});
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { flags } = regexpContext;
|
||||
return {
|
||||
onCharacterClassEnter(ccNode) {
|
||||
const { duplicates, characters, characterRanges, characterSetAndClasses, } = groupElements(ccNode.elements, flags);
|
||||
const elementsOtherThanCharacter = [
|
||||
...characterRanges,
|
||||
...characterSetAndClasses,
|
||||
];
|
||||
const subsets = new Set();
|
||||
for (const { element, duplicate } of duplicates) {
|
||||
reportDuplicate(regexpContext, duplicate, element);
|
||||
subsets.add(duplicate);
|
||||
}
|
||||
for (const char of characters) {
|
||||
for (const other of elementsOtherThanCharacter) {
|
||||
if ((0, regexp_ast_analysis_1.toUnicodeSet)(other, flags).chars.has(char.value)) {
|
||||
reportSubset(regexpContext, char, other);
|
||||
subsets.add(char);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const element of elementsOtherThanCharacter) {
|
||||
for (const other of elementsOtherThanCharacter) {
|
||||
if (element === other || subsets.has(other)) {
|
||||
continue;
|
||||
}
|
||||
if ((0, regexp_ast_analysis_1.toUnicodeSet)(element, flags).isSubsetOf((0, regexp_ast_analysis_1.toUnicodeSet)(other, flags))) {
|
||||
reportSubset(regexpContext, element, other);
|
||||
subsets.add(element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const characterTotal = (0, regexp_ast_analysis_1.toUnicodeSet)(characters.filter((c) => !subsets.has(c)), flags);
|
||||
for (const element of elementsOtherThanCharacter) {
|
||||
if (subsets.has(element)) {
|
||||
continue;
|
||||
}
|
||||
const totalOthers = characterTotal.union(...elementsOtherThanCharacter
|
||||
.filter((e) => !subsets.has(e) && e !== element)
|
||||
.map((e) => (0, regexp_ast_analysis_1.toUnicodeSet)(e, flags)));
|
||||
const elementCharSet = (0, regexp_ast_analysis_1.toUnicodeSet)(element, flags);
|
||||
if (elementCharSet.isSubsetOf(totalOthers)) {
|
||||
const superSetElements = ccNode.elements
|
||||
.filter((e) => !subsets.has(e) && e !== element)
|
||||
.filter((e) => !(0, regexp_ast_analysis_1.toUnicodeSet)(e, flags).isDisjointWith(elementCharSet));
|
||||
reportSubsetOfMany(regexpContext, element, superSetElements);
|
||||
subsets.add(element);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < characterRanges.length; i++) {
|
||||
const range = characterRanges[i];
|
||||
if (subsets.has(range)) {
|
||||
continue;
|
||||
}
|
||||
for (let j = i + 1; j < elementsOtherThanCharacter.length; j++) {
|
||||
const other = elementsOtherThanCharacter[j];
|
||||
if (range === other || subsets.has(other)) {
|
||||
continue;
|
||||
}
|
||||
const intersection = (0, regexp_ast_analysis_1.toUnicodeSet)(range, flags).intersect((0, regexp_ast_analysis_1.toUnicodeSet)(other, flags));
|
||||
if (intersection.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
const interestingRanges = intersection.chars.ranges.filter((r) => inRange(r, range.min.value) ||
|
||||
inRange(r, range.max.value));
|
||||
(0, refa_2.assertValidFlags)(flags);
|
||||
const interest = refa_1.JS.createCharSet(interestingRanges, flags);
|
||||
if (!interest.isEmpty) {
|
||||
reportOverlap(regexpContext, range, other, (0, refa_2.toCharSetSource)(interest, flags));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-disjunctions.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-disjunctions.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
863
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-disjunctions.js
generated
vendored
Normal file
863
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-dupe-disjunctions.js
generated
vendored
Normal file
|
|
@ -0,0 +1,863 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const refa_1 = require("refa");
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const char_ranges_1 = require("../utils/char-ranges");
|
||||
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const partial_parser_1 = require("../utils/partial-parser");
|
||||
const refa_2 = require("../utils/refa");
|
||||
const regexp_ast_1 = require("../utils/regexp-ast");
|
||||
const util_1 = require("../utils/util");
|
||||
function isStared(node) {
|
||||
let max = (0, regexp_ast_analysis_1.getEffectiveMaximumRepetition)(node);
|
||||
if (node.type === "Quantifier") {
|
||||
max *= node.max;
|
||||
}
|
||||
return max > 10;
|
||||
}
|
||||
function hasNothingAfterNode(node) {
|
||||
const md = (0, regexp_ast_analysis_1.getMatchingDirection)(node);
|
||||
for (let p = node;; p = p.parent) {
|
||||
if (p.type === "Assertion" || p.type === "Pattern") {
|
||||
return true;
|
||||
}
|
||||
if (p.type !== "Alternative") {
|
||||
const parent = p.parent;
|
||||
if (parent.type === "Quantifier") {
|
||||
if (parent.max > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const lastIndex = md === "ltr" ? parent.elements.length - 1 : 0;
|
||||
if (parent.elements[lastIndex] !== p) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function containsAssertions(expression) {
|
||||
try {
|
||||
(0, refa_1.visitAst)(expression, {
|
||||
onAssertionEnter() {
|
||||
throw new Error();
|
||||
},
|
||||
});
|
||||
return false;
|
||||
}
|
||||
catch (_a) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function containsAssertionsOrUnknowns(expression) {
|
||||
try {
|
||||
(0, refa_1.visitAst)(expression, {
|
||||
onAssertionEnter() {
|
||||
throw new Error();
|
||||
},
|
||||
onUnknownEnter() {
|
||||
throw new Error();
|
||||
},
|
||||
});
|
||||
return false;
|
||||
}
|
||||
catch (_a) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function isNonRegular(node) {
|
||||
return (0, regexp_ast_analysis_1.hasSomeDescendant)(node, (d) => d.type === "Assertion" || d.type === "Backreference");
|
||||
}
|
||||
function toNFA(parser, element) {
|
||||
try {
|
||||
const { expression, maxCharacter } = parser.parseElement(element, {
|
||||
backreferences: "unknown",
|
||||
assertions: "parse",
|
||||
});
|
||||
let e;
|
||||
if (containsAssertions(expression)) {
|
||||
e = (0, refa_1.transform)(refa_1.Transformers.simplify({
|
||||
ignoreAmbiguity: true,
|
||||
ignoreOrder: true,
|
||||
}), expression);
|
||||
}
|
||||
else {
|
||||
e = expression;
|
||||
}
|
||||
return {
|
||||
nfa: refa_1.NFA.fromRegex(e, { maxCharacter }, { assertions: "disable", unknowns: "disable" }),
|
||||
partial: containsAssertionsOrUnknowns(e),
|
||||
};
|
||||
}
|
||||
catch (_a) {
|
||||
return {
|
||||
nfa: refa_1.NFA.empty({
|
||||
maxCharacter: parser.maxCharacter,
|
||||
}),
|
||||
partial: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
function* iterateNestedAlternatives(alternative) {
|
||||
for (const e of alternative.elements) {
|
||||
if (e.type === "Group" || e.type === "CapturingGroup") {
|
||||
for (const a of e.alternatives) {
|
||||
if (e.alternatives.length > 1) {
|
||||
yield a;
|
||||
}
|
||||
yield* iterateNestedAlternatives(a);
|
||||
}
|
||||
}
|
||||
if (e.type === "CharacterClass" && !e.negate) {
|
||||
const nested = [];
|
||||
const addToNested = (charElement) => {
|
||||
switch (charElement.type) {
|
||||
case "CharacterClassRange": {
|
||||
const min = charElement.min;
|
||||
const max = charElement.max;
|
||||
if (min.value === max.value) {
|
||||
nested.push(charElement);
|
||||
}
|
||||
else if (min.value + 1 === max.value) {
|
||||
nested.push(min, max);
|
||||
}
|
||||
else {
|
||||
nested.push(charElement, min, max);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ClassStringDisjunction": {
|
||||
nested.push(...charElement.alternatives);
|
||||
break;
|
||||
}
|
||||
case "CharacterClass": {
|
||||
if (!charElement.negate) {
|
||||
charElement.elements.forEach(addToNested);
|
||||
}
|
||||
else {
|
||||
nested.push(charElement);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Character":
|
||||
case "CharacterSet":
|
||||
case "ExpressionCharacterClass": {
|
||||
nested.push(charElement);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw (0, util_1.assertNever)(charElement);
|
||||
}
|
||||
};
|
||||
e.elements.forEach(addToNested);
|
||||
if (nested.length > 1)
|
||||
yield* nested;
|
||||
}
|
||||
}
|
||||
}
|
||||
function* iteratePartialAlternatives(alternative, parser) {
|
||||
if (isNonRegular(alternative)) {
|
||||
return;
|
||||
}
|
||||
const maxCharacter = parser.maxCharacter;
|
||||
const partialParser = new partial_parser_1.PartialParser(parser, {
|
||||
assertions: "throw",
|
||||
backreferences: "throw",
|
||||
});
|
||||
for (const nested of iterateNestedAlternatives(alternative)) {
|
||||
try {
|
||||
const expression = partialParser.parse(alternative, nested);
|
||||
const nfa = refa_1.NFA.fromRegex(expression, { maxCharacter });
|
||||
yield { nested, nfa };
|
||||
}
|
||||
catch (_a) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function unionAll(nfas) {
|
||||
if (nfas.length === 0) {
|
||||
throw new Error("Cannot union 0 NFAs.");
|
||||
}
|
||||
else if (nfas.length === 1) {
|
||||
return nfas[0];
|
||||
}
|
||||
const total = nfas[0].copy();
|
||||
for (let i = 1; i < nfas.length; i++) {
|
||||
total.union(nfas[i]);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
const MAX_DFA_NODES = 100000;
|
||||
function isSubsetOf(superset, subset) {
|
||||
try {
|
||||
const a = refa_1.DFA.fromIntersection(superset, subset, new refa_1.DFA.LimitedNodeFactory(MAX_DFA_NODES));
|
||||
const b = refa_1.DFA.fromFA(subset, new refa_1.DFA.LimitedNodeFactory(MAX_DFA_NODES));
|
||||
a.minimize();
|
||||
b.minimize();
|
||||
return a.structurallyEqual(b);
|
||||
}
|
||||
catch (_a) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function getSubsetRelation(left, right) {
|
||||
try {
|
||||
const inter = refa_1.DFA.fromIntersection(left, right, new refa_1.DFA.LimitedNodeFactory(MAX_DFA_NODES));
|
||||
inter.minimize();
|
||||
const l = refa_1.DFA.fromFA(left, new refa_1.DFA.LimitedNodeFactory(MAX_DFA_NODES));
|
||||
l.minimize();
|
||||
const r = refa_1.DFA.fromFA(right, new refa_1.DFA.LimitedNodeFactory(MAX_DFA_NODES));
|
||||
r.minimize();
|
||||
const subset = l.structurallyEqual(inter);
|
||||
const superset = r.structurallyEqual(inter);
|
||||
if (subset && superset) {
|
||||
return 1;
|
||||
}
|
||||
else if (subset) {
|
||||
return 2;
|
||||
}
|
||||
else if (superset) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (_a) {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
function getPartialSubsetRelation(left, leftIsPartial, right, rightIsPartial) {
|
||||
const relation = getSubsetRelation(left, right);
|
||||
if (!leftIsPartial && !rightIsPartial) {
|
||||
return relation;
|
||||
}
|
||||
if (relation === 0 ||
|
||||
relation === 4) {
|
||||
return relation;
|
||||
}
|
||||
if (leftIsPartial && !rightIsPartial) {
|
||||
switch (relation) {
|
||||
case 1:
|
||||
return 3;
|
||||
case 2:
|
||||
return 0;
|
||||
case 3:
|
||||
return 3;
|
||||
default:
|
||||
return (0, util_1.assertNever)(relation);
|
||||
}
|
||||
}
|
||||
if (rightIsPartial && !leftIsPartial) {
|
||||
switch (relation) {
|
||||
case 1:
|
||||
return 2;
|
||||
case 2:
|
||||
return 2;
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
return (0, util_1.assertNever)(relation);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function faToSource(fa, flags) {
|
||||
try {
|
||||
(0, refa_2.assertValidFlags)(flags);
|
||||
return refa_1.JS.toLiteral(fa.toRegex(), { flags }).source;
|
||||
}
|
||||
catch (_a) {
|
||||
return "<ERROR>";
|
||||
}
|
||||
}
|
||||
function* findDuplicationAstFast(alternatives, flags) {
|
||||
const shortCircuit = (a) => {
|
||||
return a.type === "CapturingGroup" ? false : null;
|
||||
};
|
||||
for (let i = 0; i < alternatives.length; i++) {
|
||||
const alternative = alternatives[i];
|
||||
for (let j = 0; j < i; j++) {
|
||||
const other = alternatives[j];
|
||||
if ((0, regexp_ast_1.isEqualNodes)(other, alternative, flags, shortCircuit)) {
|
||||
yield { type: "Duplicate", alternative, others: [other] };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function* findDuplicationAst(alternatives, flags, hasNothingAfter) {
|
||||
const isCoveredOptions = {
|
||||
flags,
|
||||
canOmitRight: hasNothingAfter,
|
||||
};
|
||||
const isCoveredOptionsNoPrefix = {
|
||||
flags,
|
||||
canOmitRight: false,
|
||||
};
|
||||
for (let i = 0; i < alternatives.length; i++) {
|
||||
const alternative = alternatives[i];
|
||||
for (let j = 0; j < i; j++) {
|
||||
const other = alternatives[j];
|
||||
if ((0, regexp_ast_1.isCoveredNode)(other, alternative, isCoveredOptions)) {
|
||||
if ((0, regexp_ast_1.isEqualNodes)(other, alternative, flags)) {
|
||||
yield {
|
||||
type: "Duplicate",
|
||||
alternative,
|
||||
others: [other],
|
||||
};
|
||||
}
|
||||
else if (hasNothingAfter &&
|
||||
!(0, regexp_ast_1.isCoveredNode)(other, alternative, isCoveredOptionsNoPrefix)) {
|
||||
yield {
|
||||
type: "PrefixSubset",
|
||||
alternative,
|
||||
others: [other],
|
||||
};
|
||||
}
|
||||
else {
|
||||
yield { type: "Subset", alternative, others: [other] };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function* findPrefixDuplicationNfa(alternatives, parser) {
|
||||
if (alternatives.length === 0) {
|
||||
return;
|
||||
}
|
||||
const all = refa_1.NFA.all({ maxCharacter: alternatives[0][0].maxCharacter });
|
||||
for (let i = 0; i < alternatives.length; i++) {
|
||||
const [nfa, partial, alternative] = alternatives[i];
|
||||
if (!partial) {
|
||||
const overlapping = alternatives
|
||||
.slice(0, i)
|
||||
.filter(([otherNfa]) => !(0, refa_1.isDisjointWith)(nfa, otherNfa));
|
||||
if (overlapping.length >= 1) {
|
||||
const othersNfa = unionAll(overlapping.map(([n]) => n));
|
||||
const others = overlapping.map(([, , a]) => a);
|
||||
if (isSubsetOf(othersNfa, nfa)) {
|
||||
yield { type: "PrefixSubset", alternative, others };
|
||||
}
|
||||
else {
|
||||
const nested = tryFindNestedSubsetResult(overlapping.map((o) => [o[0], o[2]]), othersNfa, alternative, parser);
|
||||
if (nested) {
|
||||
yield { ...nested, type: "PrefixNestedSubset" };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nfa.append(all);
|
||||
}
|
||||
}
|
||||
function* findDuplicationNfa(alternatives, flags, { hasNothingAfter, parser, ignoreOverlap }) {
|
||||
const previous = [];
|
||||
for (let i = 0; i < alternatives.length; i++) {
|
||||
const alternative = alternatives[i];
|
||||
const { nfa, partial } = toNFA(parser, alternative);
|
||||
const overlapping = previous.filter(([otherNfa]) => !(0, refa_1.isDisjointWith)(nfa, otherNfa));
|
||||
if (overlapping.length >= 1) {
|
||||
const othersNfa = unionAll(overlapping.map(([n]) => n));
|
||||
const othersPartial = overlapping.some(([, p]) => p);
|
||||
const others = overlapping.map(([, , a]) => a);
|
||||
const relation = getPartialSubsetRelation(nfa, partial, othersNfa, othersPartial);
|
||||
switch (relation) {
|
||||
case 1:
|
||||
if (others.length === 1) {
|
||||
yield {
|
||||
type: "Duplicate",
|
||||
alternative,
|
||||
others: [others[0]],
|
||||
};
|
||||
}
|
||||
else {
|
||||
yield { type: "Subset", alternative, others };
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
yield { type: "Subset", alternative, others };
|
||||
break;
|
||||
case 3: {
|
||||
const reorder = (0, regexp_ast_analysis_1.canReorder)([alternative, ...others], flags);
|
||||
if (reorder) {
|
||||
for (const other of others) {
|
||||
yield {
|
||||
type: "Subset",
|
||||
alternative: other,
|
||||
others: [alternative],
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
yield { type: "Superset", alternative, others };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
case 4: {
|
||||
const nested = tryFindNestedSubsetResult(overlapping.map((o) => [o[0], o[2]]), othersNfa, alternative, parser);
|
||||
if (nested) {
|
||||
yield nested;
|
||||
break;
|
||||
}
|
||||
if (!ignoreOverlap) {
|
||||
yield {
|
||||
type: "Overlap",
|
||||
alternative,
|
||||
others,
|
||||
overlap: refa_1.NFA.fromIntersection(nfa, othersNfa),
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw (0, util_1.assertNever)(relation);
|
||||
}
|
||||
}
|
||||
previous.push([nfa, partial, alternative]);
|
||||
}
|
||||
if (hasNothingAfter) {
|
||||
yield* findPrefixDuplicationNfa(previous, parser);
|
||||
}
|
||||
}
|
||||
function tryFindNestedSubsetResult(others, othersNfa, alternative, parser) {
|
||||
const disjointElements = new Set();
|
||||
for (const { nested, nfa: nestedNfa } of iteratePartialAlternatives(alternative, parser)) {
|
||||
if ((0, regexp_ast_analysis_1.hasSomeAncestor)(nested, (a) => disjointElements.has(a))) {
|
||||
continue;
|
||||
}
|
||||
if ((0, refa_1.isDisjointWith)(othersNfa, nestedNfa)) {
|
||||
disjointElements.add(nested);
|
||||
continue;
|
||||
}
|
||||
if (isSubsetOf(othersNfa, nestedNfa)) {
|
||||
return {
|
||||
type: "NestedSubset",
|
||||
alternative,
|
||||
nested,
|
||||
others: others
|
||||
.filter((o) => !(0, refa_1.isDisjointWith)(o[0], nestedNfa))
|
||||
.map((o) => o[1]),
|
||||
};
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function* findDuplication(alternatives, flags, options) {
|
||||
if (options.fastAst) {
|
||||
yield* findDuplicationAstFast(alternatives, flags);
|
||||
}
|
||||
else {
|
||||
yield* findDuplicationAst(alternatives, flags, options.hasNothingAfter);
|
||||
}
|
||||
if (!options.noNfa) {
|
||||
yield* findDuplicationNfa(alternatives, flags, options);
|
||||
}
|
||||
}
|
||||
const RESULT_TYPE_ORDER = [
|
||||
"Duplicate",
|
||||
"Subset",
|
||||
"NestedSubset",
|
||||
"PrefixSubset",
|
||||
"PrefixNestedSubset",
|
||||
"Superset",
|
||||
"Overlap",
|
||||
];
|
||||
function deduplicateResults(unsorted, { reportExp }) {
|
||||
const results = [...unsorted].sort((a, b) => RESULT_TYPE_ORDER.indexOf(a.type) -
|
||||
RESULT_TYPE_ORDER.indexOf(b.type));
|
||||
const seen = new Map();
|
||||
return results.filter(({ alternative, type }) => {
|
||||
const firstSeen = seen.get(alternative);
|
||||
if (firstSeen === undefined) {
|
||||
seen.set(alternative, type);
|
||||
return true;
|
||||
}
|
||||
if (reportExp &&
|
||||
firstSeen === "PrefixSubset" &&
|
||||
type !== "PrefixSubset") {
|
||||
seen.set(alternative, type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
function mentionNested(nested) {
|
||||
if (nested.type === "Alternative" || nested.type === "StringAlternative") {
|
||||
return (0, mention_1.mention)(nested);
|
||||
}
|
||||
return (0, mention_1.mentionChar)(nested);
|
||||
}
|
||||
function fixRemoveNestedAlternative(context, alternative) {
|
||||
switch (alternative.type) {
|
||||
case "Alternative":
|
||||
return (0, utils_1.fixRemoveAlternative)(context, alternative);
|
||||
case "StringAlternative":
|
||||
return (0, utils_1.fixRemoveStringAlternative)(context, alternative);
|
||||
case "Character":
|
||||
case "CharacterClassRange":
|
||||
case "CharacterSet":
|
||||
case "CharacterClass":
|
||||
case "ExpressionCharacterClass":
|
||||
case "ClassStringDisjunction": {
|
||||
if (alternative.parent.type !== "CharacterClass") {
|
||||
return () => null;
|
||||
}
|
||||
return (0, utils_1.fixRemoveCharacterClassElement)(context, alternative);
|
||||
}
|
||||
default:
|
||||
throw (0, util_1.assertNever)(alternative);
|
||||
}
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-dupe-disjunctions", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow duplicate disjunctions",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
report: {
|
||||
type: "string",
|
||||
enum: ["all", "trivial", "interesting"],
|
||||
},
|
||||
reportExponentialBacktracking: {
|
||||
enum: ["none", "certain", "potential"],
|
||||
},
|
||||
reportUnreachable: {
|
||||
enum: ["certain", "potential"],
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
duplicate: "Unexpected duplicate alternative. This alternative can be removed.{{cap}}{{exp}}",
|
||||
subset: "Unexpected useless alternative. This alternative is a strict subset of {{others}} and can be removed.{{cap}}{{exp}}",
|
||||
nestedSubset: "Unexpected useless element. All paths of {{root}} that go through {{nested}} are a strict subset of {{others}}. This element can be removed.{{cap}}{{exp}}",
|
||||
prefixSubset: "Unexpected useless alternative. This alternative is already covered by {{others}} and can be removed.{{cap}}",
|
||||
prefixNestedSubset: "Unexpected useless element. All paths of {{root}} that go through {{nested}} are already covered by {{others}}. This element can be removed.{{cap}}",
|
||||
superset: "Unexpected superset. This alternative is a superset of {{others}}. It might be possible to remove the other alternative(s).{{cap}}{{exp}}",
|
||||
overlap: "Unexpected overlap. This alternative overlaps with {{others}}. The overlap is {{expr}}.{{cap}}{{exp}}",
|
||||
remove: "Remove the {{alternative}} {{type}}.",
|
||||
replaceRange: "Replace {{range}} with {{replacement}}.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const reportExponentialBacktracking = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.reportExponentialBacktracking) !== null && _b !== void 0 ? _b : "potential";
|
||||
const reportUnreachable = (_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.reportUnreachable) !== null && _d !== void 0 ? _d : "certain";
|
||||
const report = (_f = (_e = context.options[0]) === null || _e === void 0 ? void 0 : _e.report) !== null && _f !== void 0 ? _f : "trivial";
|
||||
const allowedRanges = (0, char_ranges_1.getAllowedCharRanges)(undefined, context);
|
||||
function createVisitor(regexpContext) {
|
||||
const { flags, node, getRegexpLocation, getUsageOfPattern } = regexpContext;
|
||||
const parser = (0, refa_2.getParser)(regexpContext);
|
||||
function getFilterInfo(parentNode) {
|
||||
const usage = getUsageOfPattern();
|
||||
let stared;
|
||||
if (isStared(parentNode)) {
|
||||
stared = 1;
|
||||
}
|
||||
else if (usage === get_usage_of_pattern_1.UsageOfPattern.partial ||
|
||||
usage === get_usage_of_pattern_1.UsageOfPattern.mixed) {
|
||||
stared = 2;
|
||||
}
|
||||
else {
|
||||
stared = 0;
|
||||
}
|
||||
let nothingAfter;
|
||||
if (!hasNothingAfterNode(parentNode)) {
|
||||
nothingAfter = 0;
|
||||
}
|
||||
else if (usage === get_usage_of_pattern_1.UsageOfPattern.partial ||
|
||||
usage === get_usage_of_pattern_1.UsageOfPattern.mixed) {
|
||||
nothingAfter = 2;
|
||||
}
|
||||
else {
|
||||
nothingAfter = 1;
|
||||
}
|
||||
let reportExp;
|
||||
switch (reportExponentialBacktracking) {
|
||||
case "none":
|
||||
reportExp = false;
|
||||
break;
|
||||
case "certain":
|
||||
reportExp = stared === 1;
|
||||
break;
|
||||
case "potential":
|
||||
reportExp = stared !== 0;
|
||||
break;
|
||||
default:
|
||||
(0, util_1.assertNever)(reportExponentialBacktracking);
|
||||
}
|
||||
let reportPrefix;
|
||||
switch (reportUnreachable) {
|
||||
case "certain":
|
||||
reportPrefix = nothingAfter === 1;
|
||||
break;
|
||||
case "potential":
|
||||
reportPrefix = nothingAfter !== 0;
|
||||
break;
|
||||
default:
|
||||
(0, util_1.assertNever)(reportUnreachable);
|
||||
}
|
||||
return { stared, nothingAfter, reportExp, reportPrefix };
|
||||
}
|
||||
function verify(parentNode) {
|
||||
const info = getFilterInfo(parentNode);
|
||||
const rawResults = findDuplication(parentNode.alternatives, flags, {
|
||||
fastAst: false,
|
||||
noNfa: false,
|
||||
ignoreOverlap: !info.reportExp && report !== "all",
|
||||
hasNothingAfter: info.reportPrefix,
|
||||
parser,
|
||||
});
|
||||
let results = filterResults([...rawResults], info);
|
||||
results = deduplicateResults(results, info);
|
||||
results.forEach((result) => reportResult(result, info));
|
||||
}
|
||||
function filterResults(results, { nothingAfter, reportExp, reportPrefix }) {
|
||||
switch (report) {
|
||||
case "all": {
|
||||
return results;
|
||||
}
|
||||
case "trivial": {
|
||||
return results.filter(({ type }) => {
|
||||
switch (type) {
|
||||
case "Duplicate":
|
||||
case "Subset":
|
||||
case "NestedSubset":
|
||||
return true;
|
||||
case "Overlap":
|
||||
case "Superset":
|
||||
return reportExp;
|
||||
case "PrefixSubset":
|
||||
case "PrefixNestedSubset":
|
||||
return reportPrefix;
|
||||
default:
|
||||
throw (0, util_1.assertNever)(type);
|
||||
}
|
||||
});
|
||||
}
|
||||
case "interesting": {
|
||||
return results.filter(({ type }) => {
|
||||
switch (type) {
|
||||
case "Duplicate":
|
||||
case "Subset":
|
||||
case "NestedSubset":
|
||||
return true;
|
||||
case "Overlap":
|
||||
return reportExp;
|
||||
case "Superset":
|
||||
return (reportExp ||
|
||||
nothingAfter === 0);
|
||||
case "PrefixSubset":
|
||||
case "PrefixNestedSubset":
|
||||
return reportPrefix;
|
||||
default:
|
||||
throw (0, util_1.assertNever)(type);
|
||||
}
|
||||
});
|
||||
}
|
||||
default:
|
||||
throw (0, util_1.assertNever)(report);
|
||||
}
|
||||
}
|
||||
function printChar(char) {
|
||||
if ((0, char_ranges_1.inRange)(allowedRanges, char)) {
|
||||
return String.fromCodePoint(char);
|
||||
}
|
||||
if (char === 0)
|
||||
return "\\0";
|
||||
if (char <= 0xff)
|
||||
return `\\x${char.toString(16).padStart(2, "0")}`;
|
||||
if (char <= 0xffff)
|
||||
return `\\u${char.toString(16).padStart(4, "0")}`;
|
||||
return `\\u{${char.toString(16)}}`;
|
||||
}
|
||||
function getSuggestions(result) {
|
||||
if (result.type === "Overlap" || result.type === "Superset") {
|
||||
return [];
|
||||
}
|
||||
const alternative = result.type === "NestedSubset" ||
|
||||
result.type === "PrefixNestedSubset"
|
||||
? result.nested
|
||||
: result.alternative;
|
||||
const containsCapturingGroup = (0, regexp_ast_analysis_1.hasSomeDescendant)(alternative, (d) => d.type === "CapturingGroup");
|
||||
if (containsCapturingGroup) {
|
||||
return [];
|
||||
}
|
||||
if (alternative.type === "Character" &&
|
||||
alternative.parent.type === "CharacterClassRange") {
|
||||
const range = alternative.parent;
|
||||
let replacement;
|
||||
if (range.min.value + 1 === range.max.value) {
|
||||
replacement =
|
||||
range.min === alternative
|
||||
? range.max.raw
|
||||
: range.min.raw;
|
||||
}
|
||||
else {
|
||||
if (range.min === alternative) {
|
||||
const min = printChar(range.min.value + 1);
|
||||
replacement = `${min}-${range.max.raw}`;
|
||||
}
|
||||
else {
|
||||
const max = printChar(range.max.value - 1);
|
||||
replacement = `${range.min.raw}-${max}`;
|
||||
}
|
||||
}
|
||||
return [
|
||||
{
|
||||
messageId: "replaceRange",
|
||||
data: {
|
||||
range: (0, mention_1.mentionChar)(range),
|
||||
replacement: (0, mention_1.mention)(replacement),
|
||||
},
|
||||
fix: regexpContext.fixReplaceNode(range, replacement),
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
{
|
||||
messageId: "remove",
|
||||
data: {
|
||||
alternative: mentionNested(alternative),
|
||||
type: alternative.type === "Alternative"
|
||||
? "alternative"
|
||||
: "element",
|
||||
},
|
||||
fix: fixRemoveNestedAlternative(regexpContext, alternative),
|
||||
},
|
||||
];
|
||||
}
|
||||
function reportResult(result, { stared }) {
|
||||
let exp;
|
||||
if (stared === 1) {
|
||||
exp =
|
||||
" This ambiguity is likely to cause exponential backtracking.";
|
||||
}
|
||||
else if (stared === 2) {
|
||||
exp =
|
||||
" This ambiguity might cause exponential backtracking.";
|
||||
}
|
||||
else {
|
||||
exp = "";
|
||||
}
|
||||
const reportAlternative = result.type === "NestedSubset" ||
|
||||
result.type === "PrefixNestedSubset"
|
||||
? result.nested
|
||||
: result.alternative;
|
||||
const loc = getRegexpLocation(reportAlternative);
|
||||
const cap = (0, regexp_ast_analysis_1.hasSomeDescendant)(reportAlternative, (d) => d.type === "CapturingGroup")
|
||||
? " Careful! This alternative contains capturing groups which might be difficult to remove."
|
||||
: "";
|
||||
const others = (0, mention_1.mention)(result.others.map((a) => a.raw).join("|"));
|
||||
const suggest = getSuggestions(result);
|
||||
switch (result.type) {
|
||||
case "Duplicate":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "duplicate",
|
||||
data: { exp, cap, others },
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "Subset":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "subset",
|
||||
data: { exp, cap, others },
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "NestedSubset":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "nestedSubset",
|
||||
data: {
|
||||
exp,
|
||||
cap,
|
||||
others,
|
||||
root: (0, mention_1.mention)(result.alternative),
|
||||
nested: mentionNested(result.nested),
|
||||
},
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "PrefixSubset":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "prefixSubset",
|
||||
data: { exp, cap, others },
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "PrefixNestedSubset":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "prefixNestedSubset",
|
||||
data: {
|
||||
exp,
|
||||
cap,
|
||||
others,
|
||||
root: (0, mention_1.mention)(result.alternative),
|
||||
nested: mentionNested(result.nested),
|
||||
},
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "Superset":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "superset",
|
||||
data: { exp, cap, others },
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
case "Overlap":
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "overlap",
|
||||
data: {
|
||||
exp,
|
||||
cap,
|
||||
others,
|
||||
expr: (0, mention_1.mention)(faToSource(result.overlap, flags)),
|
||||
},
|
||||
suggest,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw (0, util_1.assertNever)(result);
|
||||
}
|
||||
}
|
||||
return {
|
||||
onPatternEnter: verify,
|
||||
onGroupEnter: verify,
|
||||
onCapturingGroupEnter: verify,
|
||||
onAssertionEnter(aNode) {
|
||||
if (aNode.kind === "lookahead" ||
|
||||
aNode.kind === "lookbehind") {
|
||||
verify(aNode);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-alternative.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-alternative.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
101
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-alternative.js
generated
vendored
Normal file
101
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-alternative.js
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
function getCapturingGroupOuterSource(node) {
|
||||
const first = node.alternatives[0];
|
||||
const last = node.alternatives[node.alternatives.length - 1];
|
||||
const innerStart = first.start - node.start;
|
||||
const innerEnd = last.end - node.start;
|
||||
return [node.raw.slice(0, innerStart), node.raw.slice(innerEnd)];
|
||||
}
|
||||
function getFixedNode(regexpNode, alt) {
|
||||
var _a;
|
||||
let quant;
|
||||
if (regexpNode.alternatives.at(0) === alt) {
|
||||
quant = "??";
|
||||
}
|
||||
else if (regexpNode.alternatives.at(-1) === alt) {
|
||||
quant = "?";
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
const innerAlternatives = regexpNode.alternatives
|
||||
.filter((a) => a !== alt)
|
||||
.map((a) => a.raw)
|
||||
.join("|");
|
||||
let replacement = `(?:${innerAlternatives})${quant}`;
|
||||
if (regexpNode.type === "CapturingGroup") {
|
||||
const [before, after] = getCapturingGroupOuterSource(regexpNode);
|
||||
replacement = `${before}${replacement}${after}`;
|
||||
}
|
||||
else if (((_a = regexpNode.parent) === null || _a === void 0 ? void 0 : _a.type) === "Quantifier") {
|
||||
replacement = `(?:${replacement})`;
|
||||
}
|
||||
return replacement;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-empty-alternative", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow alternatives without elements",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
default: "warn",
|
||||
},
|
||||
schema: [],
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
empty: "This empty alternative might be a mistake. If not, use a quantifier instead.",
|
||||
suggest: "Use a quantifier instead.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, getRegexpLocation, fixReplaceNode, }) {
|
||||
function verifyAlternatives(regexpNode, suggestFixer) {
|
||||
if (regexpNode.alternatives.length >= 2) {
|
||||
for (let i = 0; i < regexpNode.alternatives.length; i++) {
|
||||
const alt = regexpNode.alternatives[i];
|
||||
const isLast = i === regexpNode.alternatives.length - 1;
|
||||
if (alt.elements.length === 0) {
|
||||
const index = alt.start;
|
||||
const loc = isLast
|
||||
? getRegexpLocation({
|
||||
start: index - 1,
|
||||
end: index,
|
||||
})
|
||||
: getRegexpLocation({
|
||||
start: index,
|
||||
end: index + 1,
|
||||
});
|
||||
const fixed = suggestFixer(alt);
|
||||
context.report({
|
||||
node,
|
||||
loc,
|
||||
messageId: "empty",
|
||||
suggest: fixed
|
||||
? [
|
||||
{
|
||||
messageId: "suggest",
|
||||
fix: fixReplaceNode(regexpNode, fixed),
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
onGroupEnter: (gNode) => verifyAlternatives(gNode, (alt) => getFixedNode(gNode, alt)),
|
||||
onCapturingGroupEnter: (cgNode) => verifyAlternatives(cgNode, (alt) => getFixedNode(cgNode, alt)),
|
||||
onPatternEnter: (pNode) => verifyAlternatives(pNode, (alt) => getFixedNode(pNode, alt)),
|
||||
onClassStringDisjunctionEnter: (csdNode) => verifyAlternatives(csdNode, () => null),
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-capturing-group.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-capturing-group.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
36
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-capturing-group.js
generated
vendored
Normal file
36
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-capturing-group.js
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-empty-capturing-group", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow capturing group that captures empty.",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected capture empty.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
return {
|
||||
onCapturingGroupEnter(cgNode) {
|
||||
if ((0, regexp_ast_analysis_1.isZeroLength)(cgNode, flags)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cgNode),
|
||||
messageId: "unexpected",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-character-class.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-character-class.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
49
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-character-class.js
generated
vendored
Normal file
49
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-character-class.js
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-empty-character-class", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow character classes that match no characters",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
empty: "This character class matches no characters because it is empty.",
|
||||
cannotMatchAny: "This character class cannot match any characters.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, getRegexpLocation, flags } = regexpContext;
|
||||
return {
|
||||
onCharacterClassEnter(ccNode) {
|
||||
if ((0, regexp_ast_analysis_1.matchesNoCharacters)(ccNode, flags)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(ccNode),
|
||||
messageId: ccNode.elements.length
|
||||
? "cannotMatchAny"
|
||||
: "empty",
|
||||
});
|
||||
}
|
||||
},
|
||||
onExpressionCharacterClassEnter(ccNode) {
|
||||
if ((0, regexp_ast_analysis_1.matchesNoCharacters)(ccNode, flags)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(ccNode),
|
||||
messageId: "cannotMatchAny",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-group.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-group.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
41
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-group.js
generated
vendored
Normal file
41
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-group.js
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-empty-group", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow empty group",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected empty group.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function verifyGroup({ node, getRegexpLocation }, gNode) {
|
||||
if (gNode.alternatives.every((alt) => alt.elements.length === 0)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(gNode),
|
||||
messageId: "unexpected",
|
||||
});
|
||||
}
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
return {
|
||||
onGroupEnter(gNode) {
|
||||
verifyGroup(regexpContext, gNode);
|
||||
},
|
||||
onCapturingGroupEnter(cgNode) {
|
||||
verifyGroup(regexpContext, cgNode);
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-lookarounds-assertion.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-lookarounds-assertion.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
44
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-lookarounds-assertion.js
generated
vendored
Normal file
44
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-lookarounds-assertion.js
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-empty-lookarounds-assertion", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow empty lookahead assertion or empty lookbehind assertion",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected empty {{kind}}. It will trivially {{result}} all inputs.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
return {
|
||||
onAssertionEnter(aNode) {
|
||||
if (aNode.kind !== "lookahead" &&
|
||||
aNode.kind !== "lookbehind") {
|
||||
return;
|
||||
}
|
||||
if ((0, regexp_ast_analysis_1.isPotentiallyEmpty)(aNode.alternatives, flags)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(aNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
kind: aNode.kind,
|
||||
result: aNode.negate ? "reject" : "accept",
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-string-literal.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-string-literal.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
36
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-string-literal.js
generated
vendored
Normal file
36
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-empty-string-literal.js
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-empty-string-literal", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow empty string literals in character classes",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected empty string literal.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, getRegexpLocation } = regexpContext;
|
||||
return {
|
||||
onClassStringDisjunctionEnter(csdNode) {
|
||||
if (csdNode.alternatives.every((alt) => alt.elements.length === 0)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(csdNode),
|
||||
messageId: "unexpected",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-escape-backspace.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-escape-backspace.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
43
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-escape-backspace.js
generated
vendored
Normal file
43
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-escape-backspace.js
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-escape-backspace", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow escape backspace (`[\\b]`)",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
unexpected: "Unexpected '[\\b]'. Use '\\u0008' instead.",
|
||||
suggest: "Use '\\u0008'.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, getRegexpLocation, fixReplaceNode, }) {
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.value === utils_1.CP_BACKSPACE && cNode.raw === "\\b") {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
suggest: [
|
||||
{
|
||||
messageId: "suggest",
|
||||
fix: fixReplaceNode(cNode, "\\u0008"),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-extra-lookaround-assertions.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-extra-lookaround-assertions.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
70
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-extra-lookaround-assertions.js
generated
vendored
Normal file
70
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-extra-lookaround-assertions.js
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-extra-lookaround-assertions", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow unnecessary nested lookaround assertions",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
canBeInlined: "This {{kind}} assertion is useless and can be inlined.",
|
||||
canBeConvertedIntoGroup: "This {{kind}} assertion is useless and can be converted into a group.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor(regexpContext) {
|
||||
return {
|
||||
onAssertionEnter(aNode) {
|
||||
if (aNode.kind === "lookahead" ||
|
||||
aNode.kind === "lookbehind") {
|
||||
verify(regexpContext, aNode);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
function verify(regexpContext, assertion) {
|
||||
for (const alternative of assertion.alternatives) {
|
||||
const nested = alternative.elements.at(assertion.kind === "lookahead"
|
||||
?
|
||||
-1
|
||||
:
|
||||
0);
|
||||
if ((nested === null || nested === void 0 ? void 0 : nested.type) === "Assertion" &&
|
||||
nested.kind === assertion.kind &&
|
||||
!nested.negate) {
|
||||
reportLookaroundAssertion(regexpContext, nested);
|
||||
}
|
||||
}
|
||||
}
|
||||
function reportLookaroundAssertion({ node, getRegexpLocation, fixReplaceNode }, assertion) {
|
||||
let messageId, replaceText;
|
||||
if (assertion.alternatives.length === 1) {
|
||||
messageId = "canBeInlined";
|
||||
replaceText = assertion.alternatives[0].raw;
|
||||
}
|
||||
else {
|
||||
messageId = "canBeConvertedIntoGroup";
|
||||
replaceText = `(?:${assertion.alternatives
|
||||
.map((alt) => alt.raw)
|
||||
.join("|")})`;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(assertion),
|
||||
messageId,
|
||||
data: {
|
||||
kind: assertion.kind,
|
||||
},
|
||||
fix: fixReplaceNode(assertion, replaceText),
|
||||
});
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invalid-regexp.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invalid-regexp.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
71
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invalid-regexp.js
generated
vendored
Normal file
71
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invalid-regexp.js
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
function getErrorIndex(error) {
|
||||
const index = error.index;
|
||||
if (typeof index === "number") {
|
||||
return index;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-invalid-regexp", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow invalid regular expression strings in `RegExp` constructors",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
error: "{{message}}",
|
||||
duplicateFlag: "Duplicate {{flag}} flag.",
|
||||
uvFlag: "Regex 'u' and 'v' flags cannot be used together.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function visitInvalid(regexpContext) {
|
||||
const { node, error, patternSource } = regexpContext;
|
||||
let loc = undefined;
|
||||
const index = getErrorIndex(error);
|
||||
if (index !== null &&
|
||||
index >= 0 &&
|
||||
index <= patternSource.value.length) {
|
||||
loc = patternSource.getAstLocation({
|
||||
start: Math.max(index - 1, 0),
|
||||
end: Math.min(index + 1, patternSource.value.length),
|
||||
});
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: loc !== null && loc !== void 0 ? loc : undefined,
|
||||
messageId: "error",
|
||||
data: { message: error.message },
|
||||
});
|
||||
}
|
||||
function visitUnknown(regexpContext) {
|
||||
const { node, flags, flagsString, getFlagsLocation } = regexpContext;
|
||||
const flagSet = new Set();
|
||||
for (const flag of flagsString !== null && flagsString !== void 0 ? flagsString : "") {
|
||||
if (flagSet.has(flag)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getFlagsLocation(),
|
||||
messageId: "duplicateFlag",
|
||||
data: { flag },
|
||||
});
|
||||
return;
|
||||
}
|
||||
flagSet.add(flag);
|
||||
}
|
||||
if (flags.unicode && flags.unicodeSets) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getFlagsLocation(),
|
||||
messageId: "uvFlag",
|
||||
});
|
||||
}
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, { visitInvalid, visitUnknown });
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invisible-character.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invisible-character.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
84
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invisible-character.js
generated
vendored
Normal file
84
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-invisible-character.js
generated
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const refa_1 = require("../utils/refa");
|
||||
exports.default = (0, utils_1.createRule)("no-invisible-character", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow invisible raw character",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected invisible character. Use '{{instead}}' instead.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
function createLiteralVisitor({ node, flags, getRegexpLocation, fixReplaceNode, }) {
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.raw === " ") {
|
||||
return;
|
||||
}
|
||||
if (cNode.raw.length === 1 && (0, utils_1.isInvisible)(cNode.value)) {
|
||||
const instead = (0, refa_1.toCharSetSource)(cNode.value, flags);
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
instead,
|
||||
},
|
||||
fix: fixReplaceNode(cNode, instead),
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
function verifyString({ node, flags }) {
|
||||
const text = sourceCode.getText(node);
|
||||
let index = 0;
|
||||
for (const c of text) {
|
||||
if (c === " ") {
|
||||
continue;
|
||||
}
|
||||
const cp = c.codePointAt(0);
|
||||
if ((0, utils_1.isInvisible)(cp)) {
|
||||
const instead = (0, refa_1.toCharSetSource)(cp, flags);
|
||||
const range = [
|
||||
node.range[0] + index,
|
||||
node.range[0] + index + c.length,
|
||||
];
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: sourceCode.getLocFromIndex(range[0]),
|
||||
end: sourceCode.getLocFromIndex(range[1]),
|
||||
},
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
instead,
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(range, instead);
|
||||
},
|
||||
});
|
||||
}
|
||||
index += c.length;
|
||||
}
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createLiteralVisitor,
|
||||
createSourceVisitor(regexpContext) {
|
||||
if (regexpContext.node.type === "Literal") {
|
||||
verifyString(regexpContext);
|
||||
}
|
||||
return {};
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-lazy-ends.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-lazy-ends.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
139
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-lazy-ends.js
generated
vendored
Normal file
139
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-lazy-ends.js
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
|
||||
function* extractLazyEndQuantifiers(alternatives) {
|
||||
for (const { elements } of alternatives) {
|
||||
if (elements.length > 0) {
|
||||
const last = elements[elements.length - 1];
|
||||
switch (last.type) {
|
||||
case "Quantifier":
|
||||
if (!last.greedy && last.min !== last.max) {
|
||||
yield last;
|
||||
}
|
||||
else if (last.max === 1) {
|
||||
const element = last.element;
|
||||
if (element.type === "Group" ||
|
||||
element.type === "CapturingGroup") {
|
||||
yield* extractLazyEndQuantifiers(element.alternatives);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "CapturingGroup":
|
||||
case "Group":
|
||||
yield* extractLazyEndQuantifiers(last.alternatives);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-lazy-ends", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow lazy quantifiers at the end of an expression",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
default: "warn",
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignorePartial: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
uselessElement: "The quantifier and the quantified element can be removed because the quantifier is lazy and has a minimum of 0.",
|
||||
uselessQuantifier: "The quantifier can be removed because the quantifier is lazy and has a minimum of 1.",
|
||||
uselessRange: "The quantifier can be replaced with '{{{min}}}' because the quantifier is lazy and has a minimum of {{min}}.",
|
||||
suggestMakeGreedy: "Make the quantifier greedy. (This changes the behavior of the regex.)",
|
||||
suggestRemoveElement: "Remove the quantified element. (This does not changes the behavior of the regex.)",
|
||||
suggestRemoveQuantifier: "Remove the quantifier. (This does not changes the behavior of the regex.)",
|
||||
suggestRange: "Replace the quantifier with '{{{min}}}'. (This does not changes the behavior of the regex.)",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const ignorePartial = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.ignorePartial) !== null && _b !== void 0 ? _b : true;
|
||||
function createVisitor({ node, getRegexpLocation, getUsageOfPattern, fixReplaceNode, }) {
|
||||
if (ignorePartial) {
|
||||
const usageOfPattern = getUsageOfPattern();
|
||||
if (usageOfPattern !== get_usage_of_pattern_1.UsageOfPattern.whole) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {
|
||||
onPatternEnter(pNode) {
|
||||
for (const lazy of extractLazyEndQuantifiers(pNode.alternatives)) {
|
||||
const makeGreedy = {
|
||||
messageId: "suggestMakeGreedy",
|
||||
fix: fixReplaceNode(lazy, lazy.raw.slice(0, -1)),
|
||||
};
|
||||
if (lazy.min === 0) {
|
||||
const replacement = pNode.alternatives.length === 1 &&
|
||||
pNode.alternatives[0].elements.length === 1 &&
|
||||
pNode.alternatives[0].elements[0] === lazy
|
||||
? "(?:)"
|
||||
: "";
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(lazy),
|
||||
messageId: "uselessElement",
|
||||
suggest: [
|
||||
{
|
||||
messageId: "suggestRemoveElement",
|
||||
fix: fixReplaceNode(lazy, replacement),
|
||||
},
|
||||
makeGreedy,
|
||||
],
|
||||
});
|
||||
}
|
||||
else if (lazy.min === 1) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(lazy),
|
||||
messageId: "uselessQuantifier",
|
||||
suggest: [
|
||||
{
|
||||
messageId: "suggestRemoveQuantifier",
|
||||
fix: fixReplaceNode(lazy, lazy.element.raw),
|
||||
},
|
||||
makeGreedy,
|
||||
],
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(lazy),
|
||||
messageId: "uselessRange",
|
||||
data: {
|
||||
min: String(lazy.min),
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "suggestRange",
|
||||
data: {
|
||||
min: String(lazy.min),
|
||||
},
|
||||
fix: fixReplaceNode(lazy, `${lazy.element.raw}{${lazy.min}}`),
|
||||
},
|
||||
makeGreedy,
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-legacy-features.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-legacy-features.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
107
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-legacy-features.js
generated
vendored
Normal file
107
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-legacy-features.js
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const type_tracker_1 = require("../utils/type-tracker");
|
||||
const eslint_utils_1 = require("@eslint-community/eslint-utils");
|
||||
const STATIC_PROPERTIES = [
|
||||
"input",
|
||||
"$_",
|
||||
"lastMatch",
|
||||
"$&",
|
||||
"lastParen",
|
||||
"$+",
|
||||
"leftContext",
|
||||
"$`",
|
||||
"rightContext",
|
||||
"$'",
|
||||
"$1",
|
||||
"$2",
|
||||
"$3",
|
||||
"$4",
|
||||
"$5",
|
||||
"$6",
|
||||
"$7",
|
||||
"$8",
|
||||
"$9",
|
||||
];
|
||||
const PROTOTYPE_METHODS = ["compile"];
|
||||
exports.default = (0, utils_1.createRule)("no-legacy-features", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow legacy RegExp features",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
staticProperties: {
|
||||
type: "array",
|
||||
items: { enum: STATIC_PROPERTIES },
|
||||
uniqueItems: true,
|
||||
},
|
||||
prototypeMethods: {
|
||||
type: "array",
|
||||
items: { enum: PROTOTYPE_METHODS },
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
forbiddenStaticProperty: "'{{name}}' static property is forbidden.",
|
||||
forbiddenPrototypeMethods: "RegExp.prototype.{{name}} method is forbidden.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b, _c, _d;
|
||||
const staticProperties = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.staticProperties) !== null && _b !== void 0 ? _b : STATIC_PROPERTIES;
|
||||
const prototypeMethods = (_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.prototypeMethods) !== null && _d !== void 0 ? _d : PROTOTYPE_METHODS;
|
||||
const typeTracer = (0, type_tracker_1.createTypeTracker)(context);
|
||||
return {
|
||||
...(staticProperties.length
|
||||
? {
|
||||
Program(program) {
|
||||
const scope = context.sourceCode.getScope(program);
|
||||
const tracker = new eslint_utils_1.ReferenceTracker(scope);
|
||||
const regexpTraceMap = {};
|
||||
for (const sp of staticProperties) {
|
||||
regexpTraceMap[sp] = { [eslint_utils_1.READ]: true };
|
||||
}
|
||||
for (const { node, path, } of tracker.iterateGlobalReferences({
|
||||
RegExp: regexpTraceMap,
|
||||
})) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "forbiddenStaticProperty",
|
||||
data: { name: path.join(".") },
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(prototypeMethods.length
|
||||
? {
|
||||
MemberExpression(node) {
|
||||
if (node.computed ||
|
||||
node.property.type !== "Identifier" ||
|
||||
!prototypeMethods.includes(node.property.name) ||
|
||||
node.object.type === "Super") {
|
||||
return;
|
||||
}
|
||||
if (typeTracer.isRegExp(node.object)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "forbiddenPrototypeMethods",
|
||||
data: { name: node.property.name },
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-capturing-group.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-capturing-group.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
305
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-capturing-group.js
generated
vendored
Normal file
305
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-capturing-group.js
generated
vendored
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const refa_1 = require("refa");
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const fix_simplify_quantifier_1 = require("../utils/fix-simplify-quantifier");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const refa_2 = require("../utils/refa");
|
||||
const regexp_ast_1 = require("../utils/regexp-ast");
|
||||
const util_1 = require("../utils/util");
|
||||
function* getStartQuantifiers(root, direction, flags) {
|
||||
if (Array.isArray(root)) {
|
||||
for (const a of root) {
|
||||
yield* getStartQuantifiers(a, direction, flags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (root.type) {
|
||||
case "Character":
|
||||
case "CharacterClass":
|
||||
case "CharacterSet":
|
||||
case "ExpressionCharacterClass":
|
||||
case "Backreference":
|
||||
break;
|
||||
case "Assertion":
|
||||
break;
|
||||
case "Alternative": {
|
||||
const elements = direction === "ltr" ? root.elements : (0, util_1.reversed)(root.elements);
|
||||
for (const e of elements) {
|
||||
if ((0, regexp_ast_analysis_1.isEmpty)(e, flags))
|
||||
continue;
|
||||
yield* getStartQuantifiers(e, direction, flags);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CapturingGroup":
|
||||
break;
|
||||
case "Group":
|
||||
yield* getStartQuantifiers(root.alternatives, direction, flags);
|
||||
break;
|
||||
case "Quantifier":
|
||||
yield root;
|
||||
if (root.max === 1) {
|
||||
yield* getStartQuantifiers(root.element, direction, flags);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
yield (0, util_1.assertNever)(root);
|
||||
}
|
||||
}
|
||||
const getCache = (0, util_1.cachedFn)((_flags) => new WeakMap());
|
||||
function getSingleRepeatedChar(element, flags, cache = getCache(flags)) {
|
||||
let value = cache.get(element);
|
||||
if (value === undefined) {
|
||||
value = uncachedGetSingleRepeatedChar(element, flags, cache);
|
||||
cache.set(element, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function uncachedGetSingleRepeatedChar(element, flags, cache) {
|
||||
switch (element.type) {
|
||||
case "Alternative": {
|
||||
let total = undefined;
|
||||
for (const e of element.elements) {
|
||||
const c = getSingleRepeatedChar(e, flags, cache);
|
||||
if (total === undefined) {
|
||||
total = c;
|
||||
}
|
||||
else {
|
||||
total = total.intersect(c);
|
||||
}
|
||||
if (total.isEmpty)
|
||||
return total;
|
||||
}
|
||||
return total !== null && total !== void 0 ? total : regexp_ast_analysis_1.Chars.empty(flags);
|
||||
}
|
||||
case "Assertion":
|
||||
return regexp_ast_analysis_1.Chars.empty(flags);
|
||||
case "Backreference":
|
||||
return regexp_ast_analysis_1.Chars.empty(flags);
|
||||
case "Character":
|
||||
case "CharacterClass":
|
||||
case "CharacterSet":
|
||||
case "ExpressionCharacterClass": {
|
||||
const set = (0, regexp_ast_analysis_1.toUnicodeSet)(element, flags);
|
||||
if (set.accept.isEmpty) {
|
||||
return set.chars;
|
||||
}
|
||||
return set.wordSets
|
||||
.map((wordSet) => {
|
||||
let total = undefined;
|
||||
for (const c of wordSet) {
|
||||
if (total === undefined) {
|
||||
total = c;
|
||||
}
|
||||
else {
|
||||
total = total.intersect(c);
|
||||
}
|
||||
if (total.isEmpty)
|
||||
return total;
|
||||
}
|
||||
return total !== null && total !== void 0 ? total : regexp_ast_analysis_1.Chars.empty(flags);
|
||||
})
|
||||
.reduce((a, b) => a.union(b));
|
||||
}
|
||||
case "CapturingGroup":
|
||||
case "Group":
|
||||
return element.alternatives
|
||||
.map((a) => getSingleRepeatedChar(a, flags, cache))
|
||||
.reduce((a, b) => a.union(b));
|
||||
case "Quantifier":
|
||||
if (element.max === 0)
|
||||
return regexp_ast_analysis_1.Chars.empty(flags);
|
||||
return getSingleRepeatedChar(element.element, flags, cache);
|
||||
default:
|
||||
return (0, util_1.assertNever)(element);
|
||||
}
|
||||
}
|
||||
function getTradingQuantifiersAfter(start, startChar, direction, flags) {
|
||||
const results = [];
|
||||
(0, regexp_ast_analysis_1.followPaths)(start, "next", startChar, {
|
||||
join(states) {
|
||||
return refa_1.CharSet.empty(startChar.maximum).union(...states);
|
||||
},
|
||||
continueAfter(_, state) {
|
||||
return !state.isEmpty;
|
||||
},
|
||||
continueInto(element, state) {
|
||||
return element.type !== "Assertion" && !state.isEmpty;
|
||||
},
|
||||
leave(element, state) {
|
||||
switch (element.type) {
|
||||
case "Assertion":
|
||||
case "Backreference":
|
||||
case "Character":
|
||||
case "CharacterClass":
|
||||
case "CharacterSet":
|
||||
case "ExpressionCharacterClass":
|
||||
return state.intersect(getSingleRepeatedChar(element, flags));
|
||||
case "CapturingGroup":
|
||||
case "Group":
|
||||
case "Quantifier":
|
||||
return state;
|
||||
default:
|
||||
return (0, util_1.assertNever)(element);
|
||||
}
|
||||
},
|
||||
enter(element, state) {
|
||||
if (element.type === "Quantifier" &&
|
||||
element.min !== element.max) {
|
||||
const qChar = getSingleRepeatedChar(element, flags);
|
||||
const intersection = qChar.intersect(state);
|
||||
if (!intersection.isEmpty) {
|
||||
results.push({
|
||||
quant: element,
|
||||
quantRepeatedChar: qChar,
|
||||
intersection,
|
||||
});
|
||||
}
|
||||
}
|
||||
return state;
|
||||
},
|
||||
}, direction);
|
||||
return results;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-misleading-capturing-group", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow capturing groups that do not behave as one would expect",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
reportBacktrackingEnds: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
removeQuant: "{{quant}} can be removed because it is already included by {{cause}}." +
|
||||
" This makes the capturing group misleading, because it actually captures less text than its pattern suggests.",
|
||||
replaceQuant: "{{quant}} can be replaced with {{fix}} because of {{cause}}." +
|
||||
" This makes the capturing group misleading, because it actually captures less text than its pattern suggests.",
|
||||
suggestionRemove: "Remove {{quant}}.",
|
||||
suggestionReplace: "Replace {{quant}} with {{fix}}.",
|
||||
nonAtomic: "The quantifier {{quant}} is not atomic for the characters {{chars}}, so it might capture fewer characters than expected. This makes the capturing group misleading, because the quantifier will capture fewer characters than its pattern suggests in some edge cases.",
|
||||
suggestionNonAtomic: "Make the quantifier atomic by adding {{fix}}. Careful! This is going to change the behavior of the regex in some edge cases.",
|
||||
trading: "The quantifier {{quant}} can exchange characters ({{chars}}) with {{other}}. This makes the capturing group misleading, because the quantifier will capture fewer characters than its pattern suggests.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const reportBacktrackingEnds = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.reportBacktrackingEnds) !== null && _b !== void 0 ? _b : true;
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, flags, getRegexpLocation } = regexpContext;
|
||||
const parser = (0, refa_2.getParser)(regexpContext);
|
||||
function reportStartQuantifiers(capturingGroup) {
|
||||
const direction = (0, regexp_ast_analysis_1.getMatchingDirection)(capturingGroup);
|
||||
const startQuantifiers = getStartQuantifiers(capturingGroup.alternatives, direction, flags);
|
||||
for (const quantifier of startQuantifiers) {
|
||||
const result = (0, regexp_ast_1.canSimplifyQuantifier)(quantifier, flags, parser);
|
||||
if (!result.canSimplify)
|
||||
return;
|
||||
const cause = (0, mention_1.joinEnglishList)(result.dependencies.map((d) => (0, mention_1.mention)(d)));
|
||||
const [replacement, fix] = (0, fix_simplify_quantifier_1.fixSimplifyQuantifier)(quantifier, result, regexpContext);
|
||||
if (quantifier.min === 0) {
|
||||
const removesCapturingGroup = (0, regexp_ast_1.hasCapturingGroup)(quantifier);
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(quantifier),
|
||||
messageId: "removeQuant",
|
||||
data: {
|
||||
quant: (0, mention_1.mention)(quantifier),
|
||||
cause,
|
||||
},
|
||||
suggest: removesCapturingGroup
|
||||
? undefined
|
||||
: [
|
||||
{
|
||||
messageId: "suggestionRemove",
|
||||
data: {
|
||||
quant: (0, mention_1.mention)(quantifier),
|
||||
},
|
||||
fix,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(quantifier),
|
||||
messageId: "replaceQuant",
|
||||
data: {
|
||||
quant: (0, mention_1.mention)(quantifier),
|
||||
fix: (0, mention_1.mention)(replacement),
|
||||
cause,
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "suggestionReplace",
|
||||
data: {
|
||||
quant: (0, mention_1.mention)(quantifier),
|
||||
fix: (0, mention_1.mention)(replacement),
|
||||
},
|
||||
fix,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function reportTradingEndQuantifiers(capturingGroup) {
|
||||
const direction = (0, regexp_ast_analysis_1.getMatchingDirection)(capturingGroup);
|
||||
const endQuantifiers = getStartQuantifiers(capturingGroup.alternatives, (0, regexp_ast_analysis_1.invertMatchingDirection)(direction), flags);
|
||||
for (const quantifier of endQuantifiers) {
|
||||
if (!quantifier.greedy) {
|
||||
continue;
|
||||
}
|
||||
if (quantifier.min === quantifier.max) {
|
||||
continue;
|
||||
}
|
||||
const qChar = getSingleRepeatedChar(quantifier, flags);
|
||||
if (qChar.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
for (const trader of getTradingQuantifiersAfter(quantifier, qChar, direction, flags)) {
|
||||
if ((0, regexp_ast_analysis_1.hasSomeDescendant)(capturingGroup, trader.quant)) {
|
||||
continue;
|
||||
}
|
||||
if (trader.quant.min >= 1 &&
|
||||
!(0, regexp_ast_analysis_1.isPotentiallyZeroLength)(trader.quant.element, flags))
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(quantifier),
|
||||
messageId: "trading",
|
||||
data: {
|
||||
quant: (0, mention_1.mention)(quantifier),
|
||||
other: (0, mention_1.mention)(trader.quant),
|
||||
chars: (0, refa_2.toCharSetSource)(trader.intersection, flags),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
onCapturingGroupLeave(capturingGroup) {
|
||||
reportStartQuantifiers(capturingGroup);
|
||||
if (reportBacktrackingEnds) {
|
||||
reportTradingEndQuantifiers(capturingGroup);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
209
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.js
generated
vendored
Normal file
209
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.js
generated
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
const segmenter = new Intl.Segmenter();
|
||||
function startsWithSurrogate(s) {
|
||||
if (s.length < 2) {
|
||||
return false;
|
||||
}
|
||||
const h = s.charCodeAt(0);
|
||||
const l = s.charCodeAt(1);
|
||||
return h >= 0xd800 && h <= 0xdbff && l >= 0xdc00 && l <= 0xdfff;
|
||||
}
|
||||
function getProblem(grapheme, flags) {
|
||||
if (grapheme.length > 2 ||
|
||||
(grapheme.length === 2 && !startsWithSurrogate(grapheme))) {
|
||||
return "Multi";
|
||||
}
|
||||
else if (!flags.unicode &&
|
||||
!flags.unicodeSets &&
|
||||
startsWithSurrogate(grapheme)) {
|
||||
return "Surrogate";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getGraphemeBeforeQuant(quant) {
|
||||
const alt = quant.parent;
|
||||
let start = quant.start;
|
||||
for (let i = alt.elements.indexOf(quant) - 1; i >= 0; i--) {
|
||||
const e = alt.elements[i];
|
||||
if (e.type === "Character" && !(0, regex_syntax_1.isEscapeSequence)(e.raw)) {
|
||||
start = e.start;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const before = alt.raw.slice(start - alt.start, quant.element.end - alt.start);
|
||||
const segments = [...segmenter.segment(before)];
|
||||
const segment = segments[segments.length - 1];
|
||||
return segment.segment;
|
||||
}
|
||||
function getGraphemeProblems(cc, flags) {
|
||||
const offset = cc.negate ? 2 : 1;
|
||||
const ignoreElements = cc.elements.filter((element) => element.type === "CharacterClass" ||
|
||||
element.type === "ExpressionCharacterClass" ||
|
||||
element.type === "ClassStringDisjunction");
|
||||
const problems = [];
|
||||
for (const { segment, index } of segmenter.segment(cc.raw.slice(offset, -1))) {
|
||||
const problem = getProblem(segment, flags);
|
||||
if (problem !== null) {
|
||||
const start = offset + index + cc.start;
|
||||
const end = start + segment.length;
|
||||
if (ignoreElements.some((ignore) => ignore.start <= start && end <= ignore.end)) {
|
||||
continue;
|
||||
}
|
||||
problems.push({
|
||||
grapheme: segment,
|
||||
problem,
|
||||
start,
|
||||
end,
|
||||
elements: cc.elements.filter((e) => e.start < end && e.end > start),
|
||||
});
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
function getGraphemeProblemsFix(problems, cc, flags) {
|
||||
if (cc.negate) {
|
||||
return null;
|
||||
}
|
||||
if (!problems.every((p) => p.start === p.elements[0].start &&
|
||||
p.end === p.elements[p.elements.length - 1].end)) {
|
||||
return null;
|
||||
}
|
||||
const prefixGraphemes = problems.map((p) => p.grapheme);
|
||||
let ccRaw = cc.raw;
|
||||
for (let i = problems.length - 1; i >= 0; i--) {
|
||||
const { start, end } = problems[i];
|
||||
ccRaw = ccRaw.slice(0, start - cc.start) + ccRaw.slice(end - cc.start);
|
||||
}
|
||||
if (flags.unicodeSets) {
|
||||
const prefix = prefixGraphemes.join("|");
|
||||
return `[\\q{${prefix}}${ccRaw.slice(1, -1)}]`;
|
||||
}
|
||||
if (ccRaw.startsWith("[^")) {
|
||||
ccRaw = `[\\${ccRaw.slice(1)}`;
|
||||
}
|
||||
const prefix = prefixGraphemes.sort((a, b) => b.length - a.length).join("|");
|
||||
let fix = prefix;
|
||||
let singleAlternative = problems.length === 1;
|
||||
if (ccRaw !== "[]") {
|
||||
fix += `|${ccRaw}`;
|
||||
singleAlternative = false;
|
||||
}
|
||||
if (singleAlternative && cc.parent.type === "Alternative") {
|
||||
return fix;
|
||||
}
|
||||
if (cc.parent.type === "Alternative" && cc.parent.elements.length === 1) {
|
||||
return fix;
|
||||
}
|
||||
return `(?:${fix})`;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-misleading-unicode-character", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow multi-code-point characters in character classes and quantifiers",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
fixable: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
fixable: "code",
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
characterClass: "The character(s) {{ graphemes }} are all represented using multiple {{ unit }}.{{ uFlag }}",
|
||||
quantifierMulti: "The character {{ grapheme }} is represented using multiple Unicode code points. The quantifier only applies to the last code point {{ last }} and not to the whole character.",
|
||||
quantifierSurrogate: "The character {{ grapheme }} is represented using a surrogate pair. The quantifier only applies to the tailing surrogate {{ last }} and not to the whole character.",
|
||||
fixCharacterClass: "Move the character(s) {{ graphemes }} outside the character class.",
|
||||
fixQuantifier: "Wrap a group around {{ grapheme }}.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const fixable = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.fixable) !== null && _b !== void 0 ? _b : false;
|
||||
function makeFix(fix, messageId, data) {
|
||||
if (fixable) {
|
||||
return { fix };
|
||||
}
|
||||
return {
|
||||
suggest: [{ messageId, data, fix }],
|
||||
};
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, patternSource, flags, getRegexpLocation, fixReplaceNode, } = regexpContext;
|
||||
return {
|
||||
onCharacterClassEnter(ccNode) {
|
||||
const problems = getGraphemeProblems(ccNode, flags);
|
||||
if (problems.length === 0) {
|
||||
return;
|
||||
}
|
||||
const range = {
|
||||
start: problems[0].start,
|
||||
end: problems[problems.length - 1].end,
|
||||
};
|
||||
const fix = getGraphemeProblemsFix(problems, ccNode, flags);
|
||||
const graphemes = problems
|
||||
.map((p) => (0, mention_1.mention)(p.grapheme))
|
||||
.join(", ");
|
||||
const uFlag = problems.every((p) => p.problem === "Surrogate");
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(range),
|
||||
messageId: "characterClass",
|
||||
data: {
|
||||
graphemes,
|
||||
unit: flags.unicode || flags.unicodeSets
|
||||
? "code points"
|
||||
: "char codes",
|
||||
uFlag: uFlag ? " Use the `u` flag." : "",
|
||||
},
|
||||
...makeFix(fixReplaceNode(ccNode, () => fix), "fixCharacterClass", { graphemes }),
|
||||
});
|
||||
},
|
||||
onQuantifierEnter(qNode) {
|
||||
if (qNode.element.type !== "Character") {
|
||||
return;
|
||||
}
|
||||
const grapheme = getGraphemeBeforeQuant(qNode);
|
||||
const problem = getProblem(grapheme, flags);
|
||||
if (problem === null) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(qNode),
|
||||
messageId: `quantifier${problem}`,
|
||||
data: {
|
||||
grapheme: (0, mention_1.mention)(grapheme),
|
||||
last: (0, mention_1.mentionChar)(qNode.element),
|
||||
},
|
||||
...makeFix((fixer) => {
|
||||
const range = patternSource.getReplaceRange({
|
||||
start: qNode.element.end - grapheme.length,
|
||||
end: qNode.element.end,
|
||||
});
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
return range.replace(fixer, `(?:${grapheme})`);
|
||||
}, "fixQuantifier", { grapheme: (0, mention_1.mention)(grapheme) }),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-missing-g-flag.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-missing-g-flag.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
97
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-missing-g-flag.js
generated
vendored
Normal file
97
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-missing-g-flag.js
generated
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const ast_utils_1 = require("../utils/ast-utils");
|
||||
const type_tracker_1 = require("../utils/type-tracker");
|
||||
function parseOption(userOption) {
|
||||
let strictTypes = true;
|
||||
if (userOption) {
|
||||
if (userOption.strictTypes != null) {
|
||||
strictTypes = userOption.strictTypes;
|
||||
}
|
||||
}
|
||||
return {
|
||||
strictTypes,
|
||||
};
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-missing-g-flag", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow missing `g` flag in patterns used in `String#matchAll` and `String#replaceAll`",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
strictTypes: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
missingGlobalFlag: "The pattern given to the argument of `String#{{method}}()` requires the `g` flag, but is missing it.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
const { strictTypes } = parseOption(context.options[0]);
|
||||
const typeTracer = (0, type_tracker_1.createTypeTracker)(context);
|
||||
function visit(regexpContext) {
|
||||
const { regexpNode, flags, flagsString } = regexpContext;
|
||||
if (flags.global ||
|
||||
flagsString == null) {
|
||||
return;
|
||||
}
|
||||
for (const ref of (0, ast_utils_1.extractExpressionReferences)(regexpNode, context)) {
|
||||
verifyExpressionReference(ref, regexpContext);
|
||||
}
|
||||
}
|
||||
function verifyExpressionReference(ref, { regexpNode, fixReplaceFlags, flagsString, }) {
|
||||
if (ref.type !== "argument") {
|
||||
return;
|
||||
}
|
||||
const node = ref.callExpression;
|
||||
if (node.arguments[0] !== ref.node ||
|
||||
!(0, ast_utils_1.isKnownMethodCall)(node, {
|
||||
matchAll: 1,
|
||||
replaceAll: 2,
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
if (strictTypes
|
||||
? !typeTracer.isString(node.callee.object)
|
||||
: !typeTracer.maybeString(node.callee.object)) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node: ref.node,
|
||||
messageId: "missingGlobalFlag",
|
||||
data: {
|
||||
method: node.callee.property.name,
|
||||
},
|
||||
fix: buildFixer(),
|
||||
});
|
||||
function buildFixer() {
|
||||
if (node.arguments[0] !== regexpNode ||
|
||||
((regexpNode.type === "NewExpression" ||
|
||||
regexpNode.type === "CallExpression") &&
|
||||
regexpNode.arguments[1] &&
|
||||
regexpNode.arguments[1].type !== "Literal")) {
|
||||
return null;
|
||||
}
|
||||
return fixReplaceFlags(`${flagsString}g`, false);
|
||||
}
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor(regexpContext) {
|
||||
visit(regexpContext);
|
||||
return {};
|
||||
},
|
||||
visitInvalid: visit,
|
||||
visitUnknown: visit,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-non-standard-flag.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-non-standard-flag.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
41
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-non-standard-flag.js
generated
vendored
Normal file
41
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-non-standard-flag.js
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const STANDARD_FLAGS = "dgimsuvy";
|
||||
exports.default = (0, utils_1.createRule)("no-non-standard-flag", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow non-standard flags",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected non-standard flag '{{flag}}'.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function visit({ regexpNode, getFlagsLocation, flagsString, }) {
|
||||
if (flagsString) {
|
||||
const nonStandard = [...flagsString].filter((f) => !STANDARD_FLAGS.includes(f));
|
||||
if (nonStandard.length > 0) {
|
||||
context.report({
|
||||
node: regexpNode,
|
||||
loc: getFlagsLocation(),
|
||||
messageId: "unexpected",
|
||||
data: { flag: nonStandard[0] },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor(regexpContext) {
|
||||
visit(regexpContext);
|
||||
return {};
|
||||
},
|
||||
visitInvalid: visit,
|
||||
visitUnknown: visit,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-obscure-range.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-obscure-range.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
68
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-obscure-range.js
generated
vendored
Normal file
68
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-obscure-range.js
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const char_ranges_1 = require("../utils/char-ranges");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
exports.default = (0, utils_1.createRule)("no-obscure-range", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow obscure character ranges",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
allowed: (0, char_ranges_1.getAllowedCharValueSchema)(),
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpected: "Unexpected obscure character range. The characters of {{range}} are not obvious.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
var _a;
|
||||
const allowedRanges = (0, char_ranges_1.getAllowedCharRanges)((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allowed, context);
|
||||
function createVisitor({ node, getRegexpLocation, }) {
|
||||
return {
|
||||
onCharacterClassRangeEnter(rNode) {
|
||||
const { min, max } = rNode;
|
||||
if (min.value === max.value) {
|
||||
return;
|
||||
}
|
||||
if ((0, regex_syntax_1.isControlEscape)(min.raw) && (0, regex_syntax_1.isControlEscape)(max.raw)) {
|
||||
return;
|
||||
}
|
||||
if ((0, regex_syntax_1.isOctalEscape)(min.raw) && (0, regex_syntax_1.isOctalEscape)(max.raw)) {
|
||||
return;
|
||||
}
|
||||
if (((0, regex_syntax_1.isHexLikeEscape)(min.raw) || min.value === 0) &&
|
||||
(0, regex_syntax_1.isHexLikeEscape)(max.raw)) {
|
||||
return;
|
||||
}
|
||||
if (!(0, regex_syntax_1.isEscapeSequence)(min.raw) &&
|
||||
!(0, regex_syntax_1.isEscapeSequence)(max.raw) &&
|
||||
(0, char_ranges_1.inRange)(allowedRanges, min.value, max.value)) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(rNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
range: (0, mention_1.mentionChar)(rNode),
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-octal.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-octal.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
60
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-octal.js
generated
vendored
Normal file
60
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-octal.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
exports.default = (0, utils_1.createRule)("no-octal", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow octal escape sequence",
|
||||
category: "Best Practices",
|
||||
recommended: false,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected octal escape sequence '{{expr}}'.",
|
||||
replaceHex: "Replace the octal escape sequence with a hexadecimal escape sequence.",
|
||||
},
|
||||
type: "suggestion",
|
||||
hasSuggestions: true,
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, fixReplaceNode, getRegexpLocation, }) {
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.raw === "\\0") {
|
||||
return;
|
||||
}
|
||||
if (!(0, regex_syntax_1.isOctalEscape)(cNode.raw)) {
|
||||
return;
|
||||
}
|
||||
const report = cNode.raw.startsWith("\\0") ||
|
||||
!(cNode.parent.type === "CharacterClass" ||
|
||||
cNode.parent.type === "CharacterClassRange");
|
||||
if (report) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
data: {
|
||||
expr: cNode.raw,
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: "replaceHex",
|
||||
fix: fixReplaceNode(cNode, () => {
|
||||
return `\\x${cNode.value
|
||||
.toString(16)
|
||||
.padStart(2, "0")}`;
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-optional-assertion.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-optional-assertion.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
81
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-optional-assertion.js
generated
vendored
Normal file
81
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-optional-assertion.js
generated
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
function isZeroQuantifier(node) {
|
||||
return node.min === 0;
|
||||
}
|
||||
function isOptional(assertion, quantifier, flags) {
|
||||
let element = assertion;
|
||||
while (element.parent !== quantifier) {
|
||||
const parent = element.parent;
|
||||
if (parent.type === "Alternative") {
|
||||
for (const e of parent.elements) {
|
||||
if (e === element) {
|
||||
continue;
|
||||
}
|
||||
if (!(0, regexp_ast_analysis_1.isZeroLength)(e, flags)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (parent.parent.type === "Pattern") {
|
||||
throw new Error("The given assertion is not a descendant of the given quantifier.");
|
||||
}
|
||||
element = parent.parent;
|
||||
}
|
||||
else {
|
||||
if (parent.max > 1 && !(0, regexp_ast_analysis_1.isZeroLength)(parent, flags)) {
|
||||
return false;
|
||||
}
|
||||
element = parent;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-optional-assertion", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow optional assertions",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
optionalAssertion: "This assertion effectively optional and does not change the pattern. Either remove the assertion or change the parent quantifier '{{quantifier}}'.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
const zeroQuantifierStack = [];
|
||||
return {
|
||||
onQuantifierEnter(q) {
|
||||
if (isZeroQuantifier(q)) {
|
||||
zeroQuantifierStack.unshift(q);
|
||||
}
|
||||
},
|
||||
onQuantifierLeave(q) {
|
||||
if (zeroQuantifierStack[0] === q) {
|
||||
zeroQuantifierStack.shift();
|
||||
}
|
||||
},
|
||||
onAssertionEnter(assertion) {
|
||||
const q = zeroQuantifierStack[0];
|
||||
if (q && isOptional(assertion, q, flags)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(assertion),
|
||||
messageId: "optionalAssertion",
|
||||
data: {
|
||||
quantifier: q.raw.substr(q.element.raw.length),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-potentially-useless-backreference.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-potentially-useless-backreference.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-potentially-useless-backreference.js
generated
vendored
Normal file
40
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-potentially-useless-backreference.js
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-potentially-useless-backreference", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow backreferences that reference a group that might not be matched",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
default: "warn",
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
potentiallyUselessBackreference: "Some paths leading to the backreference do not go through the referenced capturing group or the captured text might be reset before reaching the backreference.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
return {
|
||||
onBackreferenceEnter(backreference) {
|
||||
if ((0, regexp_ast_analysis_1.isEmptyBackreference)(backreference, flags)) {
|
||||
return;
|
||||
}
|
||||
if (!(0, regexp_ast_analysis_1.isStrictBackreference)(backreference)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(backreference),
|
||||
messageId: "potentiallyUselessBackreference",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-standalone-backslash.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-standalone-backslash.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
35
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-standalone-backslash.js
generated
vendored
Normal file
35
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-standalone-backslash.js
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
exports.default = (0, utils_1.createRule)("no-standalone-backslash", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow standalone backslashes (`\\`)",
|
||||
category: "Best Practices",
|
||||
recommended: false,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected standalone backslash (`\\`). It looks like an escape sequence, but it's a single `\\` character pattern.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, getRegexpLocation, }) {
|
||||
return {
|
||||
onCharacterEnter(cNode) {
|
||||
if (cNode.value === utils_1.CP_BACK_SLASH && cNode.raw === "\\") {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cNode),
|
||||
messageId: "unexpected",
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-backtracking.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-backtracking.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
105
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-backtracking.js
generated
vendored
Normal file
105
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-backtracking.js
generated
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const scslre_1 = require("scslre");
|
||||
const utils_1 = require("../utils");
|
||||
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const refa_1 = require("../utils/refa");
|
||||
function unionLocations(a, b) {
|
||||
function less(x, y) {
|
||||
if (x.line < y.line) {
|
||||
return true;
|
||||
}
|
||||
else if (x.line > y.line) {
|
||||
return false;
|
||||
}
|
||||
return x.column < y.column;
|
||||
}
|
||||
return {
|
||||
start: { ...(less(a.start, b.start) ? a.start : b.start) },
|
||||
end: { ...(less(a.end, b.end) ? b.end : a.end) },
|
||||
};
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-super-linear-backtracking", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow exponential and polynomial backtracking",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
report: {
|
||||
enum: ["certain", "potential"],
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
self: "This quantifier can reach itself via the loop {{parent}}." +
|
||||
" Using any string accepted by {{attack}}, this can be exploited to cause at least polynomial backtracking." +
|
||||
"{{exp}}",
|
||||
trade: "The quantifier {{start}} can exchange characters with {{end}}." +
|
||||
" Using any string accepted by {{attack}}, this can be exploited to cause at least polynomial backtracking." +
|
||||
"{{exp}}",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const reportUncertain = ((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.report) !== null && _b !== void 0 ? _b : "certain") ===
|
||||
"potential";
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, patternAst, flags, getRegexpLocation, fixReplaceNode, getUsageOfPattern, } = regexpContext;
|
||||
const result = (0, scslre_1.analyse)((0, refa_1.getJSRegexppAst)(regexpContext), {
|
||||
reportTypes: { Move: false },
|
||||
assumeRejectingSuffix: reportUncertain &&
|
||||
getUsageOfPattern() !== get_usage_of_pattern_1.UsageOfPattern.whole,
|
||||
});
|
||||
for (const report of result.reports) {
|
||||
const exp = report.exponential
|
||||
? " This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior."
|
||||
: getUsageOfPattern() !== get_usage_of_pattern_1.UsageOfPattern.whole
|
||||
? " This might cause exponential backtracking."
|
||||
: "";
|
||||
const attack = `/${report.character.literal.source}+/${flags.ignoreCase ? "i" : ""}`;
|
||||
const fix = fixReplaceNode(patternAst, () => { var _a, _b; return (_b = (_a = report.fix()) === null || _a === void 0 ? void 0 : _a.source) !== null && _b !== void 0 ? _b : null; });
|
||||
if (report.type === "Self") {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(report.quant),
|
||||
messageId: "self",
|
||||
data: {
|
||||
exp,
|
||||
attack,
|
||||
parent: (0, mention_1.mention)(report.parentQuant),
|
||||
},
|
||||
fix,
|
||||
});
|
||||
}
|
||||
else if (report.type === "Trade") {
|
||||
context.report({
|
||||
node,
|
||||
loc: unionLocations(getRegexpLocation(report.startQuant), getRegexpLocation(report.endQuant)),
|
||||
messageId: "trade",
|
||||
data: {
|
||||
exp,
|
||||
attack,
|
||||
start: (0, mention_1.mention)(report.startQuant),
|
||||
end: (0, mention_1.mention)(report.endQuant),
|
||||
},
|
||||
fix,
|
||||
});
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-move.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-move.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
194
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-move.js
generated
vendored
Normal file
194
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-super-linear-move.js
generated
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const refa_1 = require("refa");
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const scslre_1 = require("scslre");
|
||||
const utils_1 = require("../utils");
|
||||
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
|
||||
const refa_2 = require("../utils/refa");
|
||||
function dedupeReports(reports) {
|
||||
const seen = new Set();
|
||||
const result = [];
|
||||
for (const r of reports) {
|
||||
if (!seen.has(r.quant)) {
|
||||
result.push(r);
|
||||
seen.add(r.quant);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function* findReachableQuantifiers(node, flags) {
|
||||
switch (node.type) {
|
||||
case "CapturingGroup":
|
||||
case "Group":
|
||||
case "Pattern": {
|
||||
for (const a of node.alternatives) {
|
||||
yield* findReachableQuantifiers(a, flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Assertion": {
|
||||
if (node.kind === "lookahead" || node.kind === "lookbehind") {
|
||||
for (const a of node.alternatives) {
|
||||
yield* findReachableQuantifiers(a, flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Quantifier": {
|
||||
yield node;
|
||||
break;
|
||||
}
|
||||
case "Alternative": {
|
||||
const dir = (0, regexp_ast_analysis_1.getMatchingDirection)(node);
|
||||
for (let i = 0; i < node.elements.length; i++) {
|
||||
const elementIndex = dir === "ltr" ? i : node.elements.length - 1 - i;
|
||||
const element = node.elements[elementIndex];
|
||||
yield* findReachableQuantifiers(element, flags);
|
||||
if (!(0, regexp_ast_analysis_1.isPotentiallyEmpty)(element, flags)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
const TRANSFORMER_OPTIONS = {
|
||||
ignoreAmbiguity: true,
|
||||
ignoreOrder: true,
|
||||
};
|
||||
const PASS_1 = refa_1.Transformers.simplify(TRANSFORMER_OPTIONS);
|
||||
const PASS_2 = new refa_1.CombinedTransformer([
|
||||
refa_1.Transformers.inline(TRANSFORMER_OPTIONS),
|
||||
refa_1.Transformers.removeDeadBranches(TRANSFORMER_OPTIONS),
|
||||
refa_1.Transformers.replaceAssertions({
|
||||
...TRANSFORMER_OPTIONS,
|
||||
replacement: "empty-set",
|
||||
}),
|
||||
]);
|
||||
exports.default = (0, utils_1.createRule)("no-super-linear-move", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow quantifiers that cause quadratic moves",
|
||||
category: "Possible Errors",
|
||||
recommended: false,
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
report: {
|
||||
enum: ["certain", "potential"],
|
||||
},
|
||||
ignoreSticky: {
|
||||
type: "boolean",
|
||||
},
|
||||
ignorePartial: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpected: "Any attack string {{attack}} plus some rejecting suffix will cause quadratic runtime because of this quantifier.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const reportUncertain = ((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.report) !== null && _b !== void 0 ? _b : "certain") ===
|
||||
"potential";
|
||||
const ignoreSticky = (_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.ignoreSticky) !== null && _d !== void 0 ? _d : true;
|
||||
const ignorePartial = (_f = (_e = context.options[0]) === null || _e === void 0 ? void 0 : _e.ignorePartial) !== null && _f !== void 0 ? _f : true;
|
||||
function getScslreReports(regexpContext, assumeRejectingSuffix) {
|
||||
const { flags } = regexpContext;
|
||||
const result = (0, scslre_1.analyse)((0, refa_2.getJSRegexppAst)(regexpContext, true), {
|
||||
reportTypes: { Move: true, Self: false, Trade: false },
|
||||
assumeRejectingSuffix,
|
||||
});
|
||||
return result.reports.map((r) => {
|
||||
if (r.type !== "Move") {
|
||||
throw new Error("Unexpected report type");
|
||||
}
|
||||
return {
|
||||
quant: r.quant,
|
||||
attack: `/${r.character.literal.source}+/${flags.ignoreCase ? "i" : ""}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
function* getSimpleReports(regexpContext, assumeRejectingSuffix) {
|
||||
const { patternAst, flags } = regexpContext;
|
||||
const parser = refa_1.JS.Parser.fromAst((0, refa_2.getJSRegexppAst)(regexpContext, true));
|
||||
for (const q of findReachableQuantifiers(patternAst, flags)) {
|
||||
if (q.max !== Infinity) {
|
||||
continue;
|
||||
}
|
||||
if (q.element.type === "Assertion" ||
|
||||
q.element.type === "Backreference") {
|
||||
continue;
|
||||
}
|
||||
let e = parser.parseElement(q.element, {
|
||||
assertions: "parse",
|
||||
backreferences: "disable",
|
||||
}).expression;
|
||||
e = (0, refa_1.transform)(PASS_1, e);
|
||||
e = (0, refa_1.transform)(PASS_2, e);
|
||||
if (e.alternatives.length === 0) {
|
||||
continue;
|
||||
}
|
||||
let hasCharacters = false;
|
||||
(0, refa_1.visitAst)(e, {
|
||||
onCharacterClassEnter() {
|
||||
hasCharacters = true;
|
||||
},
|
||||
});
|
||||
if (!hasCharacters) {
|
||||
continue;
|
||||
}
|
||||
if (!assumeRejectingSuffix) {
|
||||
const after = (0, regexp_ast_analysis_1.getFirstConsumedCharAfter)(q, (0, regexp_ast_analysis_1.getMatchingDirection)(q), flags);
|
||||
if (after.empty && after.look.char.isAll) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const attack = `/${refa_1.JS.toLiteral({
|
||||
type: "Quantifier",
|
||||
alternatives: e.alternatives,
|
||||
min: 1,
|
||||
max: Infinity,
|
||||
lazy: false,
|
||||
}).source}/${flags.ignoreCase ? "i" : ""}`;
|
||||
yield { quant: q, attack };
|
||||
}
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, flags, getRegexpLocation, getUsageOfPattern } = regexpContext;
|
||||
if (ignoreSticky && flags.sticky) {
|
||||
return {};
|
||||
}
|
||||
const usage = getUsageOfPattern();
|
||||
if (ignorePartial && usage === get_usage_of_pattern_1.UsageOfPattern.partial) {
|
||||
return {};
|
||||
}
|
||||
const assumeRejectingSuffix = reportUncertain && usage !== get_usage_of_pattern_1.UsageOfPattern.whole;
|
||||
for (const report of dedupeReports([
|
||||
...getSimpleReports(regexpContext, assumeRejectingSuffix),
|
||||
...getScslreReports(regexpContext, assumeRejectingSuffix),
|
||||
])) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(report.quant),
|
||||
messageId: "unexpected",
|
||||
data: { attack: report.attack },
|
||||
});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-assertion.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-assertion.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
87
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-assertion.js
generated
vendored
Normal file
87
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-assertion.js
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
function isLookaround(node) {
|
||||
return (node.type === "Assertion" &&
|
||||
(node.kind === "lookahead" || node.kind === "lookbehind"));
|
||||
}
|
||||
function getTriviallyNestedAssertion(node) {
|
||||
const alternatives = node.alternatives;
|
||||
if (alternatives.length === 1) {
|
||||
const elements = alternatives[0].elements;
|
||||
if (elements.length === 1) {
|
||||
const element = elements[0];
|
||||
if (element.type === "Assertion") {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getNegatedRaw(assertion) {
|
||||
if (assertion.kind === "word") {
|
||||
return assertion.negate ? "\\b" : "\\B";
|
||||
}
|
||||
else if (assertion.kind === "lookahead") {
|
||||
return `(?${assertion.negate ? "=" : "!"}${assertion.raw.slice(3)}`;
|
||||
}
|
||||
else if (assertion.kind === "lookbehind") {
|
||||
return `(?<${assertion.negate ? "=" : "!"}${assertion.raw.slice(4)}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-trivially-nested-assertion", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow trivially nested assertions",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: "Unexpected trivially nested assertion.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, fixReplaceNode, getRegexpLocation, }) {
|
||||
return {
|
||||
onAssertionEnter(aNode) {
|
||||
if (aNode.parent.type === "Quantifier") {
|
||||
return;
|
||||
}
|
||||
if (!isLookaround(aNode)) {
|
||||
return;
|
||||
}
|
||||
const nested = getTriviallyNestedAssertion(aNode);
|
||||
if (nested === null) {
|
||||
return;
|
||||
}
|
||||
if (aNode.negate &&
|
||||
isLookaround(nested) &&
|
||||
nested.negate &&
|
||||
(0, regexp_ast_analysis_1.hasSomeDescendant)(nested, (d) => d.type === "CapturingGroup")) {
|
||||
return;
|
||||
}
|
||||
const replacement = aNode.negate
|
||||
? getNegatedRaw(nested)
|
||||
: nested.raw;
|
||||
if (replacement === null) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(aNode),
|
||||
messageId: "unexpected",
|
||||
fix: fixReplaceNode(aNode, replacement),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-quantifier.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-quantifier.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
141
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-quantifier.js
generated
vendored
Normal file
141
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-trivially-nested-quantifier.js
generated
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const regexp_ast_1 = require("../utils/regexp-ast");
|
||||
function getCombinedQuant(parent, child) {
|
||||
if (parent.max === 0 || child.max === 0) {
|
||||
return null;
|
||||
}
|
||||
else if (parent.greedy === child.greedy) {
|
||||
const greedy = parent.greedy;
|
||||
const a = child.min;
|
||||
const b = child.max;
|
||||
const c = parent.min;
|
||||
const d = parent.max;
|
||||
const condition = b === Infinity && c === 0
|
||||
? a <= 1
|
||||
: c === d || b * c + 1 >= a * (c + 1);
|
||||
if (condition) {
|
||||
return {
|
||||
min: a * c,
|
||||
max: b * d,
|
||||
greedy,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getSimplifiedChildQuant(parent, child) {
|
||||
if (parent.max === 0 || child.max === 0) {
|
||||
return null;
|
||||
}
|
||||
else if (parent.greedy !== child.greedy) {
|
||||
return null;
|
||||
}
|
||||
let min = child.min;
|
||||
let max = child.max;
|
||||
if (min === 0 && parent.min === 0) {
|
||||
min = 1;
|
||||
}
|
||||
if (parent.max === Infinity && (min === 0 || min === 1) && max > 1) {
|
||||
max = 1;
|
||||
}
|
||||
return { min, max, greedy: child.greedy };
|
||||
}
|
||||
function isTrivialQuantifier(quant) {
|
||||
return quant.min === quant.max && (quant.min === 0 || quant.min === 1);
|
||||
}
|
||||
function* iterateSingleQuantifiers(group) {
|
||||
for (const { elements } of group.alternatives) {
|
||||
if (elements.length === 1) {
|
||||
const single = elements[0];
|
||||
if (single.type === "Quantifier") {
|
||||
yield single;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-trivially-nested-quantifier", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow nested quantifiers that can be rewritten as one quantifier",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
messages: {
|
||||
nested: "These two quantifiers are trivially nested and can be replaced with '{{quant}}'.",
|
||||
childOne: "This nested quantifier can be removed.",
|
||||
childSimpler: "This nested quantifier can be simplified to '{{quant}}'.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, fixReplaceNode, fixReplaceQuant, getRegexpLocation, }) {
|
||||
return {
|
||||
onQuantifierEnter(qNode) {
|
||||
if (isTrivialQuantifier(qNode)) {
|
||||
return;
|
||||
}
|
||||
const element = qNode.element;
|
||||
if (element.type !== "Group") {
|
||||
return;
|
||||
}
|
||||
for (const child of iterateSingleQuantifiers(element)) {
|
||||
if (isTrivialQuantifier(child)) {
|
||||
continue;
|
||||
}
|
||||
if (element.alternatives.length === 1) {
|
||||
const quant = getCombinedQuant(qNode, child);
|
||||
if (!quant) {
|
||||
continue;
|
||||
}
|
||||
const quantStr = (0, regexp_ast_1.quantToString)(quant);
|
||||
const replacement = child.element.raw + quantStr;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(qNode),
|
||||
messageId: "nested",
|
||||
data: { quant: quantStr },
|
||||
fix: fixReplaceNode(qNode, replacement),
|
||||
});
|
||||
}
|
||||
else {
|
||||
const quant = getSimplifiedChildQuant(qNode, child);
|
||||
if (!quant) {
|
||||
continue;
|
||||
}
|
||||
if (quant.min === child.min &&
|
||||
quant.max === child.max) {
|
||||
continue;
|
||||
}
|
||||
if (quant.min === 1 && quant.max === 1) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(child),
|
||||
messageId: "childOne",
|
||||
fix: fixReplaceNode(child, child.element.raw),
|
||||
});
|
||||
}
|
||||
else {
|
||||
quant.greedy = undefined;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(child),
|
||||
messageId: "childSimpler",
|
||||
data: { quant: (0, regexp_ast_1.quantToString)(quant) },
|
||||
fix: fixReplaceQuant(child, quant),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-unused-capturing-group.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-unused-capturing-group.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
151
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-unused-capturing-group.js
generated
vendored
Normal file
151
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-unused-capturing-group.js
generated
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
function getCapturingGroupIdentifier(group) {
|
||||
if (group.name) {
|
||||
return `'${group.name}'`;
|
||||
}
|
||||
return `number ${(0, regexp_ast_analysis_1.getCapturingGroupNumber)(group)}`;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-unused-capturing-group", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow unused capturing group",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
fixable: { type: "boolean" },
|
||||
allowNamed: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unusedCapturingGroup: "Capturing group {{identifier}} is defined but never used.",
|
||||
makeNonCapturing: "Making this a non-capturing group.",
|
||||
},
|
||||
type: "suggestion",
|
||||
hasSuggestions: true,
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b, _c, _d;
|
||||
const fixable = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.fixable) !== null && _b !== void 0 ? _b : false;
|
||||
const allowNamed = (_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.allowNamed) !== null && _d !== void 0 ? _d : false;
|
||||
function reportUnused(unused, regexpContext) {
|
||||
const { node, getRegexpLocation, fixReplaceNode, getAllCapturingGroups, } = regexpContext;
|
||||
if (allowNamed) {
|
||||
for (const cgNode of unused) {
|
||||
if (cgNode.name) {
|
||||
unused.delete(cgNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
const fixableGroups = new Set();
|
||||
for (const group of [...getAllCapturingGroups()].reverse()) {
|
||||
if (unused.has(group)) {
|
||||
fixableGroups.add(group);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (const cgNode of unused) {
|
||||
const fix = fixableGroups.has(cgNode)
|
||||
? fixReplaceNode(cgNode, cgNode.raw.replace(/^\((?:\?<[^<>]+>)?/u, "(?:"))
|
||||
: null;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(cgNode),
|
||||
messageId: "unusedCapturingGroup",
|
||||
data: { identifier: getCapturingGroupIdentifier(cgNode) },
|
||||
fix: fixable ? fix : null,
|
||||
suggest: fix
|
||||
? [{ messageId: "makeNonCapturing", fix }]
|
||||
: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
function getCapturingGroupReferences(regexpContext) {
|
||||
const capturingGroupReferences = regexpContext.getCapturingGroupReferences();
|
||||
if (!capturingGroupReferences.length) {
|
||||
return null;
|
||||
}
|
||||
const indexRefs = [];
|
||||
const namedRefs = [];
|
||||
let hasUnknownName = false;
|
||||
let hasSplit = false;
|
||||
for (const ref of capturingGroupReferences) {
|
||||
if (ref.type === "UnknownUsage" || ref.type === "UnknownRef") {
|
||||
return null;
|
||||
}
|
||||
if (ref.type === "ArrayRef" ||
|
||||
ref.type === "ReplacementRef" ||
|
||||
ref.type === "ReplacerFunctionRef") {
|
||||
if (ref.kind === "index") {
|
||||
if (ref.ref != null) {
|
||||
indexRefs.push(ref.ref);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ref.ref) {
|
||||
namedRefs.push(ref.ref);
|
||||
}
|
||||
else {
|
||||
hasUnknownName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ref.type === "Split") {
|
||||
hasSplit = true;
|
||||
}
|
||||
}
|
||||
return {
|
||||
unusedIndexRef(index) {
|
||||
if (hasSplit) {
|
||||
return false;
|
||||
}
|
||||
return !indexRefs.includes(index);
|
||||
},
|
||||
unusedNamedRef(name) {
|
||||
if (hasUnknownName) {
|
||||
return false;
|
||||
}
|
||||
return !namedRefs.includes(name);
|
||||
},
|
||||
};
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const references = getCapturingGroupReferences(regexpContext);
|
||||
if (!references) {
|
||||
return {};
|
||||
}
|
||||
const unused = new Set();
|
||||
const allCapturingGroups = regexpContext.getAllCapturingGroups();
|
||||
for (let index = 0; index < allCapturingGroups.length; index++) {
|
||||
const cgNode = allCapturingGroups[index];
|
||||
if (cgNode.references.length ||
|
||||
!references.unusedIndexRef(index + 1)) {
|
||||
continue;
|
||||
}
|
||||
if (cgNode.name && !references.unusedNamedRef(cgNode.name)) {
|
||||
continue;
|
||||
}
|
||||
unused.add(cgNode);
|
||||
}
|
||||
reportUnused(unused, regexpContext);
|
||||
return {};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-assertions.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-assertions.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
378
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-assertions.js
generated
vendored
Normal file
378
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-assertions.js
generated
vendored
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const util_1 = require("../utils/util");
|
||||
function containsAssertion(n) {
|
||||
return (0, regexp_ast_analysis_1.hasSomeDescendant)(n, (d) => d.type === "Assertion");
|
||||
}
|
||||
function isSingleCharacterAssertion(assertion, direction, flags) {
|
||||
switch (assertion.kind) {
|
||||
case "word":
|
||||
return false;
|
||||
case "start":
|
||||
return direction === "rtl";
|
||||
case "end":
|
||||
return direction === "ltr";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(assertion.kind) !== direction) {
|
||||
return false;
|
||||
}
|
||||
return assertion.alternatives.every((alt) => {
|
||||
if (!containsAssertion(alt)) {
|
||||
const range = (0, regexp_ast_analysis_1.getLengthRange)(alt, flags);
|
||||
return range.min === 1 && range.max === 1;
|
||||
}
|
||||
let consumed = false;
|
||||
let asserted = false;
|
||||
const elements = direction === "ltr" ? alt.elements : [...alt.elements].reverse();
|
||||
for (const e of elements) {
|
||||
if (!consumed) {
|
||||
if (e.type === "Assertion" &&
|
||||
isSingleCharacterAssertion(e, direction, flags)) {
|
||||
asserted = true;
|
||||
continue;
|
||||
}
|
||||
if (containsAssertion(e)) {
|
||||
return false;
|
||||
}
|
||||
const range = (0, regexp_ast_analysis_1.getLengthRange)(e, flags);
|
||||
if (range.max === 0) {
|
||||
continue;
|
||||
}
|
||||
else if (range.min === 1 && range.max === 1) {
|
||||
consumed = true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const otherDir = (0, regexp_ast_analysis_1.invertMatchingDirection)(direction);
|
||||
if (e.type === "Assertion" &&
|
||||
isSingleCharacterAssertion(e, otherDir, flags)) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return consumed || asserted;
|
||||
});
|
||||
}
|
||||
function firstLookCharsIntersection(a, b) {
|
||||
const char = a.char.intersect(b.char);
|
||||
return {
|
||||
char: a.char.intersect(b.char),
|
||||
exact: (a.exact && b.exact) || char.isEmpty,
|
||||
edge: a.edge && b.edge,
|
||||
};
|
||||
}
|
||||
function createReorderingGetFirstCharAfter(forbidden) {
|
||||
function hasForbidden(element) {
|
||||
if (element.type === "Assertion" && forbidden.has(element)) {
|
||||
return true;
|
||||
}
|
||||
for (const f of forbidden) {
|
||||
if ((0, regexp_ast_analysis_1.hasSomeDescendant)(element, f)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return (afterThis, direction, flags) => {
|
||||
let result = (0, regexp_ast_analysis_1.getFirstCharAfter)(afterThis, direction, flags);
|
||||
if (afterThis.parent.type === "Alternative") {
|
||||
const { elements } = afterThis.parent;
|
||||
const inc = direction === "ltr" ? -1 : +1;
|
||||
const start = elements.indexOf(afterThis);
|
||||
for (let i = start + inc; i >= 0 && i < elements.length; i += inc) {
|
||||
const other = elements[i];
|
||||
if (!(0, regexp_ast_analysis_1.isZeroLength)(other, flags)) {
|
||||
break;
|
||||
}
|
||||
if (hasForbidden(other)) {
|
||||
break;
|
||||
}
|
||||
const otherResult = regexp_ast_analysis_1.FirstConsumedChars.toLook((0, regexp_ast_analysis_1.getFirstConsumedChar)(other, direction, flags));
|
||||
result = firstLookCharsIntersection(result, otherResult);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
function removeAlternative(alternative) {
|
||||
const parent = alternative.parent;
|
||||
if (parent.alternatives.length > 1) {
|
||||
let { start, end } = alternative;
|
||||
if (parent.alternatives[0] === alternative) {
|
||||
end++;
|
||||
}
|
||||
else {
|
||||
start--;
|
||||
}
|
||||
const before = parent.raw.slice(0, start - parent.start);
|
||||
const after = parent.raw.slice(end - parent.start);
|
||||
return [parent, before + after];
|
||||
}
|
||||
switch (parent.type) {
|
||||
case "Pattern":
|
||||
return [parent, "[]"];
|
||||
case "Assertion": {
|
||||
const assertionParent = parent.parent;
|
||||
if (parent.negate) {
|
||||
return [
|
||||
assertionParent.type === "Quantifier"
|
||||
? assertionParent
|
||||
: parent,
|
||||
"",
|
||||
];
|
||||
}
|
||||
if (assertionParent.type === "Quantifier") {
|
||||
if (assertionParent.min === 0) {
|
||||
return [assertionParent, ""];
|
||||
}
|
||||
return removeAlternative(assertionParent.parent);
|
||||
}
|
||||
return removeAlternative(assertionParent);
|
||||
}
|
||||
case "CapturingGroup": {
|
||||
const before = parent.raw.slice(0, alternative.start - parent.start);
|
||||
const after = parent.raw.slice(alternative.end - parent.start);
|
||||
return [parent, `${before}[]${after}`];
|
||||
}
|
||||
case "Group": {
|
||||
const groupParent = parent.parent;
|
||||
if (groupParent.type === "Quantifier") {
|
||||
if (groupParent.min === 0) {
|
||||
return [groupParent, ""];
|
||||
}
|
||||
return removeAlternative(groupParent.parent);
|
||||
}
|
||||
return removeAlternative(groupParent);
|
||||
}
|
||||
default:
|
||||
return (0, util_1.assertNever)(parent);
|
||||
}
|
||||
}
|
||||
const messages = {
|
||||
alwaysRejectByChar: "{{assertion}} will always reject because it is {{followedOrPreceded}} by a character.",
|
||||
alwaysAcceptByChar: "{{assertion}} will always accept because it is never {{followedOrPreceded}} by a character.",
|
||||
alwaysRejectByNonLineTerminator: "{{assertion}} will always reject because it is {{followedOrPreceded}} by a non-line-terminator character.",
|
||||
alwaysAcceptByLineTerminator: "{{assertion}} will always accept because it is {{followedOrPreceded}} by a line-terminator character.",
|
||||
alwaysAcceptByLineTerminatorOrEdge: "{{assertion}} will always accept because it is {{followedOrPreceded}} by a line-terminator character or the {{startOrEnd}} of the input string.",
|
||||
alwaysAcceptOrRejectFollowedByWord: "{{assertion}} will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a word character.",
|
||||
alwaysAcceptOrRejectFollowedByNonWord: "{{assertion}} will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a non-word character.",
|
||||
alwaysAcceptOrRejectPrecededByWordFollowedByNonWord: "{{assertion}} will always {{acceptOrReject}} because it is preceded by a word character and followed by a non-word character.",
|
||||
alwaysAcceptOrRejectPrecededByWordFollowedByWord: "{{assertion}} will always {{acceptOrReject}} because it is preceded by a word character and followed by a word character.",
|
||||
alwaysForLookaround: "The {{kind}} {{assertion}} will always {{acceptOrReject}}.",
|
||||
alwaysForNegativeLookaround: "The negative {{kind}} {{assertion}} will always {{acceptOrReject}}.",
|
||||
acceptSuggestion: "Remove the assertion. (Replace with empty string.)",
|
||||
rejectSuggestion: "Remove branch of the assertion. (Replace with empty set.)",
|
||||
};
|
||||
exports.default = (0, utils_1.createRule)("no-useless-assertions", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow assertions that are known to always accept (or reject)",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
schema: [],
|
||||
messages,
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, fixReplaceNode, }) {
|
||||
const reported = new Set();
|
||||
function replaceWithEmptyString(assertion) {
|
||||
if (assertion.parent.type === "Quantifier") {
|
||||
return fixReplaceNode(assertion.parent, "");
|
||||
}
|
||||
return fixReplaceNode(assertion, "");
|
||||
}
|
||||
function replaceWithEmptySet(assertion) {
|
||||
if (assertion.parent.type === "Quantifier") {
|
||||
if (assertion.parent.min === 0) {
|
||||
return fixReplaceNode(assertion.parent, "");
|
||||
}
|
||||
const [element, replacement] = removeAlternative(assertion.parent.parent);
|
||||
return fixReplaceNode(element, replacement);
|
||||
}
|
||||
const [element, replacement] = removeAlternative(assertion.parent);
|
||||
return fixReplaceNode(element, replacement);
|
||||
}
|
||||
function report(assertion, messageId, data) {
|
||||
reported.add(assertion);
|
||||
const { acceptOrReject } = data;
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(assertion),
|
||||
messageId,
|
||||
data: {
|
||||
assertion: (0, mention_1.mention)(assertion),
|
||||
...data,
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: `${acceptOrReject}Suggestion`,
|
||||
fix: acceptOrReject === "accept"
|
||||
? replaceWithEmptyString(assertion)
|
||||
: replaceWithEmptySet(assertion),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
function verifyStartOrEnd(assertion, getFirstCharAfterFn) {
|
||||
const direction = (0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(assertion.kind);
|
||||
const next = getFirstCharAfterFn(assertion, direction, flags);
|
||||
const followedOrPreceded = assertion.kind === "end" ? "followed" : "preceded";
|
||||
const lineTerminator = regexp_ast_analysis_1.Chars.lineTerminator(flags);
|
||||
if (next.edge) {
|
||||
if (!flags.multiline) {
|
||||
if (next.char.isEmpty) {
|
||||
report(assertion, "alwaysAcceptByChar", {
|
||||
followedOrPreceded,
|
||||
acceptOrReject: "accept",
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (next.char.isSubsetOf(lineTerminator)) {
|
||||
report(assertion, "alwaysAcceptByLineTerminatorOrEdge", {
|
||||
followedOrPreceded,
|
||||
startOrEnd: assertion.kind,
|
||||
acceptOrReject: "accept",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!flags.multiline) {
|
||||
report(assertion, "alwaysRejectByChar", {
|
||||
followedOrPreceded,
|
||||
acceptOrReject: "reject",
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (next.char.isDisjointWith(lineTerminator)) {
|
||||
report(assertion, "alwaysRejectByNonLineTerminator", {
|
||||
followedOrPreceded,
|
||||
acceptOrReject: "reject",
|
||||
});
|
||||
}
|
||||
else if (next.char.isSubsetOf(lineTerminator)) {
|
||||
report(assertion, "alwaysAcceptByLineTerminator", {
|
||||
followedOrPreceded,
|
||||
acceptOrReject: "accept",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function verifyWordBoundary(assertion, getFirstCharAfterFn) {
|
||||
const word = regexp_ast_analysis_1.Chars.word(flags);
|
||||
const next = getFirstCharAfterFn(assertion, "ltr", flags);
|
||||
const prev = getFirstCharAfterFn(assertion, "rtl", flags);
|
||||
const nextIsWord = next.char.isSubsetOf(word) && !next.edge;
|
||||
const prevIsWord = prev.char.isSubsetOf(word) && !prev.edge;
|
||||
const nextIsNonWord = next.char.isDisjointWith(word);
|
||||
const prevIsNonWord = prev.char.isDisjointWith(word);
|
||||
const accept = assertion.negate ? "reject" : "accept";
|
||||
const reject = assertion.negate ? "accept" : "reject";
|
||||
if (prevIsNonWord) {
|
||||
if (nextIsWord) {
|
||||
report(assertion, "alwaysAcceptOrRejectFollowedByWord", {
|
||||
acceptOrReject: accept,
|
||||
});
|
||||
}
|
||||
if (nextIsNonWord) {
|
||||
report(assertion, "alwaysAcceptOrRejectFollowedByNonWord", {
|
||||
acceptOrReject: reject,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (prevIsWord) {
|
||||
if (nextIsNonWord) {
|
||||
report(assertion, "alwaysAcceptOrRejectPrecededByWordFollowedByNonWord", {
|
||||
acceptOrReject: accept,
|
||||
});
|
||||
}
|
||||
if (nextIsWord) {
|
||||
report(assertion, "alwaysAcceptOrRejectPrecededByWordFollowedByWord", {
|
||||
acceptOrReject: reject,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function verifyLookaround(assertion, getFirstCharAfterFn) {
|
||||
if ((0, regexp_ast_analysis_1.isPotentiallyEmpty)(assertion.alternatives, flags)) {
|
||||
return;
|
||||
}
|
||||
const direction = (0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(assertion.kind);
|
||||
const after = getFirstCharAfterFn(assertion, direction, flags);
|
||||
const firstOf = regexp_ast_analysis_1.FirstConsumedChars.toLook((0, regexp_ast_analysis_1.getFirstConsumedChar)(assertion.alternatives, direction, flags));
|
||||
const accept = assertion.negate ? "reject" : "accept";
|
||||
const reject = assertion.negate ? "accept" : "reject";
|
||||
if (after.char.isDisjointWith(firstOf.char) &&
|
||||
!(after.edge && firstOf.edge)) {
|
||||
report(assertion, assertion.negate
|
||||
? "alwaysForNegativeLookaround"
|
||||
: "alwaysForLookaround", {
|
||||
kind: assertion.kind,
|
||||
acceptOrReject: reject,
|
||||
});
|
||||
}
|
||||
const edgeSubset = firstOf.edge || !after.edge;
|
||||
if (firstOf.exact &&
|
||||
edgeSubset &&
|
||||
after.char.isSubsetOf(firstOf.char) &&
|
||||
isSingleCharacterAssertion(assertion, (0, regexp_ast_analysis_1.getMatchingDirectionFromAssertionKind)(assertion.kind), flags)) {
|
||||
report(assertion, assertion.negate
|
||||
? "alwaysForNegativeLookaround"
|
||||
: "alwaysForLookaround", {
|
||||
kind: assertion.kind,
|
||||
acceptOrReject: accept,
|
||||
});
|
||||
}
|
||||
}
|
||||
function verifyAssertion(assertion, getFirstCharAfterFn) {
|
||||
switch (assertion.kind) {
|
||||
case "start":
|
||||
case "end":
|
||||
verifyStartOrEnd(assertion, getFirstCharAfterFn);
|
||||
break;
|
||||
case "word":
|
||||
verifyWordBoundary(assertion, getFirstCharAfterFn);
|
||||
break;
|
||||
case "lookahead":
|
||||
case "lookbehind":
|
||||
verifyLookaround(assertion, getFirstCharAfterFn);
|
||||
break;
|
||||
default:
|
||||
throw (0, util_1.assertNever)(assertion);
|
||||
}
|
||||
}
|
||||
const allAssertions = [];
|
||||
return {
|
||||
onAssertionEnter(assertion) {
|
||||
verifyAssertion(assertion, regexp_ast_analysis_1.getFirstCharAfter);
|
||||
allAssertions.push(assertion);
|
||||
},
|
||||
onPatternLeave() {
|
||||
const reorderingGetFirstCharAfter = createReorderingGetFirstCharAfter(reported);
|
||||
for (const assertion of allAssertions) {
|
||||
if (!reported.has(assertion)) {
|
||||
verifyAssertion(assertion, reorderingGetFirstCharAfter);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-backreference.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-backreference.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
116
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-backreference.js
generated
vendored
Normal file
116
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-backreference.js
generated
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const regexp_ast_analysis_1 = require("regexp-ast-analysis");
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
function hasNegatedLookaroundInBetween(from, to) {
|
||||
for (let p = from.parent; p && p !== to; p = p.parent) {
|
||||
if (p.type === "Assertion" &&
|
||||
(p.kind === "lookahead" || p.kind === "lookbehind") &&
|
||||
p.negate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getUselessProblem(backRef, flags) {
|
||||
const groups = [backRef.resolved].flat();
|
||||
const problems = [];
|
||||
for (const group of groups) {
|
||||
const messageId = getUselessMessageId(backRef, group, flags);
|
||||
if (!messageId) {
|
||||
return null;
|
||||
}
|
||||
problems.push({ messageId, group });
|
||||
}
|
||||
if (problems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
let problemsToReport;
|
||||
const problemsInSameDisjunction = problems.filter((problem) => problem.messageId !== "disjunctive");
|
||||
if (problemsInSameDisjunction.length) {
|
||||
problemsToReport = problemsInSameDisjunction;
|
||||
}
|
||||
else {
|
||||
problemsToReport = problems;
|
||||
}
|
||||
const [{ messageId, group }, ...other] = problemsToReport;
|
||||
let otherGroups = "";
|
||||
if (other.length === 1) {
|
||||
otherGroups = " and another group";
|
||||
}
|
||||
else if (other.length > 1) {
|
||||
otherGroups = ` and other ${other.length} groups`;
|
||||
}
|
||||
return {
|
||||
messageId,
|
||||
group,
|
||||
otherGroups,
|
||||
};
|
||||
}
|
||||
function getUselessMessageId(backRef, group, flags) {
|
||||
const closestAncestor = (0, regexp_ast_analysis_1.getClosestAncestor)(backRef, group);
|
||||
if (closestAncestor === group) {
|
||||
return "nested";
|
||||
}
|
||||
else if (closestAncestor.type !== "Alternative") {
|
||||
return "disjunctive";
|
||||
}
|
||||
if (hasNegatedLookaroundInBetween(group, closestAncestor)) {
|
||||
return "intoNegativeLookaround";
|
||||
}
|
||||
const matchingDir = (0, regexp_ast_analysis_1.getMatchingDirection)(closestAncestor);
|
||||
if (matchingDir === "ltr" && backRef.end <= group.start) {
|
||||
return "forward";
|
||||
}
|
||||
else if (matchingDir === "rtl" && group.end <= backRef.start) {
|
||||
return "backward";
|
||||
}
|
||||
if ((0, regexp_ast_analysis_1.isZeroLength)(group, flags)) {
|
||||
return "empty";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-useless-backreference", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow useless backreferences in regular expressions",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
nested: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} from within that group.",
|
||||
forward: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} which appears later in the pattern.",
|
||||
backward: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} which appears before in the same lookbehind.",
|
||||
disjunctive: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} which is in another alternative.",
|
||||
intoNegativeLookaround: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} which is in a negative lookaround.",
|
||||
empty: "Backreference {{ bref }} will be ignored. It references group {{ group }}{{ otherGroups }} which always captures zero characters.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
function createVisitor({ node, flags, getRegexpLocation, }) {
|
||||
return {
|
||||
onBackreferenceEnter(backRef) {
|
||||
const problem = getUselessProblem(backRef, flags);
|
||||
if (problem) {
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(backRef),
|
||||
messageId: problem.messageId,
|
||||
data: {
|
||||
bref: (0, mention_1.mention)(backRef),
|
||||
group: (0, mention_1.mention)(problem.group),
|
||||
otherGroups: problem.otherGroups,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-character-class.d.ts
generated
vendored
Normal file
2
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-character-class.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const _default: import("../types").RuleModule;
|
||||
export default _default;
|
||||
212
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-character-class.js
generated
vendored
Normal file
212
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-useless-character-class.js
generated
vendored
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
const ESCAPES_OUTSIDE_CHARACTER_CLASS = new Set("$()*+./?[{|");
|
||||
const ESCAPES_OUTSIDE_CHARACTER_CLASS_WITH_U = new Set([
|
||||
...ESCAPES_OUTSIDE_CHARACTER_CLASS,
|
||||
"}",
|
||||
]);
|
||||
exports.default = (0, utils_1.createRule)("no-useless-character-class", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow character class with one character",
|
||||
category: "Best Practices",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
ignores: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
minLength: 1,
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
unexpectedCharacterClassWith: "Unexpected character class with one {{type}}. Can remove brackets{{additional}}.",
|
||||
unexpectedUnnecessaryNestingCharacterClass: "Unexpected unnecessary nesting character class. Can remove brackets.",
|
||||
},
|
||||
type: "suggestion",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const ignores = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.ignores) !== null && _b !== void 0 ? _b : ["="];
|
||||
function createVisitor({ node, pattern, flags, fixReplaceNode, getRegexpLocation, }) {
|
||||
const characterClassStack = [];
|
||||
return {
|
||||
onExpressionCharacterClassEnter(eccNode) {
|
||||
characterClassStack.push(eccNode);
|
||||
},
|
||||
onExpressionCharacterClassLeave() {
|
||||
characterClassStack.pop();
|
||||
},
|
||||
onCharacterClassEnter(ccNode) {
|
||||
characterClassStack.push(ccNode);
|
||||
},
|
||||
onCharacterClassLeave(ccNode) {
|
||||
var _a, _b;
|
||||
characterClassStack.pop();
|
||||
if (ccNode.negate) {
|
||||
return;
|
||||
}
|
||||
let messageId, messageData;
|
||||
const unwrapped = ccNode.elements.map((_e, index) => {
|
||||
var _a, _b;
|
||||
const element = ccNode.elements[index];
|
||||
return ((_b = (_a = (index === 0
|
||||
? getEscapedFirstRawIfNeeded(element)
|
||||
: null)) !== null && _a !== void 0 ? _a : (index === ccNode.elements.length - 1
|
||||
? getEscapedLastRawIfNeeded(element)
|
||||
: null)) !== null && _b !== void 0 ? _b : element.raw);
|
||||
});
|
||||
if (ccNode.elements.length !== 1 &&
|
||||
ccNode.parent.type === "CharacterClass") {
|
||||
messageId = "unexpectedUnnecessaryNestingCharacterClass";
|
||||
messageData = {
|
||||
type: "unnecessary nesting character class",
|
||||
};
|
||||
if (!ccNode.elements.length) {
|
||||
const nextElement = ccNode.parent.elements[ccNode.parent.elements.indexOf(ccNode) + 1];
|
||||
if (nextElement &&
|
||||
isNeedEscapedForFirstElement(nextElement)) {
|
||||
unwrapped.push("\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ccNode.elements.length !== 1) {
|
||||
return;
|
||||
}
|
||||
const element = ccNode.elements[0];
|
||||
if (ignores.length > 0 &&
|
||||
ignores.includes(element.raw)) {
|
||||
return;
|
||||
}
|
||||
if (element.type === "Character") {
|
||||
if (element.raw === "\\b") {
|
||||
return;
|
||||
}
|
||||
if (/^\\\d+$/u.test(element.raw) &&
|
||||
!element.raw.startsWith("\\0")) {
|
||||
return;
|
||||
}
|
||||
if (ignores.length > 0 &&
|
||||
ignores.includes(String.fromCodePoint(element.value))) {
|
||||
return;
|
||||
}
|
||||
if (!(0, utils_1.canUnwrapped)(ccNode, element.raw)) {
|
||||
return;
|
||||
}
|
||||
messageData = { type: "character" };
|
||||
}
|
||||
else if (element.type === "CharacterClassRange") {
|
||||
if (element.min.value !== element.max.value) {
|
||||
return;
|
||||
}
|
||||
messageData = {
|
||||
type: "character class range",
|
||||
additional: " and range",
|
||||
};
|
||||
unwrapped[0] =
|
||||
(_b = (_a = getEscapedFirstRawIfNeeded(element.min)) !== null && _a !== void 0 ? _a : getEscapedLastRawIfNeeded(element.min)) !== null && _b !== void 0 ? _b : element.min.raw;
|
||||
}
|
||||
else if (element.type === "ClassStringDisjunction") {
|
||||
if (!characterClassStack.length) {
|
||||
return;
|
||||
}
|
||||
messageData = { type: "string literal" };
|
||||
}
|
||||
else if (element.type === "CharacterSet") {
|
||||
messageData = { type: "character class escape" };
|
||||
}
|
||||
else if (element.type === "CharacterClass" ||
|
||||
element.type === "ExpressionCharacterClass") {
|
||||
messageData = { type: "character class" };
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
messageId = "unexpectedCharacterClassWith";
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(ccNode),
|
||||
messageId,
|
||||
data: {
|
||||
type: messageData.type,
|
||||
additional: messageData.additional || "",
|
||||
},
|
||||
fix: fixReplaceNode(ccNode, unwrapped.join("")),
|
||||
});
|
||||
function isNeedEscapedForFirstElement(element) {
|
||||
const char = element.type === "Character"
|
||||
? element.raw
|
||||
: element.type === "CharacterClassRange"
|
||||
? element.min.raw
|
||||
: null;
|
||||
if (char == null) {
|
||||
return false;
|
||||
}
|
||||
if (characterClassStack.length) {
|
||||
if (regex_syntax_1.RESERVED_DOUBLE_PUNCTUATOR_CHARS.has(char) &&
|
||||
pattern[ccNode.start - 1] === char) {
|
||||
return true;
|
||||
}
|
||||
return (char === "^" &&
|
||||
ccNode.parent.type === "CharacterClass" &&
|
||||
ccNode.parent.elements[0] === ccNode);
|
||||
}
|
||||
return (flags.unicode
|
||||
? ESCAPES_OUTSIDE_CHARACTER_CLASS_WITH_U
|
||||
: ESCAPES_OUTSIDE_CHARACTER_CLASS).has(char);
|
||||
}
|
||||
function needEscapedForLastElement(element) {
|
||||
const char = element.type === "Character"
|
||||
? element.raw
|
||||
: element.type === "CharacterClassRange"
|
||||
? element.max.raw
|
||||
: null;
|
||||
if (char == null) {
|
||||
return false;
|
||||
}
|
||||
if (characterClassStack.length) {
|
||||
return (regex_syntax_1.RESERVED_DOUBLE_PUNCTUATOR_CHARS.has(char) &&
|
||||
pattern[ccNode.end] === char);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getEscapedFirstRawIfNeeded(firstElement) {
|
||||
if (isNeedEscapedForFirstElement(firstElement)) {
|
||||
return `\\${firstElement.raw}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getEscapedLastRawIfNeeded(lastElement) {
|
||||
if (needEscapedForLastElement(lastElement)) {
|
||||
const lastRaw = lastElement.type === "Character"
|
||||
? lastElement.raw
|
||||
: lastElement.type === "CharacterClassRange"
|
||||
? lastElement.max.raw
|
||||
: "";
|
||||
const prefix = lastElement.raw.slice(0, -lastRaw.length);
|
||||
return `${prefix}\\${lastRaw}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue