[rust] Partial ES2015 support in estree codegen
Adds some parts of the ES2015 spec, such as imports and ForOfStatement. This is enough to get a few more fixtures compiling. The last one uses JSX which I haven't defined yet.
Joe Savona committed
Jul 8, 2023 at 22:59 UTC
750b1e6adb4b1525d5d77de5fa46c7a969a8a36f
8 files changed
+355
-37
compiler/forget/crates/estree-codegen/src/codegen.rs
+17
-10
@@ -168,6 +168,9 @@ pub struct Field {
168
169
#[serde(default)]
170
pub flatten: bool,
171
+
172
+ #[serde(default)]
173
+ pub rename: Option<String>,
174
}
175
176
impl Field {
@@ -193,11 +196,7 @@ impl Field {
196
"Can only set nullable_item if plural"
197
)
198
}
196
- if self.nullable || self.optional {
197
- assert_eq!(
198
- self.optional, false,
199
- "Expected field to be nullable if optional"
200
- );
199
+ if self.nullable {
200
type_ = quote!(Option<#type_>);
201
}
202
let mut field = quote!(#name: #type_);
@@ -207,6 +206,12 @@ impl Field {
206
#field
207
}
208
}
209
+ if let Some(rename) = &self.rename {
210
+ field = quote! {
211
+ #[serde(rename = #rename)]
212
+ #field
213
+ }
214
+ }
215
if self.flatten {
216
field = quote! {
217
#[serde(flatten)]
@@ -238,11 +243,7 @@ impl Field {
243
"Can only set nullable_item if plural"
244
)
245
}
241
- if self.nullable || self.optional {
242
- assert_eq!(
243
- self.nullable, true,
244
- "Expected field to be nullable if optional"
245
- );
246
+ if self.nullable {
247
type_ = quote!(Option<#type_>);
248
}
249
let mut field = quote!(#name: #type_);
@@ -258,6 +259,12 @@ impl Field {
259
#field
260
}
261
}
262
+ if let Some(rename) = &self.rename {
263
+ field = quote! {
264
+ #[serde(rename = #rename)]
265
+ #field
266
+ }
267
+ }
268
if nodes.contains(&self.type_) {
269
let comment = format!(" {}", &self.type_);
270
field = quote! {
compiler/forget/crates/estree-codegen/src/ecmascript.json
+140
-11
@@ -35,8 +35,18 @@
35
"plural": true
36
},
37
"body": {
38
- "type": "BlockStatement",
38
+ "type": "FunctionBody",
39
"nullable": true
40
+ },
41
+ "is_generator": {
42
+ "type": "bool",
43
+ "optional": true,
44
+ "rename": "generator"
45
+ },
46
+ "is_async": {
47
+ "type": "bool",
48
+ "optional": true,
49
+ "rename": "async"
50
}
51
}
52
},
@@ -85,8 +95,13 @@
95
"Program": {
96
"fields": {
97
"body": {
88
- "type": "Statement",
98
+ "type": "ModuleItem",
99
"plural": true
100
+ },
101
+ "source_type": {
102
+ "type": "SourceType",
103
+ "nullable": true,
104
+ "rename": "sourceType"
105
}
106
}
107
},
@@ -94,6 +109,11 @@
109
"fields": {
110
"expression": {
111
"type": "Expression"
112
+ },
113
+ "directive": {
114
+ "type": "String",
115
+ "nullable": true,
116
+ "optional": true
117
}
118
}
119
},
@@ -272,6 +292,19 @@
292
}
293
}
294
},
295
+ "ForOfStatement": {
296
+ "fields": {
297
+ "left": {
298
+ "type": "ForInInit"
299
+ },
300
+ "right": {
301
+ "type": "Expression"
302
+ },
303
+ "body": {
304
+ "type": "Statement"
305
+ }
306
+ }
307
+ },
308
"FunctionDeclaration": {
309
"fields": {
310
"function": {
@@ -306,7 +339,7 @@
339
"ArrayExpression": {
340
"fields": {
341
"elements": {
309
- "type": "Expression",
342
+ "type": "ExpressionOrSpread",
343
"plural": true,
344
"nullable_item": true
345
}
@@ -341,6 +374,18 @@
374
}
375
}
376
},
377
+ "ArrowFunctionExpression": {
378
+ "fields": {
379
+ "function": {
380
+ "type": "Function",
381
+ "flatten": true
382
+ },
383
+ "is_expression": {
384
+ "type": "bool",
385
+ "rename": "expression"
386
+ }
387
+ }
388
+ },
389
"UnaryExpression": {
390
"fields": {
391
"operator": {
@@ -409,7 +454,7 @@
454
"MemberExpression": {
455
"fields": {
456
"object": {
412
- "type": "Expression"
457
+ "type": "ExpressionOrSuper"
458
},
459
"property": {
460
"type": "Expression"
@@ -433,37 +478,90 @@
478
}
479
},
480
"CallExpression": {
436
- "type": true,
481
"fields": {
482
"callee": {
439
- "type": "Expression"
483
+ "type": "ExpressionOrSuper"
484
},
485
"arguments": {
442
- "type": "Expression",
486
+ "type": "ExpressionOrSpread",
487
"plural": true
488
}
489
}
490
},
491
"NewExpression": {
448
- "type": true,
492
"fields": {
493
"callee": {
494
"type": "Expression"
495
},
496
"arguments": {
454
- "type": "Expression",
497
+ "type": "ExpressionOrSpread",
498
"plural": true
499
}
500
}
501
},
502
"SequenceExpression": {
460
- "type": true,
503
"fields": {
504
"expressions": {
505
"type": "Expression",
506
"plural": true
507
}
508
}
509
+ },
510
+ "Super": {},
511
+ "SpreadElement": {
512
+ "fields": {
513
+ "argument": {
514
+ "type": "Expression"
515
+ }
516
+ }
517
+ },
518
+ "YieldExpression": {
519
+ "fields": {
520
+ "argument": {
521
+ "type": "Expression",
522
+ "nullable": true,
523
+ "optional": true
524
+ },
525
+ "is_delegate": {
526
+ "type": "bool",
527
+ "rename": "delegate"
528
+ }
529
+ }
530
+ },
531
+ "ImportDeclaration": {
532
+ "fields": {
533
+ "specifiers": {
534
+ "type": "ImportDeclarationSpecifier",
535
+ "plural": true
536
+ },
537
+ "source": {
538
+ "type": "Literal"
539
+ }
540
+ }
541
+ },
542
+ "ImportSpecifier": {
543
+ "fields": {
544
+ "imported": {
545
+ "type": "Identifier"
546
+ },
547
+ "local": {
548
+ "type": "Identifier"
549
+ }
550
+ }
551
+ },
552
+ "ImportDefaultSpecifier": {
553
+ "fields": {
554
+ "local": {
555
+ "type": "Identifier"
556
+ }
557
+ }
558
+ },
559
+ "ImportNamespaceSpecifier": {
560
+ "fields": {
561
+ "local": {
562
+ "type": "Identifier"
563
+ }
564
+ }
565
}
566
},
567
"enums": {
@@ -476,6 +574,7 @@
574
"EmptyStatement",
575
"ExpressionStatement",
576
"ForInStatement",
577
+ "ForOfStatement",
578
"ForStatement",
579
"FunctionDeclaration",
580
"IfStatement",
@@ -490,6 +589,7 @@
589
],
590
"Expression": [
591
"ArrayExpression",
592
+ "ArrowFunctionExpression",
593
"AssignmentExpression",
594
"BinaryExpression",
595
"CallExpression",
@@ -504,7 +604,32 @@
604
"SequenceExpression",
605
"ThisExpression",
606
"UnaryExpression",
507
- "UpdateExpression"
607
+ "UpdateExpression",
608
+ "YieldExpression"
609
+ ],
610
+ "ImportDeclarationSpecifier": [
611
+ "ImportSpecifier",
612
+ "ImportDefaultSpecifier",
613
+ "ImportNamespaceSpecifier"
614
+ ],
615
+ "ModuleItem": [
616
+ "ImportOrExportDeclaration",
617
+ "Statement"
618
+ ],
619
+ "ImportOrExportDeclaration": [
620
+ "ImportDeclaration"
621
+ ],
622
+ "ExpressionOrSuper": [
623
+ "Expression",
624
+ "Super"
625
+ ],
626
+ "ExpressionOrSpread": [
627
+ "Expression",
628
+ "SpreadElement"
629
+ ],
630
+ "FunctionBody": [
631
+ "BlockStatement",
632
+ "Expression"
633
],
634
"Pattern": [
635
"Identifier"
@@ -591,6 +716,10 @@
716
"And": "&&",
717
"NullCoalescing": "??",
718
"Or": "||"
719
+ },
720
+ "SourceType": {
721
+ "Script": "script",
722
+ "Module": "module"
723
}
724
}
725
}
\ No newline at end of file
compiler/forget/crates/estree/src/generated.rs
+176
-7
@@ -16,7 +16,13 @@ pub struct Position {
16
pub struct Function {
17
id: Option<Identifier>,
18
params: Vec<Pattern>,
19
- body: Option<BlockStatement>,
19
+ body: Option<FunctionBody>,
20
+ #[serde(rename = "generator")]
21
+ #[serde(default)]
22
+ is_generator: bool,
23
+ #[serde(rename = "async")]
24
+ #[serde(default)]
25
+ is_async: bool,
26
}
27
#[derive(Serialize, Deserialize, Clone, Debug)]
28
pub struct RegExpValue {
@@ -47,7 +53,9 @@ pub struct Literal {
53
}
54
#[derive(Serialize, Deserialize, Clone, Debug)]
55
pub struct Program {
50
- body: Vec<Statement>,
56
+ body: Vec<ModuleItem>,
57
+ #[serde(rename = "sourceType")]
58
+ source_type: Option<SourceType>,
59
#[serde(default)]
60
pub loc: Option<SourceLocation>,
61
#[serde(default)]
@@ -57,6 +65,8 @@ pub struct Program {
65
pub struct ExpressionStatement {
66
expression: Expression,
67
#[serde(default)]
68
+ directive: Option<String>,
69
+ #[serde(default)]
70
pub loc: Option<SourceLocation>,
71
#[serde(default)]
72
pub range: Option<SourceRange>,
@@ -220,6 +230,16 @@ pub struct ForInStatement {
230
pub range: Option<SourceRange>,
231
}
232
#[derive(Serialize, Deserialize, Clone, Debug)]
233
+pub struct ForOfStatement {
234
+ left: ForInInit,
235
+ right: Expression,
236
+ body: Statement,
237
+ #[serde(default)]
238
+ pub loc: Option<SourceLocation>,
239
+ #[serde(default)]
240
+ pub range: Option<SourceRange>,
241
+}
242
+#[derive(Serialize, Deserialize, Clone, Debug)]
243
pub struct FunctionDeclaration {
244
#[serde(flatten)]
245
function: Function,
@@ -255,7 +275,7 @@ pub struct ThisExpression {
275
}
276
#[derive(Serialize, Deserialize, Clone, Debug)]
277
pub struct ArrayExpression {
258
- elements: Vec<Option<Expression>>,
278
+ elements: Vec<Option<ExpressionOrSpread>>,
279
#[serde(default)]
280
pub loc: Option<SourceLocation>,
281
#[serde(default)]
@@ -289,6 +309,17 @@ pub struct FunctionExpression {
309
pub range: Option<SourceRange>,
310
}
311
#[derive(Serialize, Deserialize, Clone, Debug)]
312
+pub struct ArrowFunctionExpression {
313
+ #[serde(flatten)]
314
+ function: Function,
315
+ #[serde(rename = "expression")]
316
+ is_expression: bool,
317
+ #[serde(default)]
318
+ pub loc: Option<SourceLocation>,
319
+ #[serde(default)]
320
+ pub range: Option<SourceRange>,
321
+}
322
+#[derive(Serialize, Deserialize, Clone, Debug)]
323
pub struct UnaryExpression {
324
operator: UnaryOperator,
325
prefix: bool,
@@ -340,7 +371,7 @@ pub struct LogicalExpression {
371
}
372
#[derive(Serialize, Deserialize, Clone, Debug)]
373
pub struct MemberExpression {
343
- object: Expression,
374
+ object: ExpressionOrSuper,
375
property: Expression,
376
computed: bool,
377
#[serde(default)]
@@ -360,8 +391,8 @@ pub struct ConditionalExpression {
391
}
392
#[derive(Serialize, Deserialize, Clone, Debug)]
393
pub struct CallExpression {
363
- callee: Expression,
364
- arguments: Vec<Expression>,
394
+ callee: ExpressionOrSuper,
395
+ arguments: Vec<ExpressionOrSpread>,
396
#[serde(default)]
397
pub loc: Option<SourceLocation>,
398
#[serde(default)]
@@ -370,7 +401,7 @@ pub struct CallExpression {
401
#[derive(Serialize, Deserialize, Clone, Debug)]
402
pub struct NewExpression {
403
callee: Expression,
373
- arguments: Vec<Expression>,
404
+ arguments: Vec<ExpressionOrSpread>,
405
#[serde(default)]
406
pub loc: Option<SourceLocation>,
407
#[serde(default)]
@@ -385,6 +416,66 @@ pub struct SequenceExpression {
416
pub range: Option<SourceRange>,
417
}
418
#[derive(Serialize, Deserialize, Clone, Debug)]
419
+pub struct Super {
420
+ #[serde(default)]
421
+ pub loc: Option<SourceLocation>,
422
+ #[serde(default)]
423
+ pub range: Option<SourceRange>,
424
+}
425
+#[derive(Serialize, Deserialize, Clone, Debug)]
426
+pub struct SpreadElement {
427
+ argument: Expression,
428
+ #[serde(default)]
429
+ pub loc: Option<SourceLocation>,
430
+ #[serde(default)]
431
+ pub range: Option<SourceRange>,
432
+}
433
+#[derive(Serialize, Deserialize, Clone, Debug)]
434
+pub struct YieldExpression {
435
+ #[serde(default)]
436
+ argument: Option<Expression>,
437
+ #[serde(rename = "delegate")]
438
+ is_delegate: bool,
439
+ #[serde(default)]
440
+ pub loc: Option<SourceLocation>,
441
+ #[serde(default)]
442
+ pub range: Option<SourceRange>,
443
+}
444
+#[derive(Serialize, Deserialize, Clone, Debug)]
445
+pub struct ImportDeclaration {
446
+ specifiers: Vec<ImportDeclarationSpecifier>,
447
+ source: Literal,
448
+ #[serde(default)]
449
+ pub loc: Option<SourceLocation>,
450
+ #[serde(default)]
451
+ pub range: Option<SourceRange>,
452
+}
453
+#[derive(Serialize, Deserialize, Clone, Debug)]
454
+pub struct ImportSpecifier {
455
+ imported: Identifier,
456
+ local: Identifier,
457
+ #[serde(default)]
458
+ pub loc: Option<SourceLocation>,
459
+ #[serde(default)]
460
+ pub range: Option<SourceRange>,
461
+}
462
+#[derive(Serialize, Deserialize, Clone, Debug)]
463
+pub struct ImportDefaultSpecifier {
464
+ local: Identifier,
465
+ #[serde(default)]
466
+ pub loc: Option<SourceLocation>,
467
+ #[serde(default)]
468
+ pub range: Option<SourceRange>,
469
+}
470
+#[derive(Serialize, Deserialize, Clone, Debug)]
471
+pub struct ImportNamespaceSpecifier {
472
+ local: Identifier,
473
+ #[serde(default)]
474
+ pub loc: Option<SourceLocation>,
475
+ #[serde(default)]
476
+ pub range: Option<SourceRange>,
477
+}
478
+#[derive(Serialize, Deserialize, Clone, Debug)]
479
#[serde(tag = "type")]
480
pub enum Statement {
481
BlockStatement(Box<BlockStatement>),
@@ -395,6 +486,7 @@ pub enum Statement {
486
EmptyStatement(Box<EmptyStatement>),
487
ExpressionStatement(Box<ExpressionStatement>),
488
ForInStatement(Box<ForInStatement>),
489
+ ForOfStatement(Box<ForOfStatement>),
490
ForStatement(Box<ForStatement>),
491
FunctionDeclaration(Box<FunctionDeclaration>),
492
IfStatement(Box<IfStatement>),
@@ -411,6 +503,7 @@ pub enum Statement {
503
#[serde(tag = "type")]
504
pub enum Expression {
505
ArrayExpression(Box<ArrayExpression>),
506
+ ArrowFunctionExpression(Box<ArrowFunctionExpression>),
507
AssignmentExpression(Box<AssignmentExpression>),
508
BinaryExpression(Box<BinaryExpression>),
509
CallExpression(Box<CallExpression>),
@@ -426,6 +519,43 @@ pub enum Expression {
519
ThisExpression(Box<ThisExpression>),
520
UnaryExpression(Box<UnaryExpression>),
521
UpdateExpression(Box<UpdateExpression>),
522
+ YieldExpression(Box<YieldExpression>),
523
+}
524
+#[derive(Serialize, Deserialize, Clone, Debug)]
525
+#[serde(tag = "type")]
526
+pub enum ImportDeclarationSpecifier {
527
+ ImportDefaultSpecifier(Box<ImportDefaultSpecifier>),
528
+ ImportNamespaceSpecifier(Box<ImportNamespaceSpecifier>),
529
+ ImportSpecifier(Box<ImportSpecifier>),
530
+}
531
+#[derive(Serialize, Deserialize, Clone, Debug)]
532
+#[serde(untagged)]
533
+pub enum ModuleItem {
534
+ ImportOrExportDeclaration(ImportOrExportDeclaration),
535
+ Statement(Statement),
536
+}
537
+#[derive(Serialize, Deserialize, Clone, Debug)]
538
+#[serde(tag = "type")]
539
+pub enum ImportOrExportDeclaration {
540
+ ImportDeclaration(Box<ImportDeclaration>),
541
+}
542
+#[derive(Serialize, Deserialize, Clone, Debug)]
543
+#[serde(untagged)]
544
+pub enum ExpressionOrSuper {
545
+ Expression(Expression),
546
+ Super(Box<Super>),
547
+}
548
+#[derive(Serialize, Deserialize, Clone, Debug)]
549
+#[serde(untagged)]
550
+pub enum ExpressionOrSpread {
551
+ Expression(Expression),
552
+ SpreadElement(Box<SpreadElement>),
553
+}
554
+#[derive(Serialize, Deserialize, Clone, Debug)]
555
+#[serde(untagged)]
556
+pub enum FunctionBody {
557
+ BlockStatement(Box<BlockStatement>),
558
+ Expression(Expression),
559
}
560
#[derive(Serialize, Deserialize, Clone, Debug)]
561
#[serde(tag = "type")]
@@ -914,3 +1044,42 @@ impl std::str::FromStr for LogicalOperator {
1044
}
1045
}
1046
}
1047
+#[derive(
1048
+ Serialize,
1049
+ Deserialize,
1050
+ Clone,
1051
+ Copy,
1052
+ Eq,
1053
+ PartialEq,
1054
+ Ord,
1055
+ PartialOrd,
1056
+ Hash,
1057
+ Debug
1058
+)]
1059
+pub enum SourceType {
1060
+ /// module
1061
+ #[serde(rename = "module")]
1062
+ Module,
1063
+ /// script
1064
+ #[serde(rename = "script")]
1065
+ Script,
1066
+}
1067
+impl std::fmt::Display for SourceType {
1068
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1069
+ let name = match self {
1070
+ Self::Module => "module",
1071
+ Self::Script => "script",
1072
+ };
1073
+ f.write_str(name)
1074
+ }
1075
+}
1076
+impl std::str::FromStr for SourceType {
1077
+ type Err = ();
1078
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
1079
+ match s {
1080
+ "module" => Ok(Self::Module),
1081
+ "script" => Ok(Self::Script),
1082
+ _ => Err(()),
1083
+ }
1084
+ }
1085
+}
compiler/forget/crates/estree/src/generated_extensions.rs
new
+8
@@ -0,0 +1,8 @@
1
+// Manual extensions to generated types
2
+use crate::SourceType;
3
+
4
+impl Default for SourceType {
5
+ fn default() -> Self {
6
+ Self::Script
7
+ }
8
+}
compiler/forget/crates/estree/src/lib.rs
+1
@@ -1,5 +1,6 @@
1
mod binding;
2
mod generated;
3
+mod generated_extensions;
4
mod js_value;
5
mod range;
6
compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@for-statement.json.snap
+4
@@ -910,6 +910,7 @@ Output:
910
"end": 84
911
}
912
},
913
+ "directive": null,
914
"loc": {
915
"source": null,
916
"start": {
@@ -1014,6 +1015,8 @@ Output:
1015
"end": 103
1016
}
1017
},
1018
+ "generator": false,
1019
+ "async": false,
1020
"loc": {
1021
"source": null,
1022
"start": {
@@ -1031,6 +1034,7 @@ Output:
1034
}
1035
}
1036
],
1037
+ "sourceType": "script",
1038
"loc": {
1039
"source": null,
1040
"start": {
compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@import.json.snap
+6
-3
@@ -111,9 +111,9 @@ Input:
111
112
Output:
113
{
114
- "sourceType": "module",
114
"body": [
115
{
116
+ "type": "ImportDeclaration",
117
"specifiers": [
118
{
119
"type": "ImportDefaultSpecifier",
@@ -154,8 +154,11 @@ Output:
154
}
155
],
156
"source": {
157
- "value": "react",
157
+ "value": {
158
+ "String": "react"
159
+ },
160
"raw": "'react'",
161
+ "regex": null,
162
"loc": {
163
"source": null,
164
"start": {
@@ -189,7 +192,7 @@ Output:
192
}
193
}
194
],
192
- "comments": [],
195
+ "sourceType": "module",
196
"loc": {
197
"source": null,
198
"start": {
compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@simple.json.snap
+3
-6
@@ -196,7 +196,6 @@ Input:
196
197
Output:
198
{
199
- "sourceType": "module",
199
"body": [
200
{
201
"type": "FunctionDeclaration",
@@ -241,10 +240,7 @@ Output:
240
}
241
}
242
],
244
- "generator": false,
245
- "async": false,
243
"body": {
247
- "type": "BlockStatement",
244
"body": [
245
{
246
"type": "ReturnStatement",
@@ -291,7 +287,6 @@ Output:
287
}
288
},
289
"computed": false,
294
- "optional": false,
290
"loc": {
291
"source": null,
292
"start": {
@@ -341,6 +336,8 @@ Output:
336
"end": 51
337
}
338
},
339
+ "generator": false,
340
+ "async": false,
341
"loc": {
342
"source": null,
343
"start": {
@@ -358,7 +355,7 @@ Output:
355
}
356
}
357
],
361
- "comments": [],
358
+ "sourceType": null,
359
"loc": {
360
"source": null,
361
"start": {