@putout/plugin-conditions 2.2.0 → 3.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/README.md CHANGED
@@ -23,7 +23,9 @@ npm i @putout/plugin-conditions -D
23
23
  "conditions/evaluate": "on",
24
24
  "conditions/remove-boolean": "on",
25
25
  "conditions/remove-constant": "on",
26
- "conditions/remove-zero": "on"
26
+ "conditions/remove-zero": "on",
27
+ "conditions/remove-useless-else": "on",
28
+ "conditions/merge-if-statements": "on"
27
29
  }
28
30
  }
29
31
  ```
@@ -195,7 +197,7 @@ if (b) {}
195
197
 
196
198
  ## simplify
197
199
 
198
- ## ❌ Example of incorrect code
200
+ ### ❌ Example of incorrect code
199
201
 
200
202
  ```js
201
203
  if (zone?.tooltipCallback) {
@@ -208,7 +210,7 @@ else
208
210
  alert('hello');
209
211
  ```
210
212
 
211
- ## ✅ Example of correct code
213
+ ### ✅ Example of correct code
212
214
 
213
215
  ```js
214
216
  zone?.tooltipCallback(e);
@@ -216,6 +218,67 @@ zone?.tooltipCallback(e);
216
218
  alert('hello');
217
219
  ```
218
220
 
221
+ ## merge-if-statements
222
+
223
+ > The `if` statement executes a statement `if` a specified condition is truthy.
224
+ >
225
+ > (c) [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
226
+
227
+ ### ❌ Example of incorrect code
228
+
229
+ ```js
230
+ if (a > b) {
231
+ if (b < c) {
232
+ console.log('hello');
233
+ }
234
+ }
235
+ ```
236
+
237
+ ### ✅ Example of correct code
238
+
239
+ ```js
240
+ if (a > b && b < c) {
241
+ console.log('hello');
242
+ }
243
+ ```
244
+
245
+ ## remove-useless-else
246
+
247
+ > You can skip the `else` block if your `if` block always executes a `return` statement, it makes code a lot easier to read.
248
+ >
249
+ > (c) [no else return](https://www.samanthaming.com/tidbits/23-no-else-return/)
250
+
251
+ Remove useless `else` before:
252
+
253
+ - `return`;
254
+ - `continue`;
255
+ - `break`;
256
+
257
+ ### ❌ Example of incorrect code
258
+
259
+ ```js
260
+ if (x)
261
+ return;
262
+ else
263
+ console.log();
264
+ ```
265
+
266
+ ### ✅ Example of correct code
267
+
268
+ ```js
269
+ if (x)
270
+ return;
271
+
272
+ console.log();
273
+ ```
274
+
275
+ ### Comparison
276
+
277
+ Linter | Rule | Fix
278
+ --------|-------|------------|
279
+ 🐊 **Putout** | [`conditions/remove-useless-else`](https://github.com/coderaiser/putout/tree/master/packages/plugin-remove-debugger#readme) | ✅
280
+ ⏣ **ESLint** | [`no-else-return`](https://eslint.org/docs/rules/no-else-return) | ✅
281
+
219
282
  ## License
220
283
 
221
284
  MIT
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const {replaceWith} = require('putout').operator;
3
+ const {operator} = require('putout');
4
+ const {remove, replaceWith} = operator;
4
5
 
5
6
  module.exports.report = () => 'Avoid empty statement in if condition';
6
7
 
@@ -24,5 +25,5 @@ module.exports.fix = (path) => {
24
25
  const consequentPath = path.get('consequent');
25
26
 
26
27
  replaceWith(consequentPath, nextPath);
27
- nextPath.remove();
28
+ remove(nextPath);
28
29
  };
package/lib/index.js CHANGED
@@ -1,16 +1,25 @@
1
1
  'use strict';
2
2
 
3
- const getRule = (a) => ({
4
- [a]: require(`./${a}`),
5
- });
3
+ const applyComparisonOrder = require('./apply-comparison-order');
4
+ const applyIf = require('./apply-if');
5
+ const evaluate = require('./evaluate');
6
+ const convertComparisonToBoolean = require('./convert-comparison-to-boolean');
7
+ const convertEqualToStrictEqual = require('./convert-equal-to-strict-equal');
8
+ const mergeIfStatements = require('./merge-if-statements');
9
+ const removeBoolean = require('./remove-boolean');
10
+ const removeZero = require('./remove-zero');
11
+ const removeUselessElse = require('./remove-useless-else');
12
+ const simplify = require('./simplify');
6
13
 
7
14
  module.exports.rules = {
8
- ...getRule('apply-comparison-order'),
9
- ...getRule('apply-if'),
10
- ...getRule('evaluate'),
11
- ...getRule('convert-comparison-to-boolean'),
12
- ...getRule('convert-equal-to-strict-equal'),
13
- ...getRule('remove-boolean'),
14
- ...getRule('remove-zero'),
15
- ...getRule('simplify'),
15
+ 'apply-comparison-order': applyComparisonOrder,
16
+ 'apply-if': applyIf,
17
+ evaluate,
18
+ 'convert-comparison-to-boolean': convertComparisonToBoolean,
19
+ 'convert-equal-to-strict-equal': convertEqualToStrictEqual,
20
+ 'merge-if-statements': mergeIfStatements,
21
+ 'remove-boolean': removeBoolean,
22
+ 'remove-zero': removeZero,
23
+ 'remove-useless-else': removeUselessElse,
24
+ simplify,
16
25
  };
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const {types, operator} = require('putout');
4
+
5
+ const {replaceWith} = operator;
6
+ const {LogicalExpression} = types;
7
+
8
+ module.exports.report = () => `Merge 'if' statements`;
9
+
10
+ module.exports.fix = ({path, consequentPath}) => {
11
+ const testPath = path.get('test');
12
+ const left = testPath.node;
13
+ const right = consequentPath.node.test;
14
+
15
+ replaceWith(testPath, LogicalExpression('&&', left, right));
16
+
17
+ replaceWith(path.get('consequent'), consequentPath.get('consequent'));
18
+ };
19
+
20
+ const getConsequent = (path) => {
21
+ const consequentPath = path.get('consequent');
22
+
23
+ if (consequentPath.isIfStatement())
24
+ return consequentPath;
25
+
26
+ const {node} = consequentPath;
27
+
28
+ if (!consequentPath.isBlock() || node.body.length > 1)
29
+ return;
30
+
31
+ const resultPath = consequentPath.get('body.0');
32
+ const {body} = consequentPath.node;
33
+
34
+ if (body.length && resultPath.isIfStatement())
35
+ return resultPath;
36
+
37
+ return null;
38
+ };
39
+
40
+ module.exports.traverse = ({push}) => ({
41
+ 'if (__) __': onIfStatement({
42
+ push,
43
+ }),
44
+ });
45
+
46
+ const onIfStatement = ({push}) => (path) => {
47
+ const consequentPath = getConsequent(path);
48
+
49
+ if (!consequentPath)
50
+ return;
51
+
52
+ if (consequentPath.node.alternate)
53
+ return;
54
+
55
+ push({
56
+ path,
57
+ consequentPath,
58
+ });
59
+ };
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ isReturnStatement,
5
+ isBlockStatement,
6
+ isContinueStatement,
7
+ isBreakStatement,
8
+ } = require('putout').types;
9
+
10
+ module.exports.report = () => `Avoid useless 'else'`;
11
+
12
+ module.exports.match = () => ({
13
+ 'if (__a) __b; else __c': ({__b}) => {
14
+ if (!isBlockStatement(__b))
15
+ return isReturnLike(__b);
16
+
17
+ const latest = __b.body.at(-1);
18
+
19
+ return isReturnLike(latest);
20
+ },
21
+ });
22
+
23
+ module.exports.replace = () => ({
24
+ 'if (__a) __b; else __c': `{
25
+ if (__a) __b;
26
+ __c;
27
+ }`,
28
+ });
29
+
30
+ function isReturnLike(node) {
31
+ if (isReturnStatement(node))
32
+ return true;
33
+
34
+ if (isContinueStatement(node))
35
+ return true;
36
+
37
+ return isBreakStatement(node);
38
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/plugin-conditions",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "type": "commonjs",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "🐊Putout plugin adds support of conditions transformations",
@@ -37,14 +37,14 @@
37
37
  "c8": "^8.0.0",
38
38
  "eslint": "^8.0.1",
39
39
  "eslint-plugin-n": "^16.0.0",
40
- "eslint-plugin-putout": "^18.0.0",
40
+ "eslint-plugin-putout": "^19.0.0",
41
41
  "lerna": "^6.0.1",
42
42
  "madrun": "^9.0.0",
43
43
  "montag": "^1.2.1",
44
44
  "nodemon": "^3.0.1"
45
45
  },
46
46
  "peerDependencies": {
47
- "putout": ">=30"
47
+ "putout": ">=32"
48
48
  },
49
49
  "license": "MIT",
50
50
  "engines": {