@putout/printer 18.5.0 → 18.6.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,14 @@
1
+ 2026.03.13, v18.6.1
2
+
3
+ feature:
4
+ - 07e38ad @putout/printer: VariableDeclaration: afterIf: move out
5
+ - 30cfca1 @putout/printer: VariableDeclaration: isNeedNewline: simplify
6
+
7
+ 2026.03.13, v18.6.0
8
+
9
+ feature:
10
+ - 43bb843 @putout/printer: type-checker: whenTestsEnds: add
11
+
1
12
  2026.03.13, v18.5.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
+ }
@@ -12,17 +12,21 @@ import {
12
12
  noTrailingComment,
13
13
  isInsideIf,
14
14
  isInsideBlock,
15
- isInsideExportDeclaration,
16
15
  isInsideTSModuleBlock,
17
16
  isInsideProgram,
18
17
  isInsideSwitchCase,
19
18
  isInsideBody,
20
19
  callWithParent,
21
20
  } from '#is';
21
+ import {afterIf} from './after-if.js';
22
22
  import {maybeSpaceAfterKeyword} from './maybe-space-after-keyword.js';
23
23
 
24
24
  const {isExportDeclaration} = types;
25
25
 
26
+ const isLast = (path) => path.parentPath?.isProgram() && !isNext(path);
27
+
28
+ const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
29
+
26
30
  const isInsideBlockLike = createTypeChecker([
27
31
  isInsideProgram,
28
32
  isInsideBlock,
@@ -31,11 +35,7 @@ const isInsideBlockLike = createTypeChecker([
31
35
  isInsideBody,
32
36
  ]);
33
37
 
34
- const isLast = (path) => path.parentPath?.isProgram() && !isNext(path);
35
-
36
- const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
37
38
  const isParentSwitchCase = (path) => path.parentPath.isSwitchCase();
38
- const isFirstInSwitch = (path) => path.parentPath.get('consequent.0') === path;
39
39
 
40
40
  const isInsideParentLike = callWithParent(createTypeChecker([
41
41
  'Program',
@@ -53,6 +53,7 @@ const isNeedSemicolon = createTypeChecker([
53
53
  ]);
54
54
 
55
55
  const isNeedNewline = createTypeChecker([
56
+ ['+', isParentSwitchCase],
56
57
  ['-: -> !', isInsideParentLike],
57
58
  ['-: -> !', isNext],
58
59
  ['+', noTrailingComment],
@@ -113,13 +114,6 @@ export const VariableDeclaration = {
113
114
 
114
115
  let wasNewline = false;
115
116
 
116
- if (isParentSwitchCase(path)) {
117
- write.newline();
118
-
119
- if (!isFirstInSwitch(path))
120
- wasNewline = true;
121
- }
122
-
123
117
  if (isNeedNewline(path)) {
124
118
  write.newline();
125
119
  wasNewline = true;
@@ -127,18 +121,7 @@ export const VariableDeclaration = {
127
121
 
128
122
  store(wasNewline);
129
123
  }),
130
- afterSatisfy: () => [
131
- isNextIf,
132
- isNextFn,
133
- noNextParentBlock,
134
- notLastCoupleLines,
135
- isNextAssign,
136
- isNextCoupleLines,
137
- notLastPrevVarNotNextVar,
138
- isNewlineBetweenSiblings,
139
- isInsideExportDeclaration,
140
- isParentTSModuleBlock,
141
- ],
124
+ afterIf,
142
125
  after(path, {maybe, store, print}) {
143
126
  const wasNewline = store();
144
127
 
@@ -156,42 +139,6 @@ const skipAfter = createTypeChecker([
156
139
  ['+: -> !', isInsideBlock],
157
140
  ]);
158
141
 
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
142
  function shouldAddNewlineBefore(path) {
196
143
  if (isFirst(path))
197
144
  return false;
@@ -213,27 +160,3 @@ function shouldAddNewlineBefore(path) {
213
160
  function isFirst(path) {
214
161
  return path.node === path.parentPath.node.body?.[0];
215
162
  }
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
- };
@@ -0,0 +1,17 @@
1
+ import {getCoverage as _getCoverage} from '#type-checker/instrument';
2
+ import {report as _report} from '#type-checker/report';
3
+
4
+ export const whenTestsEnds = (overrides = {}) => {
5
+ const {
6
+ log = console.log,
7
+ getCoverage = _getCoverage,
8
+ report = _report,
9
+ } = overrides;
10
+
11
+ const coverage = getCoverage();
12
+ const [code, message] = report(coverage);
13
+
14
+ log(message);
15
+
16
+ return code;
17
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.5.0",
3
+ "version": "18.6.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",
@@ -12,7 +12,8 @@
12
12
  "./params": "./lib/tokenize/expressions/function/params.js",
13
13
  "./type-checker": "./lib/tokenize/type-checker/type-checker.js",
14
14
  "./type-checker/instrument": "./lib/tokenize/type-checker/instrument.js",
15
- "./type-checker/report": "./lib/tokenize/type-checker/report.js"
15
+ "./type-checker/report": "./lib/tokenize/type-checker/report.js",
16
+ "./type-checker/when-tests-ends": "./lib/tokenize/type-checker/when-tests-ends.js"
16
17
  },
17
18
  "repository": {
18
19
  "type": "git",
@@ -70,6 +71,7 @@
70
71
  "#type-checker": "./lib/tokenize/type-checker/type-checker.js",
71
72
  "#type-checker/instrument": "./lib/tokenize/type-checker/instrument.js",
72
73
  "#type-checker/report": "./lib/tokenize/type-checker/report.js",
74
+ "#type-checker/when-tests-ends": "./lib/tokenize/type-checker/when-tests-ends.js",
73
75
  "#is-concatenation": "./lib/tokenize/expressions/binary-expression/is-concatenation.js",
74
76
  "#comments": "./lib/tokenize/comments/comments.js"
75
77
  },