@putout/printer 18.6.0 → 18.6.2

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,14 @@
1
+ 2026.03.13, v18.6.2
2
+
3
+ feature:
4
+ - 98623e8 @putout/printer: VariableDeclaration: beforeIf: move out
5
+
6
+ 2026.03.13, v18.6.1
7
+
8
+ feature:
9
+ - 07e38ad @putout/printer: VariableDeclaration: afterIf: move out
10
+ - 30cfca1 @putout/printer: VariableDeclaration: isNeedNewline: simplify
11
+
1
12
  2026.03.13, v18.6.0
2
13
 
3
14
  feature:
@@ -0,0 +1,79 @@
1
+ import {types} from '@putout/babel';
2
+ import {createTypeChecker} from '#type-checker';
3
+ import {
4
+ exists,
5
+ callWithNext,
6
+ isCoupleLines,
7
+ isInsideBlock,
8
+ isLast,
9
+ isNewlineBetweenSiblings,
10
+ isNext,
11
+ } from '#is';
12
+
13
+ const noNextParentBlock = createTypeChecker([
14
+ ['-', isNext],
15
+ ['+', isInsideBlock],
16
+ ]);
17
+
18
+ const {
19
+ isIfStatement,
20
+ isFunctionDeclaration,
21
+ } = types;
22
+
23
+ const notLastCoupleLines = createTypeChecker([
24
+ ['-', isLast],
25
+ ['+', isCoupleLines],
26
+ ]);
27
+
28
+ const isNextAssign = (path) => {
29
+ const nextPath = path.getNextSibling();
30
+
31
+ if (!nextPath.isExpressionStatement())
32
+ return false;
33
+
34
+ const {parentPath} = path;
35
+
36
+ if (parentPath.isBlockStatement() && parentPath.node.body.length < 3)
37
+ return false;
38
+
39
+ return nextPath.get('expression').isAssignmentExpression();
40
+ };
41
+
42
+ export const afterIf = createTypeChecker([
43
+ ['+', callWithNext(isIfStatement)],
44
+ ['+', callWithNext(isFunctionDeclaration)],
45
+ ['+', noNextParentBlock],
46
+ ['+', notLastCoupleLines],
47
+ ['+', isNextAssign],
48
+ ['+', isNextCoupleLines],
49
+ ['+', notLastPrevVarNotNextVar],
50
+ ['+', isNewlineBetweenSiblings],
51
+ ['+: parentPath -> ExportNamedDeclaration'],
52
+ ['+: parentPath -> TSModuleBlock'],
53
+ ]);
54
+
55
+ function isNextCoupleLines(path) {
56
+ const next = path.getNextSibling();
57
+ const prev = path.getPrevSibling();
58
+
59
+ if (!exists(prev.getPrevSibling()) && next.isVariableDeclaration())
60
+ return false;
61
+
62
+ if (path.node.loc?.start.line === prev.node?.loc?.start?.line + 2)
63
+ return false;
64
+
65
+ return isCoupleLines(next);
66
+ }
67
+
68
+ function notLastPrevVarNotNextVar(path) {
69
+ const prev = path.getPrevSibling();
70
+ const next = path.getNextSibling();
71
+
72
+ if (!exists(prev.getPrevSibling()))
73
+ return false;
74
+
75
+ if (path.node.loc?.start.line === prev.node?.loc?.start.line + 2)
76
+ return false;
77
+
78
+ return !isLast(path) && prev.isVariableDeclaration() && !next.isVariableDeclaration();
79
+ }
@@ -0,0 +1,13 @@
1
+ import {types} from '@putout/babel';
2
+ import {createTypeChecker} from '#type-checker';
3
+ import {hasPrevNewline} from '#mark';
4
+ import {callWithPrev, isFirst} from '#is';
5
+
6
+ const {isBlockStatement} = types;
7
+
8
+ export const beforeIf = createTypeChecker([
9
+ ['-', isFirst],
10
+ ['-', hasPrevNewline],
11
+ ['-: parentPath ->', hasPrevNewline],
12
+ ['+', callWithPrev(isBlockStatement)],
13
+ ]);
@@ -1,28 +1,26 @@
1
- import {types} from '@putout/babel';
2
- import {hasPrevNewline} from '#mark';
3
1
  import {createTypeChecker} from '#type-checker';
4
2
  import {isConcatenation} from '#is-concatenation';
5
3
  import {maybeDeclare} from '#maybe-declare';
6
4
  import {parseLeadingComments} from '#comments';
7
5
  import {
8
6
  isNext,
9
- isCoupleLines,
10
7
  isNewlineBetweenSiblings,
11
8
  exists,
12
9
  noTrailingComment,
13
10
  isInsideIf,
14
11
  isInsideBlock,
15
- isInsideExportDeclaration,
16
12
  isInsideTSModuleBlock,
17
13
  isInsideProgram,
18
14
  isInsideSwitchCase,
19
15
  isInsideBody,
20
16
  callWithParent,
17
+ isLast,
21
18
  } from '#is';
19
+ import {afterIf} from './after-if.js';
22
20
  import {maybeSpaceAfterKeyword} from './maybe-space-after-keyword.js';
21
+ import {beforeIf} from './before-if.js';
23
22
 
24
- const {isExportDeclaration} = types;
25
-
23
+ const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
26
24
  const isInsideBlockLike = createTypeChecker([
27
25
  isInsideProgram,
28
26
  isInsideBlock,
@@ -31,11 +29,7 @@ const isInsideBlockLike = createTypeChecker([
31
29
  isInsideBody,
32
30
  ]);
33
31
 
34
- const isLast = (path) => path.parentPath?.isProgram() && !isNext(path);
35
-
36
- const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
37
32
  const isParentSwitchCase = (path) => path.parentPath.isSwitchCase();
38
- const isFirstInSwitch = (path) => path.parentPath.get('consequent.0') === path;
39
33
 
40
34
  const isInsideParentLike = callWithParent(createTypeChecker([
41
35
  'Program',
@@ -53,6 +47,7 @@ const isNeedSemicolon = createTypeChecker([
53
47
  ]);
54
48
 
55
49
  const isNeedNewline = createTypeChecker([
50
+ ['+', isParentSwitchCase],
56
51
  ['-: -> !', isInsideParentLike],
57
52
  ['-: -> !', isNext],
58
53
  ['+', noTrailingComment],
@@ -60,7 +55,7 @@ const isNeedNewline = createTypeChecker([
60
55
  ]);
61
56
 
62
57
  export const VariableDeclaration = {
63
- beforeIf: shouldAddNewlineBefore,
58
+ beforeIf,
64
59
  before(path, {print}) {
65
60
  print.breakline();
66
61
  },
@@ -113,13 +108,6 @@ export const VariableDeclaration = {
113
108
 
114
109
  let wasNewline = false;
115
110
 
116
- if (isParentSwitchCase(path)) {
117
- write.newline();
118
-
119
- if (!isFirstInSwitch(path))
120
- wasNewline = true;
121
- }
122
-
123
111
  if (isNeedNewline(path)) {
124
112
  write.newline();
125
113
  wasNewline = true;
@@ -127,18 +115,7 @@ export const VariableDeclaration = {
127
115
 
128
116
  store(wasNewline);
129
117
  }),
130
- afterSatisfy: () => [
131
- isNextIf,
132
- isNextFn,
133
- noNextParentBlock,
134
- notLastCoupleLines,
135
- isNextAssign,
136
- isNextCoupleLines,
137
- notLastPrevVarNotNextVar,
138
- isNewlineBetweenSiblings,
139
- isInsideExportDeclaration,
140
- isParentTSModuleBlock,
141
- ],
118
+ afterIf,
142
119
  after(path, {maybe, store, print}) {
143
120
  const wasNewline = store();
144
121
 
@@ -155,85 +132,3 @@ const skipAfter = createTypeChecker([
155
132
  ['-: parentPath -> !', isLast],
156
133
  ['+: -> !', isInsideBlock],
157
134
  ]);
158
-
159
- const noNextParentBlock = createTypeChecker([
160
- ['-', isNext],
161
- ['+', isInsideBlock],
162
- ]);
163
-
164
- const notLastCoupleLines = createTypeChecker([
165
- ['-', isLast],
166
- ['+', isCoupleLines],
167
- ]);
168
-
169
- function notLastPrevVarNotNextVar(path) {
170
- const prev = path.getPrevSibling();
171
- const next = path.getNextSibling();
172
-
173
- if (!exists(prev.getPrevSibling()))
174
- return false;
175
-
176
- if (path.node.loc?.start.line === prev.node?.loc?.start.line + 2)
177
- return false;
178
-
179
- return !isLast(path) && prev.isVariableDeclaration() && !next.isVariableDeclaration();
180
- }
181
-
182
- function isNextCoupleLines(path) {
183
- const next = path.getNextSibling();
184
- const prev = path.getPrevSibling();
185
-
186
- if (!exists(prev.getPrevSibling()) && next.isVariableDeclaration())
187
- return false;
188
-
189
- if (path.node.loc?.start.line === prev.node?.loc?.start?.line + 2)
190
- return false;
191
-
192
- return isCoupleLines(next);
193
- }
194
-
195
- function shouldAddNewlineBefore(path) {
196
- if (isFirst(path))
197
- return false;
198
-
199
- if (hasPrevNewline(path))
200
- return false;
201
-
202
- if (hasPrevNewline(path.parentPath))
203
- return false;
204
-
205
- const prevPath = path.getPrevSibling();
206
-
207
- if (prevPath.isStatement() && !prevPath.isExpressionStatement() && !prevPath.isBlockStatement())
208
- return false;
209
-
210
- return !isExportDeclaration(path.parentPath) && isCoupleLines(path);
211
- }
212
-
213
- function isFirst(path) {
214
- return path.node === path.parentPath.node.body?.[0];
215
- }
216
-
217
- const isNextIf = (path) => {
218
- const nextPath = path.getNextSibling();
219
- return nextPath.isIfStatement();
220
- };
221
-
222
- const isNextFn = (path) => {
223
- const nextPath = path.getNextSibling();
224
- return nextPath.isFunctionDeclaration();
225
- };
226
-
227
- const isNextAssign = (path) => {
228
- const nextPath = path.getNextSibling();
229
-
230
- if (!nextPath.isExpressionStatement())
231
- return false;
232
-
233
- const {parentPath} = path;
234
-
235
- if (parentPath.isBlockStatement() && parentPath.node.body.length < 3)
236
- return false;
237
-
238
- return nextPath.get('expression').isAssignmentExpression();
239
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.6.0",
3
+ "version": "18.6.2",
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",