@putout/printer 18.1.7 → 18.2.0

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.07, v18.2.0
2
+
3
+ feature:
4
+ - 87135c0 @putout/printer: type-checker: disable instrument: add support
5
+ - 29e0a3c @putout/printer: type-checker: rm deepness
6
+
7
+ 2026.03.07, v18.1.8
8
+
9
+ feature:
10
+ - 35d83ea @putout/printer: type-checker: dsl inside array
11
+
1
12
  2026.03.07, v18.1.7
2
13
 
3
14
  feature:
@@ -71,8 +71,8 @@ const isSimpleBetweenObjects = createTypeChecker([
71
71
  ]);
72
72
 
73
73
  const isSpaceAfterComa = createTypeChecker([
74
- callWithNext(isSimpleBetweenObjects),
75
- '+: -> !ObjectExpression',
74
+ ['+', callWithNext(isSimpleBetweenObjects)],
75
+ ['+: -> !ObjectExpression'],
76
76
  ]);
77
77
 
78
78
  export const ArrayExpression = {
@@ -19,6 +19,6 @@ const isStringAndIdentifierInsideOneElementArray = createTypeChecker([
19
19
  export const beforeIf = createTypeChecker([
20
20
  ['-: -> !', isInsideArray],
21
21
  ['-: parentPath ->', isCoupleLines],
22
- isIdentifierAndIdentifier,
23
- isStringAndIdentifierInsideOneElementArray,
22
+ ['+', isIdentifierAndIdentifier],
23
+ ['+', isStringAndIdentifierInsideOneElementArray],
24
24
  ]);
@@ -30,7 +30,7 @@ const isStringAndString = (path) => {
30
30
  const isStringsInsideArray = createTypeChecker([
31
31
  ['-: -> !', isStringAndString],
32
32
  ['-: -> !', isInsideArray],
33
- '+: parentPath.node.elements.0 -> ArrayExpression',
33
+ ['+: parentPath.node.elements.0 -> ArrayExpression'],
34
34
  ]);
35
35
 
36
36
  const isTwoSimplesInsideObjectProperty = (path) => {
@@ -183,13 +183,13 @@ const isElementsMoreThenThree = (path) => {
183
183
  };
184
184
 
185
185
  const isElementsMoreThenThreeWithNotFirstObject = createTypeChecker([
186
- '-: node.elements.0 -> ObjectExpression',
187
- isElementsMoreThenThree,
186
+ ['-: node.elements.0 -> ObjectExpression'],
187
+ ['+', isElementsMoreThenThree],
188
188
  ]);
189
189
 
190
190
  const isElementsMoreThenMaxWithFirstString = createTypeChecker([
191
- '-: node.elements.0 -> !StringLiteral',
192
- isElementsMoreThenMax,
191
+ ['-: node.elements.0 -> !StringLiteral'],
192
+ ['+', isElementsMoreThenMax],
193
193
  ]);
194
194
 
195
195
  const isOne = (a) => a === 1;
@@ -204,8 +204,8 @@ export const isMultiLine = createTypeChecker([
204
204
  ['+', isBodyWithOneElement],
205
205
  ['+', isMoreThenMaxElementLengthInOneLine],
206
206
  ['+', isElementsMoreThenMaxWithFirstString],
207
- isElementsMoreThenThreeWithNotFirstObject,
208
- isSimpleAndNotEmptyObject,
207
+ ['+', isElementsMoreThenThreeWithNotFirstObject],
208
+ ['+', isSimpleAndNotEmptyObject],
209
209
  ['-', isOneSimple],
210
210
  ['-', isOneSpread],
211
211
  ['-', isIdentifierAndIdentifier],
@@ -225,8 +225,8 @@ export const isMultiLine = createTypeChecker([
225
225
  ['-', isSimpleAndObject],
226
226
  ['-', isSiblingIsArray],
227
227
  ['-', isStringsInsideArray],
228
- tooLong,
229
- isCoupleLines,
228
+ ['+', tooLong],
229
+ ['+', isCoupleLines],
230
230
  ['-', isNumbersArray],
231
231
  ]);
232
232
 
@@ -328,7 +328,7 @@ export function isIncreaseIndent(path) {
328
328
 
329
329
  const isInsideCallLoop = createTypeChecker([
330
330
  ['-: -> !', isInsideCall],
331
- '+: parentPath.parentPath -> ForOfStatement',
331
+ ['+: parentPath.parentPath -> ForOfStatement'],
332
332
  ]);
333
333
 
334
334
  const isStringAndObject = (elements) => {
@@ -53,7 +53,9 @@ export const ClassMethod = {
53
53
  print.space();
54
54
  print('__body');
55
55
  }),
56
- afterSatisfy: () => [noTrailingCommentAndNext],
56
+ afterSatisfy: () => [
57
+ noTrailingCommentAndNext,
58
+ ],
57
59
  after(path, {print}) {
58
60
  print.linebreak();
59
61
  },
@@ -23,13 +23,13 @@ const isIndentAfter = createTypeChecker([
23
23
  ]);
24
24
 
25
25
  const isNotInsideExportDefaultWithBody = createTypeChecker([
26
- '+: parentPath -> !ExportDefaultDeclaration',
26
+ ['+: parentPath -> !ExportDefaultDeclaration'],
27
27
  ['+: -> !', hasFnBody],
28
28
  ]);
29
29
 
30
30
  const isInsideBlockLike = createTypeChecker([
31
- '+: parentPath.parentPath -> TSModuleBlock',
32
- '-: parentPath -> !BlockStatement',
31
+ ['+: parentPath.parentPath -> TSModuleBlock'],
32
+ ['-: parentPath -> !BlockStatement'],
33
33
  ['+: -> !', hasFnBody],
34
34
  ]);
35
35
 
@@ -44,27 +44,27 @@ const isParens = createTypeChecker([isInsideBody, isInsideExpression]);
44
44
  const getCallee = (fn) => (a) => fn(a.get('callee'));
45
45
 
46
46
  const isMemberExpressionCallee = createTypeChecker([
47
- '-: parentPath -> !CallExpression',
47
+ ['-: parentPath -> !CallExpression'],
48
48
  ['-: parentPath -> !', getCallee(isMemberExpression)],
49
49
  ['+: parentPath', getCallee(isLooksLikeChain)],
50
50
  ]);
51
51
 
52
52
  const isInsideNestedArrayCall = createTypeChecker([
53
- isInsideTuple,
54
- '-: parentPath -> !ArrayExpression',
55
- '-: parentPath.parentPath -> !ArrayExpression',
53
+ ['+', isInsideTuple],
54
+ ['-: parentPath -> !ArrayExpression'],
55
+ ['-: parentPath.parentPath -> !ArrayExpression'],
56
56
  ['+: parentPath.parentPath', isInsideCall],
57
57
  ]);
58
58
 
59
59
  const isInsideTupleLike = createTypeChecker([
60
60
  ['+', isInsideTuple],
61
- '+: parentPath.parentPath.node.elements.0 -> StringLiteral',
61
+ ['+: parentPath.parentPath.node.elements.0 -> StringLiteral'],
62
62
  ]);
63
63
 
64
64
  export const isManyLines = createTypeChecker([
65
65
  ['-', hasNoProperties],
66
- '-: parentPath -> ForOfStatement',
67
- '+: node.properties.0 -> SpreadElement',
66
+ ['-: parentPath -> ForOfStatement'],
67
+ ['+: node.properties.0 -> SpreadElement'],
68
68
  ['-', notLastArgInsideCall],
69
69
  ['-', isForOf],
70
70
  ['-', isIf],
@@ -31,6 +31,7 @@ export const isInsideTSModuleBlock = ({parentPath}) => isTSModuleBlock(parentPat
31
31
  export const isInsideCall = ({parentPath}) => parentPath.isCallExpression();
32
32
  export const isInsideReturn = ({parentPath}) => parentPath.isReturnStatement();
33
33
  export const callWithNext = (fn) => (path) => fn(path.getNextSibling());
34
+ export const callWithParent = (fn) => (path) => fn(path.parentPath);
34
35
 
35
36
  export const isNext = (path) => {
36
37
  const next = path.getNextSibling();
@@ -16,7 +16,9 @@ export const DoWhileStatement = {
16
16
  print(')');
17
17
  print(';');
18
18
  },
19
- afterSatisfy: () => [notLast],
19
+ afterSatisfy: () => [
20
+ notLast,
21
+ ],
20
22
  after(path, {print}) {
21
23
  print.newline();
22
24
  },
@@ -20,7 +20,9 @@ export const ExportDefaultDeclaration = {
20
20
  traverse(declaration);
21
21
  maybe.print(shouldAddSemicolon(declaration), ';');
22
22
  },
23
- afterSatisfy: () => [isNext],
23
+ afterSatisfy: () => [
24
+ isNext,
25
+ ],
24
26
  after(path, {print, maybe}) {
25
27
  print.newline();
26
28
  maybe.print.newline(!isVarAfterFn(path));
@@ -16,9 +16,9 @@ function isNotLastOrParentLast(path) {
16
16
  const isNextUp = (path) => path.findParent(isNext);
17
17
 
18
18
  const isTopParentLast = createTypeChecker([
19
- '-: parentPath -> !IfStatement',
20
- '-: parentPath.parentPath -> !IfStatement',
21
- '-: parentPath.parentPath.parentPath -> !IfStatement',
19
+ ['-: parentPath -> !IfStatement'],
20
+ ['-: parentPath.parentPath -> !IfStatement'],
21
+ ['-: parentPath.parentPath.parentPath -> !IfStatement'],
22
22
  ['+: parentPath.parentPath.parentPath', isLast],
23
23
  ]);
24
24
 
@@ -32,7 +32,7 @@ const satisfyAfter = satisfy([
32
32
  const isPathIsConsequent = ({node, parentPath}) => node !== parentPath.node.consequent;
33
33
 
34
34
  const isBeforeElse = createTypeChecker([
35
- '-: parentPath -> !IfStatement',
35
+ ['-: parentPath -> !IfStatement'],
36
36
  ['-:', isPathIsConsequent],
37
37
  ['+: parentPath.node.alternate', Boolean],
38
38
  ]);
@@ -26,7 +26,7 @@ const isCallInsideExpression = createTypeChecker([
26
26
  ]);
27
27
 
28
28
  const isNextToAssignmentCall = createTypeChecker([
29
- '-: node.expression -> AssignmentExpression',
29
+ ['-: node.expression -> AssignmentExpression'],
30
30
  ['+', callWithNext(isCallInsideExpression)],
31
31
  ]);
32
32
 
@@ -39,12 +39,12 @@ const isBreaklineAfter = createTypeChecker([
39
39
  const isNextStatementWithBlockComment = createTypeChecker([
40
40
  '-: node.expression -> !CallExpression',
41
41
  '-: node.expression.arguments.0 -> !CallExpression',
42
- '+: node.trailingComments.0 -> CommentBlock',
42
+ '+: node.trailingComments.0 -> 🧨 CommentBlock',
43
43
  ]);
44
44
 
45
45
  const isBreakline = createTypeChecker([
46
- isNewlineBetweenSiblings,
47
- callWithNext(isIfStatement),
46
+ ['+', isNewlineBetweenSiblings],
47
+ ['+', callWithNext(isIfStatement)],
48
48
  ]);
49
49
 
50
50
  const isIndent = createTypeChecker([
@@ -54,7 +54,7 @@ const isIndent = createTypeChecker([
54
54
  ]);
55
55
 
56
56
  export const isIndentAfter = createTypeChecker([
57
- '-: node.expression -> !AssignmentExpression',
57
+ ['-: node.expression -> !AssignmentExpression'],
58
58
  ['+', callWithNext(hasLeadingComment)],
59
59
  ]);
60
60
 
@@ -36,7 +36,7 @@ const isStatementNotExpression = (path) => {
36
36
 
37
37
  const isInsideNestedBody = createTypeChecker([
38
38
  ['-: -> !', isInsideBlock],
39
- '+: parentPath.parentPath -> BlockStatement',
39
+ ['+: parentPath.parentPath -> BlockStatement'],
40
40
  ]);
41
41
 
42
42
  const isTopLevel = ({parentPath}) => parentPath.parentPath.isProgram();
@@ -48,7 +48,7 @@ const isLastEmptyInsideBody = createTypeChecker([
48
48
  ['-: -> !', isInsideBlock],
49
49
  ['-: -> !', isBlockConsequent],
50
50
  ['-', isConsequentHasBody],
51
- '+: parentPath.parentPath -> FunctionDeclaration',
51
+ ['+: parentPath.parentPath -> FunctionDeclaration'],
52
52
  ]);
53
53
 
54
54
  export const IfStatement = {
@@ -125,7 +125,9 @@ export const IfStatement = {
125
125
  if (isLastEmptyInsideBody(path))
126
126
  print.newline();
127
127
  },
128
- afterSatisfy: () => [isNext],
128
+ afterSatisfy: () => [
129
+ isNext,
130
+ ],
129
131
  after: (path, {print}) => {
130
132
  print.linebreak();
131
133
  markAfter(path);
@@ -69,7 +69,9 @@ export const SwitchStatement = {
69
69
  if (!isNext(path) && !isLast(path))
70
70
  print.newline();
71
71
  },
72
- afterSatisfy: () => [isNext],
72
+ afterSatisfy: () => [
73
+ isNext,
74
+ ],
73
75
  after(path, {print}) {
74
76
  print.breakline();
75
77
  print.newline();
@@ -24,7 +24,9 @@ export const TryStatement = {
24
24
  maybe.print.newline(!isNext(path));
25
25
  }
26
26
  },
27
- afterSatisfy: () => [isNext],
27
+ afterSatisfy: () => [
28
+ isNext,
29
+ ],
28
30
  after(path, {print}) {
29
31
  print.newline();
30
32
 
@@ -14,6 +14,7 @@ import {
14
14
  isInsideProgram,
15
15
  isInsideSwitchCase,
16
16
  isInsideBody,
17
+ callWithParent,
17
18
  } from '#is';
18
19
  import {maybeSpaceAfterKeyword} from './maybe-space-after-keyword.js';
19
20
  import {isConcatenation} from '../../expressions/binary-expression/concatenate.js';
@@ -36,12 +37,12 @@ const isParentTSModuleBlock = (path) => path.parentPath.isTSModuleBlock();
36
37
  const isParentSwitchCase = (path) => path.parentPath.isSwitchCase();
37
38
  const isFirstInSwitch = (path) => path.parentPath.get('consequent.0') === path;
38
39
 
39
- const isInsideParentLike = createTypeChecker('path.parentPath', [
40
+ const isInsideParentLike = callWithParent(createTypeChecker([
40
41
  'Program',
41
42
  'BlockStatement',
42
43
  'ExportNamedDeclaration',
43
44
  'LabeledStatement',
44
- ]);
45
+ ]));
45
46
 
46
47
  const isNeedSemicolon = createTypeChecker([
47
48
  isInsideParentLike,
@@ -10,12 +10,13 @@ export const instrument = (typeNames, fn, overrides = {}) => {
10
10
  const {
11
11
  env = _env,
12
12
  coverage = Coverage,
13
+ instrument = true,
13
14
  } = overrides;
14
15
 
15
16
  const {length} = typeNames;
16
17
  const error = Error();
17
18
  const location = parseCallLocation(error);
18
- const on = env.TYPE_CHECK;
19
+ const on = instrument && env.TYPE_CHECK;
19
20
  const covered = new Set();
20
21
 
21
22
  if (on && !location.includes('type-checker.spec.js'))
@@ -36,3 +37,4 @@ export const instrument = (typeNames, fn, overrides = {}) => {
36
37
  };
37
38
 
38
39
  export const getCoverage = () => Coverage;
40
+
@@ -22,6 +22,14 @@ export function parseTypeNames(typeNames) {
22
22
 
23
23
  if (isArray(typeNames)) {
24
24
  for (const typeName of typeNames) {
25
+ if (isArray(typeName) && typeName.length === 1) {
26
+ const [first] = typeName;
27
+ const tuple = createTuple(first);
28
+
29
+ tuples.push(tuple);
30
+ continue;
31
+ }
32
+
25
33
  if (isArray(typeName)) {
26
34
  tuples.push(typeName);
27
35
  continue;
@@ -1,5 +1,5 @@
1
1
  import {jessy} from 'jessy';
2
- import {instrument} from '#type-checker/instrument';
2
+ import {instrument as _instrument} from '#type-checker/instrument';
3
3
  import {parseOperation, parseTypeNames} from './parsers.js';
4
4
  import {equal, maybeCall} from './comparators.js';
5
5
 
@@ -8,26 +8,12 @@ const SKIP = [
8
8
  false,
9
9
  ];
10
10
 
11
- export const createTypeChecker = (deepness, typeNames) => {
12
- if (!typeNames) {
13
- typeNames = deepness;
14
- deepness = '';
15
- }
16
-
11
+ export const createTypeChecker = (typeNames, overrides = {}) => {
12
+ const {
13
+ instrumentCoverage = _instrument,
14
+ } = overrides;
17
15
  const tuples = parseTypeNames(typeNames);
18
-
19
- return instrument(typeNames, (path, options) => {
20
- let i = deepness.split('.').length;
21
-
22
- while (--i)
23
- path = path?.parentPath;
24
-
25
- if (!path)
26
- return [
27
- Infinity,
28
- false,
29
- ];
30
-
16
+ const typeChecker = (path, options) => {
31
17
  for (const [index, [operation, typeName]] of tuples.entries()) {
32
18
  const [result, selector, not] = parseOperation(operation);
33
19
  let currentPath = path;
@@ -48,5 +34,7 @@ export const createTypeChecker = (deepness, typeNames) => {
48
34
  }
49
35
 
50
36
  return SKIP;
51
- });
37
+ };
38
+
39
+ return instrumentCoverage(typeNames, typeChecker, overrides);
52
40
  };
@@ -15,7 +15,9 @@ export const TSModuleDeclaration = {
15
15
  print.space();
16
16
  print('__body');
17
17
  }),
18
- afterSatisfy: () => [isNext],
18
+ afterSatisfy: () => [
19
+ isNext,
20
+ ],
19
21
  after(path, {print}) {
20
22
  print.newline();
21
23
  print.newline();
@@ -6,7 +6,9 @@ export const TSExportAssignment = {
6
6
  print('__expression');
7
7
  print(';');
8
8
  },
9
- afterSatisfy: () => [isNext],
9
+ afterSatisfy: () => [
10
+ isNext,
11
+ ],
10
12
  after: (path, {print}) => {
11
13
  print.newline();
12
14
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "18.1.7",
3
+ "version": "18.2.0",
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",