@putout/printer 18.8.2 → 18.8.4

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 CHANGED
@@ -1,3 +1,16 @@
1
+ 2026.03.20, v18.8.4
2
+
3
+ feature:
4
+ - 292d01c0 @putout/printer: ObjectPattern: simplify
5
+
6
+ 2026.03.20, v18.8.3
7
+
8
+ feature:
9
+ - 527b8425 @putout/printer: ObjectPattern: shouldAddNewline: simplify
10
+ - 0332d176 @putout/printer: ObjectPattern: isFunctionParam
11
+ - 3eadc072 @putout/printer: ObjectPattern: isLessThenMaxPropertiesInOneLine
12
+ - 63c73f94 @putout/printer: ObjectPattern: hasAssignObject: simplify
13
+
1
14
  2026.03.19, v18.8.2
2
15
 
3
16
  feature:
@@ -1,25 +1,22 @@
1
1
  import {types} from '@putout/babel';
2
+ import {isAssignObject} from './is.js';
2
3
 
3
4
  const {
4
5
  isAssignmentPattern,
5
6
  isObjectPattern,
6
- isVariableDeclaration,
7
- isObjectExpression,
8
7
  } = types;
9
8
 
10
- export function hasObjectPattern(properties) {
11
- for (const property of properties) {
12
- if (isObjectPattern(property.node.value))
9
+ export function hasObjectPattern(path) {
10
+ for (const {value} of path.node.properties) {
11
+ if (isObjectPattern(value))
13
12
  return true;
14
13
  }
15
14
 
16
15
  return false;
17
16
  }
18
17
 
19
- export function hasAssign(properties) {
20
- for (const prop of properties) {
21
- const {value} = prop.node;
22
-
18
+ export function hasAssign(path) {
19
+ for (const {value} of path.node.properties) {
23
20
  if (isAssignmentPattern(value))
24
21
  return true;
25
22
  }
@@ -27,24 +24,13 @@ export function hasAssign(properties) {
27
24
  return false;
28
25
  }
29
26
 
30
- export function hasAssignObject(path, maxPropertiesLengthInOneLine) {
31
- const {parentPath} = path;
32
-
33
- if (isVariableDeclaration(parentPath.parentPath)) {
34
- const {declarations} = parentPath.parentPath.node;
35
-
36
- if (declarations.length > 1)
37
- return false;
38
- }
39
-
27
+ export function hasAssignObject(path) {
40
28
  const properties = path.get('properties');
41
29
  const n = properties.length;
42
30
 
43
31
  for (const prop of properties) {
44
- const {value} = prop.node;
45
-
46
- if (isAssignmentPattern(value) && isObjectExpression(value.right))
47
- return n > 1 || maxPropertiesLengthInOneLine <= value.left;
32
+ if (isAssignObject(prop))
33
+ return n > 1;
48
34
  }
49
35
 
50
36
  return false;
@@ -9,13 +9,10 @@ function getLength(left, right) {
9
9
  if (isIdentifier(left) && isIdentifier(right))
10
10
  return left.name.length + right.name.length;
11
11
 
12
- if (isIdentifier(left))
13
- return left.name.length;
14
-
15
- return 0;
12
+ return left.name.length;
16
13
  }
17
14
 
18
- export const moreThenMaxPropertiesLengthInOneLine = (path, {maxPropertiesLengthInOneLine}) => {
15
+ export const isMoreThenMaxPropertiesLengthInOneLine = (path, {maxPropertiesLengthInOneLine}) => {
19
16
  const {properties} = path.node;
20
17
 
21
18
  for (const {key, value} of properties) {
@@ -28,13 +25,12 @@ export const moreThenMaxPropertiesLengthInOneLine = (path, {maxPropertiesLengthI
28
25
  return true;
29
26
  }
30
27
 
31
- if (!isIdentifier(key))
32
- continue;
33
-
34
- const {name} = key;
35
-
36
- if (name.length >= maxPropertiesLengthInOneLine)
37
- return true;
28
+ if (isIdentifier(key)) {
29
+ const {name} = key;
30
+
31
+ if (name.length >= maxPropertiesLengthInOneLine)
32
+ return true;
33
+ }
38
34
  }
39
35
 
40
36
  return false;
@@ -34,22 +34,18 @@ export const isCoupleProperties = ({path, valuePath, property}) => {
34
34
  if (exists(property.getPrevSibling()))
35
35
  return false;
36
36
 
37
- const properties = path.get('properties');
38
37
  const {parentPath} = path;
39
38
 
40
- if (isVariableDeclarator(parentPath) && !hasAssign(properties))
39
+ if (isVariableDeclarator(parentPath) && !hasAssign(path))
41
40
  return false;
42
41
 
43
42
  return !isObjectProperty(parentPath);
44
43
  };
45
44
 
46
- export const isPrevAssignObject = callWithPrev(createTypeChecker([
45
+ export const isAssignObject = createTypeChecker([
47
46
  '-: node.value -> !AssignmentPattern',
48
47
  '+: node.value.right -> ObjectExpression',
49
- ]));
48
+ ]);
50
49
 
51
- export const isNextAssignObject = callWithNext(createTypeChecker([
52
- '-: node -> -',
53
- '-: node.value -> !AssignmentPattern',
54
- '+: node.value.right -> ObjectExpression',
55
- ]));
50
+ export const isPrevAssignObject = callWithPrev(isAssignObject);
51
+ export const isNextAssignObject = callWithNext(isAssignObject);
@@ -47,7 +47,7 @@ export const ObjectPattern = {
47
47
  maxPropertiesLengthInOneLine,
48
48
  });
49
49
 
50
- const hasObject = n && hasObjectPattern(properties);
50
+ const hasObject = n && hasObjectPattern(path);
51
51
  const notInsideFn = !isInsideFn(path);
52
52
 
53
53
  maybe.print.newline(is && notInsideFn);
@@ -109,7 +109,7 @@ export const ObjectPattern = {
109
109
 
110
110
  indent.dec();
111
111
 
112
- maybe.indent(is || hasAssignObject(path, maxPropertiesLengthInOneLine));
112
+ maybe.indent(is || hasAssignObject(path));
113
113
  maybe.indent.inc(!shouldIndent);
114
114
  print('}');
115
115
  }),
@@ -1,84 +1,67 @@
1
1
  import {types} from '@putout/babel';
2
- import {isForOf} from '#is';
3
- import {moreThenMaxPropertiesInOneLine} from './more-then-max-properties-in-one-line.js';
4
- import {moreThenMaxPropertiesLengthInOneLine} from './more-then-max-properties-length-in-one-line.js';
2
+ import {callWithParent, isForOf} from '#is';
3
+ import {createTypeChecker} from '#type-checker';
4
+ import {isMoreThenMaxPropertiesLengthInOneLine} from './is-more-then-max-properties-length-in-one-line.js';
5
5
  import {
6
6
  hasAssign,
7
7
  hasObjectPattern,
8
8
  } from './has.js';
9
9
 
10
+ const getMaxPropertiesInOneLine = (a, {maxPropertiesInOneLine}) => maxPropertiesInOneLine;
11
+
12
+ const isMoreCountLessLength = createTypeChecker([
13
+ ['-: node.properties.length', '>', getMaxPropertiesInOneLine],
14
+ ['-', isMoreThenMaxPropertiesLengthInOneLine],
15
+ ['+: parentPath -> VariableDeclarator'],
16
+ ]);
17
+
10
18
  const {
11
19
  isIdentifier,
12
20
  isAssignmentPattern,
13
- isVariableDeclarator,
14
21
  isObjectProperty,
22
+ isFunction,
15
23
  } = types;
16
24
 
17
- const ONE_LINE = false;
18
- const COUPLE_LINES = true;
19
-
20
- function hasPropertyLeadingComment(properties) {
21
- for (const property of properties) {
22
- if (property.node.leadingComments)
25
+ function hasPropertyLeadingComment(path) {
26
+ for (const property of path.node.properties) {
27
+ if (property.leadingComments)
23
28
  return true;
24
29
  }
25
30
 
26
31
  return false;
27
32
  }
28
33
 
29
- function isFunctionParam({parentPath}) {
30
- if (parentPath.isFunction())
31
- return true;
32
-
33
- if (!parentPath.isAssignmentPattern())
34
- return false;
35
-
36
- return parentPath.parentPath.isFunction();
37
- }
34
+ const cutOptions = (fn) => (a) => fn(a);
35
+ const isFunctionLike = cutOptions(isFunction);
38
36
 
39
- export function shouldAddNewline(path, semantics) {
40
- const {parentPath} = path;
41
- const properties = path.get('properties');
42
- const n = properties.length - 1;
43
-
44
- if (isCoupleAssigns(path))
45
- return COUPLE_LINES;
46
-
47
- if (hasPropertyLeadingComment(properties))
48
- return COUPLE_LINES;
49
-
50
- const {
51
- maxPropertiesInOneLine,
52
- maxPropertiesLengthInOneLine,
53
- } = semantics;
54
-
55
- const moreLength = moreThenMaxPropertiesLengthInOneLine(path, {
56
- maxPropertiesLengthInOneLine,
57
- });
58
-
59
- const moreCount = moreThenMaxPropertiesInOneLine(path, {
60
- maxPropertiesInOneLine,
61
- });
62
-
63
- if (hasComputed(properties))
64
- return COUPLE_LINES;
65
-
66
- const fnParam = isFunctionParam(path);
67
-
68
- if (hasObjectPattern(properties))
69
- return COUPLE_LINES;
70
-
71
- if (moreCount && !moreLength && isVariableDeclarator(path.parentPath))
72
- return ONE_LINE;
73
-
74
- if (!fnParam && n && !isForOf(path) && checkLength(properties))
75
- return COUPLE_LINES;
76
-
77
- if (!fnParam && hasAssign(properties))
78
- return COUPLE_LINES;
79
-
80
- return parentPath.isObjectProperty();
81
- }
37
+ const isFunctionParam = callWithParent(createTypeChecker([
38
+ ['+', isFunctionLike],
39
+ ['-: -> !AssignmentPattern'],
40
+ ['+: parentPath', isFunctionLike],
41
+ ]));
42
+
43
+ const isOneOfIdentifiersHasMoreLength = createTypeChecker([
44
+ ['-', isFunctionParam],
45
+ ['-', isForOf],
46
+ ['-: node.properties.length', '=', 1],
47
+ ['+', checkLength],
48
+ ]);
49
+
50
+ const hasAssignNotFunctionParam = createTypeChecker([
51
+ ['-', isFunctionParam],
52
+ ['+', hasAssign],
53
+ ]);
54
+
55
+ export const shouldAddNewline = createTypeChecker([
56
+ ['+', isCoupleAssigns],
57
+ ['+', hasPropertyLeadingComment],
58
+ ['+', hasComputed],
59
+ ['+', hasObjectPattern],
60
+ ['-', isMoreCountLessLength],
61
+ ['+', hasAssignNotFunctionParam],
62
+ ['+', isOneOfIdentifiersHasMoreLength],
63
+ ['+: parentPath -> ObjectProperty'],
64
+ ]);
82
65
 
83
66
  function isCoupleAssigns(path) {
84
67
  if (isFunctionParam(path))
@@ -97,13 +80,16 @@ function isCoupleAssigns(path) {
97
80
  return assignsCount > 1;
98
81
  }
99
82
 
100
- function checkLength(properties) {
101
- for (const prop of properties) {
102
- const {value} = prop.node;
103
-
104
- if (!isIdentifier(value))
105
- continue;
106
-
83
+ const getValue = (a) => a.value;
84
+
85
+ function checkLength(path) {
86
+ const identifiers = path
87
+ .node
88
+ .properties
89
+ .map(getValue)
90
+ .filter(isIdentifier);
91
+
92
+ for (const value of identifiers) {
107
93
  if (value.name.length > 4)
108
94
  return true;
109
95
  }
@@ -111,13 +97,12 @@ function checkLength(properties) {
111
97
  return false;
112
98
  }
113
99
 
114
- function hasComputed(properties) {
115
- for (const prop of properties) {
116
- const {computed} = prop.node;
117
-
100
+ function hasComputed(path) {
101
+ for (const {computed} of path.node.properties) {
118
102
  if (computed)
119
103
  return true;
120
104
  }
121
105
 
122
106
  return false;
123
107
  }
108
+
@@ -1,5 +1,6 @@
1
1
  import {createTuple} from './create-tuple.js';
2
2
 
3
+ const isFn = (a) => typeof a === 'function';
3
4
  const isString = (a) => typeof a === 'string';
4
5
  const {isArray} = Array;
5
6
 
@@ -46,11 +47,18 @@ export function parseTypeNames(typeNames) {
46
47
  return tuples;
47
48
  }
48
49
 
49
- const equal = (a) => (b) => b === a;
50
- const more = (a) => (b) => b > a;
51
- const less = (a) => (b) => b < a;
52
- const moreOrEqual = (a) => (b) => b >= a;
53
- const lessOrEqual = (a) => (b) => b <= a;
50
+ const createValueParser = (fn) => (a) => (b, ...c) => {
51
+ if (isFn(a))
52
+ return fn(a(b, ...c), b);
53
+
54
+ return fn(a, b);
55
+ };
56
+
57
+ const equal = createValueParser((a, b) => b === a);
58
+ const more = createValueParser((a, b) => b > a);
59
+ const less = createValueParser((a, b) => b < a);
60
+ const moreOrEqual = createValueParser((a, b) => b >= a);
61
+ const lessOrEqual = createValueParser((a, b) => b <= a);
54
62
 
55
63
  const CMP = {
56
64
  '=': equal,
@@ -63,7 +71,6 @@ const CMP = {
63
71
  function parseComparison(typeName) {
64
72
  if (typeName.length === 3) {
65
73
  const [result, comparison, value] = typeName;
66
-
67
74
  return [result, CMP[comparison](value)];
68
75
  }
69
76
 
@@ -48,6 +48,7 @@ const setLine = (name, index) => {
48
48
  line,
49
49
  column,
50
50
  ] = name.split(':');
51
+
51
52
  const newLine = Number(line) + index + 1;
52
53
 
53
54
  return [
@@ -76,12 +77,15 @@ function createRawCode(currentType) {
76
77
  if (isFn(currentType))
77
78
  return currentType.name;
78
79
 
79
- const [operator, fn] = currentType;
80
+ const [operator, fn, value] = currentType;
80
81
 
81
- if (fn) {
82
+ if (isFn(fn)) {
82
83
  const name = fn.name || fn;
83
84
  return `['${operator}', ${name}]`;
84
85
  }
85
86
 
87
+ if (isString(fn))
88
+ return `['${operator}', '${fn}', ${value}]`;
89
+
86
90
  return operator;
87
91
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.8.2",
3
+ "version": "18.8.4",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "Simplest possible opinionated Babel AST printer for 🐊Putout",
@@ -1,10 +0,0 @@
1
- export const moreThenMaxPropertiesInOneLine = (path, {maxPropertiesInOneLine}) => {
2
- const {parentPath} = path;
3
-
4
- if (parentPath.isObjectProperty())
5
- return false;
6
-
7
- const n = path.node.properties.length;
8
-
9
- return maxPropertiesInOneLine >= n;
10
- };