[rust] Codegen AST visitor
Updates `estree` codegen to emit a Visitor trait (temporarily named `Visitor2` since there is a hand-rolled one that some code is using). We use knowledge of the grammar to only visit fields whose type is a Node or Enum, or an "object" type that opts into being visitable. The latter is used for Function and Class. This will make it much easier to write the semantic analyzer.
Joe Savona committed
Aug 3, 2023 at 17:00 UTC
c6ae535e9497c86eb638c0658fb9c8c88ec32b45
3 files changed
+1153
-16
compiler/forget/crates/forget_estree/src/generated.rs
+950
@@ -8114,3 +8114,953 @@ impl std::str::FromStr for MethodKind {
8114
}
8115
}
8116
}
8117
+pub trait Visitor2 {
8118
+ fn visit_class(&mut self, ast: &Class) {
8119
+ if let Some(id) = &ast.id {
8120
+ self.visit_identifier(id);
8121
+ }
8122
+ if let Some(super_class) = &ast.super_class {
8123
+ self.visit_expression(super_class);
8124
+ }
8125
+ self.visit_class_body(&ast.body);
8126
+ }
8127
+ fn visit_function(&mut self, ast: &Function) {
8128
+ if let Some(id) = &ast.id {
8129
+ self.visit_identifier(id);
8130
+ }
8131
+ for params in &ast.params {
8132
+ self.visit_pattern(params);
8133
+ }
8134
+ if let Some(body) = &ast.body {
8135
+ self.visit_function_body(body);
8136
+ }
8137
+ }
8138
+ fn visit_identifier(&mut self, ast: &Identifier) {
8139
+ if let Some(type_annotation) = &ast.type_annotation {
8140
+ self.visit_type_annotation(type_annotation);
8141
+ }
8142
+ }
8143
+ fn visit_literal(&mut self, ast: &Literal) {}
8144
+ fn visit_numeric_literal(&mut self, ast: &NumericLiteral) {}
8145
+ fn visit_boolean_literal(&mut self, ast: &BooleanLiteral) {}
8146
+ fn visit_null_literal(&mut self, ast: &NullLiteral) {}
8147
+ fn visit_string_literal(&mut self, ast: &StringLiteral) {}
8148
+ fn visit_reg_exp_literal(&mut self, ast: &RegExpLiteral) {}
8149
+ fn visit_program(&mut self, ast: &Program) {
8150
+ for body in &ast.body {
8151
+ self.visit_module_item(body);
8152
+ }
8153
+ }
8154
+ fn visit_expression_statement(&mut self, ast: &ExpressionStatement) {
8155
+ self.visit_expression(&ast.expression);
8156
+ }
8157
+ fn visit_block_statement(&mut self, ast: &BlockStatement) {
8158
+ for body in &ast.body {
8159
+ self.visit_statement(body);
8160
+ }
8161
+ }
8162
+ fn visit_empty_statement(&mut self, ast: &EmptyStatement) {}
8163
+ fn visit_debugger_statement(&mut self, ast: &DebuggerStatement) {}
8164
+ fn visit_with_statement(&mut self, ast: &WithStatement) {
8165
+ self.visit_expression(&ast.object);
8166
+ self.visit_statement(&ast.body);
8167
+ }
8168
+ fn visit_return_statement(&mut self, ast: &ReturnStatement) {
8169
+ if let Some(argument) = &ast.argument {
8170
+ self.visit_expression(argument);
8171
+ }
8172
+ }
8173
+ fn visit_labeled_statement(&mut self, ast: &LabeledStatement) {
8174
+ self.visit_identifier(&ast.label);
8175
+ self.visit_statement(&ast.body);
8176
+ }
8177
+ fn visit_break_statement(&mut self, ast: &BreakStatement) {
8178
+ if let Some(label) = &ast.label {
8179
+ self.visit_identifier(label);
8180
+ }
8181
+ }
8182
+ fn visit_continue_statement(&mut self, ast: &ContinueStatement) {
8183
+ if let Some(label) = &ast.label {
8184
+ self.visit_identifier(label);
8185
+ }
8186
+ }
8187
+ fn visit_if_statement(&mut self, ast: &IfStatement) {
8188
+ self.visit_expression(&ast.test);
8189
+ self.visit_statement(&ast.consequent);
8190
+ if let Some(alternate) = &ast.alternate {
8191
+ self.visit_statement(alternate);
8192
+ }
8193
+ }
8194
+ fn visit_switch_statement(&mut self, ast: &SwitchStatement) {
8195
+ self.visit_expression(&ast.discriminant);
8196
+ for cases in &ast.cases {
8197
+ self.visit_switch_case(cases);
8198
+ }
8199
+ }
8200
+ fn visit_switch_case(&mut self, ast: &SwitchCase) {
8201
+ if let Some(test) = &ast.test {
8202
+ self.visit_expression(test);
8203
+ }
8204
+ for consequent in &ast.consequent {
8205
+ self.visit_statement(consequent);
8206
+ }
8207
+ }
8208
+ fn visit_throw_statement(&mut self, ast: &ThrowStatement) {
8209
+ self.visit_expression(&ast.argument);
8210
+ }
8211
+ fn visit_try_statement(&mut self, ast: &TryStatement) {
8212
+ self.visit_block_statement(&ast.block);
8213
+ if let Some(handler) = &ast.handler {
8214
+ self.visit_catch_clause(handler);
8215
+ }
8216
+ if let Some(finalizer) = &ast.finalizer {
8217
+ self.visit_block_statement(finalizer);
8218
+ }
8219
+ }
8220
+ fn visit_catch_clause(&mut self, ast: &CatchClause) {
8221
+ if let Some(param) = &ast.param {
8222
+ self.visit_pattern(param);
8223
+ }
8224
+ self.visit_block_statement(&ast.body);
8225
+ }
8226
+ fn visit_while_statement(&mut self, ast: &WhileStatement) {
8227
+ self.visit_expression(&ast.test);
8228
+ self.visit_statement(&ast.body);
8229
+ }
8230
+ fn visit_do_while_statement(&mut self, ast: &DoWhileStatement) {
8231
+ self.visit_statement(&ast.body);
8232
+ self.visit_expression(&ast.test);
8233
+ }
8234
+ fn visit_for_statement(&mut self, ast: &ForStatement) {
8235
+ if let Some(init) = &ast.init {
8236
+ self.visit_for_init(init);
8237
+ }
8238
+ if let Some(test) = &ast.test {
8239
+ self.visit_expression(test);
8240
+ }
8241
+ if let Some(update) = &ast.update {
8242
+ self.visit_expression(update);
8243
+ }
8244
+ self.visit_statement(&ast.body);
8245
+ }
8246
+ fn visit_for_in_statement(&mut self, ast: &ForInStatement) {
8247
+ self.visit_for_in_init(&ast.left);
8248
+ self.visit_expression(&ast.right);
8249
+ self.visit_statement(&ast.body);
8250
+ }
8251
+ fn visit_for_of_statement(&mut self, ast: &ForOfStatement) {
8252
+ self.visit_for_in_init(&ast.left);
8253
+ self.visit_expression(&ast.right);
8254
+ self.visit_statement(&ast.body);
8255
+ }
8256
+ fn visit_function_declaration(&mut self, ast: &FunctionDeclaration) {
8257
+ self.visit_function(&ast.function);
8258
+ }
8259
+ fn visit_class_declaration(&mut self, ast: &ClassDeclaration) {
8260
+ self.visit_class(&ast.class);
8261
+ }
8262
+ fn visit_class_expression(&mut self, ast: &ClassExpression) {
8263
+ self.visit_class(&ast.class);
8264
+ }
8265
+ fn visit_class_body(&mut self, ast: &ClassBody) {
8266
+ for body in &ast.body {
8267
+ self.visit_class_item(body);
8268
+ }
8269
+ }
8270
+ fn visit_method_definition(&mut self, ast: &MethodDefinition) {
8271
+ self.visit_expression(&ast.key);
8272
+ self.visit_function_expression(&ast.value);
8273
+ }
8274
+ fn visit_variable_declaration(&mut self, ast: &VariableDeclaration) {
8275
+ for declarations in &ast.declarations {
8276
+ self.visit_variable_declarator(declarations);
8277
+ }
8278
+ }
8279
+ fn visit_variable_declarator(&mut self, ast: &VariableDeclarator) {
8280
+ self.visit_pattern(&ast.id);
8281
+ if let Some(init) = &ast.init {
8282
+ self.visit_expression(init);
8283
+ }
8284
+ }
8285
+ fn visit_this_expression(&mut self, ast: &ThisExpression) {}
8286
+ fn visit_array_expression(&mut self, ast: &ArrayExpression) {
8287
+ for elements in &ast.elements {
8288
+ if let Some(elements) = elements {
8289
+ self.visit_expression_or_spread(elements);
8290
+ }
8291
+ }
8292
+ }
8293
+ fn visit_object_expression(&mut self, ast: &ObjectExpression) {
8294
+ for properties in &ast.properties {
8295
+ self.visit_property_or_spread_element(properties);
8296
+ }
8297
+ }
8298
+ fn visit_property(&mut self, ast: &Property) {
8299
+ self.visit_expression(&ast.key);
8300
+ self.visit_expression(&ast.value);
8301
+ }
8302
+ fn visit_function_expression(&mut self, ast: &FunctionExpression) {
8303
+ self.visit_function(&ast.function);
8304
+ }
8305
+ fn visit_arrow_function_expression(&mut self, ast: &ArrowFunctionExpression) {
8306
+ self.visit_function(&ast.function);
8307
+ }
8308
+ fn visit_unary_expression(&mut self, ast: &UnaryExpression) {
8309
+ self.visit_expression(&ast.argument);
8310
+ }
8311
+ fn visit_update_expression(&mut self, ast: &UpdateExpression) {
8312
+ self.visit_expression(&ast.argument);
8313
+ }
8314
+ fn visit_binary_expression(&mut self, ast: &BinaryExpression) {
8315
+ self.visit_expression(&ast.left);
8316
+ self.visit_expression(&ast.right);
8317
+ }
8318
+ fn visit_assignment_expression(&mut self, ast: &AssignmentExpression) {
8319
+ self.visit_assignment_target(&ast.left);
8320
+ self.visit_expression(&ast.right);
8321
+ }
8322
+ fn visit_logical_expression(&mut self, ast: &LogicalExpression) {
8323
+ self.visit_expression(&ast.left);
8324
+ self.visit_expression(&ast.right);
8325
+ }
8326
+ fn visit_member_expression(&mut self, ast: &MemberExpression) {
8327
+ self.visit_expression_or_super(&ast.object);
8328
+ self.visit_expression_or_private_identifier(&ast.property);
8329
+ }
8330
+ fn visit_conditional_expression(&mut self, ast: &ConditionalExpression) {
8331
+ self.visit_expression(&ast.test);
8332
+ self.visit_expression(&ast.alternate);
8333
+ self.visit_expression(&ast.consequent);
8334
+ }
8335
+ fn visit_call_expression(&mut self, ast: &CallExpression) {
8336
+ self.visit_expression_or_super(&ast.callee);
8337
+ for arguments in &ast.arguments {
8338
+ self.visit_expression_or_spread(arguments);
8339
+ }
8340
+ }
8341
+ fn visit_new_expression(&mut self, ast: &NewExpression) {
8342
+ self.visit_expression(&ast.callee);
8343
+ for arguments in &ast.arguments {
8344
+ self.visit_expression_or_spread(arguments);
8345
+ }
8346
+ }
8347
+ fn visit_sequence_expression(&mut self, ast: &SequenceExpression) {
8348
+ for expressions in &ast.expressions {
8349
+ self.visit_expression(expressions);
8350
+ }
8351
+ }
8352
+ fn visit_super(&mut self, ast: &Super) {}
8353
+ fn visit_spread_element(&mut self, ast: &SpreadElement) {
8354
+ self.visit_expression(&ast.argument);
8355
+ }
8356
+ fn visit_yield_expression(&mut self, ast: &YieldExpression) {
8357
+ if let Some(argument) = &ast.argument {
8358
+ self.visit_expression(argument);
8359
+ }
8360
+ }
8361
+ fn visit_import_declaration(&mut self, ast: &ImportDeclaration) {
8362
+ for specifiers in &ast.specifiers {
8363
+ self.visit_import_declaration_specifier(specifiers);
8364
+ }
8365
+ self.visit___literal(&ast.source);
8366
+ }
8367
+ fn visit_import_specifier(&mut self, ast: &ImportSpecifier) {
8368
+ self.visit_identifier(&ast.imported);
8369
+ self.visit_identifier(&ast.local);
8370
+ }
8371
+ fn visit_import_default_specifier(&mut self, ast: &ImportDefaultSpecifier) {
8372
+ self.visit_identifier(&ast.local);
8373
+ }
8374
+ fn visit_import_namespace_specifier(&mut self, ast: &ImportNamespaceSpecifier) {
8375
+ self.visit_identifier(&ast.local);
8376
+ }
8377
+ fn visit_export_named_declaration(&mut self, ast: &ExportNamedDeclaration) {
8378
+ if let Some(declaration) = &ast.declaration {
8379
+ self.visit_declaration(declaration);
8380
+ }
8381
+ for specifiers in &ast.specifiers {
8382
+ self.visit_export_specifier(specifiers);
8383
+ }
8384
+ if let Some(source) = &ast.source {
8385
+ self.visit___literal(source);
8386
+ }
8387
+ }
8388
+ fn visit_export_specifier(&mut self, ast: &ExportSpecifier) {
8389
+ self.visit_identifier(&ast.exported);
8390
+ }
8391
+ fn visit_export_default_declaration(&mut self, ast: &ExportDefaultDeclaration) {
8392
+ self.visit_declaration_or_expression(&ast.declaration);
8393
+ }
8394
+ fn visit_export_all_declaration(&mut self, ast: &ExportAllDeclaration) {
8395
+ self.visit___literal(&ast.source);
8396
+ if let Some(exported) = &ast.exported {
8397
+ self.visit_identifier(exported);
8398
+ }
8399
+ }
8400
+ fn visit_jsxidentifier(&mut self, ast: &JSXIdentifier) {}
8401
+ fn visit_jsxnamespaced_name(&mut self, ast: &JSXNamespacedName) {
8402
+ self.visit_jsxidentifier(&ast.namespace);
8403
+ self.visit_jsxidentifier(&ast.name);
8404
+ }
8405
+ fn visit_jsxmember_expression(&mut self, ast: &JSXMemberExpression) {
8406
+ self.visit_jsxmember_expression_or_identifier(&ast.object);
8407
+ self.visit_jsxidentifier(&ast.property);
8408
+ }
8409
+ fn visit_jsxempty_expression(&mut self, ast: &JSXEmptyExpression) {}
8410
+ fn visit_jsxexpression_container(&mut self, ast: &JSXExpressionContainer) {
8411
+ self.visit_jsxexpression_or_empty(&ast.expression);
8412
+ }
8413
+ fn visit_jsxspread_child(&mut self, ast: &JSXSpreadChild) {
8414
+ self.visit_expression(&ast.expression);
8415
+ }
8416
+ fn visit_jsxopening_element(&mut self, ast: &JSXOpeningElement) {
8417
+ self.visit_jsxelement_name(&ast.name);
8418
+ for attributes in &ast.attributes {
8419
+ self.visit_jsxattribute_or_spread(attributes);
8420
+ }
8421
+ }
8422
+ fn visit_jsxclosing_element(&mut self, ast: &JSXClosingElement) {
8423
+ self.visit_jsxelement_name(&ast.name);
8424
+ }
8425
+ fn visit_jsxattribute(&mut self, ast: &JSXAttribute) {
8426
+ self.visit_jsxidentifier_or_namespaced_name(&ast.name);
8427
+ if let Some(value) = &ast.value {
8428
+ self.visit_jsxattribute_value(value);
8429
+ }
8430
+ }
8431
+ fn visit_jsxspread_attribute(&mut self, ast: &JSXSpreadAttribute) {
8432
+ self.visit_expression(&ast.argument);
8433
+ }
8434
+ fn visit_jsxtext(&mut self, ast: &JSXText) {}
8435
+ fn visit_jsxstring_literal(&mut self, ast: &JSXStringLiteral) {}
8436
+ fn visit_jsxelement(&mut self, ast: &JSXElement) {
8437
+ self.visit_jsxopening_element(&ast.opening_element);
8438
+ for children in &ast.children {
8439
+ self.visit_jsxchild_item(children);
8440
+ }
8441
+ if let Some(closing_element) = &ast.closing_element {
8442
+ self.visit_jsxclosing_element(closing_element);
8443
+ }
8444
+ }
8445
+ fn visit_jsxfragment(&mut self, ast: &JSXFragment) {
8446
+ self.visit_jsxopening_fragment(&ast.opening_fragment);
8447
+ for children in &ast.children {
8448
+ self.visit_jsxchild_item(children);
8449
+ }
8450
+ self.visit_jsxclosing_fragment(&ast.closing_fragment);
8451
+ }
8452
+ fn visit_jsxopening_fragment(&mut self, ast: &JSXOpeningFragment) {}
8453
+ fn visit_jsxclosing_fragment(&mut self, ast: &JSXClosingFragment) {}
8454
+ fn visit_array_pattern(&mut self, ast: &ArrayPattern) {
8455
+ for elements in &ast.elements {
8456
+ if let Some(elements) = elements {
8457
+ self.visit_pattern(elements);
8458
+ }
8459
+ }
8460
+ }
8461
+ fn visit_object_pattern(&mut self, ast: &ObjectPattern) {
8462
+ for properties in &ast.properties {
8463
+ self.visit_assignment_property_or_rest_element(properties);
8464
+ }
8465
+ }
8466
+ fn visit_assignment_property(&mut self, ast: &AssignmentProperty) {
8467
+ self.visit_property_key(&ast.key);
8468
+ self.visit_pattern(&ast.value);
8469
+ }
8470
+ fn visit_rest_element(&mut self, ast: &RestElement) {
8471
+ self.visit_pattern(&ast.argument);
8472
+ }
8473
+ fn visit_assignment_pattern(&mut self, ast: &AssignmentPattern) {
8474
+ self.visit_pattern(&ast.left);
8475
+ self.visit_expression(&ast.right);
8476
+ }
8477
+ fn visit_template_literal(&mut self, ast: &TemplateLiteral) {
8478
+ for quasis in &ast.quasis {
8479
+ self.visit_template_element(quasis);
8480
+ }
8481
+ for expressions in &ast.expressions {
8482
+ self.visit_expression(expressions);
8483
+ }
8484
+ }
8485
+ fn visit_template_element(&mut self, ast: &TemplateElement) {}
8486
+ fn visit_tagged_template_expression(&mut self, ast: &TaggedTemplateExpression) {
8487
+ self.visit_expression(&ast.tag);
8488
+ self.visit_template_literal(&ast.quasi);
8489
+ }
8490
+ fn visit_meta_property(&mut self, ast: &MetaProperty) {
8491
+ self.visit_identifier(&ast.meta);
8492
+ self.visit_identifier(&ast.property);
8493
+ }
8494
+ fn visit_await_expression(&mut self, ast: &AwaitExpression) {
8495
+ self.visit_expression(&ast.argument);
8496
+ }
8497
+ fn visit_chain_expression(&mut self, ast: &ChainExpression) {
8498
+ self.visit_chain_element(&ast.expression);
8499
+ }
8500
+ fn visit_optional_member_expression(&mut self, ast: &OptionalMemberExpression) {
8501
+ self.visit_expression(&ast.object);
8502
+ self.visit_expression(&ast.property);
8503
+ }
8504
+ fn visit_optional_call_expression(&mut self, ast: &OptionalCallExpression) {
8505
+ self.visit_expression_or_super(&ast.callee);
8506
+ for arguments in &ast.arguments {
8507
+ self.visit_expression_or_spread(arguments);
8508
+ }
8509
+ }
8510
+ fn visit_import_expression(&mut self, ast: &ImportExpression) {
8511
+ self.visit_expression(&ast.source);
8512
+ }
8513
+ fn visit_class_property(&mut self, ast: &ClassProperty) {
8514
+ self.visit_expression(&ast.key);
8515
+ if let Some(value) = &ast.value {
8516
+ self.visit_expression(value);
8517
+ }
8518
+ }
8519
+ fn visit_class_private_property(&mut self, ast: &ClassPrivateProperty) {
8520
+ self.visit_expression_or_private_identifier(&ast.key);
8521
+ if let Some(value) = &ast.value {
8522
+ self.visit_expression(value);
8523
+ }
8524
+ }
8525
+ fn visit_private_name(&mut self, ast: &PrivateName) {
8526
+ self.visit_identifier(&ast.id);
8527
+ }
8528
+ fn visit_private_identifier(&mut self, ast: &PrivateIdentifier) {}
8529
+ fn visit_static_block(&mut self, ast: &StaticBlock) {
8530
+ for body in &ast.body {
8531
+ self.visit_statement(body);
8532
+ }
8533
+ }
8534
+ fn visit_cover_typed_identifier(&mut self, ast: &CoverTypedIdentifier) {
8535
+ self.visit_identifier(&ast.left);
8536
+ if let Some(right) = &ast.right {
8537
+ self.visit_type_annotation(right);
8538
+ }
8539
+ }
8540
+ fn visit_tstype_annotation(&mut self, ast: &TSTypeAnnotation) {}
8541
+ fn visit_tstype_alias_declaration(&mut self, ast: &TSTypeAliasDeclaration) {}
8542
+ fn visit_statement(&mut self, ast: &Statement) {
8543
+ match ast {
8544
+ Statement::BlockStatement(ast) => {
8545
+ self.visit_block_statement(ast);
8546
+ }
8547
+ Statement::BreakStatement(ast) => {
8548
+ self.visit_break_statement(ast);
8549
+ }
8550
+ Statement::ClassDeclaration(ast) => {
8551
+ self.visit_class_declaration(ast);
8552
+ }
8553
+ Statement::ContinueStatement(ast) => {
8554
+ self.visit_continue_statement(ast);
8555
+ }
8556
+ Statement::DebuggerStatement(ast) => {
8557
+ self.visit_debugger_statement(ast);
8558
+ }
8559
+ Statement::DoWhileStatement(ast) => {
8560
+ self.visit_do_while_statement(ast);
8561
+ }
8562
+ Statement::EmptyStatement(ast) => {
8563
+ self.visit_empty_statement(ast);
8564
+ }
8565
+ Statement::ExpressionStatement(ast) => {
8566
+ self.visit_expression_statement(ast);
8567
+ }
8568
+ Statement::ForInStatement(ast) => {
8569
+ self.visit_for_in_statement(ast);
8570
+ }
8571
+ Statement::ForOfStatement(ast) => {
8572
+ self.visit_for_of_statement(ast);
8573
+ }
8574
+ Statement::ForStatement(ast) => {
8575
+ self.visit_for_statement(ast);
8576
+ }
8577
+ Statement::FunctionDeclaration(ast) => {
8578
+ self.visit_function_declaration(ast);
8579
+ }
8580
+ Statement::IfStatement(ast) => {
8581
+ self.visit_if_statement(ast);
8582
+ }
8583
+ Statement::LabeledStatement(ast) => {
8584
+ self.visit_labeled_statement(ast);
8585
+ }
8586
+ Statement::ReturnStatement(ast) => {
8587
+ self.visit_return_statement(ast);
8588
+ }
8589
+ Statement::SwitchStatement(ast) => {
8590
+ self.visit_switch_statement(ast);
8591
+ }
8592
+ Statement::ThrowStatement(ast) => {
8593
+ self.visit_throw_statement(ast);
8594
+ }
8595
+ Statement::TryStatement(ast) => {
8596
+ self.visit_try_statement(ast);
8597
+ }
8598
+ Statement::TSTypeAliasDeclaration(ast) => {
8599
+ self.visit_tstype_alias_declaration(ast);
8600
+ }
8601
+ Statement::VariableDeclaration(ast) => {
8602
+ self.visit_variable_declaration(ast);
8603
+ }
8604
+ Statement::WhileStatement(ast) => {
8605
+ self.visit_while_statement(ast);
8606
+ }
8607
+ Statement::WithStatement(ast) => {
8608
+ self.visit_with_statement(ast);
8609
+ }
8610
+ }
8611
+ }
8612
+ fn visit_expression(&mut self, ast: &Expression) {
8613
+ match ast {
8614
+ Expression::ArrayExpression(ast) => {
8615
+ self.visit_array_expression(ast);
8616
+ }
8617
+ Expression::ArrowFunctionExpression(ast) => {
8618
+ self.visit_arrow_function_expression(ast);
8619
+ }
8620
+ Expression::AssignmentExpression(ast) => {
8621
+ self.visit_assignment_expression(ast);
8622
+ }
8623
+ Expression::AwaitExpression(ast) => {
8624
+ self.visit_await_expression(ast);
8625
+ }
8626
+ Expression::BinaryExpression(ast) => {
8627
+ self.visit_binary_expression(ast);
8628
+ }
8629
+ Expression::BooleanLiteral(ast) => {
8630
+ self.visit_boolean_literal(ast);
8631
+ }
8632
+ Expression::CallExpression(ast) => {
8633
+ self.visit_call_expression(ast);
8634
+ }
8635
+ Expression::ChainExpression(ast) => {
8636
+ self.visit_chain_expression(ast);
8637
+ }
8638
+ Expression::ClassExpression(ast) => {
8639
+ self.visit_class_expression(ast);
8640
+ }
8641
+ Expression::ConditionalExpression(ast) => {
8642
+ self.visit_conditional_expression(ast);
8643
+ }
8644
+ Expression::CoverTypedIdentifier(ast) => {
8645
+ self.visit_cover_typed_identifier(ast);
8646
+ }
8647
+ Expression::FunctionExpression(ast) => {
8648
+ self.visit_function_expression(ast);
8649
+ }
8650
+ Expression::Identifier(ast) => {
8651
+ self.visit_identifier(ast);
8652
+ }
8653
+ Expression::ImportExpression(ast) => {
8654
+ self.visit_import_expression(ast);
8655
+ }
8656
+ Expression::JSXElement(ast) => {
8657
+ self.visit_jsxelement(ast);
8658
+ }
8659
+ Expression::JSXFragment(ast) => {
8660
+ self.visit_jsxfragment(ast);
8661
+ }
8662
+ Expression::Literal(ast) => {
8663
+ self.visit_literal(ast);
8664
+ }
8665
+ Expression::LogicalExpression(ast) => {
8666
+ self.visit_logical_expression(ast);
8667
+ }
8668
+ Expression::MemberExpression(ast) => {
8669
+ self.visit_member_expression(ast);
8670
+ }
8671
+ Expression::MetaProperty(ast) => {
8672
+ self.visit_meta_property(ast);
8673
+ }
8674
+ Expression::NewExpression(ast) => {
8675
+ self.visit_new_expression(ast);
8676
+ }
8677
+ Expression::NullLiteral(ast) => {
8678
+ self.visit_null_literal(ast);
8679
+ }
8680
+ Expression::NumericLiteral(ast) => {
8681
+ self.visit_numeric_literal(ast);
8682
+ }
8683
+ Expression::ObjectExpression(ast) => {
8684
+ self.visit_object_expression(ast);
8685
+ }
8686
+ Expression::OptionalCallExpression(ast) => {
8687
+ self.visit_optional_call_expression(ast);
8688
+ }
8689
+ Expression::OptionalMemberExpression(ast) => {
8690
+ self.visit_optional_member_expression(ast);
8691
+ }
8692
+ Expression::RegExpLiteral(ast) => {
8693
+ self.visit_reg_exp_literal(ast);
8694
+ }
8695
+ Expression::SequenceExpression(ast) => {
8696
+ self.visit_sequence_expression(ast);
8697
+ }
8698
+ Expression::StringLiteral(ast) => {
8699
+ self.visit_string_literal(ast);
8700
+ }
8701
+ Expression::TaggedTemplateExpression(ast) => {
8702
+ self.visit_tagged_template_expression(ast);
8703
+ }
8704
+ Expression::TemplateLiteral(ast) => {
8705
+ self.visit_template_literal(ast);
8706
+ }
8707
+ Expression::ThisExpression(ast) => {
8708
+ self.visit_this_expression(ast);
8709
+ }
8710
+ Expression::UnaryExpression(ast) => {
8711
+ self.visit_unary_expression(ast);
8712
+ }
8713
+ Expression::UpdateExpression(ast) => {
8714
+ self.visit_update_expression(ast);
8715
+ }
8716
+ Expression::YieldExpression(ast) => {
8717
+ self.visit_yield_expression(ast);
8718
+ }
8719
+ }
8720
+ }
8721
+ fn visit___literal(&mut self, ast: &_Literal) {
8722
+ match ast {
8723
+ _Literal::Literal(ast) => {
8724
+ self.visit_literal(ast);
8725
+ }
8726
+ _Literal::BooleanLiteral(ast) => {
8727
+ self.visit_boolean_literal(ast);
8728
+ }
8729
+ _Literal::NullLiteral(ast) => {
8730
+ self.visit_null_literal(ast);
8731
+ }
8732
+ _Literal::StringLiteral(ast) => {
8733
+ self.visit_string_literal(ast);
8734
+ }
8735
+ _Literal::NumericLiteral(ast) => {
8736
+ self.visit_numeric_literal(ast);
8737
+ }
8738
+ }
8739
+ }
8740
+ fn visit_declaration(&mut self, ast: &Declaration) {
8741
+ match ast {
8742
+ Declaration::ClassDeclaration(ast) => {
8743
+ self.visit_class_declaration(ast);
8744
+ }
8745
+ Declaration::FunctionDeclaration(ast) => {
8746
+ self.visit_function_declaration(ast);
8747
+ }
8748
+ Declaration::VariableDeclaration(ast) => {
8749
+ self.visit_variable_declaration(ast);
8750
+ }
8751
+ Declaration::TSTypeAliasDeclaration(ast) => {
8752
+ self.visit_tstype_alias_declaration(ast);
8753
+ }
8754
+ }
8755
+ }
8756
+ fn visit_import_declaration_specifier(&mut self, ast: &ImportDeclarationSpecifier) {
8757
+ match ast {
8758
+ ImportDeclarationSpecifier::ImportSpecifier(ast) => {
8759
+ self.visit_import_specifier(ast);
8760
+ }
8761
+ ImportDeclarationSpecifier::ImportDefaultSpecifier(ast) => {
8762
+ self.visit_import_default_specifier(ast);
8763
+ }
8764
+ ImportDeclarationSpecifier::ImportNamespaceSpecifier(ast) => {
8765
+ self.visit_import_namespace_specifier(ast);
8766
+ }
8767
+ }
8768
+ }
8769
+ fn visit_module_item(&mut self, ast: &ModuleItem) {
8770
+ match ast {
8771
+ ModuleItem::ImportOrExportDeclaration(ast) => {
8772
+ self.visit_import_or_export_declaration(ast);
8773
+ }
8774
+ ModuleItem::Statement(ast) => {
8775
+ self.visit_statement(ast);
8776
+ }
8777
+ }
8778
+ }
8779
+ fn visit_import_or_export_declaration(&mut self, ast: &ImportOrExportDeclaration) {
8780
+ match ast {
8781
+ ImportOrExportDeclaration::ImportDeclaration(ast) => {
8782
+ self.visit_import_declaration(ast);
8783
+ }
8784
+ ImportOrExportDeclaration::ExportNamedDeclaration(ast) => {
8785
+ self.visit_export_named_declaration(ast);
8786
+ }
8787
+ ImportOrExportDeclaration::ExportDefaultDeclaration(ast) => {
8788
+ self.visit_export_default_declaration(ast);
8789
+ }
8790
+ ImportOrExportDeclaration::ExportAllDeclaration(ast) => {
8791
+ self.visit_export_all_declaration(ast);
8792
+ }
8793
+ }
8794
+ }
8795
+ fn visit_expression_or_super(&mut self, ast: &ExpressionOrSuper) {
8796
+ match ast {
8797
+ ExpressionOrSuper::Expression(ast) => {
8798
+ self.visit_expression(ast);
8799
+ }
8800
+ ExpressionOrSuper::Super(ast) => {
8801
+ self.visit_super(ast);
8802
+ }
8803
+ }
8804
+ }
8805
+ fn visit_expression_or_spread(&mut self, ast: &ExpressionOrSpread) {
8806
+ match ast {
8807
+ ExpressionOrSpread::Expression(ast) => {
8808
+ self.visit_expression(ast);
8809
+ }
8810
+ ExpressionOrSpread::SpreadElement(ast) => {
8811
+ self.visit_spread_element(ast);
8812
+ }
8813
+ }
8814
+ }
8815
+ fn visit_function_body(&mut self, ast: &FunctionBody) {
8816
+ match ast {
8817
+ FunctionBody::BlockStatement(ast) => {
8818
+ self.visit_block_statement(ast);
8819
+ }
8820
+ FunctionBody::Expression(ast) => {
8821
+ self.visit_expression(ast);
8822
+ }
8823
+ }
8824
+ }
8825
+ fn visit_pattern(&mut self, ast: &Pattern) {
8826
+ match ast {
8827
+ Pattern::Identifier(ast) => {
8828
+ self.visit_identifier(ast);
8829
+ }
8830
+ Pattern::ArrayPattern(ast) => {
8831
+ self.visit_array_pattern(ast);
8832
+ }
8833
+ Pattern::ObjectPattern(ast) => {
8834
+ self.visit_object_pattern(ast);
8835
+ }
8836
+ Pattern::RestElement(ast) => {
8837
+ self.visit_rest_element(ast);
8838
+ }
8839
+ Pattern::AssignmentPattern(ast) => {
8840
+ self.visit_assignment_pattern(ast);
8841
+ }
8842
+ }
8843
+ }
8844
+ fn visit_for_init(&mut self, ast: &ForInit) {
8845
+ match ast {
8846
+ ForInit::Expression(ast) => {
8847
+ self.visit_expression(ast);
8848
+ }
8849
+ ForInit::VariableDeclaration(ast) => {
8850
+ self.visit_variable_declaration(ast);
8851
+ }
8852
+ }
8853
+ }
8854
+ fn visit_for_in_init(&mut self, ast: &ForInInit) {
8855
+ match ast {
8856
+ ForInInit::Pattern(ast) => {
8857
+ self.visit_pattern(ast);
8858
+ }
8859
+ ForInInit::VariableDeclaration(ast) => {
8860
+ self.visit_variable_declaration(ast);
8861
+ }
8862
+ }
8863
+ }
8864
+ fn visit_property_or_spread_element(&mut self, ast: &PropertyOrSpreadElement) {
8865
+ match ast {
8866
+ PropertyOrSpreadElement::Property(ast) => {
8867
+ self.visit_property(ast);
8868
+ }
8869
+ PropertyOrSpreadElement::SpreadElement(ast) => {
8870
+ self.visit_spread_element(ast);
8871
+ }
8872
+ }
8873
+ }
8874
+ fn visit_assignment_property_or_rest_element(
8875
+ &mut self,
8876
+ ast: &AssignmentPropertyOrRestElement,
8877
+ ) {
8878
+ match ast {
8879
+ AssignmentPropertyOrRestElement::AssignmentProperty(ast) => {
8880
+ self.visit_assignment_property(ast);
8881
+ }
8882
+ AssignmentPropertyOrRestElement::RestElement(ast) => {
8883
+ self.visit_rest_element(ast);
8884
+ }
8885
+ }
8886
+ }
8887
+ fn visit_property_key(&mut self, ast: &PropertyKey) {
8888
+ match ast {
8889
+ PropertyKey::Identifier(ast) => {
8890
+ self.visit_identifier(ast);
8891
+ }
8892
+ PropertyKey::Literal(ast) => {
8893
+ self.visit_literal(ast);
8894
+ }
8895
+ }
8896
+ }
8897
+ fn visit_assignment_target(&mut self, ast: &AssignmentTarget) {
8898
+ match ast {
8899
+ AssignmentTarget::Expression(ast) => {
8900
+ self.visit_expression(ast);
8901
+ }
8902
+ AssignmentTarget::Pattern(ast) => {
8903
+ self.visit_pattern(ast);
8904
+ }
8905
+ }
8906
+ }
8907
+ fn visit_chain_element(&mut self, ast: &ChainElement) {
8908
+ match ast {
8909
+ ChainElement::CallExpression(ast) => {
8910
+ self.visit_call_expression(ast);
8911
+ }
8912
+ ChainElement::MemberExpression(ast) => {
8913
+ self.visit_member_expression(ast);
8914
+ }
8915
+ }
8916
+ }
8917
+ fn visit_jsxmember_expression_or_identifier(
8918
+ &mut self,
8919
+ ast: &JSXMemberExpressionOrIdentifier,
8920
+ ) {
8921
+ match ast {
8922
+ JSXMemberExpressionOrIdentifier::JSXMemberExpression(ast) => {
8923
+ self.visit_jsxmember_expression(ast);
8924
+ }
8925
+ JSXMemberExpressionOrIdentifier::JSXIdentifier(ast) => {
8926
+ self.visit_jsxidentifier(ast);
8927
+ }
8928
+ }
8929
+ }
8930
+ fn visit_jsxexpression_or_empty(&mut self, ast: &JSXExpressionOrEmpty) {
8931
+ match ast {
8932
+ JSXExpressionOrEmpty::Expression(ast) => {
8933
+ self.visit_expression(ast);
8934
+ }
8935
+ JSXExpressionOrEmpty::JSXEmptyExpression(ast) => {
8936
+ self.visit_jsxempty_expression(ast);
8937
+ }
8938
+ }
8939
+ }
8940
+ fn visit_jsxattribute_or_spread(&mut self, ast: &JSXAttributeOrSpread) {
8941
+ match ast {
8942
+ JSXAttributeOrSpread::JSXAttribute(ast) => {
8943
+ self.visit_jsxattribute(ast);
8944
+ }
8945
+ JSXAttributeOrSpread::JSXSpreadAttribute(ast) => {
8946
+ self.visit_jsxspread_attribute(ast);
8947
+ }
8948
+ }
8949
+ }
8950
+ fn visit_jsxattribute_value(&mut self, ast: &JSXAttributeValue) {
8951
+ match ast {
8952
+ JSXAttributeValue::Literal(ast) => {
8953
+ self.visit_literal(ast);
8954
+ }
8955
+ JSXAttributeValue::JSXExpressionContainer(ast) => {
8956
+ self.visit_jsxexpression_container(ast);
8957
+ }
8958
+ JSXAttributeValue::JSXElement(ast) => {
8959
+ self.visit_jsxelement(ast);
8960
+ }
8961
+ JSXAttributeValue::JSXFragment(ast) => {
8962
+ self.visit_jsxfragment(ast);
8963
+ }
8964
+ JSXAttributeValue::JSXStringLiteral(ast) => {
8965
+ self.visit_jsxstring_literal(ast);
8966
+ }
8967
+ }
8968
+ }
8969
+ fn visit_jsxelement_name(&mut self, ast: &JSXElementName) {
8970
+ match ast {
8971
+ JSXElementName::JSXIdentifier(ast) => {
8972
+ self.visit_jsxidentifier(ast);
8973
+ }
8974
+ JSXElementName::JSXMemberExpression(ast) => {
8975
+ self.visit_jsxmember_expression(ast);
8976
+ }
8977
+ JSXElementName::JSXNamespacedName(ast) => {
8978
+ self.visit_jsxnamespaced_name(ast);
8979
+ }
8980
+ }
8981
+ }
8982
+ fn visit_jsxidentifier_or_namespaced_name(
8983
+ &mut self,
8984
+ ast: &JSXIdentifierOrNamespacedName,
8985
+ ) {
8986
+ match ast {
8987
+ JSXIdentifierOrNamespacedName::JSXIdentifier(ast) => {
8988
+ self.visit_jsxidentifier(ast);
8989
+ }
8990
+ JSXIdentifierOrNamespacedName::JSXNamespacedName(ast) => {
8991
+ self.visit_jsxnamespaced_name(ast);
8992
+ }
8993
+ }
8994
+ }
8995
+ fn visit_jsxchild_item(&mut self, ast: &JSXChildItem) {
8996
+ match ast {
8997
+ JSXChildItem::JSXText(ast) => {
8998
+ self.visit_jsxtext(ast);
8999
+ }
9000
+ JSXChildItem::JSXStringLiteral(ast) => {
9001
+ self.visit_jsxstring_literal(ast);
9002
+ }
9003
+ JSXChildItem::JSXExpressionContainer(ast) => {
9004
+ self.visit_jsxexpression_container(ast);
9005
+ }
9006
+ JSXChildItem::JSXSpreadChild(ast) => {
9007
+ self.visit_jsxspread_child(ast);
9008
+ }
9009
+ JSXChildItem::JSXElement(ast) => {
9010
+ self.visit_jsxelement(ast);
9011
+ }
9012
+ JSXChildItem::JSXFragment(ast) => {
9013
+ self.visit_jsxfragment(ast);
9014
+ }
9015
+ }
9016
+ }
9017
+ fn visit_declaration_or_expression(&mut self, ast: &DeclarationOrExpression) {
9018
+ match ast {
9019
+ DeclarationOrExpression::Declaration(ast) => {
9020
+ self.visit_declaration(ast);
9021
+ }
9022
+ DeclarationOrExpression::Expression(ast) => {
9023
+ self.visit_expression(ast);
9024
+ }
9025
+ }
9026
+ }
9027
+ fn visit_class_item(&mut self, ast: &ClassItem) {
9028
+ match ast {
9029
+ ClassItem::MethodDefinition(ast) => {
9030
+ self.visit_method_definition(ast);
9031
+ }
9032
+ ClassItem::ClassProperty(ast) => {
9033
+ self.visit_class_property(ast);
9034
+ }
9035
+ ClassItem::ClassPrivateProperty(ast) => {
9036
+ self.visit_class_private_property(ast);
9037
+ }
9038
+ ClassItem::StaticBlock(ast) => {
9039
+ self.visit_static_block(ast);
9040
+ }
9041
+ }
9042
+ }
9043
+ fn visit_expression_or_private_identifier(
9044
+ &mut self,
9045
+ ast: &ExpressionOrPrivateIdentifier,
9046
+ ) {
9047
+ match ast {
9048
+ ExpressionOrPrivateIdentifier::Expression(ast) => {
9049
+ self.visit_expression(ast);
9050
+ }
9051
+ ExpressionOrPrivateIdentifier::PrivateIdentifier(ast) => {
9052
+ self.visit_private_identifier(ast);
9053
+ }
9054
+ ExpressionOrPrivateIdentifier::PrivateName(ast) => {
9055
+ self.visit_private_name(ast);
9056
+ }
9057
+ }
9058
+ }
9059
+ fn visit_type_annotation(&mut self, ast: &TypeAnnotation) {
9060
+ match ast {
9061
+ TypeAnnotation::TSTypeAnnotation(ast) => {
9062
+ self.visit_tstype_annotation(ast);
9063
+ }
9064
+ }
9065
+ }
9066
+}
compiler/forget/crates/forget_estree_codegen/src/codegen.rs
+201
-16
@@ -46,43 +46,72 @@ pub struct Grammar {
46
47
impl Grammar {
48
pub fn codegen(self) -> TokenStream {
49
- let Self {
50
- objects,
51
- nodes,
52
- enums,
53
- operators,
54
- } = self;
55
-
56
- let objects: Vec<_> = objects
49
+ let object_defs: Vec<_> = self
50
+ .objects
51
.iter()
52
.map(|(name, object)| object.codegen(name))
53
.collect();
60
- let nodes: Vec<_> = nodes
54
+ let object_visitors: Vec<_> = self
55
+ .objects
56
+ .iter()
57
+ .filter_map(|(name, object)| {
58
+ if object.visitor {
59
+ Some(object.codegen_visitor(name, &self))
60
+ } else {
61
+ None
62
+ }
63
+ })
64
+ .collect();
65
+ let node_defs: Vec<_> = self
66
+ .nodes
67
.iter()
68
.map(|(name, node)| node.codegen(name))
69
.collect();
64
- let enums: Vec<_> = enums
70
+ let node_visitors: Vec<_> = self
71
+ .nodes
72
.iter()
66
- .map(|(name, enum_)| enum_.codegen(name, &enums))
73
+ .map(|(name, node)| node.codegen_visitor(name, &self))
74
.collect();
68
- let operators: Vec<_> = operators
75
+ let enum_defs: Vec<_> = self
76
+ .enums
77
+ .iter()
78
+ .map(|(name, enum_)| enum_.codegen(name, &self.enums))
79
+ .collect();
80
+ let enum_visitors: Vec<_> = self
81
+ .enums
82
+ .iter()
83
+ .map(|(name, enum_)| enum_.codegen_visitor(name))
84
+ .collect();
85
+ let operator_defs: Vec<_> = self
86
+ .operators
87
.iter()
88
.map(|(name, operator)| operator.codegen(name))
89
.collect();
90
91
+ // println!("{}", quote! {#(#node_visitors)*});
92
+ // println!("{}", quote! {#(#enum_visitors)*});
93
+
94
quote! {
95
use std::num::NonZeroU32;
96
use serde::ser::{Serializer, SerializeMap};
97
use serde::{Serialize,Deserialize};
98
use crate::{JsValue, Binding, SourceRange, Number, ESTreeNode};
99
79
- #(#objects)*
100
+ #(#object_defs)*
101
81
- #(#nodes)*
102
+ #(#node_defs)*
103
83
- #(#enums)*
104
+ #(#enum_defs)*
105
85
- #(#operators)*
106
+ #(#operator_defs)*
107
+
108
+ pub trait Visitor2 {
109
+ #(#object_visitors)*
110
+
111
+ #(#node_visitors)*
112
+
113
+ #(#enum_visitors)*
114
+ }
115
}
116
}
117
@@ -128,6 +157,9 @@ impl Grammar {
157
pub struct Object {
158
#[serde(default)]
159
pub fields: IndexMap<String, Field>,
160
+
161
+ #[serde(default)]
162
+ pub visitor: bool,
163
}
164
165
impl Object {
@@ -147,6 +179,60 @@ impl Object {
179
}
180
}
181
}
182
+
183
+ pub fn codegen_visitor(&self, name: &str, grammar: &Grammar) -> TokenStream {
184
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(name));
185
+ let name = format_ident!("{}", name);
186
+ let field_visitors: Vec<_> = self
187
+ .fields
188
+ .iter()
189
+ .filter_map(|(name, field)| {
190
+ let (type_name_str, type_kind) = parse_type(&field.type_).unwrap();
191
+ if !grammar.nodes.contains_key(&type_name_str)
192
+ && !grammar.enums.contains_key(&type_name_str)
193
+ {
194
+ return None;
195
+ }
196
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(&type_name_str));
197
+ let field_name = format_ident!("{}", name);
198
+ Some(match type_kind {
199
+ TypeKind::Named => {
200
+ quote! {
201
+ self.#visitor_name(&ast.#field_name);
202
+ }
203
+ }
204
+ TypeKind::Option => {
205
+ quote! {
206
+ if let Some(#field_name) = &ast.#field_name {
207
+ self.#visitor_name(#field_name);
208
+ }
209
+ }
210
+ }
211
+ TypeKind::Vec => {
212
+ quote! {
213
+ for #field_name in &ast.#field_name {
214
+ self.#visitor_name(#field_name);
215
+ }
216
+ }
217
+ }
218
+ TypeKind::VecOfOption => {
219
+ quote! {
220
+ for #field_name in &ast.#field_name {
221
+ if let Some(#field_name) = #field_name {
222
+ self.#visitor_name(#field_name);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ })
228
+ })
229
+ .collect();
230
+ quote! {
231
+ fn #visitor_name(&mut self, ast: &#name) {
232
+ #(#field_visitors)*
233
+ }
234
+ }
235
+ }
236
}
237
238
#[derive(Serialize, Deserialize, Debug)]
@@ -239,6 +325,62 @@ impl Node {
325
}
326
}
327
328
+ pub fn codegen_visitor(&self, name: &str, grammar: &Grammar) -> TokenStream {
329
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(name));
330
+ let name = format_ident!("{}", name);
331
+ let field_visitors: Vec<_> = self
332
+ .fields
333
+ .iter()
334
+ .filter_map(|(name, field)| {
335
+ let (type_name_str, type_kind) = parse_type(&field.type_).unwrap();
336
+ if (!grammar.objects.contains_key(&type_name_str)
337
+ || grammar.objects.get(&type_name_str).unwrap().visitor == false)
338
+ && !grammar.nodes.contains_key(&type_name_str)
339
+ && !grammar.enums.contains_key(&type_name_str)
340
+ {
341
+ return None;
342
+ }
343
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(&type_name_str));
344
+ let field_name = format_ident!("{}", name);
345
+ Some(match type_kind {
346
+ TypeKind::Named => {
347
+ quote! {
348
+ self.#visitor_name(&ast.#field_name);
349
+ }
350
+ }
351
+ TypeKind::Option => {
352
+ quote! {
353
+ if let Some(#field_name) = &ast.#field_name {
354
+ self.#visitor_name(#field_name);
355
+ }
356
+ }
357
+ }
358
+ TypeKind::Vec => {
359
+ quote! {
360
+ for #field_name in &ast.#field_name {
361
+ self.#visitor_name(#field_name);
362
+ }
363
+ }
364
+ }
365
+ TypeKind::VecOfOption => {
366
+ quote! {
367
+ for #field_name in &ast.#field_name {
368
+ if let Some(#field_name) = #field_name {
369
+ self.#visitor_name(#field_name);
370
+ }
371
+ }
372
+ }
373
+ }
374
+ })
375
+ })
376
+ .collect();
377
+ quote! {
378
+ fn #visitor_name(&mut self, ast: &#name) {
379
+ #(#field_visitors)*
380
+ }
381
+ }
382
+ }
383
+
384
pub fn codegen_hermes(&self, name: &str) -> TokenStream {
385
let name_str = name;
386
let name = format_ident!("{}", name);
@@ -576,6 +718,30 @@ impl Enum {
718
}
719
}
720
721
+ pub fn codegen_visitor(&self, name: &str) -> TokenStream {
722
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(name));
723
+ let name = format_ident!("{}", name);
724
+ let mut tag_matches = Vec::new();
725
+
726
+ for variant in self.variants.iter() {
727
+ let node_variant = format_ident!("{}", variant);
728
+ let visitor_name = format_ident!("visit_{}", to_lower_snake_case(variant));
729
+
730
+ tag_matches.push(quote! {
731
+ #name::#node_variant(ast) => {
732
+ self.#visitor_name(ast);
733
+ }
734
+ })
735
+ }
736
+ quote! {
737
+ fn #visitor_name(&mut self, ast: &#name) {
738
+ match ast {
739
+ #(#tag_matches),*
740
+ }
741
+ }
742
+ }
743
+ }
744
+
745
pub fn codegen_hermes(&self, name: &str, grammar: &Grammar) -> TokenStream {
746
let name_str = name;
747
let name = format_ident!("{}", name);
@@ -791,3 +957,22 @@ fn parse_type(type_: &str) -> Result<(String, TypeKind), String> {
957
Ok((current.to_string(), kind))
958
}
959
}
960
+
961
+// from https://github.com/rust-lang/rust-analyzer/blob/4105378dc7479a3dbd39a4afb3eba67d083bd7f8/xtask/src/codegen/gen_syntax.rs#L406C1-L418C2
962
+fn to_lower_snake_case(s: &str) -> String {
963
+ let mut buf = String::with_capacity(s.len());
964
+ let mut prev = false;
965
+ for c in s.chars() {
966
+ if c.is_ascii_uppercase() {
967
+ if prev {
968
+ buf.push('_')
969
+ }
970
+ prev = false;
971
+ } else {
972
+ prev = true;
973
+ }
974
+
975
+ buf.push(c.to_ascii_lowercase());
976
+ }
977
+ buf
978
+}
compiler/forget/crates/forget_estree_codegen/src/ecmascript.json
+2
@@ -24,6 +24,7 @@
24
}
25
},
26
"Class": {
27
+ "visitor": true,
28
"fields": {
29
"id": {
30
"type": "Option<Identifier>"
@@ -38,6 +39,7 @@
39
}
40
},
41
"Function": {
42
+ "visitor": true,
43
"fields": {
44
"id": {
45
"type": "Option<Identifier>"