@putout/printer 18.8.2 → 18.8.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 CHANGED
@@ -1,3 +1,11 @@
1
+ 2026.03.20, v18.8.3
2
+
3
+ feature:
4
+ - 527b8425 @putout/printer: ObjectPattern: shouldAddNewline: simplify
5
+ - 0332d176 @putout/printer: ObjectPattern: isFunctionParam
6
+ - 3eadc072 @putout/printer: ObjectPattern: isLessThenMaxPropertiesInOneLine
7
+ - 63c73f94 @putout/printer: ObjectPattern: hasAssignObject: simplify
8
+
1
9
  2026.03.19, v18.8.2
2
10
 
3
11
  feature:
@@ -3,23 +3,20 @@ import {types} from '@putout/babel';
3
3
  const {
4
4
  isAssignmentPattern,
5
5
  isObjectPattern,
6
- isVariableDeclaration,
7
6
  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
  }
@@ -28,15 +25,6 @@ export function hasAssign(properties) {
28
25
  }
29
26
 
30
27
  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
-
40
28
  const properties = path.get('properties');
41
29
  const n = properties.length;
42
30
 
@@ -0,0 +1,7 @@
1
+ import {createTypeChecker} from '#type-checker';
2
+
3
+ const getMaxPropertiesInOneLine = (a, {maxPropertiesInOneLine}) => maxPropertiesInOneLine;
4
+
5
+ export const isLessThenMaxPropertiesInOneLine = createTypeChecker([
6
+ ['+: node.properties.length', '<=', getMaxPropertiesInOneLine],
7
+ ]);
@@ -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) {
@@ -34,10 +34,9 @@ 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);
@@ -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);
@@ -1,84 +1,66 @@
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 {isLessThenMaxPropertiesInOneLine} from './is-less-then-max-properties-in-one-line.js';
5
+ import {isMoreThenMaxPropertiesLengthInOneLine} from './is-more-then-max-properties-length-in-one-line.js';
5
6
  import {
6
7
  hasAssign,
7
8
  hasObjectPattern,
8
9
  } from './has.js';
9
10
 
11
+ const isMoreCountLessLength = createTypeChecker([
12
+ ['-: -> !', isLessThenMaxPropertiesInOneLine],
13
+ ['-', isMoreThenMaxPropertiesLengthInOneLine],
14
+ ['+: parentPath -> VariableDeclarator'],
15
+ ]);
16
+
10
17
  const {
11
18
  isIdentifier,
12
19
  isAssignmentPattern,
13
- isVariableDeclarator,
14
20
  isObjectProperty,
21
+ isFunction,
15
22
  } = types;
16
23
 
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)
24
+ function hasPropertyLeadingComment(path) {
25
+ for (const property of path.node.properties) {
26
+ if (property.leadingComments)
23
27
  return true;
24
28
  }
25
29
 
26
30
  return false;
27
31
  }
28
32
 
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
- }
33
+ const cutOptions = (fn) => (a) => fn(a);
34
+ const isFunctionLike = cutOptions(isFunction);
38
35
 
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
- }
36
+ const isFunctionParam = callWithParent(createTypeChecker([
37
+ ['+', isFunctionLike],
38
+ ['-: -> !AssignmentPattern'],
39
+ ['+: parentPath', isFunctionLike],
40
+ ]));
41
+
42
+ const isOneOfIdentifiersHasMoreLength = createTypeChecker([
43
+ ['-', isFunctionParam],
44
+ ['-', isForOf],
45
+ ['-: node.properties.length', '=', 1],
46
+ ['+', checkLength],
47
+ ]);
48
+
49
+ const hasAssignNotFunctionParam = createTypeChecker([
50
+ ['-', isFunctionParam],
51
+ ['+', hasAssign],
52
+ ]);
53
+
54
+ export const shouldAddNewline = createTypeChecker([
55
+ ['+', isCoupleAssigns],
56
+ ['+', hasPropertyLeadingComment],
57
+ ['+', hasComputed],
58
+ ['+', hasObjectPattern],
59
+ ['-', isMoreCountLessLength],
60
+ ['+', hasAssignNotFunctionParam],
61
+ ['+', isOneOfIdentifiersHasMoreLength],
62
+ ['+: parentPath -> ObjectProperty'],
63
+ ]);
82
64
 
83
65
  function isCoupleAssigns(path) {
84
66
  if (isFunctionParam(path))
@@ -97,13 +79,16 @@ function isCoupleAssigns(path) {
97
79
  return assignsCount > 1;
98
80
  }
99
81
 
100
- function checkLength(properties) {
101
- for (const prop of properties) {
102
- const {value} = prop.node;
103
-
104
- if (!isIdentifier(value))
105
- continue;
106
-
82
+ const getValue = (a) => a.value;
83
+
84
+ function checkLength(path) {
85
+ const identifiers = path
86
+ .node
87
+ .properties
88
+ .map(getValue)
89
+ .filter(isIdentifier);
90
+
91
+ for (const value of identifiers) {
107
92
  if (value.name.length > 4)
108
93
  return true;
109
94
  }
@@ -111,10 +96,8 @@ function checkLength(properties) {
111
96
  return false;
112
97
  }
113
98
 
114
- function hasComputed(properties) {
115
- for (const prop of properties) {
116
- const {computed} = prop.node;
117
-
99
+ function hasComputed(path) {
100
+ for (const {computed} of path.node.properties) {
118
101
  if (computed)
119
102
  return true;
120
103
  }
@@ -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.3",
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
- };