flow-parser 0.328.0 → 0.329.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 +41 -0
- package/dist/FlowParser.js +44 -10
- package/dist/FlowParser.js.flow +67 -12
- package/dist/FlowParserDeserializer.js +125 -11
- package/dist/FlowParserDeserializer.js.flow +147 -30
- package/dist/FlowParserNodeDeserializers.js +605 -0
- package/dist/FlowParserWASM.js +1 -1
- package/dist/FlowParserWASM.js.flow +10 -0
- package/dist/babel/BabelAST.js.flow +29 -0
- package/dist/index.js +1 -11
- package/dist/index.js.flow +2 -22
- package/package.json +2 -2
- package/dist/babel/TransformESTreeToBabel.js +0 -915
- package/dist/babel/TransformESTreeToBabel.js.flow +0 -1357
|
@@ -13,16 +13,27 @@
|
|
|
13
13
|
import type {HermesSourceLocation, HermesNode, HermesToken} from './HermesAST';
|
|
14
14
|
import type {FlowParserWASM} from './FlowParserWASM';
|
|
15
15
|
import type {ParserOptions} from './ParserOptions';
|
|
16
|
+
import type {BabelFile} from './babel/BabelAST';
|
|
16
17
|
|
|
17
18
|
import HermesParserDecodeUTF8String from './HermesParserDecodeUTF8String';
|
|
18
19
|
import NODE_DESERIALIZERS from './FlowParserNodeDeserializers';
|
|
19
20
|
|
|
20
21
|
type FlowComment = {
|
|
21
|
-
type: 'Block' | 'Line',
|
|
22
|
+
type: 'Block' | 'Line' | 'CommentBlock' | 'CommentLine',
|
|
22
23
|
loc: HermesSourceLocation,
|
|
23
24
|
value: ?string,
|
|
25
|
+
start?: number,
|
|
26
|
+
end?: number,
|
|
24
27
|
};
|
|
25
28
|
|
|
29
|
+
type ExtendedPosition = {
|
|
30
|
+
loc: HermesSourceLocation,
|
|
31
|
+
start: number,
|
|
32
|
+
end: number,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const LOCATION_IDENTIFIER_NAME = 1 << 0;
|
|
36
|
+
|
|
26
37
|
export type FlowParserProgram = {
|
|
27
38
|
type: 'Program',
|
|
28
39
|
loc: HermesSourceLocation,
|
|
@@ -49,15 +60,15 @@ export default class FlowParserDeserializer {
|
|
|
49
60
|
readonly positionBufferSize: number;
|
|
50
61
|
readonly stringBufferBase: number;
|
|
51
62
|
readonly locMap: {[number]: HermesSourceLocation};
|
|
63
|
+
readonly extendedPositions: Array<?ExtendedPosition>;
|
|
64
|
+
readonly extendedRanges: WeakMap<HermesSourceLocation, ExtendedPosition>;
|
|
52
65
|
readonly HEAPU8: FlowParserWASM['HEAPU8'];
|
|
53
66
|
readonly HEAPU32: FlowParserWASM['HEAPU32'];
|
|
54
67
|
readonly HEAPF64: FlowParserWASM['HEAPF64'];
|
|
55
68
|
readonly options: ParserOptions;
|
|
69
|
+
extendedLocationHeaders: boolean;
|
|
56
70
|
|
|
57
|
-
// Comment types: Flow uses ESTree-standard names
|
|
58
|
-
// Matches CommentKind enum in ast.rs: Block = 0, Line = 1
|
|
59
71
|
readonly commentTypes: ReadonlyArray<FlowComment['type']> = ['Block', 'Line'];
|
|
60
|
-
|
|
61
72
|
// Matches TokenType enum (same as Hermes for compatibility)
|
|
62
73
|
readonly tokenTypes: ReadonlyArray<HermesToken['type']> = [
|
|
63
74
|
'Boolean',
|
|
@@ -94,12 +105,15 @@ export default class FlowParserDeserializer {
|
|
|
94
105
|
// null pointer (encoded as `(0,)` with no length word).
|
|
95
106
|
this.stringBufferBase = stringBufferBase;
|
|
96
107
|
this.locMap = {};
|
|
108
|
+
this.extendedPositions = [];
|
|
109
|
+
this.extendedRanges = new WeakMap();
|
|
97
110
|
|
|
98
111
|
this.HEAPU8 = wasmParser.HEAPU8;
|
|
99
112
|
this.HEAPU32 = wasmParser.HEAPU32;
|
|
100
113
|
this.HEAPF64 = wasmParser.HEAPF64;
|
|
101
114
|
|
|
102
115
|
this.options = options;
|
|
116
|
+
this.extendedLocationHeaders = false;
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
/**
|
|
@@ -110,33 +124,35 @@ export default class FlowParserDeserializer {
|
|
|
110
124
|
return num;
|
|
111
125
|
}
|
|
112
126
|
|
|
113
|
-
deserialize(): FlowParserProgram {
|
|
127
|
+
deserialize(): FlowParserProgram | BabelFile {
|
|
128
|
+
if (this.HEAPU32[this.programBufferIdx] === 0) {
|
|
129
|
+
return this.deserializeESTreeProgram();
|
|
130
|
+
}
|
|
131
|
+
this.extendedLocationHeaders = true;
|
|
132
|
+
this.prepareExtendedPositions();
|
|
133
|
+
const root = this.deserializeNode();
|
|
134
|
+
if (root == null) {
|
|
135
|
+
throw new Error('Expected serialized parser root');
|
|
136
|
+
}
|
|
137
|
+
// $FlowExpectedError[incompatible-type] The root node kind defines the public schema.
|
|
138
|
+
return root;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
deserializeESTreeProgram(): FlowParserProgram {
|
|
114
142
|
const program: FlowParserProgram = {
|
|
115
143
|
type: 'Program',
|
|
116
144
|
loc: this.addEmptyLoc(),
|
|
117
145
|
body: this.deserializeNodeList(),
|
|
118
|
-
comments: this.
|
|
146
|
+
comments: this.deserializeESTreeComments(),
|
|
119
147
|
};
|
|
120
|
-
|
|
121
|
-
// Interpreter directive (OCaml `program` estree_translator.ml:118-123).
|
|
122
|
-
// The serializer writes a Node slot here: an `InterpreterDirective` node
|
|
123
|
-
// when `#!shebang` is present, otherwise null. Always attach the slot so
|
|
124
|
-
// the public Program shape carries `interpreter: InterpreterDirective | null`
|
|
125
|
-
// — matches upstream hermes-parser, which exposes the slot uniformly.
|
|
126
148
|
program.interpreter = this.deserializeNode();
|
|
127
|
-
|
|
128
149
|
if (this.options.tokens === true) {
|
|
129
150
|
program.tokens = this.deserializeTokens();
|
|
130
151
|
} else {
|
|
131
|
-
// Tokens slot is always written by the serializer; consume the count
|
|
132
|
-
// even when callers didn't ask for tokens.
|
|
133
152
|
this.deserializeTokens();
|
|
134
153
|
}
|
|
135
|
-
|
|
136
154
|
program.errors = this.deserializeErrors();
|
|
137
|
-
|
|
138
155
|
this.fillLocs();
|
|
139
|
-
|
|
140
156
|
return program;
|
|
141
157
|
}
|
|
142
158
|
|
|
@@ -219,9 +235,19 @@ export default class FlowParserDeserializer {
|
|
|
219
235
|
if (nodeType === 0) {
|
|
220
236
|
return null;
|
|
221
237
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
238
|
+
const deserializeNode = NODE_DESERIALIZERS[nodeType - 1];
|
|
239
|
+
if (deserializeNode == null) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`Unknown serialized node kind ${nodeType - 1} at program word ${
|
|
242
|
+
this.programBufferIdx - 1
|
|
243
|
+
}`,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
const node = deserializeNode.call(this);
|
|
247
|
+
if (this.extendedLocationHeaders) {
|
|
248
|
+
this.addExtendedRange(node);
|
|
249
|
+
}
|
|
250
|
+
return node;
|
|
225
251
|
}
|
|
226
252
|
|
|
227
253
|
/**
|
|
@@ -235,10 +261,18 @@ export default class FlowParserDeserializer {
|
|
|
235
261
|
for (let i = 0; i < size; i++) {
|
|
236
262
|
nodeList.push(this.deserializeNode());
|
|
237
263
|
}
|
|
238
|
-
|
|
239
264
|
return nodeList;
|
|
240
265
|
}
|
|
241
266
|
|
|
267
|
+
deserializeEnumRuntime(): unknown {
|
|
268
|
+
const getRuntime =
|
|
269
|
+
this.options.transformOptions?.TransformEnumSyntax?.getRuntime;
|
|
270
|
+
if (typeof getRuntime !== 'function') {
|
|
271
|
+
throw new Error('Expected TransformEnumSyntax.getRuntime callback');
|
|
272
|
+
}
|
|
273
|
+
return getRuntime();
|
|
274
|
+
}
|
|
275
|
+
|
|
242
276
|
/**
|
|
243
277
|
* Comments are serialized as a node list, where each comment is serialized
|
|
244
278
|
* as a 4-byte integer denoting comment type, followed by a 4-byte value
|
|
@@ -249,19 +283,39 @@ export default class FlowParserDeserializer {
|
|
|
249
283
|
const comments = [];
|
|
250
284
|
|
|
251
285
|
for (let i = 0; i < size; i++) {
|
|
252
|
-
const commentType = this.
|
|
286
|
+
const commentType = this.deserializeString();
|
|
287
|
+
if (commentType == null) {
|
|
288
|
+
throw new Error('Expected serialized comment type');
|
|
289
|
+
}
|
|
253
290
|
const loc = this.addEmptyLoc();
|
|
254
|
-
const
|
|
255
|
-
|
|
291
|
+
const comment: FlowComment = {
|
|
292
|
+
// $FlowExpectedError[incompatible-type] Rust emits the closed comment type set.
|
|
256
293
|
type: commentType,
|
|
257
294
|
loc,
|
|
258
|
-
value,
|
|
259
|
-
}
|
|
295
|
+
value: this.deserializeString(),
|
|
296
|
+
};
|
|
297
|
+
this.addExtendedRange(comment);
|
|
298
|
+
comments.push(comment);
|
|
260
299
|
}
|
|
261
300
|
|
|
262
301
|
return comments;
|
|
263
302
|
}
|
|
264
303
|
|
|
304
|
+
deserializeESTreeComments(): Array<FlowComment> {
|
|
305
|
+
const size = this.next();
|
|
306
|
+
const comments = [];
|
|
307
|
+
for (let i = 0; i < size; i++) {
|
|
308
|
+
const commentType = this.commentTypes[this.next()];
|
|
309
|
+
const comment: FlowComment = {
|
|
310
|
+
type: commentType,
|
|
311
|
+
loc: this.addEmptyLoc(),
|
|
312
|
+
value: this.deserializeString(),
|
|
313
|
+
};
|
|
314
|
+
comments.push(comment);
|
|
315
|
+
}
|
|
316
|
+
return comments;
|
|
317
|
+
}
|
|
318
|
+
|
|
265
319
|
deserializeTokens(): Array<HermesToken> {
|
|
266
320
|
const size = this.next();
|
|
267
321
|
const tokens = [];
|
|
@@ -270,11 +324,12 @@ export default class FlowParserDeserializer {
|
|
|
270
324
|
const tokenType = this.tokenTypes[this.next()];
|
|
271
325
|
const loc = this.addEmptyLoc();
|
|
272
326
|
const value = this.deserializeString();
|
|
273
|
-
|
|
327
|
+
const token: HermesToken = {
|
|
274
328
|
type: tokenType,
|
|
275
329
|
loc,
|
|
276
330
|
value,
|
|
277
|
-
}
|
|
331
|
+
};
|
|
332
|
+
tokens.push(token);
|
|
278
333
|
}
|
|
279
334
|
|
|
280
335
|
return tokens;
|
|
@@ -286,11 +341,70 @@ export default class FlowParserDeserializer {
|
|
|
286
341
|
* objects that are filled after the AST has been deserialized.
|
|
287
342
|
*/
|
|
288
343
|
addEmptyLoc(): HermesSourceLocation {
|
|
344
|
+
const locId = this.next();
|
|
345
|
+
if (this.extendedLocationHeaders) {
|
|
346
|
+
const flags = this.next();
|
|
347
|
+
const position = this.extendedPositions[locId];
|
|
348
|
+
if (position == null) {
|
|
349
|
+
throw new Error(`Missing serialized extended location ${locId}`);
|
|
350
|
+
}
|
|
351
|
+
const loc = position.loc;
|
|
352
|
+
if (flags & LOCATION_IDENTIFIER_NAME) {
|
|
353
|
+
const identifierName = this.deserializeString();
|
|
354
|
+
if (identifierName != null) {
|
|
355
|
+
// $FlowExpectedError[prop-missing] The extended wire location schema carries this field.
|
|
356
|
+
loc.identifierName = identifierName;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
this.extendedRanges.set(loc, position);
|
|
360
|
+
return loc;
|
|
361
|
+
}
|
|
289
362
|
const loc: HermesSourceLocation = {};
|
|
290
|
-
this.locMap[
|
|
363
|
+
this.locMap[locId] = loc;
|
|
291
364
|
return loc;
|
|
292
365
|
}
|
|
293
366
|
|
|
367
|
+
prepareExtendedPositions(): void {
|
|
368
|
+
let index = this.positionBufferIdx;
|
|
369
|
+
for (let i = 0; i < this.positionBufferSize; i++) {
|
|
370
|
+
const locId = this.HEAPU32[index++];
|
|
371
|
+
const kind = this.HEAPU32[index++];
|
|
372
|
+
const line = this.HEAPU32[index++];
|
|
373
|
+
const column = this.HEAPU32[index++];
|
|
374
|
+
const offset = this.HEAPU32[index++];
|
|
375
|
+
const position: ExtendedPosition = this.extendedPositions[locId] ?? {
|
|
376
|
+
loc: {} as HermesSourceLocation,
|
|
377
|
+
start: 0,
|
|
378
|
+
end: 0,
|
|
379
|
+
};
|
|
380
|
+
if (kind === 0) {
|
|
381
|
+
position.loc.start = {line, column};
|
|
382
|
+
position.start = offset;
|
|
383
|
+
} else {
|
|
384
|
+
position.loc.end = {line, column};
|
|
385
|
+
position.end = offset;
|
|
386
|
+
}
|
|
387
|
+
this.extendedPositions[locId] = position;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
addExtendedRange(owner: {
|
|
392
|
+
readonly loc: HermesSourceLocation,
|
|
393
|
+
start?: number,
|
|
394
|
+
end?: number,
|
|
395
|
+
...
|
|
396
|
+
}): void {
|
|
397
|
+
if (owner.loc == null) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const position = this.extendedRanges.get(owner.loc);
|
|
401
|
+
if (position == null) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
owner.start = position.start;
|
|
405
|
+
owner.end = position.end;
|
|
406
|
+
}
|
|
407
|
+
|
|
294
408
|
/**
|
|
295
409
|
* Positions are serialized as a loc ID which denotes which loc it is
|
|
296
410
|
* associated with, followed by kind which denotes whether it is a start
|
|
@@ -305,6 +419,9 @@ export default class FlowParserDeserializer {
|
|
|
305
419
|
const offset = this.HEAPU32[this.positionBufferIdx++];
|
|
306
420
|
|
|
307
421
|
const loc = this.locMap[locId];
|
|
422
|
+
if (loc == null) {
|
|
423
|
+
throw new Error(`Missing serialized location ${locId}`);
|
|
424
|
+
}
|
|
308
425
|
if (kind === 0) {
|
|
309
426
|
loc.start = {
|
|
310
427
|
line,
|