@putout/printer 18.0.0 → 18.0.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,20 @@
1
+ 2026.03.04, v18.0.2
2
+
3
+ feature:
4
+ - 854491c @putout/printer: VariableDeclaration: simplify
5
+
6
+ 2026.03.04, v18.0.1
7
+
8
+ feature:
9
+ - 5e6e906 @putout/printer: VariableDeclaration: after: simplify
10
+ - 852f982 @putout/printer: @putout/plugin-printer v8.0.0
11
+ - 7b3977d @putout/printer: VariableDeclaration: skipAfter
12
+ - 4f43a9f VariableDeclaration: isNeedNewline
13
+ - 9dece24 @putout/printer: VariableDeclaration: isSemicolon
14
+ - b9a27e0 @putout/printer: VariableDeclaration: isInsideIf
15
+ - 06d6255 @putout/printer: is: isParentProgram -> isInsideProgram
16
+ - 2a0ef4e is: isParentBlock -> isInsideBlock
17
+
1
18
  2026.03.04, v18.0.0
2
19
 
3
20
  feature:
@@ -60,6 +60,7 @@ const isSiblingIsArray = (path) => {
60
60
  };
61
61
 
62
62
  const isEmptyArray = (path) => !path.node.elements.length;
63
+
63
64
  const isAllLiterals = (path) => {
64
65
  const {elements} = path.node;
65
66
  const literals = elements.filter(isStringLiteral);
@@ -329,4 +330,3 @@ export const isCurrentNewLine = (path) => {
329
330
 
330
331
  return !path.isObjectExpression();
331
332
  };
332
-
@@ -1,7 +1,7 @@
1
1
  import {maybeParens} from '#maybe-parens';
2
2
  import {
3
- isParentBlock,
4
- isParentProgram,
3
+ isInsideBlock,
4
+ isInsideProgram,
5
5
  } from '#is';
6
6
  import {condition} from './maybe-parens-condition.js';
7
7
  import {printSeparator} from './print-separator.js';
@@ -27,7 +27,7 @@ export const AssignmentExpression = maybeParens({
27
27
  printSeparator(path, printer);
28
28
  print('__right');
29
29
 
30
- if (isParentBlock(path) || isParentProgram(path)) {
30
+ if (isInsideBlock(path) || isInsideProgram(path)) {
31
31
  print(';');
32
32
  print.breakline();
33
33
  }
@@ -1,4 +1,4 @@
1
- import {exists} from '#is';
1
+ import {exists, isInsideCall} from '#is';
2
2
  import {maybeParens} from '#maybe-parens';
3
3
 
4
4
  const {isArray} = Array;
@@ -14,7 +14,7 @@ const parseArgs = (path) => {
14
14
 
15
15
  export const CallExpression = maybeParens((path, {indent, print, maybe, traverse}) => {
16
16
  const args = parseArgs(path);
17
- const isParentCall = tooLong(args) && path.parentPath.isCallExpression();
17
+ const isParentCall = tooLong(args) && isInsideCall(path);
18
18
 
19
19
  const callee = path.get('callee');
20
20
  const typeParameters = path.get('typeArguments');
@@ -1,17 +1,17 @@
1
1
  import {types} from '@putout/babel';
2
+ import {markAfter} from '#mark';
2
3
  import {
3
4
  hasBody,
5
+ isInsideExport,
4
6
  isInsideTSModuleBlock,
5
7
  isNext,
6
8
  } from '#is';
7
- import {markAfter} from '#mark';
8
9
  import {maybeDeclare} from '../../maybe/maybe-declare.js';
9
10
  import {parseComments} from '../../comment/comment.js';
10
11
  import {maybeDecorators} from '../../maybe/maybe-decorators.js';
11
12
 
12
13
  const {isFunction} = types;
13
14
 
14
- const isInsideExport = ({parentPath}) => parentPath.isExportDeclaration();
15
15
  const isFunctionLike = (path) => isFunction(path.parentPath.parentPath);
16
16
 
17
17
  const classVisitor = maybeDecorators((path, printer, semantics) => {
@@ -107,3 +107,4 @@ export const ClassDeclaration = {
107
107
  }
108
108
  },
109
109
  };
110
+
@@ -18,8 +18,8 @@ const {
18
18
  isTSModuleBlock,
19
19
  } = types;
20
20
 
21
- export const isParentProgram = (path) => isProgram(path.parentPath);
22
- export const isParentBlock = (path) => isBlockStatement(path.parentPath);
21
+ export const isInsideProgram = (path) => isProgram(path.parentPath);
22
+ export const isInsideBlock = (path) => isBlockStatement(path.parentPath);
23
23
 
24
24
  export const isParentBlockLike = createTypeChecker('path.parentPath', [
25
25
  'Program',
@@ -59,7 +59,7 @@ export const isPrev = (path) => {
59
59
  };
60
60
 
61
61
  export const isNextParent = (path) => isNext(path.parentPath);
62
- export const isLast = (path) => isParentProgram(path) && !isNext(path);
62
+ export const isLast = (path) => isInsideProgram(path) && !isNext(path);
63
63
 
64
64
  export const isNextObject = (a) => a
65
65
  .getNextSibling()
@@ -161,6 +161,7 @@ export const isForOf = (path) => {
161
161
  };
162
162
 
163
163
  export const isInsideIf = (path) => path.parentPath?.isIfStatement();
164
+ export const isInsideExport = ({parentPath}) => parentPath.isExportDeclaration();
164
165
 
165
166
  export const isNewlineBetweenSiblings = (path) => {
166
167
  const endCurrent = path.node?.loc?.end?.line;
@@ -2,11 +2,11 @@ import {types} from '@putout/babel';
2
2
  import {createTypeChecker} from '#type-checker';
3
3
  import {
4
4
  isNext,
5
- isParentProgram,
5
+ isInsideProgram,
6
6
  isLast,
7
7
  exists,
8
8
  satisfy,
9
- isParentBlock,
9
+ isInsideBlock,
10
10
  } from '#is';
11
11
  import {insideIfWithNoBody} from './inside-if-with-no-body.js';
12
12
 
@@ -27,7 +27,7 @@ const isTopLevelWithNoNext = (path) => {
27
27
  if (isNext(path))
28
28
  return false;
29
29
 
30
- return !isNext(path.parentPath) && isParentProgram(path.parentPath);
30
+ return !isNext(path.parentPath) && isInsideProgram(path.parentPath);
31
31
  };
32
32
 
33
33
  const isInsideDoWhile = ({parentPath}) => isDoWhileStatement(parentPath);
@@ -55,7 +55,7 @@ const isNoNewline = satisfy([
55
55
  ]);
56
56
 
57
57
  export const shouldAddNewlineAfter = createTypeChecker([
58
- ['+', isParentBlock],
58
+ ['+', isInsideBlock],
59
59
  ['-', isNoNewline],
60
60
  ['+', isInsideIfWithoutElseInsideFn],
61
61
  ['-', isEmptyBodyNoNext],
@@ -1,5 +1,5 @@
1
1
  import {
2
- isParentBlock,
2
+ isInsideBlock,
3
3
  isNextParent,
4
4
  isInsideIf,
5
5
  isInsideLabel,
@@ -21,7 +21,7 @@ export const BreakStatement = {
21
21
  print(';');
22
22
  },
23
23
  afterSatisfy: () => [
24
- isParentBlock,
24
+ isInsideBlock,
25
25
  isNextParent,
26
26
  isInsideCase,
27
27
  isInsideIf,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isNext,
3
3
  isInsideIf,
4
- isParentBlock,
4
+ isInsideBlock,
5
5
  } from '#is';
6
6
 
7
7
  export const DebuggerStatement = {
@@ -11,7 +11,7 @@ export const DebuggerStatement = {
11
11
  },
12
12
  afterSatisfy: () => [
13
13
  isNext,
14
- isParentBlock,
14
+ isInsideBlock,
15
15
  isInsideIf,
16
16
  ],
17
17
  after(path, {print}) {
@@ -1,7 +1,7 @@
1
1
  import {types} from '@putout/babel';
2
2
  import {printAttributes} from '#import-attributes';
3
3
  import {
4
- isParentBlock,
4
+ isInsideBlock,
5
5
  isNewlineBetweenSiblings,
6
6
  exists,
7
7
  isNext,
@@ -169,7 +169,7 @@ export const ExportNamedDeclaration = {
169
169
  if (isNewlineBetweenSiblings(path))
170
170
  return true;
171
171
 
172
- return isParentBlock(path);
172
+ return isInsideBlock(path);
173
173
  },
174
174
  after(path, {print, indent}) {
175
175
  const next = path.getNextSibling();
@@ -2,7 +2,7 @@ import {types} from '@putout/babel';
2
2
  import {
3
3
  isNext,
4
4
  isLast,
5
- isParentBlock,
5
+ isInsideBlock,
6
6
  isParentLast,
7
7
  isNewlineBetweenSiblings,
8
8
  satisfy,
@@ -42,7 +42,7 @@ const notInsideReturn = not(isInsideReturn);
42
42
 
43
43
  const satisfyAfter = satisfy([
44
44
  isNotLastOrParentLast,
45
- isParentBlock,
45
+ isInsideBlock,
46
46
  isNext,
47
47
  isNextUp,
48
48
  ]);
@@ -1,5 +1,5 @@
1
1
  import {types} from '@putout/babel';
2
- import {isNext, isParentBlock} from '#is';
2
+ import {isNext, isInsideBlock} from '#is';
3
3
 
4
4
  const {isBlockStatement} = types;
5
5
 
@@ -24,6 +24,6 @@ export const printTrailingCommentLine = (path, printer, semantics, {printComment
24
24
 
25
25
  printComment();
26
26
 
27
- if (hasNext || isParentBlock(path))
27
+ if (hasNext || isInsideBlock(path))
28
28
  print.newline();
29
29
  };
@@ -2,7 +2,7 @@ import {types} from '@putout/babel';
2
2
  import {
3
3
  isNext,
4
4
  isNextTry,
5
- isParentBlock,
5
+ isInsideBlock,
6
6
  } from '#is';
7
7
 
8
8
  const {isExpressionStatement} = types;
@@ -55,5 +55,5 @@ export const CatchClause = (path, {print, maybe}) => {
55
55
  }
56
56
 
57
57
  print(body);
58
- maybe.print.newline(isParentBlock(parentPath));
58
+ maybe.print.newline(isInsideBlock(parentPath));
59
59
  };
@@ -8,26 +8,44 @@ import {
8
8
  exists,
9
9
  noTrailingComment,
10
10
  isParentBlockLike,
11
+ isInsideIf,
12
+ isInsideBlock,
13
+ isInsideExport,
11
14
  } from '#is';
12
15
  import {maybeSpaceAfterKeyword} from './maybe-space-after-keyword.js';
13
16
  import {isConcatenation} from '../../expressions/binary-expression/concatenate.js';
14
17
  import {parseLeadingComments} from '../../comment/comment.js';
15
18
  import {maybeDeclare} from '../../maybe/maybe-declare.js';
16
19
 
20
+ const isLast = (path) => path.parentPath?.isProgram() && !isNext(path);
21
+
17
22
  const {isExportDeclaration} = types;
18
23
 
19
24
  const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
20
25
  const isParentSwitchCase = (path) => path.parentPath.isSwitchCase();
21
26
  const isFirstInSwitch = (path) => path.parentPath.get('consequent.0') === path;
22
- const isParentIf = (path) => path.parentPath.isIfStatement();
23
27
 
24
- const isParentBlock = createTypeChecker('path.parentPath', [
28
+ const isIsideParentLike = createTypeChecker('path.parentPath', [
25
29
  'Program',
26
30
  'BlockStatement',
27
31
  'ExportNamedDeclaration',
28
32
  'LabeledStatement',
29
33
  ]);
30
34
 
35
+ const isNeedSemicolon = createTypeChecker([
36
+ isIsideParentLike,
37
+ isParentSwitchCase,
38
+ isParentTSModuleBlock,
39
+ isInsideIf,
40
+ ]);
41
+
42
+ const isNeedNewline = createTypeChecker([
43
+ ['-: -> !', isIsideParentLike],
44
+ ['-: -> !', isNext],
45
+ ['+', noTrailingComment],
46
+ ['+', isNewlineBetweenSiblings],
47
+ ]);
48
+
31
49
  export const VariableDeclaration = {
32
50
  beforeIf: shouldAddNewlineBefore,
33
51
  before(path, {print}) {
@@ -78,9 +96,7 @@ export const VariableDeclaration = {
78
96
  }
79
97
 
80
98
  maybe.indent.dec(n);
81
-
82
- if (isParentBlock(path) || isParentSwitchCase(path) || isParentTSModuleBlock(path) || isParentIf(path))
83
- write(';');
99
+ maybe.write(isNeedSemicolon(path), ';');
84
100
 
85
101
  let wasNewline = false;
86
102
 
@@ -91,7 +107,7 @@ export const VariableDeclaration = {
91
107
  wasNewline = true;
92
108
  }
93
109
 
94
- if (isParentBlock(path) && isNext(path) && (noTrailingComment(path) || isNewlineBetweenSiblings(path))) {
110
+ if (isNeedNewline(path)) {
95
111
  write.newline();
96
112
  wasNewline = true;
97
113
  }
@@ -107,41 +123,35 @@ export const VariableDeclaration = {
107
123
  isNextCoupleLines,
108
124
  notLastPrevVarNotNextVar,
109
125
  isNewlineBetweenSiblings,
110
- notLastParentExport,
126
+ isInsideExport,
111
127
  isParentTSModuleBlock,
112
128
  ],
113
- after(path, {maybe, store}) {
129
+ after(path, {maybe, store, print}) {
114
130
  const wasNewline = store();
115
131
 
116
- if (isLast(path.parentPath) && !path.parentPath.isBlockStatement() || !isParentBlock(path) && !isParentTSModuleBlock(path))
117
- return false;
132
+ if (skipAfter(path))
133
+ return;
118
134
 
119
- maybe.print.linebreak(wasNewline);
120
- maybe.print.newline(!wasNewline);
135
+ maybe.indent(wasNewline);
136
+ print.newline();
121
137
  maybe.markAfter(wasNewline, path);
122
138
  },
123
139
  };
124
140
 
125
- function noNextParentBlock(path) {
126
- if (isNext(path))
127
- return false;
128
-
129
- return path.parentPath.isBlockStatement();
130
- }
141
+ const skipAfter = createTypeChecker([
142
+ ['-: parentPath -> !', isLast],
143
+ ['+: -> !', isInsideBlock],
144
+ ]);
131
145
 
132
- function notLastParentExport(path) {
133
- if (isLast(path.parentPath))
134
- return false;
135
-
136
- return path.parentPath.isExportDeclaration();
137
- }
146
+ const noNextParentBlock = createTypeChecker([
147
+ ['-', isNext],
148
+ ['+', isInsideBlock],
149
+ ]);
138
150
 
139
- function notLastCoupleLines(path) {
140
- if (isLast(path))
141
- return false;
142
-
143
- return isCoupleLines(path);
144
- }
151
+ const notLastCoupleLines = createTypeChecker([
152
+ ['-', isLast],
153
+ ['+', isCoupleLines],
154
+ ]);
145
155
 
146
156
  function notLastPrevVarNotNextVar(path) {
147
157
  const prev = path.getPrevSibling();
@@ -169,8 +179,6 @@ function isNextCoupleLines(path) {
169
179
  return isCoupleLines(next);
170
180
  }
171
181
 
172
- const isLast = (path) => path.parentPath?.isProgram() && !isNext(path);
173
-
174
182
  function shouldAddNewlineBefore(path) {
175
183
  if (isFirst(path))
176
184
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.0.0",
3
+ "version": "18.0.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",
@@ -70,7 +70,7 @@
70
70
  "@putout/eslint": "^6.0.0",
71
71
  "@putout/eslint-flat": "^4.0.0",
72
72
  "@putout/plugin-minify": "^11.2.1",
73
- "@putout/plugin-printer": "^7.0.0",
73
+ "@putout/plugin-printer": "^8.0.0",
74
74
  "@putout/plugin-promises": "^19.0.0",
75
75
  "@putout/plugin-react-hook-form": "^6.0.0",
76
76
  "@putout/plugin-react-hooks": "^9.0.0",