@putout/plugin-destructuring 1.2.0 → 1.3.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
@@ -20,6 +20,7 @@ npm i @putout/plugin-destructuring
20
20
  - ✅ [apply-object](#apply-object);
21
21
  - ✅ [apply-array](#apply-array);
22
22
  - ✅ [convert-object-to-array](#convert-object-to-array);
23
+ - ✅ [extract-properties](#extract-properties);
23
24
  - ✅ [remove-useless-object](#remove-useless-object);
24
25
  - ✅ [remove-useless-arguments](#remove-useless-arguments);
25
26
  - ✅ [remove-useless-variables](#remove-useless-variables);
@@ -35,6 +36,7 @@ npm i @putout/plugin-destructuring
35
36
  "destructuring/apply-object": "on",
36
37
  "destructuring/apply-array": "on",
37
38
  "destructuring/convert-object-to-array": "on",
39
+ "destructuring/extract-properties": "on",
38
40
  "destructuring/remove-useless-object": "on",
39
41
  "destructuring/remove-useless-arguments": "on",
40
42
  "destructuring/remove-useless-variables": "on",
@@ -237,6 +239,42 @@ function hi(c) {
237
239
  function hi({a, b}) {}
238
240
  ```
239
241
 
242
+ ## extract-properties
243
+
244
+ ### Equal Deep
245
+
246
+ #### ❌ Example of incorrect code
247
+
248
+ ```js
249
+ const {replaceWith} = a.operate;
250
+ const {isIdentifier} = a.types;
251
+ ```
252
+
253
+ #### ✅ Example of correct code
254
+
255
+ ```js
256
+ const {operator, types} = a;
257
+
258
+ const {replaceWith} = operator;
259
+ const {isIdentifier} = types;
260
+ ```
261
+
262
+ ### Not Equal Deep
263
+
264
+ #### ❌ Example of incorrect code
265
+
266
+ ```js
267
+ const {replaceWith} = a;
268
+ const {isIdentifier} = a.types;
269
+ ```
270
+
271
+ #### ✅ Example of correct code
272
+
273
+ ```js
274
+ const {replaceWith, types} = a;
275
+ const {isIdentifier} = types;
276
+ ```
277
+
240
278
  ## License
241
279
 
242
280
  MIT
@@ -0,0 +1,78 @@
1
+ import {
2
+ template,
3
+ generate,
4
+ types,
5
+ operator,
6
+ } from 'putout';
7
+
8
+ const {
9
+ findBinding,
10
+ replaceWith,
11
+ getTemplateValues,
12
+ } = operator;
13
+
14
+ const {
15
+ isIdentifier,
16
+ isCallExpression,
17
+ } = types;
18
+
19
+ export const report = () => `Extract object properties into variables`;
20
+
21
+ const buildAst = template(`
22
+ const {PROPERTY} = OBJECT;
23
+ `);
24
+
25
+ export const fix = ({items}) => {
26
+ const names = [];
27
+
28
+ for (const item of items) {
29
+ const {object, property} = item.node;
30
+
31
+ if (isIdentifier(property) && !names.includes(property.name)) {
32
+ names.push(property.name);
33
+
34
+ const {body = item.scope.block.body} = item.scope.block.body;
35
+
36
+ body.unshift(buildAst({
37
+ PROPERTY: property,
38
+ OBJECT: object,
39
+ }));
40
+ }
41
+
42
+ replaceWith(item, item.node.property);
43
+ }
44
+ };
45
+
46
+ export const traverse = ({uplist, push}) => ({
47
+ 'const __object = __a.__b': (fullPath) => {
48
+ const {__a, __b} = getTemplateValues(fullPath, 'const __object = __a.__b');
49
+ const initPath = fullPath.get('declarations.0.init');
50
+ const {uid} = initPath.scope;
51
+
52
+ if (findBinding(fullPath, __b.name))
53
+ return;
54
+
55
+ if (isIdentifier(__a) || isCallExpression(__a)) {
56
+ const {code} = generate(__a);
57
+ const id = `${uid}-${code}`;
58
+
59
+ return uplist(id, initPath);
60
+ }
61
+ },
62
+ 'Program': {
63
+ exit: () => {
64
+ for (const items of uplist()) {
65
+ if (items.length < 2)
66
+ continue;
67
+
68
+ const index = items.length - 1;
69
+ const path = items[index];
70
+
71
+ push({
72
+ path,
73
+ items,
74
+ });
75
+ }
76
+ },
77
+ },
78
+ });
@@ -0,0 +1,72 @@
1
+ import {operator, types} from 'putout';
2
+
3
+ const {objectProperty} = types;
4
+
5
+ const {replaceWith, compare} = operator;
6
+
7
+ const SHORTHAND = true;
8
+ const COMPUTED = false;
9
+
10
+ export const report = () => `Extract object properties into variables`;
11
+
12
+ export const fix = ({path, expandPath, property}) => {
13
+ const newProperty = objectProperty(property, property, COMPUTED, SHORTHAND);
14
+
15
+ expandPath.node.properties.push(newProperty);
16
+ replaceWith(path, property);
17
+ };
18
+
19
+ export const traverse = ({listStore, push}) => ({
20
+ 'const __object = __a.__b': save({
21
+ listStore,
22
+ }),
23
+ 'const __object = __a(__args)': save({
24
+ listStore,
25
+ }),
26
+ 'Program': {
27
+ exit: exit({
28
+ push,
29
+ listStore,
30
+ }),
31
+ },
32
+ });
33
+
34
+ const save = ({listStore}) => (path) => {
35
+ const idPath = path.get('declarations.0.id');
36
+ const initPath = path.get('declarations.0.init');
37
+
38
+ listStore([initPath, idPath]);
39
+ };
40
+
41
+ const exit = ({push, listStore}) => () => {
42
+ const items = listStore();
43
+
44
+ for (const [initPath] of items) {
45
+ for (const [currentPath, expandPath] of items) {
46
+ const objectPath = initPath.get('object');
47
+
48
+ if (!objectPath.isMemberExpression() && !objectPath.isCallExpression())
49
+ continue;
50
+
51
+ const propertyPath = initPath.get('property');
52
+ const property = propertyPath.node;
53
+
54
+ const current = currentPath.node;
55
+ const {object} = initPath.node;
56
+ const {name} = property;
57
+
58
+ if (expandPath.scope.bindings[name])
59
+ continue;
60
+
61
+ if (expandPath.scope.uid !== initPath.scope.uid)
62
+ continue;
63
+
64
+ if (compare(object, current))
65
+ push({
66
+ expandPath,
67
+ path: initPath,
68
+ property,
69
+ });
70
+ }
71
+ }
72
+ };
package/lib/index.js CHANGED
@@ -1,6 +1,8 @@
1
- import * as convertObjectToArray from './convert-object-to-array/index.js';
2
1
  import * as applyObject from './apply-object/index.js';
3
2
  import * as applyArray from './apply-array/index.js';
3
+ import * as extractPropertiesEqualDeep from './extract-properties-equal-deep/index.js';
4
+ import * as extractPropertiesNotEqualDeep from './extract-properties-not-equal-deep/index.js';
5
+ import * as convertObjectToArray from './convert-object-to-array/index.js';
4
6
  import * as removeUselessObject from './remove-useless-object/index.js';
5
7
  import * as removeUselessArguments from './remove-useless-arguments/index.js';
6
8
  import * as removeUselessVariables from './remove-useless-variables/index.js';
@@ -11,10 +13,12 @@ import * as mergeProperties from './merge-properties/index.js';
11
13
  export const rules = {
12
14
  'apply-object': applyObject,
13
15
  'apply-array': applyArray,
16
+ 'convert-object-to-array': convertObjectToArray,
17
+ 'extract-properties-equal-deep': extractPropertiesEqualDeep,
18
+ 'extract-properties-not-equal-deep': extractPropertiesNotEqualDeep,
14
19
  'remove-useless-object': removeUselessObject,
15
20
  'remove-useless-arguments': removeUselessArguments,
16
21
  'remove-useless-variables': removeUselessVariables,
17
- 'convert-object-to-array': convertObjectToArray,
18
22
  'split-nested': splitNested,
19
23
  'split-call': splitCall,
20
24
  'merge-properties': mergeProperties,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/plugin-destructuring",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "🐊Putout plugin adds ability to transform destructuring",
@@ -39,6 +39,7 @@
39
39
  "@putout/plugin-printer": "*",
40
40
  "@putout/plugin-putout": "*",
41
41
  "@putout/plugin-tape": "*",
42
+ "@putout/plugin-variables": "*",
42
43
  "@putout/test": "^14.0.0",
43
44
  "c8": "^10.0.0",
44
45
  "eslint": "v10.0.0-alpha.0",