hermes-parser 0.7.0 → 0.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/dist/HermesASTAdapter.js +0 -4
- package/dist/HermesASTAdapter.js.flow +0 -6
- package/dist/HermesParserWASM.js +1 -1
- package/dist/HermesToBabelAdapter.js +83 -4
- package/dist/HermesToBabelAdapter.js.flow +92 -3
- package/dist/HermesToESTreeAdapter.js +205 -3
- package/dist/HermesToESTreeAdapter.js.flow +207 -3
- package/dist/generated/visitor-keys.js +36 -28
- package/dist/getModuleDocblock.js +111 -0
- package/dist/getModuleDocblock.js.flow +116 -0
- package/package.json +5 -3
|
@@ -89,6 +89,9 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
89
89
|
case 'ExportNamedDeclaration':
|
|
90
90
|
return this.mapExportNamedDeclaration(node);
|
|
91
91
|
|
|
92
|
+
case 'ExportNamespaceSpecifier':
|
|
93
|
+
return this.mapExportNamespaceSpecifier(node);
|
|
94
|
+
|
|
92
95
|
case 'ExportAllDeclaration':
|
|
93
96
|
return this.mapExportAllDeclaration(node);
|
|
94
97
|
|
|
@@ -102,6 +105,8 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
102
105
|
return this.mapJSXStringLiteral(node);
|
|
103
106
|
|
|
104
107
|
case 'PrivateName':
|
|
108
|
+
return this.mapPrivateName(node);
|
|
109
|
+
|
|
105
110
|
case 'ClassPrivateProperty':
|
|
106
111
|
return this.mapPrivateProperty(node);
|
|
107
112
|
|
|
@@ -113,6 +118,9 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
113
118
|
case 'OptionalIndexedAccessType':
|
|
114
119
|
return this.mapUnsupportedTypeAnnotation(node);
|
|
115
120
|
|
|
121
|
+
case 'BigIntLiteral':
|
|
122
|
+
return this.mapBigIntLiteral(node);
|
|
123
|
+
|
|
116
124
|
default:
|
|
117
125
|
return this.mapNodeDefault(node);
|
|
118
126
|
}
|
|
@@ -278,13 +286,14 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
278
286
|
typeParameters,
|
|
279
287
|
predicate
|
|
280
288
|
} = value;
|
|
281
|
-
|
|
289
|
+
const newNode = {
|
|
282
290
|
type: 'ObjectMethod',
|
|
283
291
|
loc: node.loc,
|
|
284
292
|
start: node.start,
|
|
285
293
|
end: node.end,
|
|
286
294
|
// Non getter or setter methods have `kind = method`
|
|
287
295
|
kind: node.kind === 'init' ? 'method' : node.kind,
|
|
296
|
+
method: node.kind === 'init' ? true : false,
|
|
288
297
|
computed: node.computed,
|
|
289
298
|
key,
|
|
290
299
|
id,
|
|
@@ -296,6 +305,13 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
296
305
|
typeParameters,
|
|
297
306
|
predicate
|
|
298
307
|
};
|
|
308
|
+
|
|
309
|
+
if (node.kind !== 'init') {
|
|
310
|
+
// babel emits an empty variance property on accessors for some reason
|
|
311
|
+
newNode.variance = null;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return newNode;
|
|
299
315
|
} else {
|
|
300
316
|
// Non-method property nodes should be renamed to ObjectProperty
|
|
301
317
|
node.type = 'ObjectProperty';
|
|
@@ -346,7 +362,15 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
346
362
|
|
|
347
363
|
if (annotation != null) {
|
|
348
364
|
restElement.typeAnnotation = annotation;
|
|
349
|
-
restElement.argument.typeAnnotation = null;
|
|
365
|
+
restElement.argument.typeAnnotation = null; // Unfortunately there's no way for us to recover the end location of
|
|
366
|
+
// the argument for the general case
|
|
367
|
+
|
|
368
|
+
if (restElement.argument.type === 'Identifier') {
|
|
369
|
+
restElement.argument.end = restElement.argument.start + restElement.argument.name.length;
|
|
370
|
+
restElement.argument.loc.end = { ...restElement.argument.loc.start,
|
|
371
|
+
column: restElement.argument.loc.start.column + restElement.argument.name.length
|
|
372
|
+
};
|
|
373
|
+
}
|
|
350
374
|
}
|
|
351
375
|
|
|
352
376
|
return restElement;
|
|
@@ -362,9 +386,13 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
362
386
|
end: node.end,
|
|
363
387
|
callee: {
|
|
364
388
|
type: 'Import',
|
|
365
|
-
loc: node.loc,
|
|
389
|
+
loc: { ...node.loc,
|
|
390
|
+
end: { ...node.loc.start,
|
|
391
|
+
column: node.loc.start.column + 'import'.length
|
|
392
|
+
}
|
|
393
|
+
},
|
|
366
394
|
start: node.start,
|
|
367
|
-
end: node.
|
|
395
|
+
end: node.start + 'import'.length
|
|
368
396
|
},
|
|
369
397
|
arguments: [this.mapNode(node.source)]
|
|
370
398
|
};
|
|
@@ -407,6 +435,57 @@ class HermesToBabelAdapter extends _HermesASTAdapter.default {
|
|
|
407
435
|
};
|
|
408
436
|
}
|
|
409
437
|
|
|
438
|
+
mapBigIntLiteral(node) {
|
|
439
|
+
const bigint = node.bigint.replace(/n$/, '').replace(/_/, '');
|
|
440
|
+
node.value = typeof BigInt === 'function' ? BigInt(bigint) : null;
|
|
441
|
+
return node;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
mapPrivateProperty(nodeUnprocessed) {
|
|
445
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
446
|
+
node.key = {
|
|
447
|
+
type: 'PrivateName',
|
|
448
|
+
id: { ...node.key,
|
|
449
|
+
// babel doesn't include the hash in the identifier
|
|
450
|
+
start: node.key.start + 1,
|
|
451
|
+
loc: { ...node.key.loc,
|
|
452
|
+
start: { ...node.key.loc.start,
|
|
453
|
+
column: node.key.loc.start.column + 1
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
start: node.key.start,
|
|
458
|
+
end: node.key.end,
|
|
459
|
+
loc: node.key.loc
|
|
460
|
+
};
|
|
461
|
+
return node;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
mapPrivateName(node) {
|
|
465
|
+
// babel doesn't include the hash in the identifier
|
|
466
|
+
node.id.start += 1;
|
|
467
|
+
node.id.loc.start.column += 1;
|
|
468
|
+
return node;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
mapExportNamespaceSpecifier(nodeUnprocessed) {
|
|
472
|
+
const node = this.mapNodeDefault(nodeUnprocessed); // the hermes AST emits the location as the location of the entire export
|
|
473
|
+
// but babel emits the location as *just* the "* as id" bit
|
|
474
|
+
// the end will always align with the end of the identifier (ezpz)
|
|
475
|
+
// but the start will align with the "*" token - which we can't recover from just the AST
|
|
476
|
+
// so we just fudge the start location a bit to get it "good enough"
|
|
477
|
+
// it will be wrong if the AST is anything like "export * as x from 'y'"... but oh well
|
|
478
|
+
|
|
479
|
+
node.start = node.start + 'export '.length;
|
|
480
|
+
node.loc.start.column = node.loc.start.column + 'export '.length;
|
|
481
|
+
node.end = node.exported.end;
|
|
482
|
+
node.loc.end = {
|
|
483
|
+
column: node.exported.loc.end.column,
|
|
484
|
+
line: node.exported.loc.end.line
|
|
485
|
+
};
|
|
486
|
+
return node;
|
|
487
|
+
}
|
|
488
|
+
|
|
410
489
|
}
|
|
411
490
|
|
|
412
491
|
exports.default = HermesToBabelAdapter;
|
|
@@ -21,6 +21,8 @@ import type {HermesNode} from './HermesAST';
|
|
|
21
21
|
|
|
22
22
|
import HermesASTAdapter from './HermesASTAdapter';
|
|
23
23
|
|
|
24
|
+
declare var BigInt: ?(value: $FlowFixMe) => mixed;
|
|
25
|
+
|
|
24
26
|
export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
25
27
|
fixSourceLocation(node: HermesNode): void {
|
|
26
28
|
const loc = node.loc;
|
|
@@ -67,6 +69,8 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
67
69
|
return this.mapExportDefaultDeclaration(node);
|
|
68
70
|
case 'ExportNamedDeclaration':
|
|
69
71
|
return this.mapExportNamedDeclaration(node);
|
|
72
|
+
case 'ExportNamespaceSpecifier':
|
|
73
|
+
return this.mapExportNamespaceSpecifier(node);
|
|
70
74
|
case 'ExportAllDeclaration':
|
|
71
75
|
return this.mapExportAllDeclaration(node);
|
|
72
76
|
case 'RestElement':
|
|
@@ -76,6 +80,7 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
76
80
|
case 'JSXStringLiteral':
|
|
77
81
|
return this.mapJSXStringLiteral(node);
|
|
78
82
|
case 'PrivateName':
|
|
83
|
+
return this.mapPrivateName(node);
|
|
79
84
|
case 'ClassPrivateProperty':
|
|
80
85
|
return this.mapPrivateProperty(node);
|
|
81
86
|
case 'FunctionDeclaration':
|
|
@@ -84,6 +89,8 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
84
89
|
case 'IndexedAccessType':
|
|
85
90
|
case 'OptionalIndexedAccessType':
|
|
86
91
|
return this.mapUnsupportedTypeAnnotation(node);
|
|
92
|
+
case 'BigIntLiteral':
|
|
93
|
+
return this.mapBigIntLiteral(node);
|
|
87
94
|
default:
|
|
88
95
|
return this.mapNodeDefault(node);
|
|
89
96
|
}
|
|
@@ -251,13 +258,14 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
251
258
|
predicate,
|
|
252
259
|
} = value;
|
|
253
260
|
|
|
254
|
-
|
|
261
|
+
const newNode: HermesNode = {
|
|
255
262
|
type: 'ObjectMethod',
|
|
256
263
|
loc: node.loc,
|
|
257
264
|
start: node.start,
|
|
258
265
|
end: node.end,
|
|
259
266
|
// Non getter or setter methods have `kind = method`
|
|
260
267
|
kind: node.kind === 'init' ? 'method' : node.kind,
|
|
268
|
+
method: node.kind === 'init' ? true : false,
|
|
261
269
|
computed: node.computed,
|
|
262
270
|
key,
|
|
263
271
|
id,
|
|
@@ -269,6 +277,11 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
269
277
|
typeParameters,
|
|
270
278
|
predicate,
|
|
271
279
|
};
|
|
280
|
+
if (node.kind !== 'init') {
|
|
281
|
+
// babel emits an empty variance property on accessors for some reason
|
|
282
|
+
newNode.variance = null;
|
|
283
|
+
}
|
|
284
|
+
return newNode;
|
|
272
285
|
} else {
|
|
273
286
|
// Non-method property nodes should be renamed to ObjectProperty
|
|
274
287
|
node.type = 'ObjectProperty';
|
|
@@ -322,6 +335,18 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
322
335
|
if (annotation != null) {
|
|
323
336
|
restElement.typeAnnotation = annotation;
|
|
324
337
|
restElement.argument.typeAnnotation = null;
|
|
338
|
+
// Unfortunately there's no way for us to recover the end location of
|
|
339
|
+
// the argument for the general case
|
|
340
|
+
if (restElement.argument.type === 'Identifier') {
|
|
341
|
+
restElement.argument.end =
|
|
342
|
+
restElement.argument.start + restElement.argument.name.length;
|
|
343
|
+
restElement.argument.loc.end = {
|
|
344
|
+
...restElement.argument.loc.start,
|
|
345
|
+
column:
|
|
346
|
+
restElement.argument.loc.start.column +
|
|
347
|
+
restElement.argument.name.length,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
325
350
|
}
|
|
326
351
|
|
|
327
352
|
return restElement;
|
|
@@ -337,9 +362,15 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
337
362
|
end: node.end,
|
|
338
363
|
callee: {
|
|
339
364
|
type: 'Import',
|
|
340
|
-
loc:
|
|
365
|
+
loc: {
|
|
366
|
+
...node.loc,
|
|
367
|
+
end: {
|
|
368
|
+
...node.loc.start,
|
|
369
|
+
column: node.loc.start.column + 'import'.length,
|
|
370
|
+
},
|
|
371
|
+
},
|
|
341
372
|
start: node.start,
|
|
342
|
-
end: node.
|
|
373
|
+
end: node.start + 'import'.length,
|
|
343
374
|
},
|
|
344
375
|
arguments: [this.mapNode(node.source)],
|
|
345
376
|
};
|
|
@@ -380,4 +411,62 @@ export default class HermesToBabelAdapter extends HermesASTAdapter {
|
|
|
380
411
|
end: node.end,
|
|
381
412
|
};
|
|
382
413
|
}
|
|
414
|
+
|
|
415
|
+
mapBigIntLiteral(node: HermesNode): HermesNode {
|
|
416
|
+
const bigint = node.bigint.replace(/n$/, '').replace(/_/, '');
|
|
417
|
+
node.value = typeof BigInt === 'function' ? BigInt(bigint) : null;
|
|
418
|
+
return node;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
mapPrivateProperty(nodeUnprocessed: HermesNode): HermesNode {
|
|
422
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
423
|
+
node.key = {
|
|
424
|
+
type: 'PrivateName',
|
|
425
|
+
id: {
|
|
426
|
+
...node.key,
|
|
427
|
+
// babel doesn't include the hash in the identifier
|
|
428
|
+
start: node.key.start + 1,
|
|
429
|
+
loc: {
|
|
430
|
+
...node.key.loc,
|
|
431
|
+
start: {
|
|
432
|
+
...node.key.loc.start,
|
|
433
|
+
column: node.key.loc.start.column + 1,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
start: node.key.start,
|
|
438
|
+
end: node.key.end,
|
|
439
|
+
loc: node.key.loc,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
return node;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
mapPrivateName(node: HermesNode): HermesNode {
|
|
446
|
+
// babel doesn't include the hash in the identifier
|
|
447
|
+
node.id.start += 1;
|
|
448
|
+
node.id.loc.start.column += 1;
|
|
449
|
+
return node;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
mapExportNamespaceSpecifier(nodeUnprocessed: HermesNode): HermesNode {
|
|
453
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
454
|
+
|
|
455
|
+
// the hermes AST emits the location as the location of the entire export
|
|
456
|
+
// but babel emits the location as *just* the "* as id" bit
|
|
457
|
+
|
|
458
|
+
// the end will always align with the end of the identifier (ezpz)
|
|
459
|
+
// but the start will align with the "*" token - which we can't recover from just the AST
|
|
460
|
+
// so we just fudge the start location a bit to get it "good enough"
|
|
461
|
+
// it will be wrong if the AST is anything like "export * as x from 'y'"... but oh well
|
|
462
|
+
node.start = node.start + 'export '.length;
|
|
463
|
+
node.loc.start.column = node.loc.start.column + 'export '.length;
|
|
464
|
+
node.end = node.exported.end;
|
|
465
|
+
node.loc.end = {
|
|
466
|
+
column: node.exported.loc.end.column,
|
|
467
|
+
line: node.exported.loc.end.line,
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
return node;
|
|
471
|
+
}
|
|
383
472
|
}
|
|
@@ -7,6 +7,8 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _HermesASTAdapter = _interopRequireDefault(require("./HermesASTAdapter"));
|
|
9
9
|
|
|
10
|
+
var _getModuleDocblock = require("./getModuleDocblock");
|
|
11
|
+
|
|
10
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -49,6 +51,8 @@ class HermesToESTreeAdapter extends _HermesASTAdapter.default {
|
|
|
49
51
|
end: loc.end
|
|
50
52
|
};
|
|
51
53
|
node.range = [loc.rangeStart, loc.rangeEnd];
|
|
54
|
+
delete node.start;
|
|
55
|
+
delete node.end;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
mapNode(node) {
|
|
@@ -100,12 +104,26 @@ class HermesToESTreeAdapter extends _HermesASTAdapter.default {
|
|
|
100
104
|
case 'ExportAllDeclaration':
|
|
101
105
|
return this.mapExportAllDeclaration(node);
|
|
102
106
|
|
|
107
|
+
case 'Property':
|
|
108
|
+
return this.mapProperty(node);
|
|
109
|
+
|
|
110
|
+
case 'FunctionDeclaration':
|
|
111
|
+
case 'FunctionExpression':
|
|
112
|
+
case 'ArrowFunctionExpression':
|
|
113
|
+
return this.mapFunction(node);
|
|
114
|
+
|
|
103
115
|
case 'PrivateName':
|
|
116
|
+
return this.mapPrivateName(node);
|
|
117
|
+
|
|
118
|
+
case 'ClassProperty':
|
|
104
119
|
case 'ClassPrivateProperty':
|
|
105
|
-
return this.
|
|
120
|
+
return this.mapClassProperty(node);
|
|
106
121
|
|
|
107
|
-
case '
|
|
108
|
-
|
|
122
|
+
case 'MemberExpression':
|
|
123
|
+
case 'OptionalMemberExpression':
|
|
124
|
+
case 'CallExpression':
|
|
125
|
+
case 'OptionalCallExpression':
|
|
126
|
+
return this.mapChainExpression(node);
|
|
109
127
|
|
|
110
128
|
default:
|
|
111
129
|
return this.mapNodeDefault(node);
|
|
@@ -115,6 +133,7 @@ class HermesToESTreeAdapter extends _HermesASTAdapter.default {
|
|
|
115
133
|
mapProgram(node) {
|
|
116
134
|
node = this.mapNodeDefault(node);
|
|
117
135
|
node.sourceType = this.getSourceType();
|
|
136
|
+
node.docblock = (0, _getModuleDocblock.getModuleDocblock)(node);
|
|
118
137
|
return node;
|
|
119
138
|
}
|
|
120
139
|
|
|
@@ -246,6 +265,189 @@ class HermesToESTreeAdapter extends _HermesASTAdapter.default {
|
|
|
246
265
|
return node;
|
|
247
266
|
}
|
|
248
267
|
|
|
268
|
+
mapFunction(nodeUnprocessed) {
|
|
269
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
270
|
+
|
|
271
|
+
switch (node.type) {
|
|
272
|
+
case 'FunctionDeclaration':
|
|
273
|
+
case 'FunctionExpression':
|
|
274
|
+
node.expression = false;
|
|
275
|
+
return node;
|
|
276
|
+
|
|
277
|
+
case 'ArrowFunctionExpression':
|
|
278
|
+
node.expression = node.body.type !== 'BlockStatement';
|
|
279
|
+
return node;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return node;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
mapChainExpression(nodeUnprocessed) {
|
|
286
|
+
/*
|
|
287
|
+
NOTE - In the below comments `MemberExpression` and `CallExpression`
|
|
288
|
+
are completely interchangable. For terseness we just reference
|
|
289
|
+
one each time.
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/*
|
|
293
|
+
Hermes uses the old babel-style AST:
|
|
294
|
+
```
|
|
295
|
+
(one?.two).three?.four;
|
|
296
|
+
^^^^^^^^^^^^^^^^^^^^^^ OptionalMemberExpression
|
|
297
|
+
^^^^^^^^^^^^^^^^ MemberExpression
|
|
298
|
+
^^^^^^^^ OptionalMemberExpression
|
|
299
|
+
```
|
|
300
|
+
We need to convert it to the ESTree representation:
|
|
301
|
+
```
|
|
302
|
+
(one?.two).three?.four;
|
|
303
|
+
^^^^^^^^^^^^^^^^^^^^^^ ChainExpression
|
|
304
|
+
^^^^^^^^^^^^^^^^^^^^^^ MemberExpression[optional = true]
|
|
305
|
+
^^^^^^^^^^^^^^^^ MemberExpression[optional = false]
|
|
306
|
+
^^^^^^^^ ChainExpression
|
|
307
|
+
^^^^^^^^ MemberExpression[optional = true]
|
|
308
|
+
```
|
|
309
|
+
We do this by converting the AST and its children (depth first), and then unwrapping
|
|
310
|
+
the resulting AST as appropriate.
|
|
311
|
+
Put another way:
|
|
312
|
+
1) traverse to the leaf
|
|
313
|
+
2) if the current node is an `OptionalMemberExpression`:
|
|
314
|
+
a) if the `.object` is a `ChainExpression`:
|
|
315
|
+
i) unwrap the child (`node.object = child.expression`)
|
|
316
|
+
b) convert this node to a `MemberExpression[optional = true]`
|
|
317
|
+
c) wrap this node (`node = ChainExpression[expression = node]`)
|
|
318
|
+
3) if the current node is a `MembedExpression`:
|
|
319
|
+
a) convert this node to a `MemberExpression[optional = true]`
|
|
320
|
+
*/
|
|
321
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
322
|
+
|
|
323
|
+
const {
|
|
324
|
+
child,
|
|
325
|
+
childKey,
|
|
326
|
+
isOptional
|
|
327
|
+
} = (() => {
|
|
328
|
+
const isOptional = node.optional === true;
|
|
329
|
+
|
|
330
|
+
if (node.type.endsWith('MemberExpression')) {
|
|
331
|
+
return {
|
|
332
|
+
child: node.object,
|
|
333
|
+
childKey: 'object',
|
|
334
|
+
isOptional
|
|
335
|
+
};
|
|
336
|
+
} else if (node.type.endsWith('CallExpression')) {
|
|
337
|
+
return {
|
|
338
|
+
child: node.callee,
|
|
339
|
+
childKey: 'callee',
|
|
340
|
+
isOptional
|
|
341
|
+
};
|
|
342
|
+
} else {
|
|
343
|
+
return {
|
|
344
|
+
child: node.expression,
|
|
345
|
+
childKey: 'expression',
|
|
346
|
+
isOptional: false
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
})();
|
|
350
|
+
|
|
351
|
+
const isChildUnwrappable = child.type === 'ChainExpression' && // (x?.y).z is semantically different to `x?.y.z`.
|
|
352
|
+
// In the un-parenthesised case `.z` is only executed if and only if `x?.y` returns a non-nullish value.
|
|
353
|
+
// In the parenthesised case, `.z` is **always** executed, regardless of the return of `x?.y`.
|
|
354
|
+
// As such the AST is different between the two cases.
|
|
355
|
+
//
|
|
356
|
+
// In the hermes AST - any member part of a non-short-circuited optional chain is represented with `OptionalMemberExpression`
|
|
357
|
+
// so if we see a `MemberExpression`, then we know we've hit a parenthesis boundary.
|
|
358
|
+
node.type !== 'MemberExpression' && node.type !== 'CallExpression';
|
|
359
|
+
|
|
360
|
+
if (node.type.startsWith('Optional')) {
|
|
361
|
+
node.type = node.type.replace('Optional', '');
|
|
362
|
+
node.optional = isOptional;
|
|
363
|
+
} else {
|
|
364
|
+
node.optional = false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (!isChildUnwrappable && !isOptional) {
|
|
368
|
+
return node;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (isChildUnwrappable) {
|
|
372
|
+
const newChild = child.expression;
|
|
373
|
+
node[childKey] = newChild;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
type: 'ChainExpression',
|
|
378
|
+
expression: node,
|
|
379
|
+
loc: node.loc,
|
|
380
|
+
range: node.range
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
mapClassProperty(nodeUnprocessed) {
|
|
385
|
+
const node = this.mapNodeDefault(nodeUnprocessed);
|
|
386
|
+
|
|
387
|
+
const key = (() => {
|
|
388
|
+
if (node.type === 'ClassPrivateProperty') {
|
|
389
|
+
const key = this.mapNodeDefault(node.key);
|
|
390
|
+
return {
|
|
391
|
+
type: 'PrivateIdentifier',
|
|
392
|
+
name: key.name,
|
|
393
|
+
range: key.range,
|
|
394
|
+
loc: key.loc
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return node.key;
|
|
399
|
+
})();
|
|
400
|
+
|
|
401
|
+
return { ...node,
|
|
402
|
+
computed: node.type === 'ClassPrivateProperty' ? false : node.computed,
|
|
403
|
+
key,
|
|
404
|
+
type: 'PropertyDefinition'
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
mapPrivateName(node) {
|
|
409
|
+
return {
|
|
410
|
+
type: 'PrivateIdentifier',
|
|
411
|
+
name: node.id.name,
|
|
412
|
+
// estree the location refers to the entire string including the hash token
|
|
413
|
+
range: node.range,
|
|
414
|
+
loc: node.loc
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
mapExportNamedDeclaration(nodeUnprocessed) {
|
|
419
|
+
const node = super.mapExportNamedDeclaration(nodeUnprocessed);
|
|
420
|
+
const namespaceSpecifier = node.specifiers.find(spec => spec.type === 'ExportNamespaceSpecifier');
|
|
421
|
+
|
|
422
|
+
if (namespaceSpecifier != null) {
|
|
423
|
+
var _node$exportKind;
|
|
424
|
+
|
|
425
|
+
if (node.specifiers.length !== 1) {
|
|
426
|
+
// this should already a hermes parser error - but let's be absolutely sure we're aligned with the spec
|
|
427
|
+
throw new Error('Cannot use an export all with any other specifiers');
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return {
|
|
431
|
+
type: 'ExportAllDeclaration',
|
|
432
|
+
source: node.source,
|
|
433
|
+
exportKind: (_node$exportKind = node.exportKind) != null ? _node$exportKind : 'value',
|
|
434
|
+
exported: namespaceSpecifier.exported,
|
|
435
|
+
range: node.range,
|
|
436
|
+
loc: node.loc
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return node;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
mapExportAllDeclaration(nodeUnprocessed) {
|
|
444
|
+
var _node$exported;
|
|
445
|
+
|
|
446
|
+
const node = super.mapExportAllDeclaration(nodeUnprocessed);
|
|
447
|
+
node.exported = (_node$exported = node.exported) != null ? _node$exported : null;
|
|
448
|
+
return node;
|
|
449
|
+
}
|
|
450
|
+
|
|
249
451
|
}
|
|
250
452
|
|
|
251
453
|
exports.default = HermesToESTreeAdapter;
|