eslint 8.2.0 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -11
- package/conf/globals.js +144 -0
- package/lib/cli.js +1 -1
- package/lib/config/default-config.js +11 -2
- package/lib/config/flat-config-array.js +2 -2
- package/lib/config/flat-config-helpers.js +67 -0
- package/lib/config/flat-config-schema.js +13 -8
- package/lib/config/rule-validator.js +28 -27
- package/lib/eslint/eslint.js +11 -3
- package/lib/linter/code-path-analysis/code-path-analyzer.js +6 -1
- package/lib/linter/code-path-analysis/code-path.js +1 -1
- package/lib/linter/linter.js +457 -45
- package/lib/options.js +6 -6
- package/lib/rule-tester/rule-tester.js +14 -0
- package/lib/rules/accessor-pairs.js +1 -0
- package/lib/rules/array-bracket-newline.js +1 -0
- package/lib/rules/array-bracket-spacing.js +1 -0
- package/lib/rules/array-callback-return.js +1 -0
- package/lib/rules/array-element-newline.js +1 -0
- package/lib/rules/arrow-body-style.js +1 -0
- package/lib/rules/arrow-parens.js +1 -0
- package/lib/rules/arrow-spacing.js +1 -0
- package/lib/rules/block-scoped-var.js +3 -0
- package/lib/rules/block-spacing.js +11 -3
- package/lib/rules/brace-style.js +7 -0
- package/lib/rules/callback-return.js +1 -0
- package/lib/rules/camelcase.js +1 -0
- package/lib/rules/capitalized-comments.js +1 -0
- package/lib/rules/class-methods-use-this.js +11 -1
- package/lib/rules/comma-dangle.js +1 -0
- package/lib/rules/comma-spacing.js +1 -0
- package/lib/rules/comma-style.js +1 -0
- package/lib/rules/complexity.js +15 -6
- package/lib/rules/computed-property-spacing.js +1 -0
- package/lib/rules/consistent-return.js +1 -0
- package/lib/rules/consistent-this.js +1 -0
- package/lib/rules/constructor-super.js +1 -0
- package/lib/rules/curly.js +1 -0
- package/lib/rules/default-case-last.js +1 -0
- package/lib/rules/default-case.js +1 -0
- package/lib/rules/default-param-last.js +1 -0
- package/lib/rules/dot-location.js +1 -0
- package/lib/rules/dot-notation.js +1 -0
- package/lib/rules/eol-last.js +1 -0
- package/lib/rules/eqeqeq.js +1 -0
- package/lib/rules/for-direction.js +1 -0
- package/lib/rules/func-call-spacing.js +1 -0
- package/lib/rules/func-name-matching.js +1 -0
- package/lib/rules/func-names.js +1 -0
- package/lib/rules/func-style.js +1 -0
- package/lib/rules/function-call-argument-newline.js +1 -0
- package/lib/rules/function-paren-newline.js +1 -0
- package/lib/rules/generator-star-spacing.js +1 -0
- package/lib/rules/getter-return.js +1 -0
- package/lib/rules/global-require.js +1 -0
- package/lib/rules/grouped-accessor-pairs.js +1 -0
- package/lib/rules/guard-for-in.js +1 -0
- package/lib/rules/handle-callback-err.js +1 -0
- package/lib/rules/id-blacklist.js +1 -0
- package/lib/rules/id-denylist.js +1 -0
- package/lib/rules/id-length.js +1 -0
- package/lib/rules/id-match.js +24 -0
- package/lib/rules/implicit-arrow-linebreak.js +1 -0
- package/lib/rules/indent-legacy.js +1 -0
- package/lib/rules/indent.js +22 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/init-declarations.js +1 -0
- package/lib/rules/jsx-quotes.js +1 -0
- package/lib/rules/key-spacing.js +1 -0
- package/lib/rules/keyword-spacing.js +2 -0
- package/lib/rules/line-comment-position.js +1 -0
- package/lib/rules/linebreak-style.js +1 -0
- package/lib/rules/lines-around-comment.js +55 -7
- package/lib/rules/lines-around-directive.js +1 -0
- package/lib/rules/lines-between-class-members.js +1 -0
- package/lib/rules/max-classes-per-file.js +1 -0
- package/lib/rules/max-depth.js +3 -0
- package/lib/rules/max-len.js +1 -0
- package/lib/rules/max-lines-per-function.js +1 -0
- package/lib/rules/max-lines.js +1 -0
- package/lib/rules/max-nested-callbacks.js +1 -0
- package/lib/rules/max-params.js +1 -0
- package/lib/rules/max-statements-per-line.js +1 -0
- package/lib/rules/max-statements.js +11 -0
- package/lib/rules/multiline-comment-style.js +1 -0
- package/lib/rules/multiline-ternary.js +1 -0
- package/lib/rules/new-cap.js +1 -0
- package/lib/rules/new-parens.js +1 -0
- package/lib/rules/newline-after-var.js +1 -0
- package/lib/rules/newline-before-return.js +1 -0
- package/lib/rules/newline-per-chained-call.js +1 -0
- package/lib/rules/no-alert.js +1 -0
- package/lib/rules/no-array-constructor.js +1 -0
- package/lib/rules/no-async-promise-executor.js +1 -0
- package/lib/rules/no-await-in-loop.js +1 -0
- package/lib/rules/no-bitwise.js +1 -0
- package/lib/rules/no-buffer-constructor.js +1 -0
- package/lib/rules/no-caller.js +1 -0
- package/lib/rules/no-case-declarations.js +1 -0
- package/lib/rules/no-catch-shadow.js +1 -0
- package/lib/rules/no-class-assign.js +1 -0
- package/lib/rules/no-compare-neg-zero.js +1 -0
- package/lib/rules/no-cond-assign.js +1 -0
- package/lib/rules/no-confusing-arrow.js +1 -0
- package/lib/rules/no-console.js +1 -0
- package/lib/rules/no-const-assign.js +1 -0
- package/lib/rules/no-constant-condition.js +4 -1
- package/lib/rules/no-constructor-return.js +1 -0
- package/lib/rules/no-continue.js +1 -0
- package/lib/rules/no-control-regex.js +1 -0
- package/lib/rules/no-debugger.js +1 -0
- package/lib/rules/no-delete-var.js +1 -0
- package/lib/rules/no-div-regex.js +1 -0
- package/lib/rules/no-dupe-args.js +1 -0
- package/lib/rules/no-dupe-class-members.js +1 -0
- package/lib/rules/no-dupe-else-if.js +1 -0
- package/lib/rules/no-dupe-keys.js +1 -0
- package/lib/rules/no-duplicate-case.js +1 -0
- package/lib/rules/no-duplicate-imports.js +1 -0
- package/lib/rules/no-else-return.js +1 -0
- package/lib/rules/no-empty-character-class.js +1 -0
- package/lib/rules/no-empty-function.js +1 -0
- package/lib/rules/no-empty-pattern.js +1 -0
- package/lib/rules/no-empty.js +1 -0
- package/lib/rules/no-eq-null.js +1 -0
- package/lib/rules/no-eval.js +3 -0
- package/lib/rules/no-ex-assign.js +1 -0
- package/lib/rules/no-extend-native.js +1 -0
- package/lib/rules/no-extra-bind.js +1 -0
- package/lib/rules/no-extra-boolean-cast.js +1 -0
- package/lib/rules/no-extra-label.js +1 -0
- package/lib/rules/no-extra-parens.js +1 -0
- package/lib/rules/no-extra-semi.js +2 -1
- package/lib/rules/no-fallthrough.js +1 -0
- package/lib/rules/no-floating-decimal.js +1 -0
- package/lib/rules/no-func-assign.js +1 -0
- package/lib/rules/no-global-assign.js +1 -0
- package/lib/rules/no-implicit-coercion.js +1 -0
- package/lib/rules/no-implicit-globals.js +1 -0
- package/lib/rules/no-implied-eval.js +1 -0
- package/lib/rules/no-import-assign.js +1 -0
- package/lib/rules/no-inline-comments.js +1 -0
- package/lib/rules/no-inner-declarations.js +27 -4
- package/lib/rules/no-invalid-regexp.js +1 -0
- package/lib/rules/no-invalid-this.js +5 -0
- package/lib/rules/no-irregular-whitespace.js +1 -0
- package/lib/rules/no-iterator.js +1 -0
- package/lib/rules/no-label-var.js +1 -0
- package/lib/rules/no-labels.js +1 -0
- package/lib/rules/no-lone-blocks.js +9 -2
- package/lib/rules/no-lonely-if.js +1 -0
- package/lib/rules/no-loop-func.js +1 -0
- package/lib/rules/no-loss-of-precision.js +1 -0
- package/lib/rules/no-magic-numbers.js +1 -0
- package/lib/rules/no-misleading-character-class.js +1 -0
- package/lib/rules/no-mixed-operators.js +1 -0
- package/lib/rules/no-mixed-requires.js +1 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +1 -0
- package/lib/rules/no-multi-assign.js +1 -0
- package/lib/rules/no-multi-spaces.js +1 -0
- package/lib/rules/no-multi-str.js +1 -0
- package/lib/rules/no-multiple-empty-lines.js +1 -0
- package/lib/rules/no-native-reassign.js +1 -0
- package/lib/rules/no-negated-condition.js +1 -0
- package/lib/rules/no-negated-in-lhs.js +1 -0
- package/lib/rules/no-nested-ternary.js +1 -0
- package/lib/rules/no-new-func.js +1 -0
- package/lib/rules/no-new-object.js +1 -0
- package/lib/rules/no-new-require.js +1 -0
- package/lib/rules/no-new-symbol.js +1 -0
- package/lib/rules/no-new-wrappers.js +1 -0
- package/lib/rules/no-new.js +1 -0
- package/lib/rules/no-nonoctal-decimal-escape.js +1 -0
- package/lib/rules/no-obj-calls.js +1 -0
- package/lib/rules/no-octal-escape.js +1 -0
- package/lib/rules/no-octal.js +1 -0
- package/lib/rules/no-param-reassign.js +1 -0
- package/lib/rules/no-path-concat.js +1 -0
- package/lib/rules/no-plusplus.js +1 -0
- package/lib/rules/no-process-env.js +1 -0
- package/lib/rules/no-process-exit.js +1 -0
- package/lib/rules/no-promise-executor-return.js +1 -0
- package/lib/rules/no-proto.js +1 -0
- package/lib/rules/no-prototype-builtins.js +1 -0
- package/lib/rules/no-redeclare.js +3 -0
- package/lib/rules/no-regex-spaces.js +1 -0
- package/lib/rules/no-restricted-exports.js +1 -0
- package/lib/rules/no-restricted-globals.js +1 -0
- package/lib/rules/no-restricted-imports.js +1 -0
- package/lib/rules/no-restricted-modules.js +1 -0
- package/lib/rules/no-restricted-properties.js +1 -0
- package/lib/rules/no-restricted-syntax.js +1 -0
- package/lib/rules/no-return-assign.js +1 -0
- package/lib/rules/no-return-await.js +1 -0
- package/lib/rules/no-script-url.js +1 -0
- package/lib/rules/no-self-assign.js +1 -0
- package/lib/rules/no-self-compare.js +1 -0
- package/lib/rules/no-sequences.js +1 -0
- package/lib/rules/no-setter-return.js +1 -0
- package/lib/rules/no-shadow-restricted-names.js +1 -0
- package/lib/rules/no-shadow.js +1 -0
- package/lib/rules/no-spaced-func.js +1 -0
- package/lib/rules/no-sparse-arrays.js +1 -0
- package/lib/rules/no-sync.js +1 -0
- package/lib/rules/no-tabs.js +1 -0
- package/lib/rules/no-template-curly-in-string.js +1 -0
- package/lib/rules/no-ternary.js +1 -0
- package/lib/rules/no-this-before-super.js +1 -0
- package/lib/rules/no-throw-literal.js +1 -0
- package/lib/rules/no-trailing-spaces.js +1 -0
- package/lib/rules/no-undef-init.js +1 -0
- package/lib/rules/no-undef.js +1 -0
- package/lib/rules/no-undefined.js +1 -0
- package/lib/rules/no-underscore-dangle.js +1 -0
- package/lib/rules/no-unexpected-multiline.js +1 -0
- package/lib/rules/no-unmodified-loop-condition.js +1 -0
- package/lib/rules/no-unneeded-ternary.js +1 -0
- package/lib/rules/no-unreachable-loop.js +1 -0
- package/lib/rules/no-unreachable.js +1 -0
- package/lib/rules/no-unsafe-finally.js +1 -0
- package/lib/rules/no-unsafe-negation.js +1 -0
- package/lib/rules/no-unsafe-optional-chaining.js +1 -0
- package/lib/rules/no-unused-expressions.js +7 -0
- package/lib/rules/no-unused-labels.js +1 -0
- package/lib/rules/no-unused-private-class-members.js +1 -0
- package/lib/rules/no-unused-vars.js +1 -0
- package/lib/rules/no-use-before-define.js +33 -9
- package/lib/rules/no-useless-backreference.js +1 -0
- package/lib/rules/no-useless-call.js +1 -0
- package/lib/rules/no-useless-catch.js +1 -0
- package/lib/rules/no-useless-computed-key.js +1 -0
- package/lib/rules/no-useless-concat.js +1 -0
- package/lib/rules/no-useless-constructor.js +1 -0
- package/lib/rules/no-useless-escape.js +1 -0
- package/lib/rules/no-useless-rename.js +1 -0
- package/lib/rules/no-useless-return.js +1 -0
- package/lib/rules/no-var.js +1 -0
- package/lib/rules/no-void.js +1 -0
- package/lib/rules/no-warning-comments.js +1 -0
- package/lib/rules/no-whitespace-before-property.js +1 -0
- package/lib/rules/no-with.js +1 -0
- package/lib/rules/nonblock-statement-body-position.js +1 -0
- package/lib/rules/object-curly-newline.js +1 -0
- package/lib/rules/object-curly-spacing.js +1 -0
- package/lib/rules/object-property-newline.js +1 -0
- package/lib/rules/object-shorthand.js +1 -0
- package/lib/rules/one-var-declaration-per-line.js +1 -0
- package/lib/rules/one-var.js +6 -1
- package/lib/rules/operator-assignment.js +1 -0
- package/lib/rules/operator-linebreak.js +1 -0
- package/lib/rules/padded-blocks.js +9 -0
- package/lib/rules/padding-line-between-statements.js +3 -0
- package/lib/rules/prefer-arrow-callback.js +1 -0
- package/lib/rules/prefer-const.js +2 -1
- package/lib/rules/prefer-destructuring.js +1 -0
- package/lib/rules/prefer-exponentiation-operator.js +1 -0
- package/lib/rules/prefer-named-capture-group.js +1 -0
- package/lib/rules/prefer-numeric-literals.js +1 -0
- package/lib/rules/prefer-object-has-own.js +112 -0
- package/lib/rules/prefer-object-spread.js +1 -0
- package/lib/rules/prefer-promise-reject-errors.js +1 -0
- package/lib/rules/prefer-reflect.js +1 -0
- package/lib/rules/prefer-regex-literals.js +218 -1
- package/lib/rules/prefer-rest-params.js +1 -0
- package/lib/rules/prefer-spread.js +1 -0
- package/lib/rules/prefer-template.js +2 -1
- package/lib/rules/quote-props.js +1 -0
- package/lib/rules/quotes.js +1 -0
- package/lib/rules/radix.js +1 -0
- package/lib/rules/require-atomic-updates.js +15 -2
- package/lib/rules/require-await.js +1 -0
- package/lib/rules/require-jsdoc.js +1 -0
- package/lib/rules/require-unicode-regexp.js +1 -0
- package/lib/rules/require-yield.js +1 -0
- package/lib/rules/rest-spread-spacing.js +1 -0
- package/lib/rules/semi-spacing.js +1 -0
- package/lib/rules/semi-style.js +9 -2
- package/lib/rules/semi.js +19 -9
- package/lib/rules/sort-imports.js +1 -0
- package/lib/rules/sort-keys.js +1 -0
- package/lib/rules/sort-vars.js +1 -0
- package/lib/rules/space-before-blocks.js +1 -0
- package/lib/rules/space-before-function-paren.js +1 -0
- package/lib/rules/space-in-parens.js +1 -0
- package/lib/rules/space-infix-ops.js +1 -0
- package/lib/rules/space-unary-ops.js +1 -0
- package/lib/rules/spaced-comment.js +1 -0
- package/lib/rules/strict.js +1 -0
- package/lib/rules/switch-colon-spacing.js +1 -0
- package/lib/rules/symbol-description.js +1 -0
- package/lib/rules/template-curly-spacing.js +1 -0
- package/lib/rules/template-tag-spacing.js +1 -0
- package/lib/rules/unicode-bom.js +1 -0
- package/lib/rules/use-isnan.js +1 -0
- package/lib/rules/utils/ast-utils.js +15 -3
- package/lib/rules/valid-jsdoc.js +1 -0
- package/lib/rules/valid-typeof.js +1 -0
- package/lib/rules/vars-on-top.js +26 -12
- package/lib/rules/wrap-iife.js +1 -0
- package/lib/rules/wrap-regex.js +1 -0
- package/lib/rules/yield-star-spacing.js +1 -0
- package/lib/rules/yoda.js +1 -0
- package/lib/shared/types.js +10 -0
- package/package.json +8 -8
@@ -11,11 +11,15 @@
|
|
11
11
|
|
12
12
|
const astUtils = require("./utils/ast-utils");
|
13
13
|
const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("eslint-utils");
|
14
|
+
const { RegExpValidator, visitRegExpAST, RegExpParser } = require("regexpp");
|
15
|
+
const { canTokensBeAdjacent } = require("./utils/ast-utils");
|
14
16
|
|
15
17
|
//------------------------------------------------------------------------------
|
16
18
|
// Helpers
|
17
19
|
//------------------------------------------------------------------------------
|
18
20
|
|
21
|
+
const REGEXPP_LATEST_ECMA_VERSION = 2022;
|
22
|
+
|
19
23
|
/**
|
20
24
|
* Determines whether the given node is a string literal.
|
21
25
|
* @param {ASTNode} node Node to check.
|
@@ -43,11 +47,77 @@ function isStaticTemplateLiteral(node) {
|
|
43
47
|
return node.type === "TemplateLiteral" && node.expressions.length === 0;
|
44
48
|
}
|
45
49
|
|
50
|
+
const validPrecedingTokens = [
|
51
|
+
"(",
|
52
|
+
";",
|
53
|
+
"[",
|
54
|
+
",",
|
55
|
+
"=",
|
56
|
+
"+",
|
57
|
+
"*",
|
58
|
+
"-",
|
59
|
+
"?",
|
60
|
+
"~",
|
61
|
+
"%",
|
62
|
+
"**",
|
63
|
+
"!",
|
64
|
+
"typeof",
|
65
|
+
"instanceof",
|
66
|
+
"&&",
|
67
|
+
"||",
|
68
|
+
"??",
|
69
|
+
"return",
|
70
|
+
"...",
|
71
|
+
"delete",
|
72
|
+
"void",
|
73
|
+
"in",
|
74
|
+
"<",
|
75
|
+
">",
|
76
|
+
"<=",
|
77
|
+
">=",
|
78
|
+
"==",
|
79
|
+
"===",
|
80
|
+
"!=",
|
81
|
+
"!==",
|
82
|
+
"<<",
|
83
|
+
">>",
|
84
|
+
">>>",
|
85
|
+
"&",
|
86
|
+
"|",
|
87
|
+
"^",
|
88
|
+
":",
|
89
|
+
"{",
|
90
|
+
"=>",
|
91
|
+
"*=",
|
92
|
+
"<<=",
|
93
|
+
">>=",
|
94
|
+
">>>=",
|
95
|
+
"^=",
|
96
|
+
"|=",
|
97
|
+
"&=",
|
98
|
+
"??=",
|
99
|
+
"||=",
|
100
|
+
"&&=",
|
101
|
+
"**=",
|
102
|
+
"+=",
|
103
|
+
"-=",
|
104
|
+
"/=",
|
105
|
+
"%=",
|
106
|
+
"/",
|
107
|
+
"do",
|
108
|
+
"break",
|
109
|
+
"continue",
|
110
|
+
"debugger",
|
111
|
+
"case",
|
112
|
+
"throw"
|
113
|
+
];
|
114
|
+
|
46
115
|
|
47
116
|
//------------------------------------------------------------------------------
|
48
117
|
// Rule Definition
|
49
118
|
//------------------------------------------------------------------------------
|
50
119
|
|
120
|
+
/** @type {import('../shared/types').Rule} */
|
51
121
|
module.exports = {
|
52
122
|
meta: {
|
53
123
|
type: "suggestion",
|
@@ -58,6 +128,8 @@ module.exports = {
|
|
58
128
|
url: "https://eslint.org/docs/rules/prefer-regex-literals"
|
59
129
|
},
|
60
130
|
|
131
|
+
hasSuggestions: true,
|
132
|
+
|
61
133
|
schema: [
|
62
134
|
{
|
63
135
|
type: "object",
|
@@ -73,6 +145,7 @@ module.exports = {
|
|
73
145
|
|
74
146
|
messages: {
|
75
147
|
unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.",
|
148
|
+
replaceWithLiteral: "Replace with an equivalent regular expression literal.",
|
76
149
|
unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.",
|
77
150
|
unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor."
|
78
151
|
}
|
@@ -80,6 +153,7 @@ module.exports = {
|
|
80
153
|
|
81
154
|
create(context) {
|
82
155
|
const [{ disallowRedundantWrapping = false } = {}] = context.options;
|
156
|
+
const sourceCode = context.getSourceCode();
|
83
157
|
|
84
158
|
/**
|
85
159
|
* Determines whether the given identifier node is a reference to a global variable.
|
@@ -106,6 +180,27 @@ module.exports = {
|
|
106
180
|
isStaticTemplateLiteral(node.quasi);
|
107
181
|
}
|
108
182
|
|
183
|
+
/**
|
184
|
+
* Gets the value of a string
|
185
|
+
* @param {ASTNode} node The node to get the string of.
|
186
|
+
* @returns {string|null} The value of the node.
|
187
|
+
*/
|
188
|
+
function getStringValue(node) {
|
189
|
+
if (isStringLiteral(node)) {
|
190
|
+
return node.value;
|
191
|
+
}
|
192
|
+
|
193
|
+
if (isStaticTemplateLiteral(node)) {
|
194
|
+
return node.quasis[0].value.cooked;
|
195
|
+
}
|
196
|
+
|
197
|
+
if (isStringRawTaggedStaticTemplateLiteral(node)) {
|
198
|
+
return node.quasi.quasis[0].value.raw;
|
199
|
+
}
|
200
|
+
|
201
|
+
return null;
|
202
|
+
}
|
203
|
+
|
109
204
|
/**
|
110
205
|
* Determines whether the given node is considered to be a static string by the logic of this rule.
|
111
206
|
* @param {ASTNode} node Node to check.
|
@@ -151,6 +246,53 @@ module.exports = {
|
|
151
246
|
return false;
|
152
247
|
}
|
153
248
|
|
249
|
+
/**
|
250
|
+
* Returns a ecmaVersion compatible for regexpp.
|
251
|
+
* @param {any} ecmaVersion The ecmaVersion to convert.
|
252
|
+
* @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
|
253
|
+
*/
|
254
|
+
function getRegexppEcmaVersion(ecmaVersion) {
|
255
|
+
if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) {
|
256
|
+
return 5;
|
257
|
+
}
|
258
|
+
return Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION);
|
259
|
+
}
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Makes a character escaped or else returns null.
|
263
|
+
* @param {string} character The character to escape.
|
264
|
+
* @returns {string} The resulting escaped character.
|
265
|
+
*/
|
266
|
+
function resolveEscapes(character) {
|
267
|
+
switch (character) {
|
268
|
+
case "\n":
|
269
|
+
case "\\\n":
|
270
|
+
return "\\n";
|
271
|
+
|
272
|
+
case "\r":
|
273
|
+
case "\\\r":
|
274
|
+
return "\\r";
|
275
|
+
|
276
|
+
case "\t":
|
277
|
+
case "\\\t":
|
278
|
+
return "\\t";
|
279
|
+
|
280
|
+
case "\v":
|
281
|
+
case "\\\v":
|
282
|
+
return "\\v";
|
283
|
+
|
284
|
+
case "\f":
|
285
|
+
case "\\\f":
|
286
|
+
return "\\f";
|
287
|
+
|
288
|
+
case "/":
|
289
|
+
return "\\/";
|
290
|
+
|
291
|
+
default:
|
292
|
+
return null;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
154
296
|
return {
|
155
297
|
Program() {
|
156
298
|
const scope = context.getScope();
|
@@ -170,7 +312,82 @@ module.exports = {
|
|
170
312
|
context.report({ node, messageId: "unexpectedRedundantRegExp" });
|
171
313
|
}
|
172
314
|
} else if (hasOnlyStaticStringArguments(node)) {
|
173
|
-
|
315
|
+
let regexContent = getStringValue(node.arguments[0]);
|
316
|
+
let noFix = false;
|
317
|
+
let flags;
|
318
|
+
|
319
|
+
if (node.arguments[1]) {
|
320
|
+
flags = getStringValue(node.arguments[1]);
|
321
|
+
}
|
322
|
+
|
323
|
+
const regexppEcmaVersion = getRegexppEcmaVersion(context.parserOptions.ecmaVersion);
|
324
|
+
const RegExpValidatorInstance = new RegExpValidator({ ecmaVersion: regexppEcmaVersion });
|
325
|
+
|
326
|
+
try {
|
327
|
+
RegExpValidatorInstance.validatePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
|
328
|
+
if (flags) {
|
329
|
+
RegExpValidatorInstance.validateFlags(flags);
|
330
|
+
}
|
331
|
+
} catch {
|
332
|
+
noFix = true;
|
333
|
+
}
|
334
|
+
|
335
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
336
|
+
|
337
|
+
if (tokenBefore && !validPrecedingTokens.includes(tokenBefore.value)) {
|
338
|
+
noFix = true;
|
339
|
+
}
|
340
|
+
|
341
|
+
if (!/^[-a-zA-Z0-9\\[\](){} \t\r\n\v\f!@#$%^&*+^_=/~`.><?,'"|:;]*$/u.test(regexContent)) {
|
342
|
+
noFix = true;
|
343
|
+
}
|
344
|
+
|
345
|
+
if (sourceCode.getCommentsInside(node).length > 0) {
|
346
|
+
noFix = true;
|
347
|
+
}
|
348
|
+
|
349
|
+
if (regexContent && !noFix) {
|
350
|
+
let charIncrease = 0;
|
351
|
+
|
352
|
+
const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
|
353
|
+
|
354
|
+
visitRegExpAST(ast, {
|
355
|
+
onCharacterEnter(characterNode) {
|
356
|
+
const escaped = resolveEscapes(characterNode.raw);
|
357
|
+
|
358
|
+
if (escaped) {
|
359
|
+
regexContent =
|
360
|
+
regexContent.slice(0, characterNode.start + charIncrease) +
|
361
|
+
escaped +
|
362
|
+
regexContent.slice(characterNode.end + charIncrease);
|
363
|
+
|
364
|
+
if (characterNode.raw.length === 1) {
|
365
|
+
charIncrease += 1;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
}
|
369
|
+
});
|
370
|
+
}
|
371
|
+
|
372
|
+
const newRegExpValue = `/${regexContent || "(?:)"}/${flags || ""}`;
|
373
|
+
|
374
|
+
context.report({
|
375
|
+
node,
|
376
|
+
messageId: "unexpectedRegExp",
|
377
|
+
suggest: noFix ? [] : [{
|
378
|
+
messageId: "replaceWithLiteral",
|
379
|
+
fix(fixer) {
|
380
|
+
const tokenAfter = sourceCode.getTokenAfter(node);
|
381
|
+
|
382
|
+
return fixer.replaceText(
|
383
|
+
node,
|
384
|
+
(tokenBefore && !canTokensBeAdjacent(tokenBefore, newRegExpValue) && tokenBefore.range[1] === node.range[0] ? " " : "") +
|
385
|
+
newRegExpValue +
|
386
|
+
(tokenAfter && !canTokensBeAdjacent(newRegExpValue, tokenAfter) && node.range[1] === tokenAfter.range[0] ? " " : "")
|
387
|
+
);
|
388
|
+
}
|
389
|
+
}]
|
390
|
+
});
|
174
391
|
}
|
175
392
|
}
|
176
393
|
}
|
@@ -43,6 +43,7 @@ function isValidThisArg(expectedThis, thisArg, context) {
|
|
43
43
|
// Rule Definition
|
44
44
|
//------------------------------------------------------------------------------
|
45
45
|
|
46
|
+
/** @type {import('../shared/types').Rule} */
|
46
47
|
module.exports = {
|
47
48
|
meta: {
|
48
49
|
type: "suggestion",
|
@@ -122,6 +122,7 @@ function endsWithTemplateCurly(node) {
|
|
122
122
|
// Rule Definition
|
123
123
|
//------------------------------------------------------------------------------
|
124
124
|
|
125
|
+
/** @type {import('../shared/types').Rule} */
|
125
126
|
module.exports = {
|
126
127
|
meta: {
|
127
128
|
type: "suggestion",
|
@@ -187,7 +188,7 @@ module.exports = {
|
|
187
188
|
return sourceCode.getText(currentNode);
|
188
189
|
}
|
189
190
|
|
190
|
-
if (isConcatenation(currentNode) && hasStringLiteral(currentNode)
|
191
|
+
if (isConcatenation(currentNode) && hasStringLiteral(currentNode)) {
|
191
192
|
const plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, token => token.value === "+");
|
192
193
|
const textBeforePlus = getTextBetween(currentNode.left, plusSign);
|
193
194
|
const textAfterPlus = getTextBetween(plusSign, currentNode.right);
|
package/lib/rules/quote-props.js
CHANGED
package/lib/rules/quotes.js
CHANGED
package/lib/rules/radix.js
CHANGED
@@ -165,6 +165,7 @@ class SegmentInfo {
|
|
165
165
|
// Rule Definition
|
166
166
|
//------------------------------------------------------------------------------
|
167
167
|
|
168
|
+
/** @type {import('../shared/types').Rule} */
|
168
169
|
module.exports = {
|
169
170
|
meta: {
|
170
171
|
type: "problem",
|
@@ -176,7 +177,17 @@ module.exports = {
|
|
176
177
|
},
|
177
178
|
|
178
179
|
fixable: null,
|
179
|
-
|
180
|
+
|
181
|
+
schema: [{
|
182
|
+
type: "object",
|
183
|
+
properties: {
|
184
|
+
allowProperties: {
|
185
|
+
type: "boolean",
|
186
|
+
default: false
|
187
|
+
}
|
188
|
+
},
|
189
|
+
additionalProperties: false
|
190
|
+
}],
|
180
191
|
|
181
192
|
messages: {
|
182
193
|
nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.",
|
@@ -185,6 +196,8 @@ module.exports = {
|
|
185
196
|
},
|
186
197
|
|
187
198
|
create(context) {
|
199
|
+
const allowProperties = !!context.options[0] && context.options[0].allowProperties;
|
200
|
+
|
188
201
|
const sourceCode = context.getSourceCode();
|
189
202
|
const assignmentReferences = new Map();
|
190
203
|
const segmentInfo = new SegmentInfo();
|
@@ -284,7 +297,7 @@ module.exports = {
|
|
284
297
|
value: variable.name
|
285
298
|
}
|
286
299
|
});
|
287
|
-
} else {
|
300
|
+
} else if (!allowProperties) {
|
288
301
|
context.report({
|
289
302
|
node: node.parent,
|
290
303
|
messageId: "nonAtomicObjectUpdate",
|
package/lib/rules/semi-style.js
CHANGED
@@ -25,7 +25,8 @@ const SELECTOR = [
|
|
25
25
|
|
26
26
|
/**
|
27
27
|
* Get the child node list of a given node.
|
28
|
-
* This returns `
|
28
|
+
* This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
|
29
|
+
* `ClassBody#body`, or `SwitchCase#consequent`.
|
29
30
|
* This is used to check whether a node is the first/last child.
|
30
31
|
* @param {Node} node A node to get child node list.
|
31
32
|
* @returns {Node[]|null} The child node list.
|
@@ -33,7 +34,12 @@ const SELECTOR = [
|
|
33
34
|
function getChildren(node) {
|
34
35
|
const t = node.type;
|
35
36
|
|
36
|
-
if (
|
37
|
+
if (
|
38
|
+
t === "BlockStatement" ||
|
39
|
+
t === "StaticBlock" ||
|
40
|
+
t === "Program" ||
|
41
|
+
t === "ClassBody"
|
42
|
+
) {
|
37
43
|
return node.body;
|
38
44
|
}
|
39
45
|
if (t === "SwitchCase") {
|
@@ -61,6 +67,7 @@ function isLastChild(node) {
|
|
61
67
|
return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc.
|
62
68
|
}
|
63
69
|
|
70
|
+
/** @type {import('../shared/types').Rule} */
|
64
71
|
module.exports = {
|
65
72
|
meta: {
|
66
73
|
type: "layout",
|
package/lib/rules/semi.js
CHANGED
@@ -15,6 +15,7 @@ const astUtils = require("./utils/ast-utils");
|
|
15
15
|
// Rule Definition
|
16
16
|
//------------------------------------------------------------------------------
|
17
17
|
|
18
|
+
/** @type {import('../shared/types').Rule} */
|
18
19
|
module.exports = {
|
19
20
|
meta: {
|
20
21
|
type: "layout",
|
@@ -306,22 +307,31 @@ module.exports = {
|
|
306
307
|
}
|
307
308
|
|
308
309
|
/**
|
309
|
-
* Checks a node to see if it's in a one-liner block
|
310
|
+
* Checks a node to see if it's the last item in a one-liner block.
|
311
|
+
* Block is any `BlockStatement` or `StaticBlock` node. Block is a one-liner if its
|
312
|
+
* braces (and consequently everything between them) are on the same line.
|
310
313
|
* @param {ASTNode} node The node to check.
|
311
|
-
* @returns {boolean} whether the node is in a one-liner block
|
314
|
+
* @returns {boolean} whether the node is the last item in a one-liner block.
|
312
315
|
*/
|
313
|
-
function
|
316
|
+
function isLastInOneLinerBlock(node) {
|
314
317
|
const parent = node.parent;
|
315
318
|
const nextToken = sourceCode.getTokenAfter(node);
|
316
319
|
|
317
320
|
if (!nextToken || nextToken.value !== "}") {
|
318
321
|
return false;
|
319
322
|
}
|
320
|
-
|
321
|
-
|
322
|
-
parent.
|
323
|
-
|
324
|
-
|
323
|
+
|
324
|
+
if (parent.type === "BlockStatement") {
|
325
|
+
return parent.loc.start.line === parent.loc.end.line;
|
326
|
+
}
|
327
|
+
|
328
|
+
if (parent.type === "StaticBlock") {
|
329
|
+
const openingBrace = sourceCode.getFirstToken(parent, { skip: 1 }); // skip the `static` token
|
330
|
+
|
331
|
+
return openingBrace.loc.start.line === parent.loc.end.line;
|
332
|
+
}
|
333
|
+
|
334
|
+
return false;
|
325
335
|
}
|
326
336
|
|
327
337
|
/**
|
@@ -343,7 +353,7 @@ module.exports = {
|
|
343
353
|
report(node);
|
344
354
|
}
|
345
355
|
} else {
|
346
|
-
const oneLinerBlock = (exceptOneLine &&
|
356
|
+
const oneLinerBlock = (exceptOneLine && isLastInOneLinerBlock(node));
|
347
357
|
|
348
358
|
if (isSemi && oneLinerBlock) {
|
349
359
|
report(node, true);
|
package/lib/rules/sort-keys.js
CHANGED
package/lib/rules/sort-vars.js
CHANGED
@@ -146,6 +146,7 @@ function createNeverStylePattern(markers) {
|
|
146
146
|
// Rule Definition
|
147
147
|
//------------------------------------------------------------------------------
|
148
148
|
|
149
|
+
/** @type {import('../shared/types').Rule} */
|
149
150
|
module.exports = {
|
150
151
|
meta: {
|
151
152
|
type: "suggestion",
|
package/lib/rules/strict.js
CHANGED