@putout/printer 1.4.0 → 1.4.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 +11 -0
- package/lib/tokenize/expressions/array-expression.js +31 -7
- package/lib/tokenize/expressions/array-pattern.js +1 -0
- package/lib/tokenize/expressions/call-expression.js +3 -5
- package/lib/tokenize/expressions/object-expression.js +26 -15
- package/lib/tokenize/expressions/unary-expressions.js +4 -4
- package/lib/tokenize/is.js +7 -0
- package/lib/tokenize/literals/index.js +2 -1
- package/lib/tokenize/statements/for-of-statement.js +3 -10
- package/lib/tokenize/statements/if-statement.js +1 -4
- package/lib/tokenize/statements/variable-declaration.js +12 -14
- package/lib/tokenize/tokenize.js +7 -1
- package/package.json +3 -1
package/ChangeLog
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
2023.03.17, v1.4.1
|
|
2
|
+
|
|
3
|
+
feature:
|
|
4
|
+
- 1948ce5 @putout/printer: improve support of ObjectExpression
|
|
5
|
+
- 09e1a5c @putout/printer: improve support of ObjectExpression
|
|
6
|
+
- 2d13bc2 @putout/printer: ArrayExpression: newlines
|
|
7
|
+
- 9fc6a00 @putout/printer: improve support of ArrayExpression
|
|
8
|
+
- b91d908 @putout/printer: UnaryExpression: add support of delete
|
|
9
|
+
- 337492b @putout/printer: improve support of NumericLiteral
|
|
10
|
+
- 166085c @putout/printer: add support of hex numbers
|
|
11
|
+
|
|
1
12
|
2023.03.17, v1.4.0
|
|
2
13
|
|
|
3
14
|
feature:
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const {isObjectProperty} = require('@babel/types');
|
|
3
4
|
const {entries} = Object;
|
|
4
5
|
const isForOf = ({parentPath}) => parentPath.isForOfStatement();
|
|
5
6
|
|
|
6
|
-
module.exports.ArrayExpression = (path, {write,
|
|
7
|
-
write('[');
|
|
8
|
-
|
|
7
|
+
module.exports.ArrayExpression = (path, {write, maybe, traverse}) => {
|
|
9
8
|
const elements = path.get('elements');
|
|
9
|
+
const elementIsObject = isElementObject(path);
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
write('[');
|
|
12
|
+
maybe.indent.inc(!elementIsObject);
|
|
12
13
|
|
|
13
|
-
const isNewLine = !isNumbers(elements) && !isForOf(path);
|
|
14
|
+
const isNewLine = !isNumbers(elements) && !isForOf(path) && isLastArg(path) && !isParentProperty(path);
|
|
14
15
|
const n = elements.length - 1;
|
|
15
16
|
|
|
16
17
|
maybe.write(isNewLine && elements.length, '\n');
|
|
@@ -24,8 +25,7 @@ module.exports.ArrayExpression = (path, {write, indent, maybe, traverse}) => {
|
|
|
24
25
|
maybe.write(!isNewLine && index < n, ', ');
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
indent.dec();
|
|
28
|
-
|
|
28
|
+
maybe.indent.dec(!elementIsObject);
|
|
29
29
|
maybe.indent(elements.length && isNewLine);
|
|
30
30
|
|
|
31
31
|
write(']');
|
|
@@ -40,3 +40,27 @@ function isNumbers(elements) {
|
|
|
40
40
|
return false;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function isLastArg(path) {
|
|
44
|
+
const {parentPath} = path;
|
|
45
|
+
|
|
46
|
+
if (!parentPath.isCallExpression())
|
|
47
|
+
return true;
|
|
48
|
+
|
|
49
|
+
const args = parentPath.get('arguments');
|
|
50
|
+
const n = args.length - 1;
|
|
51
|
+
|
|
52
|
+
return path === args[n];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isParentProperty(path) {
|
|
56
|
+
return path.find(isObjectProperty);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isElementObject(path) {
|
|
60
|
+
const elements = path.get('elements');
|
|
61
|
+
|
|
62
|
+
if (!elements.length)
|
|
63
|
+
return false;
|
|
64
|
+
|
|
65
|
+
return elements[0].isObjectExpression();
|
|
66
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
|
-
hasPrevNewline,
|
|
5
4
|
isMarkedParentBefore,
|
|
5
|
+
isMarkedPrevAfter,
|
|
6
6
|
} = require('../mark');
|
|
7
7
|
|
|
8
8
|
const {entries} = Object;
|
|
@@ -10,10 +10,8 @@ const {entries} = Object;
|
|
|
10
10
|
module.exports.CallExpression = (path, {traverse, indent, write, incIndent, decIndent, maybeWrite}) => {
|
|
11
11
|
const isParentCall = toLong(path) && path.parentPath.isCallExpression();
|
|
12
12
|
|
|
13
|
-
if (shouldAddNewLine(path) && !
|
|
14
|
-
write.
|
|
15
|
-
write.indent();
|
|
16
|
-
}
|
|
13
|
+
if (shouldAddNewLine(path) && !isMarkedParentBefore(path) && !isMarkedPrevAfter(path.parentPath))
|
|
14
|
+
write.linebreak();
|
|
17
15
|
|
|
18
16
|
traverse(path.get('callee'));
|
|
19
17
|
write('(');
|
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const {isCoupleLines} = require('../is');
|
|
3
4
|
const isBodyOfArrow = (path) => path.parentPath.node.body === path.node;
|
|
4
5
|
const isForOf = (path) => {
|
|
5
6
|
if (path.parentPath.isForOfStatement())
|
|
6
7
|
return true;
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
return true;
|
|
10
|
-
|
|
11
|
-
return false;
|
|
9
|
+
return path.parentPath?.parentPath?.isForOfStatement();
|
|
12
10
|
};
|
|
13
11
|
|
|
14
|
-
const isFirstMethod = (path) => path.get('properties.0').isObjectMethod();
|
|
15
|
-
|
|
16
12
|
module.exports.ObjectExpression = (path, {traverse, write, maybe, indent}) => {
|
|
17
13
|
indent.inc();
|
|
18
14
|
|
|
19
15
|
const properties = path.get('properties');
|
|
20
|
-
const parens = isBodyOfArrow(path);
|
|
21
|
-
const isCall = path.parentPath.isCallExpression();
|
|
22
16
|
const {length} = properties;
|
|
23
|
-
const
|
|
17
|
+
const parens = isBodyOfArrow(path);
|
|
18
|
+
const manyLines = !isOneLine(path);
|
|
24
19
|
|
|
25
20
|
maybe.write(parens, '(');
|
|
26
21
|
write('{');
|
|
27
22
|
|
|
28
|
-
maybe.write(
|
|
23
|
+
maybe.write(manyLines, '\n');
|
|
29
24
|
|
|
30
25
|
for (const property of properties) {
|
|
31
26
|
if (property.isSpreadElement()) {
|
|
32
|
-
maybe.indent(
|
|
27
|
+
maybe.indent(length > 1);
|
|
33
28
|
traverse(property);
|
|
34
29
|
|
|
35
|
-
if (
|
|
30
|
+
if (length > 1) {
|
|
36
31
|
write(',');
|
|
37
32
|
write.newline();
|
|
38
33
|
}
|
|
@@ -42,7 +37,7 @@ module.exports.ObjectExpression = (path, {traverse, write, maybe, indent}) => {
|
|
|
42
37
|
|
|
43
38
|
const {shorthand, computed} = property.node;
|
|
44
39
|
|
|
45
|
-
maybe.indent(
|
|
40
|
+
maybe.indent(manyLines);
|
|
46
41
|
|
|
47
42
|
if (property.isObjectMethod()) {
|
|
48
43
|
traverse(property);
|
|
@@ -58,11 +53,27 @@ module.exports.ObjectExpression = (path, {traverse, write, maybe, indent}) => {
|
|
|
58
53
|
traverse(property.get('value'));
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
maybe.write(
|
|
56
|
+
maybe.write(manyLines, ',\n');
|
|
62
57
|
}
|
|
63
58
|
|
|
64
59
|
indent.dec();
|
|
65
|
-
|
|
60
|
+
|
|
61
|
+
maybe.indent(manyLines);
|
|
66
62
|
write('}');
|
|
67
63
|
maybe.write(parens, ')');
|
|
68
64
|
};
|
|
65
|
+
function isOneLine(path) {
|
|
66
|
+
const isCall = path.parentPath.isCallExpression();
|
|
67
|
+
const {length} = path.get('properties');
|
|
68
|
+
|
|
69
|
+
if (isCoupleLines(path))
|
|
70
|
+
return false;
|
|
71
|
+
|
|
72
|
+
if (!length)
|
|
73
|
+
return true;
|
|
74
|
+
|
|
75
|
+
if (isCall && length < 2)
|
|
76
|
+
return true;
|
|
77
|
+
|
|
78
|
+
return isForOf(path);
|
|
79
|
+
}
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
module.exports.UnaryExpression = unaryExpressions;
|
|
4
4
|
module.exports.UpdateExpression = unaryExpressions;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const isWord = (a) => /delete|typeof/.test(a);
|
|
7
|
+
|
|
8
|
+
function unaryExpressions(path, {traverse, write, maybe}) {
|
|
7
9
|
const {prefix, operator} = path.node;
|
|
8
10
|
|
|
9
11
|
if (prefix)
|
|
10
12
|
write(operator);
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
write(' ');
|
|
14
|
-
|
|
14
|
+
maybe.write(isWord(operator), ' ');
|
|
15
15
|
traverse(path.get('argument'));
|
|
16
16
|
|
|
17
17
|
if (!prefix)
|
package/lib/tokenize/is.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
module.exports.isFirst = (path) => path.node === path.parentPath.node.body[0];
|
|
3
4
|
module.exports.isPrevBody = (path) => path.getPrevSibling().isBlockStatement();
|
|
4
5
|
module.exports.isNext = (path) => path.getNextSibling().node;
|
|
6
|
+
module.exports.isCoupleLines = (path) => {
|
|
7
|
+
const start = path.node?.loc?.start.line;
|
|
8
|
+
const end = path.node?.loc?.end.line;
|
|
9
|
+
|
|
10
|
+
return end > start;
|
|
11
|
+
};
|
|
@@ -5,7 +5,8 @@ const {TemplateLiteral} = require('./template-literal');
|
|
|
5
5
|
module.exports = {
|
|
6
6
|
TemplateLiteral,
|
|
7
7
|
NumericLiteral(path, {write}) {
|
|
8
|
-
|
|
8
|
+
const {extra, raw} = path.node;
|
|
9
|
+
write(raw || extra.raw);
|
|
9
10
|
},
|
|
10
11
|
BooleanLiteral(path, {write}) {
|
|
11
12
|
write(path.node.value);
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const
|
|
5
|
-
const prev = path.getPrevSibling();
|
|
6
|
-
|
|
7
|
-
if (!prev.node)
|
|
8
|
-
return true;
|
|
9
|
-
|
|
10
|
-
return isMarkedAfter(prev);
|
|
11
|
-
};
|
|
3
|
+
const {isMarkedPrevAfter} = require('../mark');
|
|
4
|
+
const {isFirst} = require('../is');
|
|
12
5
|
|
|
13
6
|
module.exports.ForOfStatement = (path, {write, indent, traverse}) => {
|
|
14
|
-
if (!
|
|
7
|
+
if (!isFirst(path) && !isMarkedPrevAfter(path)) {
|
|
15
8
|
write.indent();
|
|
16
9
|
write.newline();
|
|
17
10
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {hasPrevNewline} = require('../mark');
|
|
4
|
+
const {isFirst} = require('../is');
|
|
4
5
|
|
|
5
6
|
module.exports.IfStatement = (path, {write, indent, traverse, incIndent, decIndent}) => {
|
|
6
7
|
if (!isFirst(path) && !hasPrevNewline(path)) {
|
|
@@ -36,7 +37,3 @@ module.exports.IfStatement = (path, {write, indent, traverse, incIndent, decInde
|
|
|
36
37
|
write('\n');
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
function isFirst(path) {
|
|
40
|
-
return path.node === path.parentPath.node.body[0];
|
|
41
|
-
}
|
|
42
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {isNext} = require('../is');
|
|
3
|
+
const {isNext, isCoupleLines} = require('../is');
|
|
4
4
|
const isNextAssign = (path) => {
|
|
5
5
|
const nextPath = path.getNextSibling();
|
|
6
6
|
|
|
@@ -27,21 +27,25 @@ module.exports.VariableDeclaration = (path, {write, maybe, maybeIndent, traverse
|
|
|
27
27
|
traverse(initPath);
|
|
28
28
|
maybe.write(isParentBlock, ';\n');
|
|
29
29
|
|
|
30
|
-
const is = isNext(path) &&
|
|
30
|
+
const is = isNext(path) && isCoupleLines(path) && !isNextAssign(path);
|
|
31
31
|
|
|
32
32
|
maybe.indent(is);
|
|
33
33
|
maybe.write(is, '\n');
|
|
34
34
|
maybe.markAfter(is, path);
|
|
35
35
|
};
|
|
36
|
-
function isCoupleLinesExpression(path) {
|
|
37
|
-
const start = path.node?.loc?.start.line;
|
|
38
|
-
const end = path.node?.loc?.end.line;
|
|
39
|
-
|
|
40
|
-
return end > start;
|
|
41
|
-
}
|
|
42
36
|
|
|
43
37
|
function shouldAddNewLine(path) {
|
|
44
38
|
const prevPath = path.getPrevSibling();
|
|
39
|
+
|
|
40
|
+
if (prevPath.isStatement() && !prevPath.isExpressionStatement() && !prevPath.isBlockStatement())
|
|
41
|
+
return false;
|
|
42
|
+
|
|
43
|
+
if (prevPath.isExpressionStatement() && prevPath.get('expression').isStringLiteral())
|
|
44
|
+
return false;
|
|
45
|
+
|
|
46
|
+
if (isCoupleLines(path))
|
|
47
|
+
return true;
|
|
48
|
+
|
|
45
49
|
const nextPath = path.getNextSibling();
|
|
46
50
|
const nextNextPath = nextPath.getNextSibling();
|
|
47
51
|
|
|
@@ -50,12 +54,6 @@ function shouldAddNewLine(path) {
|
|
|
50
54
|
if (!twoNext)
|
|
51
55
|
return false;
|
|
52
56
|
|
|
53
|
-
if (prevPath.isVariableDeclaration() || prevPath.isExpressionStatement() && prevPath.get('expression').isStringLiteral())
|
|
54
|
-
return false;
|
|
55
|
-
|
|
56
|
-
if (prevPath.isIfStatement())
|
|
57
|
-
return false;
|
|
58
|
-
|
|
59
57
|
return true;
|
|
60
58
|
}
|
|
61
59
|
|
package/lib/tokenize/tokenize.js
CHANGED
|
@@ -32,11 +32,12 @@ module.exports.tokenize = (ast) => {
|
|
|
32
32
|
|
|
33
33
|
const maybeWrite = (a, b) => a && write(b);
|
|
34
34
|
const maybeIndent = (a) => a && indent();
|
|
35
|
+
const maybeIndentInc = (a) => a && indent.inc();
|
|
36
|
+
const maybeIndentDec = (a) => a && indent.dec();
|
|
35
37
|
|
|
36
38
|
let i = 0;
|
|
37
39
|
const incIndent = () => ++i;
|
|
38
40
|
const decIndent = () => --i;
|
|
39
|
-
|
|
40
41
|
const indent = () => {
|
|
41
42
|
tokens.push({
|
|
42
43
|
type: TYPES.INDENT,
|
|
@@ -76,6 +77,11 @@ module.exports.tokenize = (ast) => {
|
|
|
76
77
|
markAfter: maybeMarkAfter,
|
|
77
78
|
};
|
|
78
79
|
|
|
80
|
+
assign(maybe.indent, {
|
|
81
|
+
inc: maybeIndentInc,
|
|
82
|
+
dec: maybeIndentDec,
|
|
83
|
+
});
|
|
84
|
+
|
|
79
85
|
const printer = {
|
|
80
86
|
incIndent,
|
|
81
87
|
decIndent,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/printer",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "Easiest possible opinionated Babel AST printer made with ❤️ to use in 🐊Putout",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@babel/parser": "^7.19.0",
|
|
30
30
|
"@babel/traverse": "^7.21.2",
|
|
31
|
+
"@babel/types": "^7.21.3",
|
|
31
32
|
"just-snake-case": "^3.2.0"
|
|
32
33
|
},
|
|
33
34
|
"keywords": [
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
"eslint": "^8.0.1",
|
|
45
46
|
"eslint-plugin-n": "^15.2.4",
|
|
46
47
|
"eslint-plugin-putout": "^17.0.0",
|
|
48
|
+
"estree-to-babel": "^5.0.1",
|
|
47
49
|
"just-kebab-case": "^4.2.0",
|
|
48
50
|
"lerna": "^6.0.1",
|
|
49
51
|
"madrun": "^9.0.0",
|