@putout/printer 1.7.3 → 1.8.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 +10 -0
- package/lib/print-tokens/cook.js +0 -1
- package/lib/tokenize/comments.js +22 -3
- package/lib/tokenize/debug.js +33 -1
- package/lib/tokenize/expressions/call-expression.js +2 -1
- package/lib/tokenize/statements/block-statement.js +2 -2
- package/lib/tokenize/statements/expression-statement.js +7 -9
- package/lib/tokenize/statements/for-of-statement.js +8 -3
- package/lib/tokenize/statements/index.js +2 -0
- package/lib/tokenize/statements/switch-statement.js +47 -0
- package/lib/tokenize/statements/variable-declaration.js +22 -17
- package/lib/tokenize/tokenize.js +27 -10
- package/package.json +2 -1
package/ChangeLog
CHANGED
package/lib/print-tokens/cook.js
CHANGED
package/lib/tokenize/comments.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const {isFirst} = require('./is');
|
|
4
|
+
const {markBefore} = require('./mark');
|
|
5
|
+
|
|
6
|
+
module.exports.parseComments = (path, {print, indent, maybe}) => {
|
|
4
7
|
const {leadingComments} = path.node;
|
|
5
8
|
|
|
6
9
|
if (leadingComments)
|
|
7
|
-
parseLeadingComments(path, {print});
|
|
10
|
+
parseLeadingComments(path, {print, indent, maybe});
|
|
8
11
|
};
|
|
9
12
|
|
|
10
|
-
function parseLeadingComments(path, {print}) {
|
|
13
|
+
function parseLeadingComments(path, {print, indent}) {
|
|
11
14
|
const {leadingComments} = path.node;
|
|
12
15
|
|
|
16
|
+
if (shouldAddNewlineBefore(path))
|
|
17
|
+
print.linebreak();
|
|
18
|
+
|
|
13
19
|
for (const {type, value} of leadingComments) {
|
|
20
|
+
indent();
|
|
21
|
+
|
|
14
22
|
if (type === 'CommentLine') {
|
|
15
23
|
print(`//${value}`);
|
|
16
24
|
print.newline();
|
|
@@ -19,7 +27,18 @@ function parseLeadingComments(path, {print}) {
|
|
|
19
27
|
|
|
20
28
|
if (type === 'CommentBlock') {
|
|
21
29
|
print(`/*${value}*/`);
|
|
30
|
+
|
|
31
|
+
if (path.isStatement()) {
|
|
32
|
+
print.newline();
|
|
33
|
+
markBefore(path);
|
|
34
|
+
}
|
|
35
|
+
|
|
22
36
|
continue;
|
|
23
37
|
}
|
|
24
38
|
}
|
|
25
39
|
}
|
|
40
|
+
|
|
41
|
+
function shouldAddNewlineBefore(path) {
|
|
42
|
+
return path.isStatement() && !isFirst(path);
|
|
43
|
+
}
|
|
44
|
+
|
package/lib/tokenize/debug.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const {TYPES} = require('../types');
|
|
4
4
|
const toSnakeCase = require('just-snake-case');
|
|
5
|
-
const {DEBUG} = process.env;
|
|
5
|
+
const {LOG, DEBUG} = process.env;
|
|
6
|
+
const {codeFrameColumns} = require('@babel/code-frame');
|
|
6
7
|
|
|
7
8
|
module.exports.createDebug = (tokens) => (a) => {
|
|
8
9
|
if (!DEBUG)
|
|
@@ -13,3 +14,34 @@ module.exports.createDebug = (tokens) => (a) => {
|
|
|
13
14
|
value: `/*__${toSnakeCase(a)}*/`,
|
|
14
15
|
});
|
|
15
16
|
};
|
|
17
|
+
|
|
18
|
+
module.exports.createLog = ({newline = '\n', store = createStore()} = {}) => (chunk) => {
|
|
19
|
+
if (!LOG)
|
|
20
|
+
return;
|
|
21
|
+
|
|
22
|
+
if (chunk === newline) {
|
|
23
|
+
console.log(codeFrameColumns(store(), {}, {
|
|
24
|
+
highlightCode: true,
|
|
25
|
+
}));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
store(chunk);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function createStore() {
|
|
33
|
+
let chunks = [];
|
|
34
|
+
|
|
35
|
+
return (chunk) => {
|
|
36
|
+
if (chunk) {
|
|
37
|
+
chunks.push(chunk);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const result = chunks.join('');
|
|
42
|
+
chunks = [];
|
|
43
|
+
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
@@ -20,8 +20,9 @@ module.exports.CallExpression = CallExpression;
|
|
|
20
20
|
function CallExpression(path, {indent, print, maybe}) {
|
|
21
21
|
const isParentCall = toLong(path) && path.parentPath.isCallExpression();
|
|
22
22
|
|
|
23
|
-
if (isNewLineBefore(path) && !isMarkedParentBefore(path) && !hasPrevNewline(path.parentPath))
|
|
23
|
+
if (isNewLineBefore(path) && !isMarkedParentBefore(path) && !hasPrevNewline(path.parentPath)) {
|
|
24
24
|
print.breakline();
|
|
25
|
+
}
|
|
25
26
|
|
|
26
27
|
print('__callee');
|
|
27
28
|
print('(');
|
|
@@ -26,9 +26,9 @@ module.exports.BlockStatement = (path, {indent, maybe, print}) => {
|
|
|
26
26
|
print(',');
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const shouldAddNewline = isAddNewLineAfter(path);
|
|
30
30
|
|
|
31
|
-
if (
|
|
31
|
+
if (shouldAddNewline) {
|
|
32
32
|
print.newline();
|
|
33
33
|
}
|
|
34
34
|
};
|
|
@@ -8,21 +8,19 @@ const {
|
|
|
8
8
|
|
|
9
9
|
const {isNext} = require('../is');
|
|
10
10
|
|
|
11
|
-
module.exports.ExpressionStatement = (path, {
|
|
12
|
-
if (isCoupleLinesExpression(path) && !isFirst(path) &&
|
|
11
|
+
module.exports.ExpressionStatement = (path, {indent, print}) => {
|
|
12
|
+
if (isCoupleLinesExpression(path) && !isFirst(path) && shouldAddNewline(path) && !hasPrevNewline(path)) {
|
|
13
13
|
print.breakline();
|
|
14
14
|
markBefore(path);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const expressionPath = path.get('expression');
|
|
18
|
-
|
|
19
17
|
indent();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
print('__expression');
|
|
19
|
+
print(';');
|
|
20
|
+
print.newline();
|
|
23
21
|
|
|
24
22
|
if (isStrictMode(path) || isCoupleLinesExpression(path) && isNext(path)) {
|
|
25
|
-
|
|
23
|
+
print.newline();
|
|
26
24
|
markAfter(path);
|
|
27
25
|
}
|
|
28
26
|
};
|
|
@@ -49,7 +47,7 @@ function isFirst(path) {
|
|
|
49
47
|
return path.node === path.parentPath.node.body[0];
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
function
|
|
50
|
+
function shouldAddNewline(path) {
|
|
53
51
|
const prev = path.getPrevSibling();
|
|
54
52
|
|
|
55
53
|
if (prev.isVariableDeclaration())
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
hasPrevNewline,
|
|
5
|
+
markAfter,
|
|
6
|
+
markBefore,
|
|
7
|
+
} = require('../mark');
|
|
4
8
|
|
|
5
9
|
const {isFirst} = require('../is');
|
|
6
10
|
|
|
@@ -8,6 +12,7 @@ module.exports.ForOfStatement = (path, {indent, print}) => {
|
|
|
8
12
|
if (!isFirst(path) && !hasPrevNewline(path)) {
|
|
9
13
|
print.indent();
|
|
10
14
|
print.newline();
|
|
15
|
+
markBefore(path);
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
indent();
|
|
@@ -22,7 +27,7 @@ module.exports.ForOfStatement = (path, {indent, print}) => {
|
|
|
22
27
|
if (bodyPath.isExpressionStatement()) {
|
|
23
28
|
indent.inc();
|
|
24
29
|
print.newline();
|
|
25
|
-
print(
|
|
30
|
+
print('__body');
|
|
26
31
|
indent.dec();
|
|
27
32
|
print.newline();
|
|
28
33
|
|
|
@@ -31,7 +36,7 @@ module.exports.ForOfStatement = (path, {indent, print}) => {
|
|
|
31
36
|
|
|
32
37
|
if (bodyPath.isBlockStatement()) {
|
|
33
38
|
print(' ');
|
|
34
|
-
print(
|
|
39
|
+
print('__body');
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
if (path.getNextSibling().node) {
|
|
@@ -12,6 +12,7 @@ const {ForStatement} = require('./for-statement');
|
|
|
12
12
|
const importDeclarations = require('./import-declarations');
|
|
13
13
|
const exportDeclarations = require('./export-declarations');
|
|
14
14
|
const {WhileStatement} = require('./while-statement');
|
|
15
|
+
const {SwitchStatement} = require('./switch-statement');
|
|
15
16
|
|
|
16
17
|
module.exports = {
|
|
17
18
|
...importDeclarations,
|
|
@@ -27,6 +28,7 @@ module.exports = {
|
|
|
27
28
|
Program(path, {traverse}) {
|
|
28
29
|
path.get('body').forEach(traverse);
|
|
29
30
|
},
|
|
31
|
+
SwitchStatement,
|
|
30
32
|
...TryStatements,
|
|
31
33
|
BreakStatement(path, {print, indent}) {
|
|
32
34
|
indent();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {entries} = Object;
|
|
4
|
+
|
|
5
|
+
module.exports.SwitchStatement = (path, {print, maybe}) => {
|
|
6
|
+
print('switch');
|
|
7
|
+
print.space();
|
|
8
|
+
print('(');
|
|
9
|
+
print('__discriminant');
|
|
10
|
+
print(') {');
|
|
11
|
+
|
|
12
|
+
print.newline();
|
|
13
|
+
|
|
14
|
+
const cases = path.get('cases');
|
|
15
|
+
const n = cases.length - 1;
|
|
16
|
+
|
|
17
|
+
for (const [index, switchCase] of entries(cases)) {
|
|
18
|
+
print('case');
|
|
19
|
+
print.space();
|
|
20
|
+
print(switchCase.get('test'));
|
|
21
|
+
print(':');
|
|
22
|
+
|
|
23
|
+
const isBlock = switchCase.get('consequent.0').isBlockStatement();
|
|
24
|
+
|
|
25
|
+
maybe.indent.inc(!isBlock);
|
|
26
|
+
maybe.print.newline(!isBlock);
|
|
27
|
+
|
|
28
|
+
for (const consequent of switchCase.get('consequent')) {
|
|
29
|
+
if (!consequent.isBlockStatement()) {
|
|
30
|
+
print(consequent);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
print.space();
|
|
35
|
+
print(consequent);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (index < n) {
|
|
39
|
+
print.indent();
|
|
40
|
+
maybe.indent.dec(!isBlock);
|
|
41
|
+
print.newline();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
print('}');
|
|
46
|
+
};
|
|
47
|
+
|
|
@@ -9,19 +9,9 @@ const {
|
|
|
9
9
|
markAfter,
|
|
10
10
|
} = require('../mark');
|
|
11
11
|
|
|
12
|
-
const isNextAssign = (path) => {
|
|
13
|
-
const nextPath = path.getNextSibling();
|
|
14
|
-
|
|
15
|
-
if (!nextPath.isExpressionStatement())
|
|
16
|
-
return false;
|
|
17
|
-
|
|
18
|
-
return nextPath.get('expression').isAssignmentExpression();
|
|
19
|
-
};
|
|
20
|
-
|
|
21
12
|
module.exports.VariableDeclaration = (path, {maybe, print}) => {
|
|
22
|
-
if (
|
|
13
|
+
if (shouldAddNewlineBefore(path))
|
|
23
14
|
print.breakline();
|
|
24
|
-
}
|
|
25
15
|
|
|
26
16
|
const isParentBlock = /Program|BlockStatement/.test(path.parentPath.type);
|
|
27
17
|
|
|
@@ -36,7 +26,7 @@ module.exports.VariableDeclaration = (path, {maybe, print}) => {
|
|
|
36
26
|
maybe.print(isParentBlock, ';');
|
|
37
27
|
maybe.print.newline(isParentBlock);
|
|
38
28
|
|
|
39
|
-
const is =
|
|
29
|
+
const is = shouldAddNewlineAfter(path);
|
|
40
30
|
|
|
41
31
|
if (is) {
|
|
42
32
|
print.linebreak();
|
|
@@ -44,7 +34,7 @@ module.exports.VariableDeclaration = (path, {maybe, print}) => {
|
|
|
44
34
|
}
|
|
45
35
|
};
|
|
46
36
|
|
|
47
|
-
function
|
|
37
|
+
function shouldAddNewlineAfter(path) {
|
|
48
38
|
if (isLast(path))
|
|
49
39
|
return true;
|
|
50
40
|
|
|
@@ -65,13 +55,19 @@ function shouldAddNewLineAfter(path) {
|
|
|
65
55
|
|
|
66
56
|
const isLast = (path) => path.parentPath.isProgram() && !isNext(path);
|
|
67
57
|
|
|
68
|
-
function
|
|
69
|
-
|
|
58
|
+
function shouldAddNewlineBefore(path) {
|
|
59
|
+
if (isFirst(path))
|
|
60
|
+
return false;
|
|
70
61
|
|
|
71
|
-
if (
|
|
62
|
+
if (hasPrevNewline(path))
|
|
72
63
|
return false;
|
|
73
64
|
|
|
74
|
-
if (
|
|
65
|
+
if (hasPrevNewline(path.parentPath))
|
|
66
|
+
return false;
|
|
67
|
+
|
|
68
|
+
const prevPath = path.getPrevSibling();
|
|
69
|
+
|
|
70
|
+
if (prevPath.isStatement() && !prevPath.isExpressionStatement() && !prevPath.isBlockStatement())
|
|
75
71
|
return false;
|
|
76
72
|
|
|
77
73
|
if (isCoupleLines(path))
|
|
@@ -90,3 +86,12 @@ function isNewLineBefore(path) {
|
|
|
90
86
|
function isFirst(path) {
|
|
91
87
|
return path.node === path.parentPath.node.body[0];
|
|
92
88
|
}
|
|
89
|
+
const isNextAssign = (path) => {
|
|
90
|
+
const nextPath = path.getNextSibling();
|
|
91
|
+
|
|
92
|
+
if (!nextPath.isExpressionStatement())
|
|
93
|
+
return false;
|
|
94
|
+
|
|
95
|
+
return nextPath.get('expression').isAssignmentExpression();
|
|
96
|
+
};
|
|
97
|
+
|
package/lib/tokenize/tokenize.js
CHANGED
|
@@ -6,7 +6,7 @@ const expressions = require('./expressions');
|
|
|
6
6
|
const statements = require('./statements');
|
|
7
7
|
const literals = require('./literals');
|
|
8
8
|
const {TYPES} = require('../types');
|
|
9
|
-
const {createDebug} = require('./debug');
|
|
9
|
+
const {createDebug, createLog} = require('./debug');
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
maybeMarkAfter,
|
|
@@ -33,13 +33,24 @@ function initFormat(format) {
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const createAddToken = (tokens) => {
|
|
37
|
+
const log = createLog();
|
|
38
|
+
return (token) => {
|
|
39
|
+
const {value} = token;
|
|
40
|
+
|
|
41
|
+
log(value);
|
|
42
|
+
tokens.push(token);
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
36
46
|
module.exports.tokenize = (ast, overrides = {}) => {
|
|
37
47
|
const format = initFormat(overrides.format);
|
|
38
48
|
const tokens = [];
|
|
49
|
+
const addToken = createAddToken(tokens);
|
|
39
50
|
const debug = createDebug(tokens);
|
|
40
51
|
|
|
41
52
|
const write = (value) => {
|
|
42
|
-
|
|
53
|
+
addToken({
|
|
43
54
|
type: TYPES.TOKEN,
|
|
44
55
|
value,
|
|
45
56
|
});
|
|
@@ -55,7 +66,7 @@ module.exports.tokenize = (ast, overrides = {}) => {
|
|
|
55
66
|
const decIndent = () => --i;
|
|
56
67
|
|
|
57
68
|
const indent = () => {
|
|
58
|
-
|
|
69
|
+
addToken({
|
|
59
70
|
type: TYPES.INDENT,
|
|
60
71
|
value: printIndent(i, format.indent),
|
|
61
72
|
});
|
|
@@ -67,21 +78,28 @@ module.exports.tokenize = (ast, overrides = {}) => {
|
|
|
67
78
|
});
|
|
68
79
|
|
|
69
80
|
const linebreak = () => {
|
|
70
|
-
|
|
81
|
+
addToken({
|
|
71
82
|
type: TYPES.NEWLINE,
|
|
72
83
|
value: `${printIndent(i, format.indent)}\n`,
|
|
73
84
|
});
|
|
74
85
|
};
|
|
75
86
|
|
|
87
|
+
const space = () => {
|
|
88
|
+
addToken({
|
|
89
|
+
type: TYPES.SPACE,
|
|
90
|
+
value: ' ',
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
76
94
|
const breakline = () => {
|
|
77
|
-
|
|
95
|
+
addToken({
|
|
78
96
|
type: TYPES.NEWLINE,
|
|
79
97
|
value: `\n${printIndent(i, format.indent)}`,
|
|
80
98
|
});
|
|
81
99
|
};
|
|
82
100
|
|
|
83
101
|
const newline = () => {
|
|
84
|
-
|
|
102
|
+
addToken({
|
|
85
103
|
type: TYPES.NEWLINE,
|
|
86
104
|
value: '\n',
|
|
87
105
|
});
|
|
@@ -106,12 +124,9 @@ module.exports.tokenize = (ast, overrides = {}) => {
|
|
|
106
124
|
});
|
|
107
125
|
|
|
108
126
|
const printer = {
|
|
109
|
-
incIndent,
|
|
110
|
-
decIndent,
|
|
111
127
|
indent,
|
|
112
128
|
write,
|
|
113
129
|
debug,
|
|
114
|
-
maybeIndent,
|
|
115
130
|
traverse,
|
|
116
131
|
maybe,
|
|
117
132
|
};
|
|
@@ -140,7 +155,9 @@ module.exports.tokenize = (ast, overrides = {}) => {
|
|
|
140
155
|
traverse,
|
|
141
156
|
});
|
|
142
157
|
|
|
143
|
-
assign(print, write
|
|
158
|
+
assign(print, write, {
|
|
159
|
+
space,
|
|
160
|
+
});
|
|
144
161
|
|
|
145
162
|
assign(printer, {
|
|
146
163
|
print,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/printer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
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",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"report": "madrun report"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@babel/code-frame": "^7.18.6",
|
|
29
30
|
"@babel/parser": "^7.19.0",
|
|
30
31
|
"@babel/traverse": "^7.21.2",
|
|
31
32
|
"@babel/types": "^7.21.3",
|