@putout/printer 18.2.12 → 18.3.1

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,19 @@
1
+ 2026.03.08, v18.3.1
2
+
3
+ feature:
4
+ - 00f7cc1 @putout/printer: ArrayExpression: isCommaAfterElement
5
+
6
+ 2026.03.08, v18.3.0
7
+
8
+ feature:
9
+ - 31aa6f8 @putout/printer: ArrayExpression: isIndentBeforeElement
10
+ - e21a6cd @putout/printer: ArrayExpression: simplify
11
+ - 00b646d @putout/printer: ArrayExpression: maybePrintSpace
12
+ - 56e83f6 @putout/printer: ArrayExpression: maybePrintCommaWithSpace
13
+ - 9be2086 @putout/printer: ArrayExpression: afterIf: simplify
14
+ - 2ccc185 @putout/printer: ArrayExpression: isCommaBeforeClosingSquareBrace
15
+ - 35e1a1a @putout/printer: ArrayExpression: neesComma
16
+
1
17
  2026.03.08, v18.2.12
2
18
 
3
19
  feature:
@@ -12,7 +28,7 @@ feature:
12
28
  2026.03.08, v18.2.10
13
29
 
14
30
  feature:
15
- - 7a73310 @putout/printer: ArrayExpresison: maybeSecondIndent
31
+ - 7a73310 @putout/printer: ArrayExpresison: maybeAdditionalIndent
16
32
  - cfcf1ce @putout/printer: ArrayExpression: isSecondIndent
17
33
  - 0acb26a @putout/printer: ArrayExpression: isSecondIndent
18
34
 
@@ -0,0 +1,15 @@
1
+ import {
2
+ isCoupleLines,
3
+ isIdentifierAndIdentifier,
4
+ isStringAndIdentifier,
5
+ } from '#is';
6
+ import {createTypeChecker} from '#type-checker';
7
+ import {isInsideOneElementArray} from './before-if.js';
8
+
9
+ export const afterIf = createTypeChecker([
10
+ ['-: parentPath -> !ArrayExpression'],
11
+ ['-: parentPath ->', isCoupleLines],
12
+ ['+', isIdentifierAndIdentifier],
13
+ ['-: -> !', isStringAndIdentifier],
14
+ ['+', isInsideOneElementArray],
15
+ ]);
@@ -1,46 +1,24 @@
1
1
  import {types} from '@putout/babel';
2
2
  import {createTypeChecker} from '#type-checker';
3
+ import {callWithNext, callWithPrev} from '#is';
3
4
  import {
4
- isCoupleLines,
5
- isStringAndIdentifier,
6
- isIdentifierAndIdentifier,
7
- isSimpleAndNotEmptyObject,
8
- callWithNext,
9
- callWithPrev,
10
- } from '#is';
11
- import {
12
- isCurrentNewLine,
5
+ isIndentBeforeElement,
13
6
  isMultiLine,
14
- isNewlineAfterComma,
15
7
  } from './newline.js';
16
- import {isObjectAfterSimple} from './is-object-after-simple.js';
17
8
  import {
18
9
  isNeedIndent,
19
- maybeSecondIndent,
10
+ maybeAdditionalIndent,
20
11
  } from './indent.js';
12
+ import {beforeIf} from './before-if.js';
13
+ import {afterIf} from './after-if.js';
21
14
  import {
22
- beforeIf,
23
- isInsideOneElementArray,
24
- } from './before-if.js';
25
-
26
- const {
27
- isObjectExpression,
28
- isSpreadElement,
29
- isIdentifier,
30
- isCallExpression,
31
- } = types;
32
-
33
- const isSimpleBetweenObjects = createTypeChecker([
34
- ['+', callWithNext(isObjectExpression)],
35
- ['-', isSpreadElement],
36
- ['-', isIdentifier],
37
- ['+: -> !', isCallExpression],
38
- ]);
15
+ isCommaAfterElement,
16
+ isNewlineAfterComma,
17
+ isSpaceAfterComa,
18
+ } from './comma.js';
19
+ import {isBreaklineBeforeClosingSquareBrace} from './breakline.js';
39
20
 
40
- const isSpaceAfterComa = createTypeChecker([
41
- ['+', callWithNext(isSimpleBetweenObjects)],
42
- ['+: -> !ObjectExpression'],
43
- ]);
21
+ const {isObjectExpression} = types;
44
22
 
45
23
  export const ArrayExpression = {
46
24
  beforeIf,
@@ -48,7 +26,11 @@ export const ArrayExpression = {
48
26
  print.breakline();
49
27
  },
50
28
  print(path, printer, semantics) {
51
- const {print, maybe} = printer;
29
+ const {
30
+ print,
31
+ maybe,
32
+ indent,
33
+ } = printer;
52
34
 
53
35
  const {
54
36
  maxElementsInOneLine,
@@ -56,73 +38,64 @@ export const ArrayExpression = {
56
38
  maxElementLengthInOneLine,
57
39
  } = semantics;
58
40
 
59
- const elements = path.get('elements');
60
-
61
- print('[');
62
-
63
41
  const needIndent = isNeedIndent(path);
64
42
 
65
- maybe.indent.inc(needIndent);
66
-
67
- const needsNewline = isMultiLine(path, {
43
+ const multiline = isMultiLine(path, {
68
44
  maxElementsInOneLine,
69
45
  maxElementLengthInOneLine,
70
46
  });
71
47
 
72
- const n = elements.length - 1;
48
+ const elements = path.get('elements');
73
49
 
74
- if (needsNewline)
75
- print.newline();
50
+ print('[');
51
+ maybe.indent.inc(needIndent);
52
+ maybe.print.newline(multiline);
53
+
54
+ const n = elements.length - 1;
76
55
 
77
56
  for (const [index, element] of elements.entries()) {
78
- const is = needsNewline && isCurrentNewLine(element);
57
+ const isLast = index === n;
58
+ const needsIndentBeforeElement = isIndentBeforeElement(element, {
59
+ multiline,
60
+ });
61
+
62
+ const needsComma = isCommaAfterElement(path, {
63
+ trailingComma,
64
+ isLast,
65
+ needsIndentBeforeElement,
66
+ });
79
67
 
80
- if (isSimpleAfterObject(element))
68
+ if (isNewlineBeforeElement(element))
81
69
  print.newline();
82
70
 
83
- maybe.indent(is);
71
+ if (needsIndentBeforeElement)
72
+ indent();
73
+
84
74
  print(element);
85
75
 
86
- if (index < n || trailingComma)
87
- maybe.print(is, ',');
76
+ if (needsComma)
77
+ print(',');
88
78
 
89
- if (needsNewline && isNewlineAfterComma(element))
79
+ if (isNewlineAfterComma(element, {multiline})) {
90
80
  print.newline();
91
-
92
- maybe.print.space(is && isObjectAfterSimple(element));
93
-
94
- if (!is && index < n) {
95
- print(',');
96
- maybe.print.space(isSpaceAfterComa(element));
81
+ continue;
97
82
  }
83
+
84
+ if (isSpaceAfterComa(element, {isLast}))
85
+ print.space();
98
86
  }
99
87
 
100
88
  maybe.indent.dec(needIndent);
101
- maybeSecondIndent(path, printer, semantics, {
102
- needsNewline,
89
+ maybeAdditionalIndent(path, printer, semantics, {
90
+ multiline,
103
91
  });
104
92
 
105
- if (isSimpleAndNotEmptyObject(path) && !isSpreadElement(elements.at(-1)) && !isCallExpression(elements.at(-1))) {
106
- print(',');
93
+ if (isBreaklineBeforeClosingSquareBrace(path))
107
94
  print.breakline();
108
- }
109
95
 
110
96
  print(']');
111
97
  },
112
- afterIf(path) {
113
- const {parentPath} = path;
114
-
115
- if (!parentPath.isArrayExpression())
116
- return false;
117
-
118
- if (isCoupleLines(parentPath))
119
- return false;
120
-
121
- if (isStringAndIdentifier(path) && isInsideOneElementArray(path))
122
- return true;
123
-
124
- return isIdentifierAndIdentifier(path);
125
- },
98
+ afterIf,
126
99
  after(path, {print, indent}) {
127
100
  indent.dec();
128
101
  print.breakline();
@@ -136,7 +109,7 @@ const isSimple = createTypeChecker([
136
109
  '+: -> !CallExpression',
137
110
  ]);
138
111
 
139
- const isSimpleAfterObject = createTypeChecker([
112
+ const isNewlineBeforeElement = createTypeChecker([
140
113
  ['-', isSimple],
141
114
  ['-', callWithNext(isObjectExpression)],
142
115
  ['+', callWithPrev(isObjectExpression)],
@@ -0,0 +1,16 @@
1
+ import {types} from '@putout/babel';
2
+ import {createTypeChecker} from '#type-checker';
3
+ import {isSimpleAndNotEmptyObject} from '#is';
4
+
5
+ const {
6
+ isSpreadElement,
7
+ isCallExpression,
8
+ } = types;
9
+
10
+ const callWithLastElement = (fn) => (a) => fn(a.at(-1));
11
+
12
+ export const isBreaklineBeforeClosingSquareBrace = createTypeChecker([
13
+ ['-: -> !', isSimpleAndNotEmptyObject],
14
+ ['-: node.elements', callWithLastElement(isSpreadElement)],
15
+ ['+: node.elements -> !', callWithLastElement(isCallExpression)],
16
+ ]);
@@ -0,0 +1,47 @@
1
+ import {types} from '@putout/babel';
2
+ import {createTypeChecker} from '#type-checker';
3
+ import {callWithNext} from '#is';
4
+ import {isBreaklineBeforeClosingSquareBrace} from './breakline.js';
5
+ import {
6
+ isLastOption,
7
+ isMultilineOption,
8
+ isNeedsIndentBeforeElementOption,
9
+ isTrailingCommaOption,
10
+ } from './is.js';
11
+
12
+ const {
13
+ isSpreadElement,
14
+ isCallExpression,
15
+ isObjectExpression,
16
+ isIdentifier,
17
+ } = types;
18
+
19
+ const isCommaAfterElementByOption = createTypeChecker([
20
+ ['+: -> !', isLastOption],
21
+ ['-: -> !', isNeedsIndentBeforeElementOption],
22
+ ['+', isTrailingCommaOption],
23
+ ]);
24
+
25
+ export const isCommaAfterElement = createTypeChecker([
26
+ ['+', isCommaAfterElementByOption],
27
+ ['+', isBreaklineBeforeClosingSquareBrace],
28
+ ]);
29
+
30
+ export const isNewlineAfterComma = createTypeChecker([
31
+ ['-: -> !', isMultilineOption],
32
+ ['-', callWithNext(isObjectExpression)],
33
+ ['+: -> !ObjectExpression'],
34
+ ]);
35
+
36
+ const isSimpleBetweenObjects = createTypeChecker([
37
+ ['+', callWithNext(isObjectExpression)],
38
+ ['-', isSpreadElement],
39
+ ['-', isIdentifier],
40
+ ['+: -> !', isCallExpression],
41
+ ]);
42
+
43
+ export const isSpaceAfterComa = createTypeChecker([
44
+ ['-', isLastOption],
45
+ ['+', callWithNext(isSimpleBetweenObjects)],
46
+ ['+: -> !ObjectExpression'],
47
+ ]);
@@ -6,7 +6,7 @@ import {
6
6
  isStringAndArray,
7
7
  } from '#is';
8
8
  import {
9
- isNeedsNewlineOption,
9
+ isMultilineOption,
10
10
  isNeedsToHideIndentOption,
11
11
  } from './is.js';
12
12
 
@@ -109,19 +109,19 @@ export const isHideIndent = createTypeChecker([
109
109
  const isLastElementObjectExpression = ({node}) => isObjectExpression(node.elements.at(-1));
110
110
 
111
111
  export const isSecondIndent = createTypeChecker([
112
- ['-: -> !', isNeedsNewlineOption],
112
+ ['-: -> !', isMultilineOption],
113
113
  ['+', isNeedsToHideIndentOption],
114
114
  ['-: ->', isArrayInsideArray],
115
115
  ['+: -> !', isLastElementObjectExpression],
116
116
  ]);
117
117
 
118
- export function maybeSecondIndent(path, printer, semantics, options) {
118
+ export function maybeAdditionalIndent(path, printer, semantics, options) {
119
119
  const {maybe, indent} = printer;
120
- const {needsNewline} = options;
120
+ const {multiline} = options;
121
121
  const needsToHideIndent = isHideIndent(path);
122
122
 
123
123
  const needsToMakeSecondIndent = isSecondIndent(path, {
124
- needsNewline,
124
+ multiline,
125
125
  needsToHideIndent,
126
126
  });
127
127
 
@@ -1,3 +1,6 @@
1
- export const isNeedsNewlineOption = (a, {needsNewline}) => needsNewline;
2
-
1
+ export const isMultilineOption = (a, {multiline}) => multiline;
3
2
  export const isNeedsToHideIndentOption = (a, {needsToHideIndent}) => needsToHideIndent;
3
+ export const isLastOption = (a, {isLast}) => isLast;
4
+
5
+ export const isTrailingCommaOption = (a, {trailingComma}) => trailingComma;
6
+ export const isNeedsIndentBeforeElementOption = (a, {needsIndentBeforeElement}) => needsIndentBeforeElement;
@@ -11,9 +11,9 @@ import {
11
11
  isSimpleAndNotEmptyObject,
12
12
  isInsideCall,
13
13
  isInsideArray,
14
- callWithNext,
15
14
  } from '#is';
16
15
  import {isIncreaseIndent} from './indent.js';
16
+ import {isMultilineOption} from './is.js';
17
17
 
18
18
  const isParentProperty = (path) => path.find(isObjectProperty);
19
19
 
@@ -306,12 +306,8 @@ function isNumbers(elements) {
306
306
  return false;
307
307
  }
308
308
 
309
- export const isCurrentNewLine = createTypeChecker([
310
- '+: -> SpreadElement',
311
- '+: -> !ObjectExpression',
312
- ]);
313
-
314
- export const isNewlineAfterComma = createTypeChecker([
315
- ['-', callWithNext(isObjectExpression)],
309
+ export const isIndentBeforeElement = createTypeChecker([
310
+ ['-: -> !', isMultilineOption],
311
+ ['+: -> SpreadElement'],
316
312
  ['+: -> !ObjectExpression'],
317
313
  ]);
@@ -61,10 +61,6 @@ export const isPrev = (path) => {
61
61
  export const isNextParent = (path) => isNext(path.parentPath);
62
62
  export const isLast = (path) => isInsideProgram(path) && !isNext(path);
63
63
 
64
- export const isNextObject = (a) => a
65
- .getNextSibling()
66
- .isObjectExpression();
67
-
68
64
  export const isFirst = (path) => path.node === path.parentPath.node.body?.[0];
69
65
  export const isPrevBody = (path) => path
70
66
  .getPrevSibling()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.2.12",
3
+ "version": "18.3.1",
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,18 +0,0 @@
1
- import {isNextObject} from '#is';
2
- import {createTypeChecker} from '#type-checker';
3
-
4
- const SIMPLE_TYPES = [
5
- 'ArrayExpression',
6
- 'ObjectExpression',
7
- 'SpreadElement',
8
- 'CallExpression',
9
- 'Identifier',
10
- 'NewExpression',
11
- ];
12
-
13
- const isSimpleType = ({type}) => SIMPLE_TYPES.includes(type);
14
-
15
- export const isObjectAfterSimple = createTypeChecker([
16
- ['-: -> !', isNextObject],
17
- ['+', isSimpleType],
18
- ]);