@putout/printer 18.3.5 → 18.3.6

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.10, v18.3.6
2
+
3
+ feature:
4
+ - a3281ef @putout/printer: ObjectExpression: isMultiline
5
+ - da64dc7 @putout/printer: ObjectExpression: isCommaAfterProperty
6
+ - 69ff480 @putout/printer: ObjectExpression: hasTrailingComment
7
+ - 50f7e07 @putout/printer: ObjectExpression: isIndentBeforeClosingCurlyBrace
8
+
1
9
  2026.03.10, v18.3.5
2
10
 
3
11
  feature:
@@ -0,0 +1,24 @@
1
+ import {createTypeChecker} from '#type-checker';
2
+ import {
3
+ isMultilineOption,
4
+ isTrailingCommaOption,
5
+ } from '../array-expression/is.js';
6
+
7
+ const isCouple = (a) => a > 1;
8
+ const isLastProperty = ({node, parentPath}) => node === parentPath.node.properties.at(-1);
9
+
10
+ const isCoupleOrManyLines = createTypeChecker([
11
+ ['+: parentPath.node.properties.length ->', isCouple],
12
+ ['+', isMultilineOption],
13
+ ]);
14
+
15
+ const isLastOrTrailingComma = createTypeChecker([
16
+ ['+: -> !', isLastProperty],
17
+ ['+', isTrailingCommaOption],
18
+ ]);
19
+
20
+ export const isCommaAfterProperty = createTypeChecker([
21
+ ['-: -> !SpreadElement'],
22
+ ['-: -> !', isCoupleOrManyLines],
23
+ ['+', isLastOrTrailingComma],
24
+ ]);
@@ -4,17 +4,21 @@ import {
4
4
  isCoupleLines,
5
5
  isForOf,
6
6
  isIf,
7
- noTrailingComment,
8
7
  isNewlineBetweenSiblings,
9
8
  hasLeadingComment,
10
- exists,
11
9
  isInsideCall,
12
10
  isInsideBody,
13
11
  isInsideExpression,
12
+ callWithNext,
13
+ hasTrailingComment,
14
14
  } from '#is';
15
15
  import {parseComments} from '../../comment/comment.js';
16
16
  import {isInsideTuple} from './is-inside-tuple.js';
17
17
  import {isLooksLikeChain} from '../member-expression/is-looks-like-chain.js';
18
+ import {isCommaAfterProperty} from './comma.js';
19
+ import {isMultilineOption} from '../array-expression/is.js';
20
+
21
+ const hasNextLeadingComment = callWithNext(hasLeadingComment);
18
22
 
19
23
  const notLastArgInsideCall = (path) => {
20
24
  const {parentPath} = path;
@@ -31,7 +35,10 @@ const notLastArgInsideCall = (path) => {
31
35
  const hasNoProperties = (path) => !path.node.properties.length;
32
36
  const hasValue = (path) => path.node.properties[0].value;
33
37
 
34
- const {isMemberExpression} = types;
38
+ const {
39
+ isMemberExpression,
40
+ isSpreadElement,
41
+ } = types;
35
42
 
36
43
  const isParens = createTypeChecker([isInsideBody, isInsideExpression]);
37
44
 
@@ -55,7 +62,7 @@ const isInsideTupleLike = createTypeChecker([
55
62
  ['+: parentPath.parentPath.node.elements.0 -> StringLiteral'],
56
63
  ]);
57
64
 
58
- export const isManyLines = createTypeChecker([
65
+ export const isMultiline = createTypeChecker([
59
66
  ['-', hasNoProperties],
60
67
  ['-: parentPath -> ForOfStatement'],
61
68
  ['+: node.properties.0 -> SpreadElement'],
@@ -66,10 +73,8 @@ export const isManyLines = createTypeChecker([
66
73
  ['+', hasValue],
67
74
  ]);
68
75
 
69
- const isManyLinesOption = (a, {manyLines}) => manyLines;
70
-
71
76
  const isIndentBeforeProperty = createTypeChecker([
72
- ['-: -> !', isManyLinesOption],
77
+ ['-: -> !', isMultilineOption],
73
78
  ['+: -> !', hasLeadingComment],
74
79
  ]);
75
80
 
@@ -88,23 +93,20 @@ export const ObjectExpression = (path, printer, semantics) => {
88
93
  const properties = path.get('properties');
89
94
  const {length} = properties;
90
95
  const parens = isParens(path);
91
- const manyLines = isManyLines(path);
96
+ const multiline = isMultiline(path);
92
97
 
93
98
  maybe.print(parens, '(');
94
99
  print('{');
95
100
  parseComments(path, printer, semantics);
96
- maybe.print.newline(manyLines);
97
-
98
- const n = properties.length - 1;
101
+ maybe.print.newline(multiline);
99
102
 
100
103
  const memberCallee = isMemberExpressionCallee(path);
101
104
  maybe.indent.inc(memberCallee);
102
105
 
103
- for (const [index, property] of properties.entries()) {
106
+ for (const property of properties) {
104
107
  const couple = length > 1;
105
- const isLast = index === n;
106
108
 
107
- if (isIndentBeforeProperty(property, {manyLines}))
109
+ if (isIndentBeforeProperty(property, {multiline}))
108
110
  indent();
109
111
 
110
112
  print(property);
@@ -112,29 +114,28 @@ export const ObjectExpression = (path, printer, semantics) => {
112
114
  if (property.isObjectMethod())
113
115
  continue;
114
116
 
115
- if (property.isSpreadElement()) {
116
- if (noTrailingComment(property) && (couple || manyLines)) {
117
- maybe.print(!isLast || trailingComma, ',');
118
- print.newline();
119
- }
120
-
117
+ if (hasTrailingComment(property))
121
118
  continue;
122
- }
123
119
 
124
- if (noTrailingComment(property) && !hasNextLeadingComment(property)) {
125
- maybe.print.newline(manyLines);
126
- maybe.print.linebreak(isNewlineBetweenSiblings(property));
127
- }
120
+ maybe.print(isCommaAfterProperty(property, {
121
+ multiline,
122
+ trailingComma,
123
+ }), ',');
124
+
125
+ if (!isSpreadElement(property) && !hasNextLeadingComment(property) && multiline || property.isSpreadElement() && (couple || multiline))
126
+ print.newline();
127
+
128
+ if (!isSpreadElement(property) && !hasNextLeadingComment(property) && isNewlineBetweenSiblings(property))
129
+ print.linebreak();
128
130
  }
129
131
 
130
132
  indent.dec();
131
133
 
132
- if (!insideNestedArrayCall) {
133
- maybe.indent(manyLines);
134
- } else if (isInsideTupleLike(path)) {
134
+ if (isIndentBeforeClosingCurlyBrace(path, {multiline}))
135
135
  indent();
136
+
137
+ if (insideNestedArrayCall)
136
138
  indent.inc();
137
- }
138
139
 
139
140
  print('}');
140
141
  maybe.print(parens, ')');
@@ -142,11 +143,8 @@ export const ObjectExpression = (path, printer, semantics) => {
142
143
  maybe.indent.dec(memberCallee);
143
144
  };
144
145
 
145
- const hasNextLeadingComment = (path) => {
146
- const next = path.getNextSibling();
147
-
148
- if (!exists(next))
149
- return false;
150
-
151
- return hasLeadingComment(next);
152
- };
146
+ const isIndentBeforeClosingCurlyBrace = createTypeChecker([
147
+ ['+', isInsideTupleLike],
148
+ ['-: -> !', isMultilineOption],
149
+ ['+: -> !', isInsideNestedArrayCall],
150
+ ]);
@@ -1,5 +1,5 @@
1
1
  import {isConcatenation} from '../binary-expression/concatenate.js';
2
- import {isManyLines} from './object-expression.js';
2
+ import {isMultiline} from './object-expression.js';
3
3
  import {printKey} from './print-key.js';
4
4
 
5
5
  export const ObjectProperty = (path, printer, semantics) => {
@@ -14,7 +14,7 @@ export const ObjectProperty = (path, printer, semantics) => {
14
14
  const value = path.get('value');
15
15
  const properties = path.parentPath.get('properties');
16
16
  const isLast = path === properties.at(-1);
17
- const manyLines = isManyLines(path.parentPath);
17
+ const multiline = isMultiline(path.parentPath);
18
18
 
19
19
  printKey(path, printer);
20
20
 
@@ -24,7 +24,7 @@ export const ObjectProperty = (path, printer, semantics) => {
24
24
  traverse(value);
25
25
  }
26
26
 
27
- if (manyLines) {
27
+ if (multiline) {
28
28
  maybe.write(!isLast || trailingComma, ',');
29
29
  return;
30
30
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.3.5",
3
+ "version": "18.3.6",
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",