esrap 1.3.7 → 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/README.md +19 -2
- package/package.json +1 -1
- package/src/handlers.js +78 -37
- package/src/index.js +19 -33
- package/src/types.d.ts +8 -13
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -35,12 +35,29 @@ If the nodes of the input AST have `loc` properties (e.g. the AST was generated
|
|
|
35
35
|
|
|
36
36
|
## Options
|
|
37
37
|
|
|
38
|
-
You can pass
|
|
38
|
+
You can pass the following options:
|
|
39
39
|
|
|
40
40
|
```js
|
|
41
41
|
const { code, map } = print(ast, {
|
|
42
|
+
// Populate the `sources` field of the resulting sourcemap
|
|
43
|
+
// (note that the AST is assumed to come from a single file)
|
|
42
44
|
sourceMapSource: 'input.js',
|
|
43
|
-
|
|
45
|
+
|
|
46
|
+
// Populate the `sourcesContent` field of the resulting sourcemap
|
|
47
|
+
sourceMapContent: fs.readFileSync('input.js', 'utf-8'),
|
|
48
|
+
|
|
49
|
+
// Whether to encode the `mappings` field of the resulting sourcemap
|
|
50
|
+
// as a VLQ string, rather than an unencoded array. Defaults to `true`
|
|
51
|
+
sourceMapEncodeMappings: false,
|
|
52
|
+
|
|
53
|
+
// String to use for indentation — defaults to '\t'
|
|
54
|
+
indent: ' ',
|
|
55
|
+
|
|
56
|
+
// Whether to wrap strings in single or double quotes — defaults to 'single'.
|
|
57
|
+
// This only applies to string literals with no `raw` value, which generally
|
|
58
|
+
// means the AST node was generated programmatically, rather than parsed
|
|
59
|
+
// from an original source
|
|
60
|
+
quotes: 'single'
|
|
44
61
|
});
|
|
45
62
|
```
|
|
46
63
|
|
package/package.json
CHANGED
package/src/handlers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { TSESTree } from '@typescript-eslint/types' */
|
|
2
|
-
/** @import {
|
|
2
|
+
/** @import { Command, Dedent, Handlers, Location, Indent, Newline, NodeWithComments, State, TypeAnnotationNodes } from './types' */
|
|
3
3
|
|
|
4
4
|
/** @type {Newline} */
|
|
5
5
|
const newline = { type: 'Newline' };
|
|
@@ -11,11 +11,10 @@ const indent = { type: 'Indent' };
|
|
|
11
11
|
const dedent = { type: 'Dedent' };
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* @
|
|
15
|
-
* @returns {Sequence}
|
|
14
|
+
* @returns {Command[]}
|
|
16
15
|
*/
|
|
17
|
-
function create_sequence(
|
|
18
|
-
return
|
|
16
|
+
function create_sequence() {
|
|
17
|
+
return [];
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -30,11 +29,11 @@ function measure(commands, from, to = commands.length) {
|
|
|
30
29
|
const command = commands[i];
|
|
31
30
|
if (typeof command === 'string') {
|
|
32
31
|
total += command.length;
|
|
33
|
-
} else if (command
|
|
34
|
-
total +=
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
} else if (Array.isArray(command)) {
|
|
33
|
+
total +=
|
|
34
|
+
command.length === 0
|
|
35
|
+
? 2 // assume this is ', '
|
|
36
|
+
: measure(command, 0);
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -66,17 +65,32 @@ export function handle(node, state) {
|
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @param {number} line
|
|
70
|
+
* @param {number} column
|
|
71
|
+
* @returns {Location}
|
|
72
|
+
*/
|
|
73
|
+
function l(line, column) {
|
|
74
|
+
return {
|
|
75
|
+
type: 'Location',
|
|
76
|
+
line,
|
|
77
|
+
column
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
/**
|
|
70
82
|
* @param {string} content
|
|
71
83
|
* @param {TSESTree.Node} node
|
|
72
|
-
* @returns {
|
|
84
|
+
* @returns {string | Command[]}
|
|
73
85
|
*/
|
|
74
86
|
function c(content, node) {
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
return node.loc
|
|
88
|
+
? [
|
|
89
|
+
l(node.loc.start.line, node.loc.start.column),
|
|
90
|
+
content,
|
|
91
|
+
l(node.loc.end.line, node.loc.end.column)
|
|
92
|
+
]
|
|
93
|
+
: content;
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
/**
|
|
@@ -96,6 +110,33 @@ function prepend_comments(comments, state, newlines) {
|
|
|
96
110
|
}
|
|
97
111
|
}
|
|
98
112
|
|
|
113
|
+
/**
|
|
114
|
+
* @param {string} string
|
|
115
|
+
* @param {'\'' | '"'} char
|
|
116
|
+
*/
|
|
117
|
+
function quote(string, char) {
|
|
118
|
+
let out = char;
|
|
119
|
+
let escaped = false;
|
|
120
|
+
|
|
121
|
+
for (const c of string) {
|
|
122
|
+
if (escaped) {
|
|
123
|
+
out += c;
|
|
124
|
+
escaped = false;
|
|
125
|
+
} else if (c === '\\') {
|
|
126
|
+
out += '\\\\';
|
|
127
|
+
escaped = true;
|
|
128
|
+
} else if (c === char) {
|
|
129
|
+
out += '\\' + c;
|
|
130
|
+
} else if (c === '\n') {
|
|
131
|
+
out += '\\n';
|
|
132
|
+
} else {
|
|
133
|
+
out += c;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return out + char;
|
|
138
|
+
}
|
|
139
|
+
|
|
99
140
|
const OPERATOR_PRECEDENCE = {
|
|
100
141
|
'||': 2,
|
|
101
142
|
'&&': 3,
|
|
@@ -280,7 +321,7 @@ const handle_body = (nodes, state) => {
|
|
|
280
321
|
grouped_expression_types.includes(last_statement.type)) &&
|
|
281
322
|
last_statement.type !== statement.type)
|
|
282
323
|
) {
|
|
283
|
-
margin.
|
|
324
|
+
margin.push('\n');
|
|
284
325
|
}
|
|
285
326
|
|
|
286
327
|
let add_newline = false;
|
|
@@ -324,11 +365,11 @@ const handle_var_declaration = (node, state) => {
|
|
|
324
365
|
|
|
325
366
|
if (multiline) {
|
|
326
367
|
state.multiline = true;
|
|
327
|
-
if (node.declarations.length > 1) open.
|
|
328
|
-
join.
|
|
368
|
+
if (node.declarations.length > 1) open.push(indent);
|
|
369
|
+
join.push(',', newline);
|
|
329
370
|
if (node.declarations.length > 1) state.commands.push(dedent);
|
|
330
371
|
} else {
|
|
331
|
-
join.
|
|
372
|
+
join.push(', ');
|
|
332
373
|
}
|
|
333
374
|
};
|
|
334
375
|
|
|
@@ -400,13 +441,13 @@ function sequence(nodes, state, spaces, fn, separator = ',') {
|
|
|
400
441
|
if (multiline) {
|
|
401
442
|
state.multiline = true;
|
|
402
443
|
|
|
403
|
-
open.
|
|
404
|
-
join.
|
|
405
|
-
close.
|
|
444
|
+
open.push(indent, newline);
|
|
445
|
+
join.push(newline);
|
|
446
|
+
close.push(dedent, newline);
|
|
406
447
|
} else {
|
|
407
|
-
if (spaces) open.
|
|
408
|
-
join.
|
|
409
|
-
if (spaces) close.
|
|
448
|
+
if (spaces) open.push(' ');
|
|
449
|
+
join.push(' ');
|
|
450
|
+
if (spaces) close.push(' ');
|
|
410
451
|
}
|
|
411
452
|
}
|
|
412
453
|
|
|
@@ -702,11 +743,11 @@ const shared = {
|
|
|
702
743
|
}
|
|
703
744
|
|
|
704
745
|
if (multiline) {
|
|
705
|
-
open.
|
|
706
|
-
join.
|
|
707
|
-
close.
|
|
746
|
+
open.push(indent, newline);
|
|
747
|
+
join.push(',', newline);
|
|
748
|
+
close.push(dedent, newline);
|
|
708
749
|
} else {
|
|
709
|
-
join.
|
|
750
|
+
join.push(', ');
|
|
710
751
|
}
|
|
711
752
|
},
|
|
712
753
|
|
|
@@ -898,12 +939,12 @@ const handlers = {
|
|
|
898
939
|
const multiline = child_state.multiline;
|
|
899
940
|
|
|
900
941
|
if (multiline) {
|
|
901
|
-
if_true.
|
|
902
|
-
if_false.
|
|
942
|
+
if_true.push(indent, newline, '? ');
|
|
943
|
+
if_false.push(newline, ': ');
|
|
903
944
|
state.commands.push(dedent);
|
|
904
945
|
} else {
|
|
905
|
-
if_true.
|
|
906
|
-
if_false.
|
|
946
|
+
if_true.push(' ? ');
|
|
947
|
+
if_false.push(' : ');
|
|
907
948
|
}
|
|
908
949
|
},
|
|
909
950
|
|
|
@@ -1125,9 +1166,9 @@ const handlers = {
|
|
|
1125
1166
|
// TODO do we need to handle weird unicode characters somehow?
|
|
1126
1167
|
// str.replace(/\\u(\d{4})/g, (m, n) => String.fromCharCode(+n))
|
|
1127
1168
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1169
|
+
const value =
|
|
1170
|
+
node.raw ||
|
|
1171
|
+
(typeof node.value === 'string' ? quote(node.value, state.quote) : String(node.value));
|
|
1131
1172
|
|
|
1132
1173
|
state.commands.push(c(value, node));
|
|
1133
1174
|
},
|
package/src/index.js
CHANGED
|
@@ -37,7 +37,8 @@ export function print(node, opts = {}) {
|
|
|
37
37
|
const state = {
|
|
38
38
|
commands: [],
|
|
39
39
|
comments: [],
|
|
40
|
-
multiline: false
|
|
40
|
+
multiline: false,
|
|
41
|
+
quote: opts.quotes === 'double' ? '"' : "'"
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
handle(/** @type {TSESTree.Node} */ (node), state);
|
|
@@ -69,6 +70,7 @@ export function print(node, opts = {}) {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
let newline = '\n';
|
|
73
|
+
const indent = opts.indent ?? '\t';
|
|
72
74
|
|
|
73
75
|
/** @param {Command} command */
|
|
74
76
|
function run(command) {
|
|
@@ -77,30 +79,21 @@ export function print(node, opts = {}) {
|
|
|
77
79
|
return;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
current_column,
|
|
87
|
-
0, // source index is always zero
|
|
88
|
-
loc.start.line - 1,
|
|
89
|
-
loc.start.column
|
|
90
|
-
]);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
append(command.content);
|
|
94
|
-
|
|
95
|
-
if (loc) {
|
|
96
|
-
current_line.push([
|
|
97
|
-
current_column,
|
|
98
|
-
0, // source index is always zero
|
|
99
|
-
loc.end.line - 1,
|
|
100
|
-
loc.end.column
|
|
101
|
-
]);
|
|
102
|
-
}
|
|
82
|
+
if (Array.isArray(command)) {
|
|
83
|
+
for (let i = 0; i < command.length; i += 1) {
|
|
84
|
+
run(command[i]);
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
103
88
|
|
|
89
|
+
switch (command.type) {
|
|
90
|
+
case 'Location':
|
|
91
|
+
current_line.push([
|
|
92
|
+
current_column,
|
|
93
|
+
0, // source index is always zero
|
|
94
|
+
command.line - 1,
|
|
95
|
+
command.column
|
|
96
|
+
]);
|
|
104
97
|
break;
|
|
105
98
|
|
|
106
99
|
case 'Newline':
|
|
@@ -108,18 +101,11 @@ export function print(node, opts = {}) {
|
|
|
108
101
|
break;
|
|
109
102
|
|
|
110
103
|
case 'Indent':
|
|
111
|
-
newline +=
|
|
104
|
+
newline += indent;
|
|
112
105
|
break;
|
|
113
106
|
|
|
114
107
|
case 'Dedent':
|
|
115
|
-
newline = newline.slice(0, -
|
|
116
|
-
break;
|
|
117
|
-
|
|
118
|
-
case 'Sequence':
|
|
119
|
-
for (let i = 0; i < command.children.length; i += 1) {
|
|
120
|
-
run(command.children[i]);
|
|
121
|
-
}
|
|
122
|
-
|
|
108
|
+
newline = newline.slice(0, -indent.length);
|
|
123
109
|
break;
|
|
124
110
|
|
|
125
111
|
case 'Comment':
|
package/src/types.d.ts
CHANGED
|
@@ -35,15 +35,13 @@ export interface State {
|
|
|
35
35
|
commands: Command[];
|
|
36
36
|
comments: TSESTree.Comment[];
|
|
37
37
|
multiline: boolean;
|
|
38
|
+
quote: "'" | '"';
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
export interface
|
|
41
|
-
type: '
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
start: { line: number; column: number };
|
|
45
|
-
end: { line: number; column: number };
|
|
46
|
-
};
|
|
41
|
+
export interface Location {
|
|
42
|
+
type: 'Location';
|
|
43
|
+
line: number;
|
|
44
|
+
column: number;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
export interface Newline {
|
|
@@ -63,20 +61,17 @@ export interface IndentChange {
|
|
|
63
61
|
offset: number;
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
export interface Sequence {
|
|
67
|
-
type: 'Sequence';
|
|
68
|
-
children: Command[];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
64
|
export interface CommentChunk {
|
|
72
65
|
type: 'Comment';
|
|
73
66
|
comment: TSESTree.Comment;
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
export type Command = string |
|
|
69
|
+
export type Command = string | Location | Newline | Indent | Dedent | CommentChunk | Command[];
|
|
77
70
|
|
|
78
71
|
export interface PrintOptions {
|
|
79
72
|
sourceMapSource?: string;
|
|
80
73
|
sourceMapContent?: string;
|
|
81
74
|
sourceMapEncodeMappings?: boolean; // default true
|
|
75
|
+
indent?: string; // default tab
|
|
76
|
+
quotes?: 'single' | 'double'; // default single
|
|
82
77
|
}
|
package/types/index.d.ts
CHANGED