eslint 5.14.1 → 5.15.3
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/CHANGELOG.md +51 -0
- package/README.md +2 -2
- package/lib/built-in-rules-index.js +1 -0
- package/lib/cli-engine.js +2 -2
- package/lib/config/config-file.js +3 -3
- package/lib/config/config-initializer.js +1 -1
- package/lib/config/config-validator.js +13 -13
- package/lib/config/plugins.js +1 -1
- package/lib/formatters/codeframe.js +1 -1
- package/lib/formatters/stylish.js +2 -2
- package/lib/linter.js +23 -8
- package/lib/rules/array-bracket-newline.js +2 -4
- package/lib/rules/array-callback-return.js +2 -2
- package/lib/rules/array-element-newline.js +2 -4
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/camelcase.js +2 -2
- package/lib/rules/capitalized-comments.js +12 -17
- package/lib/rules/complexity.js +6 -5
- package/lib/rules/curly.js +1 -1
- package/lib/rules/default-case.js +2 -2
- package/lib/rules/dot-notation.js +2 -2
- package/lib/rules/eol-last.js +1 -1
- package/lib/rules/eqeqeq.js +1 -2
- package/lib/rules/func-call-spacing.js +3 -4
- package/lib/rules/getter-return.js +1 -1
- package/lib/rules/handle-callback-err.js +1 -1
- package/lib/rules/id-match.js +1 -1
- package/lib/rules/implicit-arrow-linebreak.js +17 -172
- package/lib/rules/indent-legacy.js +1 -1
- package/lib/rules/indent.js +2 -2
- package/lib/rules/init-declarations.js +1 -2
- package/lib/rules/jsx-quotes.js +2 -2
- package/lib/rules/key-spacing.js +28 -55
- package/lib/rules/keyword-spacing.js +7 -7
- package/lib/rules/line-comment-position.js +5 -7
- package/lib/rules/lines-around-comment.js +1 -1
- package/lib/rules/max-depth.js +6 -5
- package/lib/rules/max-len.js +4 -4
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/max-lines.js +4 -7
- package/lib/rules/max-nested-callbacks.js +6 -5
- package/lib/rules/max-params.js +6 -5
- package/lib/rules/max-statements-per-line.js +1 -1
- package/lib/rules/max-statements.js +6 -5
- package/lib/rules/multiline-comment-style.js +9 -9
- package/lib/rules/new-cap.js +2 -2
- package/lib/rules/no-alert.js +1 -1
- package/lib/rules/no-caller.js +1 -1
- package/lib/rules/no-dupe-keys.js +2 -2
- package/lib/rules/no-else-return.js +2 -2
- package/lib/rules/no-empty-character-class.js +1 -1
- package/lib/rules/no-extra-parens.js +11 -5
- package/lib/rules/no-fallthrough.js +2 -2
- package/lib/rules/no-implicit-coercion.js +1 -1
- package/lib/rules/no-implied-eval.js +1 -1
- package/lib/rules/no-invalid-regexp.js +2 -2
- package/lib/rules/no-irregular-whitespace.js +3 -3
- package/lib/rules/no-lonely-if.js +1 -1
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-mixed-requires.js +3 -5
- package/lib/rules/no-mixed-spaces-and-tabs.js +2 -2
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-octal.js +1 -1
- package/lib/rules/no-param-reassign.js +1 -1
- package/lib/rules/no-path-concat.js +1 -1
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-return-assign.js +1 -1
- package/lib/rules/no-self-assign.js +1 -1
- package/lib/rules/no-tabs.js +2 -2
- package/lib/rules/no-template-curly-in-string.js +1 -1
- package/lib/rules/no-trailing-spaces.js +2 -2
- package/lib/rules/no-unexpected-multiline.js +1 -1
- package/lib/rules/no-unmodified-loop-condition.js +5 -5
- package/lib/rules/no-unsafe-finally.js +3 -3
- package/lib/rules/no-unused-expressions.js +2 -2
- package/lib/rules/no-unused-vars.js +10 -14
- package/lib/rules/no-use-before-define.js +5 -5
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-var.js +1 -1
- package/lib/rules/no-warning-comments.js +6 -6
- package/lib/rules/object-curly-newline.js +4 -6
- package/lib/rules/object-shorthand.js +4 -8
- package/lib/rules/one-var.js +3 -6
- package/lib/rules/padding-line-between-statements.js +4 -3
- package/lib/rules/prefer-const.js +3 -3
- package/lib/rules/prefer-destructuring.js +7 -14
- package/lib/rules/prefer-named-capture-group.js +123 -0
- package/lib/rules/prefer-object-spread.js +1 -1
- package/lib/rules/prefer-template.js +3 -3
- package/lib/rules/quote-props.js +5 -10
- package/lib/rules/quotes.js +4 -6
- package/lib/rules/semi.js +7 -8
- package/lib/rules/space-before-function-paren.js +3 -6
- package/lib/rules/spaced-comment.js +4 -4
- package/lib/rules/template-curly-spacing.js +2 -2
- package/lib/rules/use-isnan.js +1 -1
- package/lib/rules/valid-jsdoc.js +2 -2
- package/lib/rules/vars-on-top.js +1 -1
- package/lib/rules/yield-star-spacing.js +2 -2
- package/lib/rules/yoda.js +2 -2
- package/lib/testers/rule-tester.js +1 -1
- package/lib/util/ast-utils.js +12 -12
- package/lib/util/config-comment-parser.js +4 -4
- package/lib/util/glob-utils.js +15 -4
- package/lib/util/ignored-paths.js +4 -4
- package/lib/util/interpolate.js +1 -1
- package/lib/util/naming.js +6 -6
- package/lib/util/node-event-generator.js +1 -1
- package/lib/util/path-utils.js +2 -2
- package/lib/util/patterns/letters.js +1 -1
- package/lib/util/source-code.js +2 -2
- package/lib/util/xml-escape.js +1 -1
- package/package.json +10 -9
@@ -37,26 +37,22 @@ module.exports = {
|
|
37
37
|
type: "object",
|
38
38
|
properties: {
|
39
39
|
vars: {
|
40
|
-
enum: ["all", "local"]
|
41
|
-
default: "all"
|
40
|
+
enum: ["all", "local"]
|
42
41
|
},
|
43
42
|
varsIgnorePattern: {
|
44
43
|
type: "string"
|
45
44
|
},
|
46
45
|
args: {
|
47
|
-
enum: ["all", "after-used", "none"]
|
48
|
-
default: "after-used"
|
46
|
+
enum: ["all", "after-used", "none"]
|
49
47
|
},
|
50
48
|
ignoreRestSiblings: {
|
51
|
-
type: "boolean"
|
52
|
-
default: false
|
49
|
+
type: "boolean"
|
53
50
|
},
|
54
51
|
argsIgnorePattern: {
|
55
52
|
type: "string"
|
56
53
|
},
|
57
54
|
caughtErrors: {
|
58
|
-
enum: ["all", "none"]
|
59
|
-
default: "none"
|
55
|
+
enum: ["all", "none"]
|
60
56
|
},
|
61
57
|
caughtErrorsIgnorePattern: {
|
62
58
|
type: "string"
|
@@ -71,7 +67,7 @@ module.exports = {
|
|
71
67
|
create(context) {
|
72
68
|
const sourceCode = context.getSourceCode();
|
73
69
|
|
74
|
-
const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)
|
70
|
+
const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/u;
|
75
71
|
|
76
72
|
const config = {
|
77
73
|
vars: "all",
|
@@ -92,15 +88,15 @@ module.exports = {
|
|
92
88
|
config.caughtErrors = firstOption.caughtErrors || config.caughtErrors;
|
93
89
|
|
94
90
|
if (firstOption.varsIgnorePattern) {
|
95
|
-
config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern);
|
91
|
+
config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); // eslint-disable-line require-unicode-regexp
|
96
92
|
}
|
97
93
|
|
98
94
|
if (firstOption.argsIgnorePattern) {
|
99
|
-
config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern);
|
95
|
+
config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); // eslint-disable-line require-unicode-regexp
|
100
96
|
}
|
101
97
|
|
102
98
|
if (firstOption.caughtErrorsIgnorePattern) {
|
103
|
-
config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern);
|
99
|
+
config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); // eslint-disable-line require-unicode-regexp
|
104
100
|
}
|
105
101
|
}
|
106
102
|
}
|
@@ -147,7 +143,7 @@ module.exports = {
|
|
147
143
|
// Helpers
|
148
144
|
//--------------------------------------------------------------------------
|
149
145
|
|
150
|
-
const STATEMENT_TYPE = /(?:Statement|Declaration)
|
146
|
+
const STATEMENT_TYPE = /(?:Statement|Declaration)$/u;
|
151
147
|
|
152
148
|
/**
|
153
149
|
* Determines if a given variable is being exported from a module.
|
@@ -600,7 +596,7 @@ module.exports = {
|
|
600
596
|
* @private
|
601
597
|
*/
|
602
598
|
function getColumnInComment(variable, comment) {
|
603
|
-
const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "
|
599
|
+
const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "gu");
|
604
600
|
|
605
601
|
// To ignore the first text "global".
|
606
602
|
namePattern.lastIndex = comment.value.indexOf("global") + 6;
|
@@ -9,8 +9,8 @@
|
|
9
9
|
// Helpers
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)
|
13
|
-
const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement
|
12
|
+
const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
|
13
|
+
const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
|
14
14
|
|
15
15
|
/**
|
16
16
|
* Parses a given value as options.
|
@@ -154,9 +154,9 @@ module.exports = {
|
|
154
154
|
{
|
155
155
|
type: "object",
|
156
156
|
properties: {
|
157
|
-
functions: { type: "boolean"
|
158
|
-
classes: { type: "boolean"
|
159
|
-
variables: { type: "boolean"
|
157
|
+
functions: { type: "boolean" },
|
158
|
+
classes: { type: "boolean" },
|
159
|
+
variables: { type: "boolean" }
|
160
160
|
},
|
161
161
|
additionalProperties: false
|
162
162
|
}
|
package/lib/rules/no-var.js
CHANGED
@@ -77,7 +77,7 @@ function isDeclarationInitialized(node) {
|
|
77
77
|
return node.declarations.every(declarator => declarator.init !== null);
|
78
78
|
}
|
79
79
|
|
80
|
-
const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)
|
80
|
+
const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/u;
|
81
81
|
|
82
82
|
/**
|
83
83
|
* Gets the scope node which directly contains a given node.
|
@@ -47,7 +47,7 @@ module.exports = {
|
|
47
47
|
configuration = context.options[0] || {},
|
48
48
|
warningTerms = configuration.terms || ["todo", "fixme", "xxx"],
|
49
49
|
location = configuration.location || "start",
|
50
|
-
selfConfigRegEx = /\bno-warning-comments\b
|
50
|
+
selfConfigRegEx = /\bno-warning-comments\b/u;
|
51
51
|
|
52
52
|
/**
|
53
53
|
* Convert a warning term into a RegExp which will match a comment containing that whole word in the specified
|
@@ -58,7 +58,7 @@ module.exports = {
|
|
58
58
|
* @returns {RegExp} The term converted to a RegExp
|
59
59
|
*/
|
60
60
|
function convertToRegExp(term) {
|
61
|
-
const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/
|
61
|
+
const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/gu, "\\$&");
|
62
62
|
const wordBoundary = "\\b";
|
63
63
|
const eitherOrWordBoundary = `|${wordBoundary}`;
|
64
64
|
let prefix;
|
@@ -73,7 +73,7 @@ module.exports = {
|
|
73
73
|
* In these cases, use no bounding match. Same applies for the
|
74
74
|
* prefix, handled below.
|
75
75
|
*/
|
76
|
-
const suffix = /\w
|
76
|
+
const suffix = /\w$/u.test(term) ? "\\b" : "";
|
77
77
|
|
78
78
|
if (location === "start") {
|
79
79
|
|
@@ -82,7 +82,7 @@ module.exports = {
|
|
82
82
|
* there's no need to worry about word boundaries.
|
83
83
|
*/
|
84
84
|
prefix = "^\\s*";
|
85
|
-
} else if (/^\w
|
85
|
+
} else if (/^\w/u.test(term)) {
|
86
86
|
prefix = wordBoundary;
|
87
87
|
} else {
|
88
88
|
prefix = "";
|
@@ -95,7 +95,7 @@ module.exports = {
|
|
95
95
|
* ^\s*TERM\b. This checks the word boundary
|
96
96
|
* at the beginning of the comment.
|
97
97
|
*/
|
98
|
-
return new RegExp(prefix + escaped + suffix, "i");
|
98
|
+
return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
|
99
99
|
}
|
100
100
|
|
101
101
|
/*
|
@@ -103,7 +103,7 @@ module.exports = {
|
|
103
103
|
* \bTERM\b|\bTERM\b, this checks the entire comment
|
104
104
|
* for the term.
|
105
105
|
*/
|
106
|
-
return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i");
|
106
|
+
return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
|
107
107
|
}
|
108
108
|
|
109
109
|
const warningRegExps = warningTerms.map(convertToRegExp);
|
@@ -26,16 +26,14 @@ const OPTION_VALUE = {
|
|
26
26
|
type: "object",
|
27
27
|
properties: {
|
28
28
|
multiline: {
|
29
|
-
type: "boolean"
|
30
|
-
default: false
|
29
|
+
type: "boolean"
|
31
30
|
},
|
32
31
|
minProperties: {
|
33
32
|
type: "integer",
|
34
33
|
minimum: 0
|
35
34
|
},
|
36
35
|
consistent: {
|
37
|
-
type: "boolean"
|
38
|
-
default: false
|
36
|
+
type: "boolean"
|
39
37
|
}
|
40
38
|
},
|
41
39
|
additionalProperties: false,
|
@@ -61,9 +59,9 @@ function normalizeOptionValue(value) {
|
|
61
59
|
} else if (value === "never") {
|
62
60
|
minProperties = Number.POSITIVE_INFINITY;
|
63
61
|
} else {
|
64
|
-
multiline = value.multiline;
|
62
|
+
multiline = Boolean(value.multiline);
|
65
63
|
minProperties = value.minProperties || Number.POSITIVE_INFINITY;
|
66
|
-
consistent = value.consistent;
|
64
|
+
consistent = Boolean(value.consistent);
|
67
65
|
}
|
68
66
|
} else {
|
69
67
|
consistent = true;
|
@@ -57,8 +57,7 @@ module.exports = {
|
|
57
57
|
type: "object",
|
58
58
|
properties: {
|
59
59
|
avoidQuotes: {
|
60
|
-
type: "boolean"
|
61
|
-
default: false
|
60
|
+
type: "boolean"
|
62
61
|
}
|
63
62
|
},
|
64
63
|
additionalProperties: false
|
@@ -77,16 +76,13 @@ module.exports = {
|
|
77
76
|
type: "object",
|
78
77
|
properties: {
|
79
78
|
ignoreConstructors: {
|
80
|
-
type: "boolean"
|
81
|
-
default: false
|
79
|
+
type: "boolean"
|
82
80
|
},
|
83
81
|
avoidQuotes: {
|
84
|
-
type: "boolean"
|
85
|
-
default: false
|
82
|
+
type: "boolean"
|
86
83
|
},
|
87
84
|
avoidExplicitReturnArrows: {
|
88
|
-
type: "boolean"
|
89
|
-
default: false
|
85
|
+
type: "boolean"
|
90
86
|
}
|
91
87
|
},
|
92
88
|
additionalProperties: false
|
package/lib/rules/one-var.js
CHANGED
@@ -36,16 +36,13 @@ module.exports = {
|
|
36
36
|
default: false
|
37
37
|
},
|
38
38
|
var: {
|
39
|
-
enum: ["always", "never", "consecutive"]
|
40
|
-
default: "always"
|
39
|
+
enum: ["always", "never", "consecutive"]
|
41
40
|
},
|
42
41
|
let: {
|
43
|
-
enum: ["always", "never", "consecutive"]
|
44
|
-
default: "always"
|
42
|
+
enum: ["always", "never", "consecutive"]
|
45
43
|
},
|
46
44
|
const: {
|
47
|
-
enum: ["always", "never", "consecutive"]
|
48
|
-
default: "always"
|
45
|
+
enum: ["always", "never", "consecutive"]
|
49
46
|
}
|
50
47
|
},
|
51
48
|
additionalProperties: false
|
@@ -17,10 +17,11 @@ const astUtils = require("../util/ast-utils");
|
|
17
17
|
|
18
18
|
const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`;
|
19
19
|
const PADDING_LINE_SEQUENCE = new RegExp(
|
20
|
-
String.raw`^(\s*?${LT})\s*${LT}(\s*;?)
|
20
|
+
String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`,
|
21
|
+
"u"
|
21
22
|
);
|
22
|
-
const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)
|
23
|
-
const CJS_IMPORT = /^require\(
|
23
|
+
const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
|
24
|
+
const CJS_IMPORT = /^require\(/u;
|
24
25
|
|
25
26
|
/**
|
26
27
|
* Creates tester which check if a node starts with specific keyword.
|
@@ -11,9 +11,9 @@ const astUtils = require("../util/ast-utils");
|
|
11
11
|
// Helpers
|
12
12
|
//------------------------------------------------------------------------------
|
13
13
|
|
14
|
-
const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)
|
15
|
-
const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)
|
16
|
-
const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)
|
14
|
+
const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u;
|
15
|
+
const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u;
|
16
|
+
const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u;
|
17
17
|
|
18
18
|
/**
|
19
19
|
* Checks whether a given node is located at `ForStatement.init` or not.
|
@@ -36,12 +36,10 @@ module.exports = {
|
|
36
36
|
type: "object",
|
37
37
|
properties: {
|
38
38
|
array: {
|
39
|
-
type: "boolean"
|
40
|
-
default: true
|
39
|
+
type: "boolean"
|
41
40
|
},
|
42
41
|
object: {
|
43
|
-
type: "boolean"
|
44
|
-
default: true
|
42
|
+
type: "boolean"
|
45
43
|
}
|
46
44
|
},
|
47
45
|
additionalProperties: false
|
@@ -50,12 +48,10 @@ module.exports = {
|
|
50
48
|
type: "object",
|
51
49
|
properties: {
|
52
50
|
array: {
|
53
|
-
type: "boolean"
|
54
|
-
default: true
|
51
|
+
type: "boolean"
|
55
52
|
},
|
56
53
|
object: {
|
57
|
-
type: "boolean"
|
58
|
-
default: true
|
54
|
+
type: "boolean"
|
59
55
|
}
|
60
56
|
},
|
61
57
|
additionalProperties: false
|
@@ -67,12 +63,10 @@ module.exports = {
|
|
67
63
|
type: "object",
|
68
64
|
properties: {
|
69
65
|
array: {
|
70
|
-
type: "boolean"
|
71
|
-
default: true
|
66
|
+
type: "boolean"
|
72
67
|
},
|
73
68
|
object: {
|
74
|
-
type: "boolean"
|
75
|
-
default: true
|
69
|
+
type: "boolean"
|
76
70
|
}
|
77
71
|
},
|
78
72
|
additionalProperties: false
|
@@ -83,8 +77,7 @@ module.exports = {
|
|
83
77
|
type: "object",
|
84
78
|
properties: {
|
85
79
|
enforceForRenamedProperties: {
|
86
|
-
type: "boolean"
|
87
|
-
default: false
|
80
|
+
type: "boolean"
|
88
81
|
}
|
89
82
|
},
|
90
83
|
additionalProperties: false
|
@@ -0,0 +1,123 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to enforce requiring named capture groups in regular expression.
|
3
|
+
* @author Pig Fang <https://github.com/g-plane>
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const {
|
13
|
+
CALL,
|
14
|
+
CONSTRUCT,
|
15
|
+
ReferenceTracker,
|
16
|
+
getStringIfConstant
|
17
|
+
} = require("eslint-utils");
|
18
|
+
const regexpp = require("regexpp");
|
19
|
+
|
20
|
+
//------------------------------------------------------------------------------
|
21
|
+
// Helpers
|
22
|
+
//------------------------------------------------------------------------------
|
23
|
+
|
24
|
+
const parser = new regexpp.RegExpParser();
|
25
|
+
|
26
|
+
//------------------------------------------------------------------------------
|
27
|
+
// Rule Definition
|
28
|
+
//------------------------------------------------------------------------------
|
29
|
+
|
30
|
+
module.exports = {
|
31
|
+
meta: {
|
32
|
+
type: "suggestion",
|
33
|
+
|
34
|
+
docs: {
|
35
|
+
description: "enforce using named capture group in regular expression",
|
36
|
+
category: "Best Practices",
|
37
|
+
recommended: false,
|
38
|
+
url: "https://eslint.org/docs/rules/prefer-named-capture-group"
|
39
|
+
},
|
40
|
+
|
41
|
+
schema: [],
|
42
|
+
|
43
|
+
messages: {
|
44
|
+
required: "Capture group '{{group}}' should be converted to a named or non-capturing group."
|
45
|
+
}
|
46
|
+
},
|
47
|
+
|
48
|
+
create(context) {
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Function to check regular expression.
|
52
|
+
*
|
53
|
+
* @param {string} regex The regular expression to be check.
|
54
|
+
* @param {ASTNode} node AST node which contains regular expression.
|
55
|
+
* @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not.
|
56
|
+
* @returns {void}
|
57
|
+
*/
|
58
|
+
function checkRegex(regex, node, uFlag) {
|
59
|
+
let ast;
|
60
|
+
|
61
|
+
try {
|
62
|
+
ast = parser.parsePattern(regex, 0, regex.length, uFlag);
|
63
|
+
} catch (_) {
|
64
|
+
|
65
|
+
// ignore regex syntax errors
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
regexpp.visitRegExpAST(ast, {
|
70
|
+
onCapturingGroupEnter(group) {
|
71
|
+
if (!group.name) {
|
72
|
+
const locNode = node.type === "Literal" ? node : node.arguments[0];
|
73
|
+
|
74
|
+
context.report({
|
75
|
+
node,
|
76
|
+
messageId: "required",
|
77
|
+
loc: {
|
78
|
+
start: {
|
79
|
+
line: locNode.loc.start.line,
|
80
|
+
column: locNode.loc.start.column + group.start + 1
|
81
|
+
},
|
82
|
+
end: {
|
83
|
+
line: locNode.loc.start.line,
|
84
|
+
column: locNode.loc.start.column + group.end + 1
|
85
|
+
}
|
86
|
+
},
|
87
|
+
data: {
|
88
|
+
group: group.raw
|
89
|
+
}
|
90
|
+
});
|
91
|
+
}
|
92
|
+
}
|
93
|
+
});
|
94
|
+
}
|
95
|
+
|
96
|
+
return {
|
97
|
+
Literal(node) {
|
98
|
+
if (node.regex) {
|
99
|
+
checkRegex(node.regex.pattern, node, node.regex.flags.includes("u"));
|
100
|
+
}
|
101
|
+
},
|
102
|
+
Program() {
|
103
|
+
const scope = context.getScope();
|
104
|
+
const tracker = new ReferenceTracker(scope);
|
105
|
+
const traceMap = {
|
106
|
+
RegExp: {
|
107
|
+
[CALL]: true,
|
108
|
+
[CONSTRUCT]: true
|
109
|
+
}
|
110
|
+
};
|
111
|
+
|
112
|
+
for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
|
113
|
+
const regex = getStringIfConstant(node.arguments[0]);
|
114
|
+
const flags = getStringIfConstant(node.arguments[1]);
|
115
|
+
|
116
|
+
if (regex) {
|
117
|
+
checkRegex(regex, node, flags && flags.includes("u"));
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
};
|
122
|
+
}
|
123
|
+
};
|
@@ -52,7 +52,7 @@ function isOctalEscapeSequence(node) {
|
|
52
52
|
return false;
|
53
53
|
}
|
54
54
|
|
55
|
-
const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/);
|
55
|
+
const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/u);
|
56
56
|
|
57
57
|
if (match) {
|
58
58
|
|
@@ -187,14 +187,14 @@ module.exports = {
|
|
187
187
|
* for some reason, don't add another backslash, because that would change the meaning of the code (it would cause
|
188
188
|
* an actual backslash character to appear before the dollar sign).
|
189
189
|
*/
|
190
|
-
return `\`${currentNode.raw.slice(1, -1).replace(/\\*(
|
190
|
+
return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\$\{|`)/gu, matched => {
|
191
191
|
if (matched.lastIndexOf("\\") % 2) {
|
192
192
|
return `\\${matched}`;
|
193
193
|
}
|
194
194
|
return matched;
|
195
195
|
|
196
196
|
// Unescape any quotes that appear in the original Literal that no longer need to be escaped.
|
197
|
-
}).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "
|
197
|
+
}).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "gu"), currentNode.raw[0])}\``;
|
198
198
|
}
|
199
199
|
|
200
200
|
if (currentNode.type === "TemplateLiteral") {
|
package/lib/rules/quote-props.js
CHANGED
@@ -32,8 +32,7 @@ module.exports = {
|
|
32
32
|
type: "array",
|
33
33
|
items: [
|
34
34
|
{
|
35
|
-
enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
|
36
|
-
default: "always"
|
35
|
+
enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
|
37
36
|
}
|
38
37
|
],
|
39
38
|
minItems: 0,
|
@@ -43,23 +42,19 @@ module.exports = {
|
|
43
42
|
type: "array",
|
44
43
|
items: [
|
45
44
|
{
|
46
|
-
enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
|
47
|
-
default: "always"
|
45
|
+
enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
|
48
46
|
},
|
49
47
|
{
|
50
48
|
type: "object",
|
51
49
|
properties: {
|
52
50
|
keywords: {
|
53
|
-
type: "boolean"
|
54
|
-
default: false
|
51
|
+
type: "boolean"
|
55
52
|
},
|
56
53
|
unnecessary: {
|
57
|
-
type: "boolean"
|
58
|
-
default: true
|
54
|
+
type: "boolean"
|
59
55
|
},
|
60
56
|
numbers: {
|
61
|
-
type: "boolean"
|
62
|
-
default: false
|
57
|
+
type: "boolean"
|
63
58
|
}
|
64
59
|
},
|
65
60
|
additionalProperties: false
|
package/lib/rules/quotes.js
CHANGED
@@ -34,7 +34,7 @@ const QUOTE_SETTINGS = {
|
|
34
34
|
};
|
35
35
|
|
36
36
|
// An unescaped newline is a newline preceded by an even number of backslashes.
|
37
|
-
const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]
|
37
|
+
const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u");
|
38
38
|
|
39
39
|
/**
|
40
40
|
* Switches quoting of javascript string between ' " and `
|
@@ -54,7 +54,7 @@ QUOTE_SETTINGS.backtick.convert = function(str) {
|
|
54
54
|
if (newQuote === oldQuote) {
|
55
55
|
return str;
|
56
56
|
}
|
57
|
-
return newQuote + str.slice(1, -1).replace(/\\(
|
57
|
+
return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => {
|
58
58
|
if (escaped === oldQuote || oldQuote === "`" && escaped === "${") {
|
59
59
|
return escaped; // unescape
|
60
60
|
}
|
@@ -100,12 +100,10 @@ module.exports = {
|
|
100
100
|
type: "object",
|
101
101
|
properties: {
|
102
102
|
avoidEscape: {
|
103
|
-
type: "boolean"
|
104
|
-
default: false
|
103
|
+
type: "boolean"
|
105
104
|
},
|
106
105
|
allowTemplateLiterals: {
|
107
|
-
type: "boolean"
|
108
|
-
default: false
|
106
|
+
type: "boolean"
|
109
107
|
}
|
110
108
|
},
|
111
109
|
additionalProperties: false
|
package/lib/rules/semi.js
CHANGED
@@ -40,8 +40,7 @@ module.exports = {
|
|
40
40
|
type: "object",
|
41
41
|
properties: {
|
42
42
|
beforeStatementContinuationChars: {
|
43
|
-
enum: ["always", "any", "never"]
|
44
|
-
default: "any"
|
43
|
+
enum: ["always", "any", "never"]
|
45
44
|
}
|
46
45
|
},
|
47
46
|
additionalProperties: false
|
@@ -59,7 +58,7 @@ module.exports = {
|
|
59
58
|
{
|
60
59
|
type: "object",
|
61
60
|
properties: {
|
62
|
-
omitLastInOneLineBlock: { type: "boolean"
|
61
|
+
omitLastInOneLineBlock: { type: "boolean" }
|
63
62
|
},
|
64
63
|
additionalProperties: false
|
65
64
|
}
|
@@ -73,11 +72,11 @@ module.exports = {
|
|
73
72
|
|
74
73
|
create(context) {
|
75
74
|
|
76
|
-
const OPT_OUT_PATTERN = /^[-[(/+`]
|
75
|
+
const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-`
|
77
76
|
const options = context.options[1];
|
78
77
|
const never = context.options[0] === "never";
|
79
|
-
const exceptOneLine = options && options.omitLastInOneLineBlock;
|
80
|
-
const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars;
|
78
|
+
const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
|
79
|
+
const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any";
|
81
80
|
const sourceCode = context.getSourceCode();
|
82
81
|
|
83
82
|
//--------------------------------------------------------------------------
|
@@ -292,7 +291,7 @@ module.exports = {
|
|
292
291
|
const parent = node.parent;
|
293
292
|
|
294
293
|
if ((parent.type !== "ForStatement" || parent.init !== node) &&
|
295
|
-
(!/^For(?:In|Of)Statement
|
294
|
+
(!/^For(?:In|Of)Statement/u.test(parent.type) || parent.left !== node)
|
296
295
|
) {
|
297
296
|
checkForSemicolon(node);
|
298
297
|
}
|
@@ -319,7 +318,7 @@ module.exports = {
|
|
319
318
|
}
|
320
319
|
},
|
321
320
|
ExportDefaultDeclaration(node) {
|
322
|
-
if (!/(?:Class|Function)Declaration
|
321
|
+
if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) {
|
323
322
|
checkForSemicolon(node);
|
324
323
|
}
|
325
324
|
}
|
@@ -37,16 +37,13 @@ module.exports = {
|
|
37
37
|
type: "object",
|
38
38
|
properties: {
|
39
39
|
anonymous: {
|
40
|
-
enum: ["always", "never", "ignore"]
|
41
|
-
default: "always"
|
40
|
+
enum: ["always", "never", "ignore"]
|
42
41
|
},
|
43
42
|
named: {
|
44
|
-
enum: ["always", "never", "ignore"]
|
45
|
-
default: "always"
|
43
|
+
enum: ["always", "never", "ignore"]
|
46
44
|
},
|
47
45
|
asyncArrow: {
|
48
|
-
enum: ["always", "never", "ignore"]
|
49
|
-
default: "always"
|
46
|
+
enum: ["always", "never", "ignore"]
|
50
47
|
}
|
51
48
|
},
|
52
49
|
additionalProperties: false
|