@putout/printer 1.5.4 → 1.6.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 +10 -0
- package/README.md +29 -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 +38 -18
- package/package.json +1 -1
package/ChangeLog
CHANGED
package/README.md
CHANGED
|
@@ -32,6 +32,35 @@ 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
|
+
indent: ' ',
|
|
52
|
+
visitors: {
|
|
53
|
+
AssignmentPattern(path, {print}) {
|
|
54
|
+
print(' /* [hello world] */= ');
|
|
55
|
+
print('__right');
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// returns
|
|
61
|
+
'const {a /* [hello world] */= 5} = b;\n';
|
|
62
|
+
```
|
|
63
|
+
|
|
35
64
|
## License
|
|
36
65
|
|
|
37
66
|
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,12 @@ 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
|
-
|
|
91
|
-
const maybePrint = (a, b) => a && print(b);
|
|
92
87
|
|
|
93
88
|
const maybe = {
|
|
94
89
|
write: maybeWrite,
|
|
95
90
|
indent: maybeIndent,
|
|
96
91
|
markBefore: maybeMarkBefore,
|
|
97
92
|
markAfter: maybeMarkAfter,
|
|
98
|
-
print: maybePrint,
|
|
99
93
|
};
|
|
100
94
|
|
|
101
95
|
assign(maybe.indent, {
|
|
@@ -103,12 +97,6 @@ module.exports.tokenize = (ast) => {
|
|
|
103
97
|
dec: maybeIndentDec,
|
|
104
98
|
});
|
|
105
99
|
|
|
106
|
-
assign(print, write);
|
|
107
|
-
assign(maybePrint, {
|
|
108
|
-
newline: maybeNewline,
|
|
109
|
-
breakline: maybeBreakline,
|
|
110
|
-
});
|
|
111
|
-
|
|
112
100
|
const printer = {
|
|
113
101
|
incIndent,
|
|
114
102
|
decIndent,
|
|
@@ -119,7 +107,11 @@ module.exports.tokenize = (ast) => {
|
|
|
119
107
|
maybeIndent,
|
|
120
108
|
traverse,
|
|
121
109
|
maybe,
|
|
122
|
-
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const currentTraversers = {
|
|
113
|
+
...traversers,
|
|
114
|
+
...overrides.visitors,
|
|
123
115
|
};
|
|
124
116
|
|
|
125
117
|
babelTraverse(ast, {
|
|
@@ -131,11 +123,27 @@ module.exports.tokenize = (ast) => {
|
|
|
131
123
|
|
|
132
124
|
function traverse(path) {
|
|
133
125
|
const {type} = path;
|
|
134
|
-
const currentTraverse =
|
|
126
|
+
const currentTraverse = currentTraversers[type];
|
|
135
127
|
|
|
136
128
|
if (!path.node)
|
|
137
129
|
return;
|
|
138
130
|
|
|
131
|
+
const print = createPrint(path, {write, traverse});
|
|
132
|
+
assign(print, write);
|
|
133
|
+
assign(printer, {
|
|
134
|
+
print,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const maybePrint = (a, b) => a && print(b);
|
|
138
|
+
|
|
139
|
+
assign(maybePrint, {
|
|
140
|
+
newline: maybeNewline,
|
|
141
|
+
breakline: maybeBreakline,
|
|
142
|
+
});
|
|
143
|
+
assign(printer.maybe, {
|
|
144
|
+
print: maybePrint,
|
|
145
|
+
});
|
|
146
|
+
|
|
139
147
|
if (!currentTraverse)
|
|
140
148
|
throw Error(`Node type '${type}' is not supported yet: '${path}'`);
|
|
141
149
|
|
|
@@ -158,3 +166,15 @@ function printIndent(i) {
|
|
|
158
166
|
return result;
|
|
159
167
|
}
|
|
160
168
|
|
|
169
|
+
const createPrint = (path, {traverse, write}) => (maybeLine) => {
|
|
170
|
+
if (maybeLine === path)
|
|
171
|
+
return null;
|
|
172
|
+
|
|
173
|
+
if (!isString(maybeLine))
|
|
174
|
+
return traverse(maybeLine);
|
|
175
|
+
|
|
176
|
+
if (maybeLine.startsWith(GET))
|
|
177
|
+
return traverse(get(path, maybeLine));
|
|
178
|
+
|
|
179
|
+
return write(maybeLine);
|
|
180
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/printer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.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",
|