@putout/printer 1.5.4 → 1.6.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 +5 -0
- package/README.md +26 -0
- package/lib/printer.js +2 -2
- package/lib/tokenize/expressions/array-expression.js +7 -7
- package/lib/tokenize/expressions/array-pattern.js +7 -7
- package/lib/tokenize/expressions/assignment-expression.js +11 -5
- package/lib/tokenize/expressions/assignment-pattern.js +4 -3
- package/lib/tokenize/expressions/functions.js +40 -40
- package/lib/tokenize/statements/block-statement.js +4 -1
- package/lib/tokenize/statements/for-of-statement.js +14 -13
- package/lib/tokenize/tokenize.js +47 -16
- package/package.json +1 -1
package/ChangeLog
CHANGED
package/README.md
CHANGED
|
@@ -32,6 +32,32 @@ const a = (b, c) => {
|
|
|
32
32
|
`;
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
## Overrides
|
|
36
|
+
|
|
37
|
+
When you need to extend syntax of `@putout/printer` just pass a function which receives:
|
|
38
|
+
|
|
39
|
+
- `path`, Babel Path
|
|
40
|
+
- `print`, a function to output result of printing into token array;
|
|
41
|
+
|
|
42
|
+
When `path` contains to dashes `__` and name, it is the same as: `print(path.get('right'))`, and this is
|
|
43
|
+
actually `traverse(path.get('right'))` shortened to simplify read and process.
|
|
44
|
+
|
|
45
|
+
Here is how you can override `AssignmentPattern`:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
const ast = parse('const {a = 5} = b');
|
|
49
|
+
|
|
50
|
+
print(ast, {
|
|
51
|
+
AssignmentPattern(path, {print}) {
|
|
52
|
+
print(' /* [hello world] */= ');
|
|
53
|
+
print('__right');
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// returns
|
|
58
|
+
'const {a /* [hello world] */= 5} = b;\n';
|
|
59
|
+
```
|
|
60
|
+
|
|
35
61
|
## License
|
|
36
62
|
|
|
37
63
|
MIT
|
package/lib/printer.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const {tokenize} = require('./tokenize/tokenize');
|
|
4
4
|
const {printTokens} = require('./print-tokens');
|
|
5
5
|
|
|
6
|
-
module.exports.print = (ast) => {
|
|
7
|
-
const tokens = tokenize(ast);
|
|
6
|
+
module.exports.print = (ast, overrides) => {
|
|
7
|
+
const tokens = tokenize(ast, overrides);
|
|
8
8
|
return printTokens(tokens);
|
|
9
9
|
};
|
|
@@ -4,31 +4,31 @@ const {isObjectProperty} = require('@babel/types');
|
|
|
4
4
|
const {entries} = Object;
|
|
5
5
|
const isForOf = ({parentPath}) => parentPath.isForOfStatement();
|
|
6
6
|
|
|
7
|
-
module.exports.ArrayExpression = (path, {
|
|
7
|
+
module.exports.ArrayExpression = (path, {print, maybe}) => {
|
|
8
8
|
const elements = path.get('elements');
|
|
9
9
|
const elementIsObject = isElementObject(path);
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
print('[');
|
|
12
12
|
maybe.indent.inc(!elementIsObject);
|
|
13
13
|
|
|
14
14
|
const isNewLine = !isNumbers(elements) && !isForOf(path) && isLastArg(path) && !isParentProperty(path);
|
|
15
15
|
const n = elements.length - 1;
|
|
16
16
|
|
|
17
|
-
maybe.
|
|
17
|
+
maybe.print(isNewLine && elements.length, '\n');
|
|
18
18
|
|
|
19
19
|
for (const [index, element] of entries(elements)) {
|
|
20
20
|
maybe.indent(isNewLine);
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
print(element);
|
|
23
23
|
|
|
24
|
-
maybe.
|
|
25
|
-
maybe.
|
|
24
|
+
maybe.print(isNewLine, ',\n');
|
|
25
|
+
maybe.print(!isNewLine && index < n, ', ');
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
maybe.indent.dec(!elementIsObject);
|
|
29
29
|
maybe.indent(elements.length && isNewLine);
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
print(']');
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
function isNumbers(elements) {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const {entries} = Object;
|
|
4
4
|
const isForOf = ({parentPath}) => parentPath.parentPath.parentPath.isForOfStatement();
|
|
5
5
|
|
|
6
|
-
module.exports.ArrayPattern = (path, {
|
|
7
|
-
|
|
6
|
+
module.exports.ArrayPattern = (path, {indent, maybe, print}) => {
|
|
7
|
+
print('[');
|
|
8
8
|
|
|
9
9
|
const elements = path.get('elements');
|
|
10
10
|
|
|
@@ -13,21 +13,21 @@ module.exports.ArrayPattern = (path, {write, indent, maybe, traverse}) => {
|
|
|
13
13
|
const isNewLine = !isForOf(path) && elements.length > 2;
|
|
14
14
|
const n = elements.length - 1;
|
|
15
15
|
|
|
16
|
-
maybe.
|
|
16
|
+
maybe.print(isNewLine && elements.length, '\n');
|
|
17
17
|
|
|
18
18
|
for (const [index, element] of entries(elements)) {
|
|
19
19
|
maybe.indent(isNewLine);
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
print(element);
|
|
22
22
|
|
|
23
|
-
maybe.
|
|
24
|
-
maybe.
|
|
23
|
+
maybe.print(isNewLine, ',\n');
|
|
24
|
+
maybe.print(!isNewLine && index < n, ', ');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
indent.dec();
|
|
28
28
|
|
|
29
29
|
maybe.indent(elements.length && isNewLine);
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
print(']');
|
|
32
32
|
};
|
|
33
33
|
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
module.exports.AssignmentExpression = (path, {
|
|
3
|
+
module.exports.AssignmentExpression = (path, {print}) => {
|
|
4
|
+
const {operator} = path.node;
|
|
5
|
+
const left = path.get('left');
|
|
6
|
+
const right = path.get('right');
|
|
7
|
+
|
|
4
8
|
if (shouldAddNewLine(path))
|
|
5
|
-
|
|
9
|
+
print('\n');
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
print(left);
|
|
12
|
+
print(' ');
|
|
13
|
+
print(operator);
|
|
14
|
+
print(' ');
|
|
15
|
+
print(right);
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
function shouldAddNewLine({parentPath}) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const {isMarkedPrevAfter} = require('../mark');
|
|
4
4
|
const isFirst = (path) => path.node === path.parentPath.node.body[0];
|
|
5
5
|
|
|
6
|
-
module.exports.FunctionExpression = (path, {
|
|
6
|
+
module.exports.FunctionExpression = (path, {print, maybe}) => {
|
|
7
7
|
const {node} = path;
|
|
8
8
|
|
|
9
9
|
const {
|
|
@@ -11,105 +11,105 @@ module.exports.FunctionExpression = (path, {write, maybe, traverse}) => {
|
|
|
11
11
|
async,
|
|
12
12
|
} = node;
|
|
13
13
|
|
|
14
|
-
maybe.
|
|
15
|
-
|
|
16
|
-
maybe.
|
|
17
|
-
|
|
14
|
+
maybe.print(async, 'async ');
|
|
15
|
+
print('function');
|
|
16
|
+
maybe.print(generator, '*');
|
|
17
|
+
print(' (');
|
|
18
18
|
|
|
19
19
|
const params = path.get('params');
|
|
20
20
|
const n = params.length;
|
|
21
21
|
|
|
22
22
|
for (let i = 0; i < n; i++) {
|
|
23
|
-
|
|
23
|
+
print(params[i]);
|
|
24
24
|
|
|
25
25
|
if (i < n - 1)
|
|
26
|
-
|
|
26
|
+
print(', ');
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
print(') ');
|
|
30
|
+
print('__body');
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
module.exports.ArrowFunctionExpression = ArrowFunctionExpression;
|
|
34
|
-
function ArrowFunctionExpression(path, {
|
|
34
|
+
function ArrowFunctionExpression(path, {print, maybe}) {
|
|
35
35
|
const {async} = path.node;
|
|
36
|
-
maybe.
|
|
36
|
+
maybe.print(async, 'async ');
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
print('(');
|
|
39
39
|
|
|
40
40
|
const params = path.get('params');
|
|
41
41
|
const n = params.length;
|
|
42
42
|
|
|
43
43
|
for (let i = 0; i < n; i++) {
|
|
44
|
-
|
|
44
|
+
print(params[i]);
|
|
45
45
|
|
|
46
46
|
if (i < n - 1)
|
|
47
|
-
|
|
47
|
+
print(', ');
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
print(') => ');
|
|
51
|
+
print('__body');
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
module.exports.ObjectMethod = (path, {
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
module.exports.ObjectMethod = (path, {print}) => {
|
|
55
|
+
print(path.get('key'));
|
|
56
|
+
print('(');
|
|
57
57
|
|
|
58
58
|
const params = path.get('params');
|
|
59
59
|
const n = params.length - 1;
|
|
60
60
|
|
|
61
61
|
for (let i = 0; i <= n; i++) {
|
|
62
|
-
|
|
62
|
+
print(params[i]);
|
|
63
63
|
|
|
64
64
|
if (i < n)
|
|
65
|
-
|
|
65
|
+
print(', ');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
print(') ');
|
|
69
|
+
print(path.get('body'));
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
module.exports.FunctionDeclaration = (path, {
|
|
72
|
+
module.exports.FunctionDeclaration = (path, {print, maybe}) => {
|
|
73
73
|
const {async} = path.node;
|
|
74
74
|
|
|
75
75
|
if (!isFirst(path) && !isMarkedPrevAfter(path))
|
|
76
|
-
|
|
76
|
+
print('\n');
|
|
77
77
|
|
|
78
|
-
maybe.
|
|
78
|
+
maybe.print(async, 'async ');
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
print('function ');
|
|
81
|
+
print(path.get('id'));
|
|
82
|
+
print('(');
|
|
83
83
|
|
|
84
84
|
const params = path.get('params');
|
|
85
85
|
const n = params.length - 1;
|
|
86
86
|
|
|
87
87
|
for (let i = 0; i <= n; i++) {
|
|
88
|
-
|
|
88
|
+
print(params[i]);
|
|
89
89
|
|
|
90
90
|
if (i < n)
|
|
91
|
-
|
|
91
|
+
print(', ');
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
print(') ');
|
|
95
|
+
print(path.get('body'));
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
module.exports.ClassMethod = (path, {
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
module.exports.ClassMethod = (path, {print}) => {
|
|
99
|
+
print(path.get('key'));
|
|
100
|
+
print('(');
|
|
101
101
|
|
|
102
102
|
const params = path.get('params');
|
|
103
103
|
const n = params.length;
|
|
104
104
|
|
|
105
105
|
for (let i = 0; i < n; i++) {
|
|
106
|
-
|
|
106
|
+
print(params[i]);
|
|
107
107
|
|
|
108
108
|
if (i < n - 1)
|
|
109
|
-
|
|
109
|
+
print(', ');
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
print(') ');
|
|
113
|
+
print(path.get('body'));
|
|
114
114
|
};
|
|
115
115
|
|
|
@@ -14,7 +14,10 @@ module.exports.BlockStatement = (path, {indent, maybe, print}) => {
|
|
|
14
14
|
if (body.length > 1 || isFirstStatement(path))
|
|
15
15
|
print.newline();
|
|
16
16
|
|
|
17
|
-
body
|
|
17
|
+
for (const element of body) {
|
|
18
|
+
print(element);
|
|
19
|
+
}
|
|
20
|
+
|
|
18
21
|
indent.dec();
|
|
19
22
|
|
|
20
23
|
maybe.indent(body.length);
|
|
@@ -3,31 +3,32 @@
|
|
|
3
3
|
const {isMarkedPrevAfter} = require('../mark');
|
|
4
4
|
const {isFirst} = require('../is');
|
|
5
5
|
|
|
6
|
-
module.exports.ForOfStatement = (path, {
|
|
6
|
+
module.exports.ForOfStatement = (path, {indent, print}) => {
|
|
7
7
|
if (!isFirst(path) && !isMarkedPrevAfter(path)) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
print.indent();
|
|
9
|
+
print.newline();
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
indent();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
print('for (');
|
|
14
|
+
print('__left');
|
|
15
|
+
print(' of ');
|
|
16
|
+
print('__right');
|
|
17
|
+
print(')');
|
|
18
18
|
|
|
19
19
|
const bodyPath = path.get('body');
|
|
20
20
|
|
|
21
21
|
if (bodyPath.isExpressionStatement()) {
|
|
22
22
|
indent.inc();
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
print.newline();
|
|
24
|
+
print(bodyPath);
|
|
25
25
|
indent.dec();
|
|
26
|
-
|
|
26
|
+
print.newline();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (bodyPath.isBlockStatement()) {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
print(' ');
|
|
31
|
+
print(bodyPath);
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
+
|
package/lib/tokenize/tokenize.js
CHANGED
|
@@ -22,7 +22,10 @@ const traversers = {
|
|
|
22
22
|
...literals,
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
const GET = '__';
|
|
26
|
+
const get = (path, command) => path.get(command.replace(GET, ''));
|
|
27
|
+
|
|
28
|
+
module.exports.tokenize = (ast, overrides) => {
|
|
26
29
|
const tokens = [];
|
|
27
30
|
const debug = createDebug(tokens);
|
|
28
31
|
const write = (value) => {
|
|
@@ -81,21 +84,15 @@ module.exports.tokenize = (ast) => {
|
|
|
81
84
|
linebreak,
|
|
82
85
|
breakline,
|
|
83
86
|
});
|
|
84
|
-
const print = (maybeLine) => {
|
|
85
|
-
if (isString(maybeLine))
|
|
86
|
-
return write(maybeLine);
|
|
87
|
-
|
|
88
|
-
return traverse(maybeLine);
|
|
89
|
-
};
|
|
90
87
|
|
|
91
|
-
const maybePrint = (a, b) => a && print(b);
|
|
88
|
+
//const maybePrint = (a, b) => a && print(b);
|
|
92
89
|
|
|
93
90
|
const maybe = {
|
|
94
91
|
write: maybeWrite,
|
|
95
92
|
indent: maybeIndent,
|
|
96
93
|
markBefore: maybeMarkBefore,
|
|
97
94
|
markAfter: maybeMarkAfter,
|
|
98
|
-
print: maybePrint,
|
|
95
|
+
//print: maybePrint,
|
|
99
96
|
};
|
|
100
97
|
|
|
101
98
|
assign(maybe.indent, {
|
|
@@ -103,11 +100,7 @@ module.exports.tokenize = (ast) => {
|
|
|
103
100
|
dec: maybeIndentDec,
|
|
104
101
|
});
|
|
105
102
|
|
|
106
|
-
assign(print, write);
|
|
107
|
-
assign(maybePrint, {
|
|
108
|
-
newline: maybeNewline,
|
|
109
|
-
breakline: maybeBreakline,
|
|
110
|
-
});
|
|
103
|
+
//assign(print, write);
|
|
111
104
|
|
|
112
105
|
const printer = {
|
|
113
106
|
incIndent,
|
|
@@ -119,7 +112,11 @@ module.exports.tokenize = (ast) => {
|
|
|
119
112
|
maybeIndent,
|
|
120
113
|
traverse,
|
|
121
114
|
maybe,
|
|
122
|
-
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const currentTraversers = {
|
|
118
|
+
...traversers,
|
|
119
|
+
...overrides,
|
|
123
120
|
};
|
|
124
121
|
|
|
125
122
|
babelTraverse(ast, {
|
|
@@ -131,11 +128,27 @@ module.exports.tokenize = (ast) => {
|
|
|
131
128
|
|
|
132
129
|
function traverse(path) {
|
|
133
130
|
const {type} = path;
|
|
134
|
-
const currentTraverse =
|
|
131
|
+
const currentTraverse = currentTraversers[type];
|
|
135
132
|
|
|
136
133
|
if (!path.node)
|
|
137
134
|
return;
|
|
138
135
|
|
|
136
|
+
const print = createPrint(path, {write, traverse});
|
|
137
|
+
assign(print, write);
|
|
138
|
+
assign(printer, {
|
|
139
|
+
print,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const maybePrint = (a, b) => a && print(b);
|
|
143
|
+
|
|
144
|
+
assign(maybePrint, {
|
|
145
|
+
newline: maybeNewline,
|
|
146
|
+
breakline: maybeBreakline,
|
|
147
|
+
});
|
|
148
|
+
assign(printer.maybe, {
|
|
149
|
+
print: maybePrint,
|
|
150
|
+
});
|
|
151
|
+
|
|
139
152
|
if (!currentTraverse)
|
|
140
153
|
throw Error(`Node type '${type}' is not supported yet: '${path}'`);
|
|
141
154
|
|
|
@@ -158,3 +171,21 @@ function printIndent(i) {
|
|
|
158
171
|
return result;
|
|
159
172
|
}
|
|
160
173
|
|
|
174
|
+
/*
|
|
175
|
+
const createCompute = (path, {traverse}) => (maybeLine) => {
|
|
176
|
+
if (maybeLine.startsWith(GET))
|
|
177
|
+
return traverse(get(path, maybeLine));
|
|
178
|
+
};
|
|
179
|
+
*/
|
|
180
|
+
const createPrint = (path, {traverse, write}) => (maybeLine) => {
|
|
181
|
+
if (maybeLine === path)
|
|
182
|
+
return null;
|
|
183
|
+
|
|
184
|
+
if (!isString(maybeLine))
|
|
185
|
+
return traverse(maybeLine);
|
|
186
|
+
|
|
187
|
+
if (maybeLine.startsWith(GET))
|
|
188
|
+
return traverse(get(path, maybeLine));
|
|
189
|
+
|
|
190
|
+
return write(maybeLine);
|
|
191
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/printer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.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",
|