esrap 1.2.3 → 1.3.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/README.md +4 -0
- package/package.json +11 -9
- package/src/handlers.js +371 -76
- package/src/index.js +6 -11
- package/src/public.d.ts +2 -0
- package/src/types.d.ts +35 -6
- package/types/index.d.ts +10 -7
- package/types/index.d.ts.map +4 -1
package/README.md
CHANGED
|
@@ -44,6 +44,10 @@ const { code, map } = print(ast, {
|
|
|
44
44
|
});
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
## TypeScript
|
|
48
|
+
|
|
49
|
+
`esrap` can also print TypeScript nodes, assuming they match the ESTree-like [`@typescript-eslint/types`](https://www.npmjs.com/package/@typescript-eslint/types).
|
|
50
|
+
|
|
47
51
|
## Why not just use Prettier?
|
|
48
52
|
|
|
49
53
|
Because it's ginormous.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esrap",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Parse in reverse",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,24 +19,26 @@
|
|
|
19
19
|
},
|
|
20
20
|
"types": "./types/index.d.ts",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@vitest/ui": "^2.
|
|
23
|
-
"acorn": "^8.
|
|
24
|
-
"
|
|
22
|
+
"@vitest/ui": "^2.1.1",
|
|
23
|
+
"acorn": "^8.11.3",
|
|
24
|
+
"acorn-typescript": "^1.4.13",
|
|
25
|
+
"dts-buddy": "^0.5.4",
|
|
25
26
|
"prettier": "^3.0.3",
|
|
26
|
-
"typescript": "^5.
|
|
27
|
-
"vitest": "^2.
|
|
27
|
+
"typescript": "^5.7.2",
|
|
28
|
+
"vitest": "^2.1.1",
|
|
28
29
|
"zimmerframe": "^1.0.0"
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
31
32
|
"check": "tsc",
|
|
32
|
-
"prepublishOnly": "pnpm test && dts-buddy",
|
|
33
|
+
"prepublishOnly": "pnpm test && dts-buddy -m dts-buddy:./src/public.d.ts",
|
|
33
34
|
"sandbox": "node test/sandbox/index.js",
|
|
34
|
-
"test": "vitest --run"
|
|
35
|
+
"test": "vitest --run",
|
|
36
|
+
"test:ui": "vitest --ui"
|
|
35
37
|
},
|
|
36
38
|
"license": "MIT",
|
|
37
39
|
"dependencies": {
|
|
38
40
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
39
|
-
"@types
|
|
41
|
+
"@typescript-eslint/types": "^8.2.0"
|
|
40
42
|
},
|
|
41
43
|
"packageManager": "pnpm@9.8.0"
|
|
42
44
|
}
|
package/src/handlers.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
/** @
|
|
1
|
+
/** @import { TSESTree } from '@typescript-eslint/types' */
|
|
2
|
+
/** @import { Chunk, Command, Dedent, Handlers, Indent, Newline, NodeWithComments, Sequence, State, TypeAnnotationNodes } from './types' */
|
|
3
|
+
|
|
4
|
+
/** @type {Newline} */
|
|
2
5
|
const newline = { type: 'Newline' };
|
|
3
6
|
|
|
4
|
-
/** @type {
|
|
7
|
+
/** @type {Indent} */
|
|
5
8
|
const indent = { type: 'Indent' };
|
|
6
9
|
|
|
7
|
-
/** @type {
|
|
10
|
+
/** @type {Dedent} */
|
|
8
11
|
const dedent = { type: 'Dedent' };
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
|
-
* @param {
|
|
12
|
-
* @returns {
|
|
14
|
+
* @param {Command[]} children
|
|
15
|
+
* @returns {Sequence}
|
|
13
16
|
*/
|
|
14
17
|
function create_sequence(...children) {
|
|
15
18
|
return { type: 'Sequence', children };
|
|
@@ -17,7 +20,7 @@ function create_sequence(...children) {
|
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* Rough estimate of the combined width of a group of commands
|
|
20
|
-
* @param {
|
|
23
|
+
* @param {Command[]} commands
|
|
21
24
|
* @param {number} from
|
|
22
25
|
* @param {number} to
|
|
23
26
|
*/
|
|
@@ -39,32 +42,34 @@ function measure(commands, from, to = commands.length) {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
* @param {
|
|
43
|
-
* @param {
|
|
45
|
+
* @param {TSESTree.Node} node
|
|
46
|
+
* @param {State} state
|
|
44
47
|
*/
|
|
45
48
|
export function handle(node, state) {
|
|
49
|
+
const node_with_comments = /** @type {NodeWithComments} */ (node);
|
|
50
|
+
|
|
46
51
|
const handler = handlers[node.type];
|
|
47
52
|
|
|
48
53
|
if (!handler) {
|
|
49
54
|
throw new Error(`Not implemented ${node.type}`);
|
|
50
55
|
}
|
|
51
56
|
|
|
52
|
-
if (
|
|
53
|
-
prepend_comments(
|
|
57
|
+
if (node_with_comments.leadingComments) {
|
|
58
|
+
prepend_comments(node_with_comments.leadingComments, state, false);
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
// @ts-expect-error
|
|
57
62
|
handler(node, state);
|
|
58
63
|
|
|
59
|
-
if (
|
|
60
|
-
state.comments.push(
|
|
64
|
+
if (node_with_comments.trailingComments) {
|
|
65
|
+
state.comments.push(node_with_comments.trailingComments[0]); // there is only ever one
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
/**
|
|
65
70
|
* @param {string} content
|
|
66
|
-
* @param {
|
|
67
|
-
* @returns {
|
|
71
|
+
* @param {TSESTree.Node} node
|
|
72
|
+
* @returns {Chunk}
|
|
68
73
|
*/
|
|
69
74
|
function c(content, node) {
|
|
70
75
|
return {
|
|
@@ -75,8 +80,8 @@ function c(content, node) {
|
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
/**
|
|
78
|
-
* @param {
|
|
79
|
-
* @param {
|
|
83
|
+
* @param {TSESTree.Comment[]} comments
|
|
84
|
+
* @param {State} state
|
|
80
85
|
* @param {boolean} newlines
|
|
81
86
|
*/
|
|
82
87
|
function prepend_comments(comments, state, newlines) {
|
|
@@ -119,13 +124,16 @@ const OPERATOR_PRECEDENCE = {
|
|
|
119
124
|
'**': 13
|
|
120
125
|
};
|
|
121
126
|
|
|
122
|
-
/** @type {Record<
|
|
127
|
+
/** @type {Record<TSESTree.Expression['type'] | 'Super' | 'RestElement', number>} */
|
|
123
128
|
const EXPRESSIONS_PRECEDENCE = {
|
|
129
|
+
JSXFragment: 20,
|
|
130
|
+
JSXElement: 20,
|
|
131
|
+
ArrayPattern: 20,
|
|
132
|
+
ObjectPattern: 20,
|
|
124
133
|
ArrayExpression: 20,
|
|
125
134
|
TaggedTemplateExpression: 20,
|
|
126
135
|
ThisExpression: 20,
|
|
127
136
|
Identifier: 20,
|
|
128
|
-
Literal: 18,
|
|
129
137
|
TemplateLiteral: 20,
|
|
130
138
|
Super: 20,
|
|
131
139
|
SequenceExpression: 20,
|
|
@@ -135,10 +143,16 @@ const EXPRESSIONS_PRECEDENCE = {
|
|
|
135
143
|
ChainExpression: 19,
|
|
136
144
|
ImportExpression: 19,
|
|
137
145
|
NewExpression: 19,
|
|
146
|
+
Literal: 18,
|
|
147
|
+
TSSatisfiesExpression: 18,
|
|
148
|
+
TSInstantiationExpression: 18,
|
|
149
|
+
TSNonNullExpression: 18,
|
|
150
|
+
TSTypeAssertion: 18,
|
|
138
151
|
AwaitExpression: 17,
|
|
139
152
|
ClassExpression: 17,
|
|
140
153
|
FunctionExpression: 17,
|
|
141
154
|
ObjectExpression: 17,
|
|
155
|
+
TSAsExpression: 16,
|
|
142
156
|
UpdateExpression: 16,
|
|
143
157
|
UnaryExpression: 15,
|
|
144
158
|
BinaryExpression: 14,
|
|
@@ -152,12 +166,14 @@ const EXPRESSIONS_PRECEDENCE = {
|
|
|
152
166
|
|
|
153
167
|
/**
|
|
154
168
|
*
|
|
155
|
-
* @param {
|
|
156
|
-
* @param {
|
|
169
|
+
* @param {TSESTree.Expression | TSESTree.PrivateIdentifier} node
|
|
170
|
+
* @param {TSESTree.BinaryExpression | TSESTree.LogicalExpression} parent
|
|
157
171
|
* @param {boolean} is_right
|
|
158
172
|
* @returns
|
|
159
173
|
*/
|
|
160
174
|
function needs_parens(node, parent, is_right) {
|
|
175
|
+
if (node.type === 'PrivateIdentifier') return false;
|
|
176
|
+
|
|
161
177
|
// special case where logical expressions and coalesce expressions cannot be mixed,
|
|
162
178
|
// either of them need to be wrapped with parentheses
|
|
163
179
|
if (
|
|
@@ -186,7 +202,7 @@ function needs_parens(node, parent, is_right) {
|
|
|
186
202
|
}
|
|
187
203
|
|
|
188
204
|
if (
|
|
189
|
-
/** @type {
|
|
205
|
+
/** @type {TSESTree.BinaryExpression} */ (node).operator === '**' &&
|
|
190
206
|
parent.operator === '**'
|
|
191
207
|
) {
|
|
192
208
|
// Exponentiation operator has right-to-left associativity
|
|
@@ -196,18 +212,18 @@ function needs_parens(node, parent, is_right) {
|
|
|
196
212
|
if (is_right) {
|
|
197
213
|
// Parenthesis are used if both operators have the same precedence
|
|
198
214
|
return (
|
|
199
|
-
OPERATOR_PRECEDENCE[/** @type {
|
|
215
|
+
OPERATOR_PRECEDENCE[/** @type {TSESTree.BinaryExpression} */ (node).operator] <=
|
|
200
216
|
OPERATOR_PRECEDENCE[parent.operator]
|
|
201
217
|
);
|
|
202
218
|
}
|
|
203
219
|
|
|
204
220
|
return (
|
|
205
|
-
OPERATOR_PRECEDENCE[/** @type {
|
|
221
|
+
OPERATOR_PRECEDENCE[/** @type {TSESTree.BinaryExpression} */ (node).operator] <
|
|
206
222
|
OPERATOR_PRECEDENCE[parent.operator]
|
|
207
223
|
);
|
|
208
224
|
}
|
|
209
225
|
|
|
210
|
-
/** @param {
|
|
226
|
+
/** @param {TSESTree.Node} node */
|
|
211
227
|
function has_call_expression(node) {
|
|
212
228
|
while (node) {
|
|
213
229
|
if (node.type === 'CallExpression') {
|
|
@@ -228,11 +244,13 @@ const grouped_expression_types = [
|
|
|
228
244
|
];
|
|
229
245
|
|
|
230
246
|
/**
|
|
231
|
-
* @param {
|
|
232
|
-
* @param {
|
|
247
|
+
* @param {TSESTree.Node[]} nodes
|
|
248
|
+
* @param {State} state
|
|
233
249
|
*/
|
|
234
250
|
const handle_body = (nodes, state) => {
|
|
235
|
-
let last_statement = /** @type {
|
|
251
|
+
let last_statement = /** @type {TSESTree.Node} */ ({
|
|
252
|
+
type: 'EmptyStatement'
|
|
253
|
+
});
|
|
236
254
|
let first = true;
|
|
237
255
|
let needs_margin = false;
|
|
238
256
|
|
|
@@ -244,11 +262,12 @@ const handle_body = (nodes, state) => {
|
|
|
244
262
|
if (!first) state.commands.push(margin, newline);
|
|
245
263
|
first = false;
|
|
246
264
|
|
|
247
|
-
const
|
|
248
|
-
|
|
265
|
+
const statement_with_comments = /** @type {NodeWithComments} */ (statement);
|
|
266
|
+
const leading_comments = statement_with_comments.leadingComments;
|
|
267
|
+
delete statement_with_comments.leadingComments;
|
|
249
268
|
|
|
250
|
-
if (
|
|
251
|
-
prepend_comments(
|
|
269
|
+
if (leading_comments && leading_comments.length > 0) {
|
|
270
|
+
prepend_comments(leading_comments, state, true);
|
|
252
271
|
}
|
|
253
272
|
|
|
254
273
|
const child_state = { ...state, multiline: false };
|
|
@@ -267,7 +286,7 @@ const handle_body = (nodes, state) => {
|
|
|
267
286
|
let add_newline = false;
|
|
268
287
|
|
|
269
288
|
while (state.comments.length) {
|
|
270
|
-
const comment = /** @type {
|
|
289
|
+
const comment = /** @type {TSESTree.Comment} */ (state.comments.shift());
|
|
271
290
|
|
|
272
291
|
state.commands.push(add_newline ? newline : ' ', { type: 'Comment', comment });
|
|
273
292
|
add_newline = comment.type === 'Line';
|
|
@@ -279,8 +298,8 @@ const handle_body = (nodes, state) => {
|
|
|
279
298
|
};
|
|
280
299
|
|
|
281
300
|
/**
|
|
282
|
-
* @param {
|
|
283
|
-
* @param {
|
|
301
|
+
* @param {TSESTree.VariableDeclaration} node
|
|
302
|
+
* @param {State} state
|
|
284
303
|
*/
|
|
285
304
|
const handle_var_declaration = (node, state) => {
|
|
286
305
|
const index = state.commands.length;
|
|
@@ -314,13 +333,13 @@ const handle_var_declaration = (node, state) => {
|
|
|
314
333
|
};
|
|
315
334
|
|
|
316
335
|
/**
|
|
317
|
-
* @template {
|
|
336
|
+
* @template {TSESTree.Node} T
|
|
318
337
|
* @param {Array<T | null>} nodes
|
|
319
|
-
* @param {
|
|
338
|
+
* @param {State} state
|
|
320
339
|
* @param {boolean} spaces
|
|
321
|
-
* @param {(node: T, state:
|
|
340
|
+
* @param {(node: T, state: State) => void} fn
|
|
322
341
|
*/
|
|
323
|
-
function sequence(nodes, state, spaces, fn) {
|
|
342
|
+
function sequence(nodes, state, spaces, fn, separator = ',') {
|
|
324
343
|
if (nodes.length === 0) return;
|
|
325
344
|
|
|
326
345
|
const index = state.commands.length;
|
|
@@ -348,14 +367,14 @@ function sequence(nodes, state, spaces, fn) {
|
|
|
348
367
|
fn(node, child_state);
|
|
349
368
|
|
|
350
369
|
if (!is_last) {
|
|
351
|
-
state.commands.push(
|
|
370
|
+
state.commands.push(separator);
|
|
352
371
|
}
|
|
353
372
|
|
|
354
373
|
if (state.comments.length > 0) {
|
|
355
374
|
state.commands.push(' ');
|
|
356
375
|
|
|
357
376
|
while (state.comments.length) {
|
|
358
|
-
const comment = /** @type {
|
|
377
|
+
const comment = /** @type {TSESTree.Comment} */ (state.comments.shift());
|
|
359
378
|
state.commands.push({ type: 'Comment', comment });
|
|
360
379
|
if (!is_last) state.commands.push(join);
|
|
361
380
|
}
|
|
@@ -368,7 +387,7 @@ function sequence(nodes, state, spaces, fn) {
|
|
|
368
387
|
// This is only used for ArrayPattern and ArrayExpression, but
|
|
369
388
|
// it makes more sense to have the logic here than there, because
|
|
370
389
|
// otherwise we'd duplicate a lot more stuff
|
|
371
|
-
state.commands.push(
|
|
390
|
+
state.commands.push(separator);
|
|
372
391
|
}
|
|
373
392
|
|
|
374
393
|
prev = node;
|
|
@@ -391,21 +410,172 @@ function sequence(nodes, state, spaces, fn) {
|
|
|
391
410
|
}
|
|
392
411
|
}
|
|
393
412
|
|
|
394
|
-
/**
|
|
413
|
+
/**
|
|
414
|
+
* @param {TypeAnnotationNodes} node
|
|
415
|
+
* @param {State} state
|
|
416
|
+
*/
|
|
417
|
+
function handle_type_annotation(node, state) {
|
|
418
|
+
switch (node.type) {
|
|
419
|
+
case 'TSNumberKeyword':
|
|
420
|
+
state.commands.push('number');
|
|
421
|
+
break;
|
|
422
|
+
case 'TSStringKeyword':
|
|
423
|
+
state.commands.push('string');
|
|
424
|
+
break;
|
|
425
|
+
case 'TSBooleanKeyword':
|
|
426
|
+
state.commands.push('boolean');
|
|
427
|
+
break;
|
|
428
|
+
case 'TSAnyKeyword':
|
|
429
|
+
state.commands.push('any');
|
|
430
|
+
break;
|
|
431
|
+
case 'TSVoidKeyword':
|
|
432
|
+
state.commands.push('void');
|
|
433
|
+
break;
|
|
434
|
+
case 'TSUnknownKeyword':
|
|
435
|
+
state.commands.push('unknown');
|
|
436
|
+
break;
|
|
437
|
+
case 'TSNeverKeyword':
|
|
438
|
+
state.commands.push('never');
|
|
439
|
+
break;
|
|
440
|
+
case 'TSArrayType':
|
|
441
|
+
handle_type_annotation(node.elementType, state);
|
|
442
|
+
state.commands.push('[]');
|
|
443
|
+
break;
|
|
444
|
+
case 'TSTypeAnnotation':
|
|
445
|
+
state.commands.push(': ');
|
|
446
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
447
|
+
break;
|
|
448
|
+
case 'TSTypeLiteral':
|
|
449
|
+
state.commands.push('{ ');
|
|
450
|
+
sequence(node.members, state, false, handle_type_annotation, ';');
|
|
451
|
+
state.commands.push(' }');
|
|
452
|
+
break;
|
|
453
|
+
case 'TSPropertySignature':
|
|
454
|
+
handle(node.key, state);
|
|
455
|
+
if (node.optional) state.commands.push('?');
|
|
456
|
+
if (node.typeAnnotation) handle_type_annotation(node.typeAnnotation, state);
|
|
457
|
+
break;
|
|
458
|
+
case 'TSTypeReference':
|
|
459
|
+
handle(node.typeName, state);
|
|
460
|
+
|
|
461
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
462
|
+
if (node.typeParameters) handle_type_annotation(node.typeParameters, state);
|
|
463
|
+
break;
|
|
464
|
+
case 'TSTypeParameterInstantiation':
|
|
465
|
+
case 'TSTypeParameterDeclaration':
|
|
466
|
+
state.commands.push('<');
|
|
467
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
468
|
+
handle_type_annotation(node.params[i], state);
|
|
469
|
+
if (i != node.params.length - 1) state.commands.push(', ');
|
|
470
|
+
}
|
|
471
|
+
state.commands.push('>');
|
|
472
|
+
break;
|
|
473
|
+
case 'TSTypeParameter':
|
|
474
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
475
|
+
state.commands.push(node.name);
|
|
476
|
+
|
|
477
|
+
if (node.constraint) {
|
|
478
|
+
state.commands.push(' extends ');
|
|
479
|
+
handle_type_annotation(node.constraint, state);
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
482
|
+
case 'TSTypeQuery':
|
|
483
|
+
state.commands.push('typeof ');
|
|
484
|
+
handle(node.exprName, state);
|
|
485
|
+
break;
|
|
486
|
+
case 'TSEnumMember':
|
|
487
|
+
handle(node.id, state);
|
|
488
|
+
if (node.initializer) {
|
|
489
|
+
state.commands.push(' = ');
|
|
490
|
+
handle(node.initializer, state);
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
case 'TSFunctionType':
|
|
494
|
+
if (node.typeParameters) handle_type_annotation(node.typeParameters, state);
|
|
495
|
+
|
|
496
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
497
|
+
const parameters = node.parameters;
|
|
498
|
+
state.commands.push('(');
|
|
499
|
+
sequence(parameters, state, false, handle);
|
|
500
|
+
|
|
501
|
+
state.commands.push(') => ');
|
|
502
|
+
|
|
503
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
504
|
+
handle_type_annotation(node.typeAnnotation.typeAnnotation, state);
|
|
505
|
+
break;
|
|
506
|
+
case 'TSIndexSignature':
|
|
507
|
+
const indexParameters = node.parameters;
|
|
508
|
+
state.commands.push('[');
|
|
509
|
+
sequence(indexParameters, state, false, handle);
|
|
510
|
+
state.commands.push(']');
|
|
511
|
+
|
|
512
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
513
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
514
|
+
break;
|
|
515
|
+
case 'TSMethodSignature':
|
|
516
|
+
handle(node.key, state);
|
|
517
|
+
|
|
518
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
519
|
+
const parametersSignature = node.parameters;
|
|
520
|
+
state.commands.push('(');
|
|
521
|
+
sequence(parametersSignature, state, false, handle);
|
|
522
|
+
state.commands.push(')');
|
|
523
|
+
|
|
524
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
525
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
526
|
+
break;
|
|
527
|
+
case 'TSExpressionWithTypeArguments':
|
|
528
|
+
handle(node.expression, state);
|
|
529
|
+
break;
|
|
530
|
+
case 'TSTupleType':
|
|
531
|
+
state.commands.push('[');
|
|
532
|
+
sequence(node.elementTypes, state, false, handle_type_annotation);
|
|
533
|
+
state.commands.push(']');
|
|
534
|
+
break;
|
|
535
|
+
case 'TSNamedTupleMember':
|
|
536
|
+
handle(node.label, state);
|
|
537
|
+
state.commands.push(': ');
|
|
538
|
+
handle_type_annotation(node.elementType, state);
|
|
539
|
+
|
|
540
|
+
break;
|
|
541
|
+
case 'TSUnionType':
|
|
542
|
+
sequence(node.types, state, false, handle_type_annotation, ' |');
|
|
543
|
+
break;
|
|
544
|
+
case 'TSIntersectionType':
|
|
545
|
+
sequence(node.types, state, false, handle_type_annotation, ' &');
|
|
546
|
+
break;
|
|
547
|
+
case 'TSLiteralType':
|
|
548
|
+
handle(node.literal, state);
|
|
549
|
+
break;
|
|
550
|
+
case 'TSConditionalType':
|
|
551
|
+
handle_type_annotation(node.checkType, state);
|
|
552
|
+
state.commands.push(' extends ');
|
|
553
|
+
handle_type_annotation(node.extendsType, state);
|
|
554
|
+
state.commands.push(' ? ');
|
|
555
|
+
handle_type_annotation(node.trueType, state);
|
|
556
|
+
state.commands.push(' : ');
|
|
557
|
+
handle_type_annotation(node.falseType, state);
|
|
558
|
+
break;
|
|
559
|
+
default:
|
|
560
|
+
throw new Error(`Not implemented type annotation ${node.type}`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/** @satisfies {Record<string, (node: any, state: State) => undefined>} */
|
|
395
565
|
const shared = {
|
|
396
566
|
/**
|
|
397
|
-
* @param {
|
|
398
|
-
* @param {
|
|
567
|
+
* @param {TSESTree.ArrayExpression | TSESTree.ArrayPattern} node
|
|
568
|
+
* @param {State} state
|
|
399
569
|
*/
|
|
400
570
|
'ArrayExpression|ArrayPattern': (node, state) => {
|
|
401
571
|
state.commands.push('[');
|
|
402
|
-
sequence(/** @type {
|
|
572
|
+
sequence(/** @type {TSESTree.Node[]} */ (node.elements), state, false, handle);
|
|
403
573
|
state.commands.push(']');
|
|
404
574
|
},
|
|
405
575
|
|
|
406
576
|
/**
|
|
407
|
-
* @param {
|
|
408
|
-
* @param {
|
|
577
|
+
* @param {TSESTree.BinaryExpression | TSESTree.LogicalExpression} node
|
|
578
|
+
* @param {State} state
|
|
409
579
|
*/
|
|
410
580
|
'BinaryExpression|LogicalExpression': (node, state) => {
|
|
411
581
|
// TODO
|
|
@@ -435,8 +605,8 @@ const shared = {
|
|
|
435
605
|
},
|
|
436
606
|
|
|
437
607
|
/**
|
|
438
|
-
* @param {
|
|
439
|
-
* @param {
|
|
608
|
+
* @param {TSESTree.BlockStatement | TSESTree.ClassBody} node
|
|
609
|
+
* @param {State} state
|
|
440
610
|
*/
|
|
441
611
|
'BlockStatement|ClassBody': (node, state) => {
|
|
442
612
|
if (node.body.length === 0) {
|
|
@@ -452,12 +622,10 @@ const shared = {
|
|
|
452
622
|
},
|
|
453
623
|
|
|
454
624
|
/**
|
|
455
|
-
* @param {
|
|
456
|
-
* @param {
|
|
625
|
+
* @param {TSESTree.CallExpression | TSESTree.NewExpression} node
|
|
626
|
+
* @param {State} state
|
|
457
627
|
*/
|
|
458
628
|
'CallExpression|NewExpression': (node, state) => {
|
|
459
|
-
const index = state.commands.length;
|
|
460
|
-
|
|
461
629
|
if (node.type === 'NewExpression') {
|
|
462
630
|
state.commands.push('new ');
|
|
463
631
|
}
|
|
@@ -474,10 +642,13 @@ const shared = {
|
|
|
474
642
|
handle(node.callee, state);
|
|
475
643
|
}
|
|
476
644
|
|
|
477
|
-
if (/** @type {
|
|
645
|
+
if (/** @type {TSESTree.CallExpression} */ (node).optional) {
|
|
478
646
|
state.commands.push('?.');
|
|
479
647
|
}
|
|
480
648
|
|
|
649
|
+
// @ts-expect-error
|
|
650
|
+
if (node.typeParameters) handle_type_annotation(node.typeParameters, state);
|
|
651
|
+
|
|
481
652
|
const open = create_sequence();
|
|
482
653
|
const join = create_sequence();
|
|
483
654
|
const close = create_sequence();
|
|
@@ -495,7 +666,7 @@ const shared = {
|
|
|
495
666
|
state.commands.push(', ');
|
|
496
667
|
|
|
497
668
|
while (state.comments.length) {
|
|
498
|
-
const comment = /** @type {
|
|
669
|
+
const comment = /** @type {TSESTree.Comment} */ (state.comments.shift());
|
|
499
670
|
|
|
500
671
|
state.commands.push({ type: 'Comment', comment });
|
|
501
672
|
|
|
@@ -534,8 +705,8 @@ const shared = {
|
|
|
534
705
|
},
|
|
535
706
|
|
|
536
707
|
/**
|
|
537
|
-
* @param {
|
|
538
|
-
* @param {
|
|
708
|
+
* @param {TSESTree.ClassDeclaration | TSESTree.ClassExpression} node
|
|
709
|
+
* @param {State} state
|
|
539
710
|
*/
|
|
540
711
|
'ClassDeclaration|ClassExpression': (node, state) => {
|
|
541
712
|
state.commands.push('class ');
|
|
@@ -551,12 +722,17 @@ const shared = {
|
|
|
551
722
|
state.commands.push(' ');
|
|
552
723
|
}
|
|
553
724
|
|
|
725
|
+
if (node.implements) {
|
|
726
|
+
state.commands.push('implements ');
|
|
727
|
+
sequence(node.implements, state, false, handle_type_annotation);
|
|
728
|
+
}
|
|
729
|
+
|
|
554
730
|
handle(node.body, state);
|
|
555
731
|
},
|
|
556
732
|
|
|
557
733
|
/**
|
|
558
|
-
* @param {
|
|
559
|
-
* @param {
|
|
734
|
+
* @param {TSESTree.ForInStatement | TSESTree.ForOfStatement} node
|
|
735
|
+
* @param {State} state
|
|
560
736
|
*/
|
|
561
737
|
'ForInStatement|ForOfStatement': (node, state) => {
|
|
562
738
|
state.commands.push('for ');
|
|
@@ -576,32 +752,43 @@ const shared = {
|
|
|
576
752
|
},
|
|
577
753
|
|
|
578
754
|
/**
|
|
579
|
-
* @param {
|
|
580
|
-
* @param {
|
|
755
|
+
* @param {TSESTree.FunctionDeclaration | TSESTree.FunctionExpression} node
|
|
756
|
+
* @param {State} state
|
|
581
757
|
*/
|
|
582
758
|
'FunctionDeclaration|FunctionExpression': (node, state) => {
|
|
583
759
|
if (node.async) state.commands.push('async ');
|
|
584
760
|
state.commands.push(node.generator ? 'function* ' : 'function ');
|
|
585
761
|
if (node.id) handle(node.id, state);
|
|
586
762
|
|
|
763
|
+
if (node.typeParameters) {
|
|
764
|
+
handle_type_annotation(node.typeParameters, state);
|
|
765
|
+
}
|
|
766
|
+
|
|
587
767
|
state.commands.push('(');
|
|
588
768
|
sequence(node.params, state, false, handle);
|
|
589
|
-
state.commands.push(')
|
|
769
|
+
state.commands.push(')');
|
|
770
|
+
|
|
771
|
+
if (node.returnType) handle_type_annotation(node.returnType, state);
|
|
772
|
+
|
|
773
|
+
state.commands.push(' ');
|
|
590
774
|
|
|
591
775
|
handle(node.body, state);
|
|
592
776
|
},
|
|
593
777
|
|
|
594
778
|
/**
|
|
595
|
-
* @param {
|
|
596
|
-
* @param {
|
|
779
|
+
* @param {TSESTree.RestElement | TSESTree.SpreadElement} node
|
|
780
|
+
* @param {State} state
|
|
597
781
|
*/
|
|
598
782
|
'RestElement|SpreadElement': (node, state) => {
|
|
599
783
|
state.commands.push('...');
|
|
600
784
|
handle(node.argument, state);
|
|
785
|
+
|
|
786
|
+
// @ts-expect-error `acorn-typescript` and `@typescript-esling/types` have slightly different type definitions
|
|
787
|
+
if (node.typeAnnotation) handle_type_annotation(node.typeAnnotation, state);
|
|
601
788
|
}
|
|
602
789
|
};
|
|
603
790
|
|
|
604
|
-
/** @type {
|
|
791
|
+
/** @type {Handlers} */
|
|
605
792
|
const handlers = {
|
|
606
793
|
ArrayExpression: shared['ArrayExpression|ArrayPattern'],
|
|
607
794
|
|
|
@@ -728,6 +915,12 @@ const handlers = {
|
|
|
728
915
|
state.commands.push(c('debugger', node), ';');
|
|
729
916
|
},
|
|
730
917
|
|
|
918
|
+
Decorator(node, state) {
|
|
919
|
+
state.commands.push('@');
|
|
920
|
+
handle(node.expression, state);
|
|
921
|
+
state.commands.push(newline);
|
|
922
|
+
},
|
|
923
|
+
|
|
731
924
|
DoWhileStatement(node, state) {
|
|
732
925
|
state.commands.push('do ');
|
|
733
926
|
handle(node.body, state);
|
|
@@ -831,6 +1024,8 @@ const handlers = {
|
|
|
831
1024
|
Identifier(node, state) {
|
|
832
1025
|
let name = node.name;
|
|
833
1026
|
state.commands.push(c(name, node));
|
|
1027
|
+
|
|
1028
|
+
if (node.typeAnnotation) handle_type_annotation(node.typeAnnotation, state);
|
|
834
1029
|
},
|
|
835
1030
|
|
|
836
1031
|
IfStatement(node, state) {
|
|
@@ -853,13 +1048,13 @@ const handlers = {
|
|
|
853
1048
|
return;
|
|
854
1049
|
}
|
|
855
1050
|
|
|
856
|
-
/** @type {
|
|
1051
|
+
/** @type {TSESTree.ImportNamespaceSpecifier | null} */
|
|
857
1052
|
let namespace_specifier = null;
|
|
858
1053
|
|
|
859
|
-
/** @type {
|
|
1054
|
+
/** @type {TSESTree.ImportDefaultSpecifier | null} */
|
|
860
1055
|
let default_specifier = null;
|
|
861
1056
|
|
|
862
|
-
/** @type {
|
|
1057
|
+
/** @type {TSESTree.ImportSpecifier[]} */
|
|
863
1058
|
const named_specifiers = [];
|
|
864
1059
|
|
|
865
1060
|
for (const s of node.specifiers) {
|
|
@@ -873,6 +1068,7 @@ const handlers = {
|
|
|
873
1068
|
}
|
|
874
1069
|
|
|
875
1070
|
state.commands.push('import ');
|
|
1071
|
+
if (node.importKind == 'type') state.commands.push('type ');
|
|
876
1072
|
|
|
877
1073
|
if (default_specifier) {
|
|
878
1074
|
state.commands.push(c(default_specifier.local.name, default_specifier));
|
|
@@ -891,6 +1087,7 @@ const handlers = {
|
|
|
891
1087
|
state.commands.push(' as ');
|
|
892
1088
|
}
|
|
893
1089
|
|
|
1090
|
+
if (s.importKind == 'type') state.commands.push('type ');
|
|
894
1091
|
handle(s.local, state);
|
|
895
1092
|
});
|
|
896
1093
|
state.commands.push('}');
|
|
@@ -916,9 +1113,10 @@ const handlers = {
|
|
|
916
1113
|
Literal(node, state) {
|
|
917
1114
|
// TODO do we need to handle weird unicode characters somehow?
|
|
918
1115
|
// str.replace(/\\u(\d{4})/g, (m, n) => String.fromCharCode(+n))
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1116
|
+
|
|
1117
|
+
let value = node.raw;
|
|
1118
|
+
if (!value)
|
|
1119
|
+
value = typeof node.value === 'string' ? JSON.stringify(node.value) : String(node.value);
|
|
922
1120
|
|
|
923
1121
|
state.commands.push(c(value, node));
|
|
924
1122
|
},
|
|
@@ -954,6 +1152,12 @@ const handlers = {
|
|
|
954
1152
|
},
|
|
955
1153
|
|
|
956
1154
|
MethodDefinition(node, state) {
|
|
1155
|
+
if (node.decorators) {
|
|
1156
|
+
for (const decorator of node.decorators) {
|
|
1157
|
+
handle(decorator, state);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
957
1161
|
if (node.static) {
|
|
958
1162
|
state.commands.push('static ');
|
|
959
1163
|
}
|
|
@@ -979,7 +1183,7 @@ const handlers = {
|
|
|
979
1183
|
sequence(node.value.params, state, false, handle);
|
|
980
1184
|
state.commands.push(') ');
|
|
981
1185
|
|
|
982
|
-
handle(node.value.body, state);
|
|
1186
|
+
if (node.value.body) handle(node.value.body, state);
|
|
983
1187
|
},
|
|
984
1188
|
|
|
985
1189
|
NewExpression: shared['CallExpression|NewExpression'],
|
|
@@ -988,7 +1192,7 @@ const handlers = {
|
|
|
988
1192
|
state.commands.push('{');
|
|
989
1193
|
sequence(node.properties, state, true, (p, state) => {
|
|
990
1194
|
if (p.type === 'Property' && p.value.type === 'FunctionExpression') {
|
|
991
|
-
const fn = /** @type {
|
|
1195
|
+
const fn = /** @type {TSESTree.FunctionExpression} */ (p.value);
|
|
992
1196
|
|
|
993
1197
|
if (p.kind === 'get' || p.kind === 'set') {
|
|
994
1198
|
state.commands.push(p.kind + ' ');
|
|
@@ -1017,6 +1221,8 @@ const handlers = {
|
|
|
1017
1221
|
state.commands.push('{');
|
|
1018
1222
|
sequence(node.properties, state, true, handle);
|
|
1019
1223
|
state.commands.push('}');
|
|
1224
|
+
|
|
1225
|
+
if (node.typeAnnotation) handle_type_annotation(node.typeAnnotation, state);
|
|
1020
1226
|
},
|
|
1021
1227
|
|
|
1022
1228
|
// @ts-expect-error this isn't a real node type, but Acorn produces it
|
|
@@ -1054,6 +1260,10 @@ const handlers = {
|
|
|
1054
1260
|
},
|
|
1055
1261
|
|
|
1056
1262
|
PropertyDefinition(node, state) {
|
|
1263
|
+
if (node.accessibility) {
|
|
1264
|
+
state.commands.push(node.accessibility, ' ');
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1057
1267
|
if (node.static) {
|
|
1058
1268
|
state.commands.push('static ');
|
|
1059
1269
|
}
|
|
@@ -1066,6 +1276,11 @@ const handlers = {
|
|
|
1066
1276
|
handle(node.key, state);
|
|
1067
1277
|
}
|
|
1068
1278
|
|
|
1279
|
+
if (node.typeAnnotation) {
|
|
1280
|
+
state.commands.push(': ');
|
|
1281
|
+
handle_type_annotation(node.typeAnnotation.typeAnnotation, state);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1069
1284
|
if (node.value) {
|
|
1070
1285
|
state.commands.push(' = ');
|
|
1071
1286
|
|
|
@@ -1079,9 +1294,10 @@ const handlers = {
|
|
|
1079
1294
|
|
|
1080
1295
|
ReturnStatement(node, state) {
|
|
1081
1296
|
if (node.argument) {
|
|
1297
|
+
const argumentWithComment = /** @type {NodeWithComments} */ (node.argument);
|
|
1082
1298
|
const contains_comment =
|
|
1083
|
-
|
|
1084
|
-
|
|
1299
|
+
argumentWithComment.leadingComments &&
|
|
1300
|
+
argumentWithComment.leadingComments.some((comment) => comment.type === 'Line');
|
|
1085
1301
|
|
|
1086
1302
|
state.commands.push(contains_comment ? 'return (' : 'return ');
|
|
1087
1303
|
handle(node.argument, state);
|
|
@@ -1175,7 +1391,7 @@ const handlers = {
|
|
|
1175
1391
|
|
|
1176
1392
|
ThrowStatement(node, state) {
|
|
1177
1393
|
state.commands.push('throw ');
|
|
1178
|
-
handle(node.argument, state);
|
|
1394
|
+
if (node.argument) handle(node.argument, state);
|
|
1179
1395
|
state.commands.push(';');
|
|
1180
1396
|
},
|
|
1181
1397
|
|
|
@@ -1201,6 +1417,85 @@ const handlers = {
|
|
|
1201
1417
|
}
|
|
1202
1418
|
},
|
|
1203
1419
|
|
|
1420
|
+
TSAsExpression(node, state) {
|
|
1421
|
+
if (node.expression) {
|
|
1422
|
+
const needs_parens =
|
|
1423
|
+
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSAsExpression;
|
|
1424
|
+
|
|
1425
|
+
if (needs_parens) {
|
|
1426
|
+
state.commands.push('(');
|
|
1427
|
+
handle(node.expression, state);
|
|
1428
|
+
state.commands.push(')');
|
|
1429
|
+
} else {
|
|
1430
|
+
handle(node.expression, state);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
state.commands.push(' as ');
|
|
1434
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
1435
|
+
},
|
|
1436
|
+
|
|
1437
|
+
TSEnumDeclaration(node, state) {
|
|
1438
|
+
state.commands.push('enum ');
|
|
1439
|
+
handle(node.id, state);
|
|
1440
|
+
state.commands.push(' {', indent, newline);
|
|
1441
|
+
sequence(node.members, state, false, handle_type_annotation);
|
|
1442
|
+
state.commands.push(dedent, newline, '}', newline);
|
|
1443
|
+
},
|
|
1444
|
+
|
|
1445
|
+
TSNonNullExpression(node, state) {
|
|
1446
|
+
handle(node.expression, state);
|
|
1447
|
+
state.commands.push('!');
|
|
1448
|
+
},
|
|
1449
|
+
|
|
1450
|
+
TSInterfaceBody(node, state) {
|
|
1451
|
+
sequence(node.body, state, false, handle_type_annotation, ';');
|
|
1452
|
+
},
|
|
1453
|
+
|
|
1454
|
+
TSInterfaceDeclaration(node, state) {
|
|
1455
|
+
state.commands.push('interface ');
|
|
1456
|
+
handle(node.id, state);
|
|
1457
|
+
if (node.typeParameters) handle_type_annotation(node.typeParameters, state);
|
|
1458
|
+
if (node.extends) {
|
|
1459
|
+
state.commands.push(' extends ');
|
|
1460
|
+
sequence(node.extends, state, false, handle_type_annotation);
|
|
1461
|
+
}
|
|
1462
|
+
state.commands.push(' {');
|
|
1463
|
+
handle(node.body, state);
|
|
1464
|
+
state.commands.push('}');
|
|
1465
|
+
},
|
|
1466
|
+
|
|
1467
|
+
TSSatisfiesExpression(node, state) {
|
|
1468
|
+
if (node.expression) {
|
|
1469
|
+
const needs_parens =
|
|
1470
|
+
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSSatisfiesExpression;
|
|
1471
|
+
|
|
1472
|
+
if (needs_parens) {
|
|
1473
|
+
state.commands.push('(');
|
|
1474
|
+
handle(node.expression, state);
|
|
1475
|
+
state.commands.push(')');
|
|
1476
|
+
} else {
|
|
1477
|
+
handle(node.expression, state);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
state.commands.push(' satisfies ');
|
|
1481
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
1482
|
+
},
|
|
1483
|
+
|
|
1484
|
+
TSTypeAliasDeclaration(node, state) {
|
|
1485
|
+
state.commands.push('type ');
|
|
1486
|
+
handle(node.id, state);
|
|
1487
|
+
if (node.typeParameters) handle_type_annotation(node.typeParameters, state);
|
|
1488
|
+
state.commands.push(' = ');
|
|
1489
|
+
handle_type_annotation(node.typeAnnotation, state);
|
|
1490
|
+
state.commands.push(';');
|
|
1491
|
+
},
|
|
1492
|
+
|
|
1493
|
+
TSQualifiedName(node, state) {
|
|
1494
|
+
handle(node.left, state);
|
|
1495
|
+
state.commands.push('.');
|
|
1496
|
+
handle(node.right, state);
|
|
1497
|
+
},
|
|
1498
|
+
|
|
1204
1499
|
UnaryExpression(node, state) {
|
|
1205
1500
|
state.commands.push(node.operator);
|
|
1206
1501
|
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @import { TSESTree } from '@typescript-eslint/types' */
|
|
2
|
+
/** @import { Command, PrintOptions, State } from './types' */
|
|
1
3
|
import { handle } from './handlers.js';
|
|
2
4
|
import { encode } from '@jridgewell/sourcemap-codec';
|
|
3
5
|
|
|
@@ -15,15 +17,7 @@ if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
|
-
* @
|
|
19
|
-
* sourceMapSource?: string;
|
|
20
|
-
* sourceMapContent?: string;
|
|
21
|
-
* sourceMapEncodeMappings?: boolean; // default true
|
|
22
|
-
* }} PrintOptions
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @param {import('estree').Node} node
|
|
20
|
+
* @param {TSESTree.Node} node
|
|
27
21
|
* @param {PrintOptions} opts
|
|
28
22
|
* @returns {{ code: string, map: any }} // TODO
|
|
29
23
|
*/
|
|
@@ -31,6 +25,7 @@ export function print(node, opts = {}) {
|
|
|
31
25
|
if (Array.isArray(node)) {
|
|
32
26
|
return print(
|
|
33
27
|
{
|
|
28
|
+
//@ts-expect-error
|
|
34
29
|
type: 'Program',
|
|
35
30
|
body: node,
|
|
36
31
|
sourceType: 'module'
|
|
@@ -39,7 +34,7 @@ export function print(node, opts = {}) {
|
|
|
39
34
|
);
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
/** @type {
|
|
37
|
+
/** @type {State} */
|
|
43
38
|
const state = {
|
|
44
39
|
commands: [],
|
|
45
40
|
comments: [],
|
|
@@ -76,7 +71,7 @@ export function print(node, opts = {}) {
|
|
|
76
71
|
|
|
77
72
|
let newline = '\n';
|
|
78
73
|
|
|
79
|
-
/** @param {
|
|
74
|
+
/** @param {Command} command */
|
|
80
75
|
function run(command) {
|
|
81
76
|
if (typeof command === 'string') {
|
|
82
77
|
append(command);
|
package/src/public.d.ts
ADDED
package/src/types.d.ts
CHANGED
|
@@ -1,16 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/types';
|
|
4
2
|
|
|
5
3
|
type Handler<T> = (node: T, state: State) => undefined;
|
|
6
4
|
|
|
7
5
|
export type Handlers = {
|
|
8
|
-
[
|
|
6
|
+
[T in TSESTree.Node['type']]: Handler<Extract<TSESTree.Node, { type: T }>>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TypeAnnotationNodes =
|
|
10
|
+
| TSESTree.TypeNode
|
|
11
|
+
| TSESTree.TypeElement
|
|
12
|
+
| TSESTree.TSTypeAnnotation
|
|
13
|
+
| TSESTree.TSPropertySignature
|
|
14
|
+
| TSESTree.TSTypeParameter
|
|
15
|
+
| TSESTree.TSTypeParameterDeclaration
|
|
16
|
+
| TSESTree.TSTypeParameterInstantiation
|
|
17
|
+
| TSESTree.TSEnumMember
|
|
18
|
+
| TSESTree.TSInterfaceHeritage
|
|
19
|
+
| TSESTree.TSClassImplements
|
|
20
|
+
| TSExpressionWithTypeArguments;
|
|
21
|
+
|
|
22
|
+
type TSExpressionWithTypeArguments = {
|
|
23
|
+
type: 'TSExpressionWithTypeArguments';
|
|
24
|
+
expression: any;
|
|
9
25
|
};
|
|
10
26
|
|
|
27
|
+
// `@typescript-eslint/types` differs from the official `estree` spec by handling
|
|
28
|
+
// comments differently. This is a node which we can use to ensure type saftey.
|
|
29
|
+
export type NodeWithComments = {
|
|
30
|
+
leadingComments?: TSESTree.Comment[] | undefined;
|
|
31
|
+
trailingComments?: TSESTree.Comment[] | undefined;
|
|
32
|
+
} & TSESTree.Node;
|
|
33
|
+
|
|
11
34
|
export interface State {
|
|
12
35
|
commands: Command[];
|
|
13
|
-
comments: Comment[];
|
|
36
|
+
comments: TSESTree.Comment[];
|
|
14
37
|
multiline: boolean;
|
|
15
38
|
}
|
|
16
39
|
|
|
@@ -47,7 +70,13 @@ export interface Sequence {
|
|
|
47
70
|
|
|
48
71
|
export interface CommentChunk {
|
|
49
72
|
type: 'Comment';
|
|
50
|
-
comment: Comment;
|
|
73
|
+
comment: TSESTree.Comment;
|
|
51
74
|
}
|
|
52
75
|
|
|
53
76
|
export type Command = string | Chunk | Newline | Indent | Dedent | Sequence | CommentChunk;
|
|
77
|
+
|
|
78
|
+
export interface PrintOptions {
|
|
79
|
+
sourceMapSource?: string;
|
|
80
|
+
sourceMapContent?: string;
|
|
81
|
+
sourceMapEncodeMappings?: boolean; // default true
|
|
82
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
declare module '
|
|
1
|
+
declare module 'dts-buddy' {
|
|
2
|
+
import type { TSESTree } from '@typescript-eslint/types';
|
|
3
|
+
export interface PrintOptions {
|
|
4
|
+
sourceMapSource?: string;
|
|
5
|
+
sourceMapContent?: string;
|
|
6
|
+
sourceMapEncodeMappings?: boolean; // default true
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* @returns // TODO
|
|
4
10
|
*/
|
|
5
|
-
export function print(node:
|
|
11
|
+
export function print(node: TSESTree.Node, opts?: PrintOptions): {
|
|
6
12
|
code: string;
|
|
7
13
|
map: any;
|
|
8
14
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
sourceMapContent?: string;
|
|
12
|
-
sourceMapEncodeMappings?: boolean;
|
|
13
|
-
};
|
|
15
|
+
|
|
16
|
+
export {};
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
//# sourceMappingURL=index.d.ts.map
|
package/types/index.d.ts.map
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"file": "index.d.ts",
|
|
4
4
|
"names": [
|
|
5
|
+
"PrintOptions",
|
|
5
6
|
"print"
|
|
6
7
|
],
|
|
7
8
|
"sources": [
|
|
9
|
+
"../src/types.d.ts",
|
|
8
10
|
"../src/index.js"
|
|
9
11
|
],
|
|
10
12
|
"sourcesContent": [
|
|
13
|
+
null,
|
|
11
14
|
null
|
|
12
15
|
],
|
|
13
|
-
"mappings": "
|
|
16
|
+
"mappings": ";;kBA6EiBA,YAAYA;;;;;;;;iBCtDbC,KAAKA",
|
|
14
17
|
"ignoreList": []
|
|
15
18
|
}
|