eslint-plugin-unicorn 42.0.0 → 43.0.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/configs/recommended.js +3 -3
- package/index.js +1 -0
- package/package.json +24 -24
- package/readme.md +5 -4
- package/rules/ast/index.js +20 -0
- package/rules/ast/is-arrow-function-body.js +7 -0
- package/rules/{utils → ast}/is-static-require.js +3 -2
- package/rules/ast/is-undefined.js +7 -0
- package/rules/ast/literal.js +29 -0
- package/rules/better-regex.js +4 -10
- package/rules/consistent-function-scoping.js +0 -1
- package/rules/explicit-length-check.js +3 -3
- package/rules/filename-case.js +1 -1
- package/rules/fix/switch-new-expression-to-call-expression.js +3 -3
- package/rules/new-for-builtins.js +47 -44
- package/rules/no-array-for-each.js +78 -58
- package/rules/no-array-reduce.js +54 -42
- package/rules/no-await-expression-member.js +2 -2
- package/rules/no-console-spaces.js +2 -5
- package/rules/no-for-loop.js +3 -3
- package/rules/no-useless-undefined.js +3 -2
- package/rules/no-zero-fractions.js +3 -2
- package/rules/number-literal-case.js +3 -3
- package/rules/numeric-separators-style.js +2 -1
- package/rules/prefer-add-event-listener.js +2 -11
- package/rules/prefer-array-find.js +1 -2
- package/rules/prefer-array-some.js +3 -4
- package/rules/prefer-at.js +2 -2
- package/rules/prefer-event-target.js +39 -0
- package/rules/prefer-includes.js +2 -2
- package/rules/prefer-json-parse-buffer.js +1 -0
- package/rules/prefer-keyboard-event-key.js +2 -2
- package/rules/prefer-logical-operator-over-ternary.js +155 -0
- package/rules/prefer-module.js +1 -1
- package/rules/prefer-negative-index.js +2 -2
- package/rules/prefer-node-protocol.js +22 -43
- package/rules/prefer-number-properties.js +76 -97
- package/rules/prefer-query-selector.js +9 -14
- package/rules/prefer-reflect-apply.js +3 -5
- package/rules/prefer-regexp-test.js +5 -12
- package/rules/prefer-spread.js +3 -3
- package/rules/prefer-string-replace-all.js +4 -9
- package/rules/prefer-string-slice.js +5 -7
- package/rules/prefer-type-error.js +4 -4
- package/rules/prevent-abbreviations.js +2 -2
- package/rules/selectors/not-dom-node.js +3 -1
- package/rules/shared/abbreviations.js +2 -0
- package/rules/shared/negative-index.js +2 -2
- package/rules/text-encoding-identifier-case.js +17 -1
- package/rules/utils/boolean.js +6 -16
- package/rules/utils/get-documentation-url.js +1 -1
- package/rules/utils/is-logical-expression.js +1 -2
- package/rules/utils/is-number.js +1 -1
- package/rules/utils/is-same-reference.js +1 -1
- package/rules/utils/numeric.js +5 -7
- package/rules/utils/rule.js +2 -2
- package/rules/utils/should-add-parentheses-to-logical-expression-child.js +12 -4
- package/rules/import-index.js +0 -63
- package/rules/utils/is-literal-value.js +0 -12
package/configs/recommended.js
CHANGED
|
@@ -22,7 +22,6 @@ module.exports = {
|
|
|
22
22
|
'unicorn/expiring-todo-comments': 'error',
|
|
23
23
|
'unicorn/explicit-length-check': 'error',
|
|
24
24
|
'unicorn/filename-case': 'error',
|
|
25
|
-
'unicorn/import-index': 'off',
|
|
26
25
|
'unicorn/import-style': 'error',
|
|
27
26
|
'unicorn/new-for-builtins': 'error',
|
|
28
27
|
'unicorn/no-abusive-eslint-disable': 'error',
|
|
@@ -79,10 +78,12 @@ module.exports = {
|
|
|
79
78
|
'unicorn/prefer-dom-node-dataset': 'error',
|
|
80
79
|
'unicorn/prefer-dom-node-remove': 'error',
|
|
81
80
|
'unicorn/prefer-dom-node-text-content': 'error',
|
|
81
|
+
'unicorn/prefer-event-target': 'error',
|
|
82
82
|
'unicorn/prefer-export-from': 'error',
|
|
83
83
|
'unicorn/prefer-includes': 'error',
|
|
84
84
|
'unicorn/prefer-json-parse-buffer': 'off',
|
|
85
85
|
'unicorn/prefer-keyboard-event-key': 'error',
|
|
86
|
+
'unicorn/prefer-logical-operator-over-ternary': 'error',
|
|
86
87
|
'unicorn/prefer-math-trunc': 'error',
|
|
87
88
|
'unicorn/prefer-modern-dom-apis': 'error',
|
|
88
89
|
'unicorn/prefer-modern-math-apis': 'error',
|
|
@@ -106,8 +107,7 @@ module.exports = {
|
|
|
106
107
|
'unicorn/prefer-string-trim-start-end': 'error',
|
|
107
108
|
'unicorn/prefer-switch': 'error',
|
|
108
109
|
'unicorn/prefer-ternary': 'error',
|
|
109
|
-
|
|
110
|
-
'unicorn/prefer-top-level-await': 'off',
|
|
110
|
+
'unicorn/prefer-top-level-await': 'error',
|
|
111
111
|
'unicorn/prefer-type-error': 'error',
|
|
112
112
|
'unicorn/prevent-abbreviations': 'error',
|
|
113
113
|
'unicorn/relative-url-style': 'error',
|
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const allRulesEnabledConfig = require('./configs/all.js');
|
|
|
6
6
|
|
|
7
7
|
const deprecatedRules = createDeprecatedRules({
|
|
8
8
|
// {ruleId: ReplacementRuleId | ReplacementRuleId[]}, if no replacement, use `{ruleId: []}`
|
|
9
|
+
'import-index': [],
|
|
9
10
|
'no-array-instanceof': 'unicorn/no-instanceof-array',
|
|
10
11
|
'no-fn-reference-in-iterator': 'unicorn/no-array-callback-reference',
|
|
11
12
|
'no-reduce': 'unicorn/no-array-reduce',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-unicorn",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "43.0.0",
|
|
4
|
+
"description": "More than 100 powerful ESLint rules",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/eslint-plugin-unicorn",
|
|
7
7
|
"funding": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://sindresorhus.com"
|
|
12
12
|
},
|
|
13
13
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
14
|
+
"node": ">=14.18"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"create-rule": "node ./scripts/create-rule.mjs && npm run generate-rule-notices && npm run generate-rules-table",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"xo"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@babel/helper-validator-identifier": "^7.
|
|
50
|
-
"ci-info": "^3.3.
|
|
49
|
+
"@babel/helper-validator-identifier": "^7.18.6",
|
|
50
|
+
"ci-info": "^3.3.2",
|
|
51
51
|
"clean-regexp": "^1.0.0",
|
|
52
52
|
"eslint-utils": "^3.0.0",
|
|
53
53
|
"esquery": "^1.4.0",
|
|
@@ -58,39 +58,39 @@
|
|
|
58
58
|
"read-pkg-up": "^7.0.1",
|
|
59
59
|
"regexp-tree": "^0.1.24",
|
|
60
60
|
"safe-regex": "^2.1.1",
|
|
61
|
-
"semver": "^7.3.
|
|
61
|
+
"semver": "^7.3.7",
|
|
62
62
|
"strip-indent": "^3.0.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@babel/code-frame": "^7.
|
|
66
|
-
"@babel/core": "^7.
|
|
67
|
-
"@babel/eslint-parser": "^7.
|
|
65
|
+
"@babel/code-frame": "^7.18.6",
|
|
66
|
+
"@babel/core": "^7.18.6",
|
|
67
|
+
"@babel/eslint-parser": "^7.18.2",
|
|
68
68
|
"@lubien/fixture-beta-package": "^1.0.0-beta.1",
|
|
69
|
-
"@typescript-eslint/parser": "^5.
|
|
69
|
+
"@typescript-eslint/parser": "^5.30.0",
|
|
70
70
|
"ava": "^3.15.0",
|
|
71
|
-
"c8": "^7.11.
|
|
72
|
-
"chalk": "^5.0.
|
|
71
|
+
"c8": "^7.11.3",
|
|
72
|
+
"chalk": "^5.0.1",
|
|
73
73
|
"enquirer": "^2.3.6",
|
|
74
|
-
"eslint": "^8.
|
|
74
|
+
"eslint": "^8.18.0",
|
|
75
75
|
"eslint-ava-rule-tester": "^4.0.0",
|
|
76
|
-
"eslint-plugin-eslint-plugin": "^4.
|
|
76
|
+
"eslint-plugin-eslint-plugin": "^4.3.0",
|
|
77
77
|
"eslint-plugin-internal-rules": "file:./scripts/internal-rules/",
|
|
78
|
-
"eslint-remote-tester": "^
|
|
79
|
-
"eslint-remote-tester-repositories": "^0.0.
|
|
80
|
-
"execa": "^6.
|
|
78
|
+
"eslint-remote-tester": "^3.0.0",
|
|
79
|
+
"eslint-remote-tester-repositories": "^0.0.6",
|
|
80
|
+
"execa": "^6.1.0",
|
|
81
81
|
"listr": "^0.14.3",
|
|
82
82
|
"lodash-es": "^4.17.21",
|
|
83
|
-
"markdownlint-cli": "^0.
|
|
84
|
-
"mem": "^9.0.
|
|
85
|
-
"npm-package-json-lint": "^
|
|
83
|
+
"markdownlint-cli": "^0.31.1",
|
|
84
|
+
"mem": "^9.0.2",
|
|
85
|
+
"npm-package-json-lint": "^6.3.0",
|
|
86
86
|
"npm-run-all": "^4.1.5",
|
|
87
87
|
"outdent": "^0.8.0",
|
|
88
|
-
"typescript": "^4.
|
|
89
|
-
"vue-eslint-parser": "^
|
|
90
|
-
"xo": "^0.
|
|
88
|
+
"typescript": "^4.7.4",
|
|
89
|
+
"vue-eslint-parser": "^9.0.3",
|
|
90
|
+
"xo": "^0.50.0"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
|
-
"eslint": ">=8.
|
|
93
|
+
"eslint": ">=8.18.0"
|
|
94
94
|
},
|
|
95
95
|
"ava": {
|
|
96
96
|
"files": [
|
package/readme.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<!-- markdownlint-disable-next-line no-inline-html -->
|
|
4
4
|
<img src="https://cloud.githubusercontent.com/assets/170270/18659176/1cc373d0-7f33-11e6-890f-0ba35362ee7e.jpg" width="180" align="right">
|
|
5
5
|
|
|
6
|
-
>
|
|
6
|
+
> More than 100 powerful ESLint rules
|
|
7
7
|
|
|
8
8
|
You might want to check out [XO](https://github.com/xojs/xo), which includes this plugin.
|
|
9
9
|
|
|
@@ -64,12 +64,11 @@ Each rule has emojis denoting:
|
|
|
64
64
|
| [expiring-todo-comments](docs/rules/expiring-todo-comments.md) | Add expiration conditions to TODO comments. | ✅ | | |
|
|
65
65
|
| [explicit-length-check](docs/rules/explicit-length-check.md) | Enforce explicitly comparing the `length` or `size` property of a value. | ✅ | 🔧 | 💡 |
|
|
66
66
|
| [filename-case](docs/rules/filename-case.md) | Enforce a case style for filenames. | ✅ | | |
|
|
67
|
-
| [import-index](docs/rules/import-index.md) | Enforce importing index files with `.`. | | 🔧 | |
|
|
68
67
|
| [import-style](docs/rules/import-style.md) | Enforce specific import styles per module. | ✅ | | |
|
|
69
68
|
| [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | ✅ | 🔧 | |
|
|
70
69
|
| [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) | Enforce specifying rules to disable in `eslint-disable` comments. | ✅ | | |
|
|
71
70
|
| [no-array-callback-reference](docs/rules/no-array-callback-reference.md) | Prevent passing a function reference directly to iterator methods. | ✅ | | 💡 |
|
|
72
|
-
| [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `for…of` over `
|
|
71
|
+
| [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `for…of` over the `forEach` method. | ✅ | 🔧 | 💡 |
|
|
73
72
|
| [no-array-method-this-argument](docs/rules/no-array-method-this-argument.md) | Disallow using the `this` argument in array methods. | ✅ | 🔧 | 💡 |
|
|
74
73
|
| [no-array-push-push](docs/rules/no-array-push-push.md) | Enforce combining multiple `Array#push()` into one call. | ✅ | 🔧 | 💡 |
|
|
75
74
|
| [no-array-reduce](docs/rules/no-array-reduce.md) | Disallow `Array#reduce()` and `Array#reduceRight()`. | ✅ | | |
|
|
@@ -119,10 +118,12 @@ Each rule has emojis denoting:
|
|
|
119
118
|
| [prefer-dom-node-dataset](docs/rules/prefer-dom-node-dataset.md) | Prefer using `.dataset` on DOM elements over calling attribute methods. | ✅ | 🔧 | |
|
|
120
119
|
| [prefer-dom-node-remove](docs/rules/prefer-dom-node-remove.md) | Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`. | ✅ | 🔧 | 💡 |
|
|
121
120
|
| [prefer-dom-node-text-content](docs/rules/prefer-dom-node-text-content.md) | Prefer `.textContent` over `.innerText`. | ✅ | | 💡 |
|
|
121
|
+
| [prefer-event-target](docs/rules/prefer-event-target.md) | Prefer `EventTarget` over `EventEmitter`. | ✅ | | |
|
|
122
122
|
| [prefer-export-from](docs/rules/prefer-export-from.md) | Prefer `export…from` when re-exporting. | ✅ | 🔧 | 💡 |
|
|
123
123
|
| [prefer-includes](docs/rules/prefer-includes.md) | Prefer `.includes()` over `.indexOf()` and `Array#some()` when checking for existence or non-existence. | ✅ | 🔧 | 💡 |
|
|
124
124
|
| [prefer-json-parse-buffer](docs/rules/prefer-json-parse-buffer.md) | Prefer reading a JSON file as a buffer. | | 🔧 | |
|
|
125
125
|
| [prefer-keyboard-event-key](docs/rules/prefer-keyboard-event-key.md) | Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. | ✅ | 🔧 | |
|
|
126
|
+
| [prefer-logical-operator-over-ternary](docs/rules/prefer-logical-operator-over-ternary.md) | Prefer using a logical operator over a ternary. | ✅ | | 💡 |
|
|
126
127
|
| [prefer-math-trunc](docs/rules/prefer-math-trunc.md) | Enforce the use of `Math.trunc` instead of bitwise operators. | ✅ | 🔧 | 💡 |
|
|
127
128
|
| [prefer-modern-dom-apis](docs/rules/prefer-modern-dom-apis.md) | Prefer `.before()` over `.insertBefore()`, `.replaceWith()` over `.replaceChild()`, prefer one of `.before()`, `.after()`, `.append()` or `.prepend()` over `insertAdjacentText()` and `insertAdjacentElement()`. | ✅ | 🔧 | |
|
|
128
129
|
| [prefer-modern-math-apis](docs/rules/prefer-modern-math-apis.md) | Prefer modern `Math` APIs over legacy patterns. | ✅ | 🔧 | |
|
|
@@ -145,7 +146,7 @@ Each rule has emojis denoting:
|
|
|
145
146
|
| [prefer-string-trim-start-end](docs/rules/prefer-string-trim-start-end.md) | Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`. | ✅ | 🔧 | |
|
|
146
147
|
| [prefer-switch](docs/rules/prefer-switch.md) | Prefer `switch` over multiple `else-if`. | ✅ | 🔧 | |
|
|
147
148
|
| [prefer-ternary](docs/rules/prefer-ternary.md) | Prefer ternary expressions over simple `if-else` statements. | ✅ | 🔧 | |
|
|
148
|
-
| [prefer-top-level-await](docs/rules/prefer-top-level-await.md) | Prefer top-level await over top-level promises and async function calls. |
|
|
149
|
+
| [prefer-top-level-await](docs/rules/prefer-top-level-await.md) | Prefer top-level await over top-level promises and async function calls. | ✅ | | 💡 |
|
|
149
150
|
| [prefer-type-error](docs/rules/prefer-type-error.md) | Enforce throwing `TypeError` in type checking conditions. | ✅ | 🔧 | |
|
|
150
151
|
| [prevent-abbreviations](docs/rules/prevent-abbreviations.md) | Prevent abbreviations. | ✅ | 🔧 | |
|
|
151
152
|
| [relative-url-style](docs/rules/relative-url-style.md) | Enforce consistent relative URL style. | ✅ | 🔧 | 💡 |
|
package/rules/ast/index.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isLiteral,
|
|
5
|
+
isStringLiteral,
|
|
6
|
+
isNumberLiteral,
|
|
7
|
+
isBigIntLiteral,
|
|
8
|
+
isNullLiteral,
|
|
9
|
+
isRegexLiteral,
|
|
10
|
+
} = require('./literal.js');
|
|
11
|
+
|
|
2
12
|
module.exports = {
|
|
13
|
+
isLiteral,
|
|
14
|
+
isStringLiteral,
|
|
15
|
+
isNumberLiteral,
|
|
16
|
+
isBigIntLiteral,
|
|
17
|
+
isNullLiteral,
|
|
18
|
+
isRegexLiteral,
|
|
19
|
+
|
|
20
|
+
isArrowFunctionBody: require('./is-arrow-function-body.js'),
|
|
3
21
|
isEmptyNode: require('./is-empty-node.js'),
|
|
22
|
+
isStaticRequire: require('./is-static-require.js'),
|
|
23
|
+
isUndefined: require('./is-undefined.js'),
|
|
4
24
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const {isStringLiteral} = require('./literal.js');
|
|
4
|
+
|
|
3
5
|
const isStaticRequire = node => Boolean(
|
|
4
6
|
node
|
|
5
7
|
&& node.type === 'CallExpression'
|
|
@@ -8,8 +10,7 @@ const isStaticRequire = node => Boolean(
|
|
|
8
10
|
&& node.callee.name === 'require'
|
|
9
11
|
&& !node.optional
|
|
10
12
|
&& node.arguments.length === 1
|
|
11
|
-
&& node.arguments[0]
|
|
12
|
-
&& typeof node.arguments[0].value === 'string',
|
|
13
|
+
&& isStringLiteral(node.arguments[0]),
|
|
13
14
|
);
|
|
14
15
|
|
|
15
16
|
module.exports = isStaticRequire;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function isLiteral(node, value) {
|
|
4
|
+
if (node?.type !== 'Literal') {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (value === null) {
|
|
9
|
+
return node.raw === 'null';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return node.value === value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const isStringLiteral = node => node?.type === 'Literal' && typeof node.value === 'string';
|
|
16
|
+
const isNumberLiteral = node => node.type === 'Literal' && typeof node.value === 'number';
|
|
17
|
+
const isRegexLiteral = node => node.type === 'Literal' && Boolean(node.regex);
|
|
18
|
+
// eslint-disable-next-line unicorn/no-null
|
|
19
|
+
const isNullLiteral = node => isLiteral(node, null);
|
|
20
|
+
const isBigIntLiteral = node => node.type === 'Literal' && Boolean(node.bigint);
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
isLiteral,
|
|
24
|
+
isStringLiteral,
|
|
25
|
+
isNumberLiteral,
|
|
26
|
+
isBigIntLiteral,
|
|
27
|
+
isNullLiteral,
|
|
28
|
+
isRegexLiteral,
|
|
29
|
+
};
|
package/rules/better-regex.js
CHANGED
|
@@ -3,16 +3,14 @@ const cleanRegexp = require('clean-regexp');
|
|
|
3
3
|
const {optimize} = require('regexp-tree');
|
|
4
4
|
const quoteString = require('./utils/quote-string.js');
|
|
5
5
|
const {newExpressionSelector} = require('./selectors/index.js');
|
|
6
|
+
const {isStringLiteral} = require('./ast/index.js');
|
|
6
7
|
|
|
7
8
|
const MESSAGE_ID = 'better-regex';
|
|
8
9
|
const messages = {
|
|
9
10
|
[MESSAGE_ID]: '{{original}} can be optimized to {{optimized}}.',
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
const newRegExp =
|
|
13
|
-
newExpressionSelector({name: 'RegExp', minimumArguments: 1}),
|
|
14
|
-
'[arguments.0.type="Literal"]',
|
|
15
|
-
].join('');
|
|
13
|
+
const newRegExp = newExpressionSelector({name: 'RegExp', minimumArguments: 1});
|
|
16
14
|
|
|
17
15
|
/** @param {import('eslint').Rule.RuleContext} context */
|
|
18
16
|
const create = context => {
|
|
@@ -66,16 +64,12 @@ const create = context => {
|
|
|
66
64
|
[newRegExp](node) {
|
|
67
65
|
const [patternNode, flagsNode] = node.arguments;
|
|
68
66
|
|
|
69
|
-
if (
|
|
67
|
+
if (!isStringLiteral(patternNode)) {
|
|
70
68
|
return;
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
const oldPattern = patternNode.value;
|
|
74
|
-
const flags = (
|
|
75
|
-
flagsNode
|
|
76
|
-
&& flagsNode.type === 'Literal'
|
|
77
|
-
&& typeof flagsNode.value === 'string'
|
|
78
|
-
)
|
|
72
|
+
const flags = isStringLiteral(flagsNode)
|
|
79
73
|
? flagsNode.value
|
|
80
74
|
: '';
|
|
81
75
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const {isParenthesized, getStaticValue} = require('eslint-utils');
|
|
3
3
|
const {checkVueTemplate} = require('./utils/rule.js');
|
|
4
|
-
const isLiteralValue = require('./utils/is-literal-value.js');
|
|
5
4
|
const isLogicalExpression = require('./utils/is-logical-expression.js');
|
|
6
5
|
const {isBooleanNode, getBooleanAncestor} = require('./utils/boolean.js');
|
|
7
6
|
const {memberExpressionSelector} = require('./selectors/index.js');
|
|
8
7
|
const {fixSpaceAroundKeyword} = require('./fix/index.js');
|
|
8
|
+
const {isLiteral} = require('./ast/index.js');
|
|
9
9
|
|
|
10
10
|
const TYPE_NON_ZERO = 'non-zero';
|
|
11
11
|
const TYPE_ZERO = 'zero';
|
|
@@ -19,11 +19,11 @@ const messages = {
|
|
|
19
19
|
const isCompareRight = (node, operator, value) =>
|
|
20
20
|
node.type === 'BinaryExpression'
|
|
21
21
|
&& node.operator === operator
|
|
22
|
-
&&
|
|
22
|
+
&& isLiteral(node.right, value);
|
|
23
23
|
const isCompareLeft = (node, operator, value) =>
|
|
24
24
|
node.type === 'BinaryExpression'
|
|
25
25
|
&& node.operator === operator
|
|
26
|
-
&&
|
|
26
|
+
&& isLiteral(node.left, value);
|
|
27
27
|
const nonZeroStyles = new Map([
|
|
28
28
|
[
|
|
29
29
|
'greater-than',
|
package/rules/filename-case.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
const isNewExpressionWithParentheses = require('../utils/is-new-expression-with-parentheses.js');
|
|
3
3
|
const {isParenthesized} = require('../utils/parentheses.js');
|
|
4
4
|
|
|
5
|
-
function *
|
|
5
|
+
function * fixReturnOrThrowStatementArgument(newExpression, sourceCode, fixer) {
|
|
6
6
|
const {parent} = newExpression;
|
|
7
7
|
if (
|
|
8
|
-
parent.type !== 'ReturnStatement'
|
|
8
|
+
(parent.type !== 'ReturnStatement' && parent.type !== 'ThrowStatement')
|
|
9
9
|
|| parent.argument !== newExpression
|
|
10
10
|
|| isParenthesized(newExpression, sourceCode)
|
|
11
11
|
) {
|
|
@@ -48,7 +48,7 @@ function * switchNewExpressionToCallExpression(node, sourceCode, fixer) {
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
*/
|
|
51
|
-
yield *
|
|
51
|
+
yield * fixReturnOrThrowStatementArgument(node, sourceCode, fixer);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
module.exports = switchNewExpressionToCallExpression;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
const {ReferenceTracker} = require('eslint-utils');
|
|
2
3
|
const builtins = require('./utils/builtins.js');
|
|
3
|
-
const isShadowed = require('./utils/is-shadowed.js');
|
|
4
|
-
const {callExpressionSelector, newExpressionSelector} = require('./selectors/index.js');
|
|
5
4
|
const {
|
|
6
5
|
switchCallExpressionToNewExpression,
|
|
7
6
|
switchNewExpressionToCallExpression,
|
|
@@ -12,60 +11,64 @@ const messages = {
|
|
|
12
11
|
disallow: 'Use `{{name}}()` instead of `new {{name}}()`.',
|
|
13
12
|
};
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
[callExpressionSelector(builtins.enforceNew)](node) {
|
|
21
|
-
const {callee, parent} = node;
|
|
22
|
-
if (isShadowed(context.getScope(), callee)) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const {name} = callee;
|
|
14
|
+
function * enforceNewExpression({sourceCode, tracker}) {
|
|
15
|
+
const traceMap = Object.fromEntries(
|
|
16
|
+
builtins.enforceNew.map(name => [name, {[ReferenceTracker.CALL]: true}]),
|
|
17
|
+
);
|
|
27
18
|
|
|
19
|
+
for (const {node, path: [name]} of tracker.iterateGlobalReferences(traceMap)) {
|
|
20
|
+
if (name === 'Object') {
|
|
21
|
+
const {parent} = node;
|
|
28
22
|
if (
|
|
29
|
-
|
|
30
|
-
&& parent
|
|
31
|
-
&& parent.type === 'BinaryExpression'
|
|
23
|
+
parent.type === 'BinaryExpression'
|
|
32
24
|
&& (parent.operator === '===' || parent.operator === '!==')
|
|
33
25
|
&& (parent.left === node || parent.right === node)
|
|
34
26
|
) {
|
|
35
|
-
|
|
27
|
+
continue;
|
|
36
28
|
}
|
|
29
|
+
}
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const {callee} = node;
|
|
31
|
+
yield {
|
|
32
|
+
node,
|
|
33
|
+
messageId: 'enforce',
|
|
34
|
+
data: {name},
|
|
35
|
+
fix: fixer => switchCallExpressionToNewExpression(node, sourceCode, fixer),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
function * enforceCallExpression({sourceCode, tracker}) {
|
|
41
|
+
const traceMap = Object.fromEntries(
|
|
42
|
+
builtins.disallowNew.map(name => [name, {[ReferenceTracker.CONSTRUCT]: true}]),
|
|
43
|
+
);
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
for (const {node, path: [name]} of tracker.iterateGlobalReferences(traceMap)) {
|
|
46
|
+
const problem = {
|
|
47
|
+
node,
|
|
48
|
+
messageId: 'disallow',
|
|
49
|
+
data: {name},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
if (name !== 'String' && name !== 'Boolean' && name !== 'Number') {
|
|
53
|
+
problem.fix = function * (fixer) {
|
|
54
|
+
yield * switchNewExpressionToCallExpression(node, sourceCode, fixer);
|
|
57
55
|
};
|
|
56
|
+
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
};
|
|
63
|
-
}
|
|
58
|
+
yield problem;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
/** @param {import('eslint').Rule.RuleContext} context */
|
|
63
|
+
const create = context => ({
|
|
64
|
+
* 'Program:exit'() {
|
|
65
|
+
const sourceCode = context.getSourceCode();
|
|
66
|
+
const tracker = new ReferenceTracker(context.getScope());
|
|
67
|
+
|
|
68
|
+
yield * enforceNewExpression({sourceCode, tracker});
|
|
69
|
+
yield * enforceCallExpression({sourceCode, tracker});
|
|
70
|
+
},
|
|
71
|
+
});
|
|
69
72
|
|
|
70
73
|
/** @type {import('eslint').Rule.RuleModule} */
|
|
71
74
|
module.exports = {
|