Rust: refactor pre_emit! and post_emit! to a trait

This commit is contained in:
Paolo Tranquilli
2025-06-24 09:19:22 +02:00
parent e5cb639e28
commit d0c7550119
8 changed files with 369 additions and 459 deletions

View File

@@ -52,6 +52,32 @@ fn property_name(type_name: &str, field_name: &str) -> String {
name.to_owned()
}
fn has_special_emission(type_name: &str) -> bool {
matches!(
type_name,
"Item"
| "AssocItem"
| "ExternItem"
| "Meta"
| "MacroCall"
| "Fn"
| "Struct"
| "Enum"
| "Union"
| "Trait"
| "Module"
| "Variant"
| "PathExpr"
| "RecordExpr"
| "PathPat"
| "RecordPat"
| "TupleStructPat"
| "MethodCallExpr"
| "PathSegment"
| "Const"
)
}
fn to_lower_snake_case(s: &str) -> String {
let mut buf = String::with_capacity(s.len());
let mut prev = false;
@@ -355,6 +381,7 @@ struct ExtractorEnumInfo {
snake_case_name: String,
ast_name: String,
variants: Vec<EnumVariantInfo>,
has_special_emission: bool,
}
#[derive(Serialize, Default)]
@@ -376,6 +403,7 @@ struct ExtractorNodeInfo {
ast_name: String,
fields: Vec<ExtractorNodeFieldInfo>,
has_attrs: bool,
has_special_emission: bool,
}
#[derive(Serialize)]
@@ -406,6 +434,7 @@ fn enum_to_extractor_info(node: &AstEnumSrc) -> Option<ExtractorEnumInfo> {
}
})
.collect(),
has_special_emission: has_special_emission(&node.name),
})
}
@@ -460,6 +489,7 @@ fn node_to_extractor_info(node: &AstNodeSrc) -> ExtractorNodeInfo {
ast_name: node.name.clone(),
fields,
has_attrs,
has_special_emission: has_special_emission(&node.name),
}
}

View File

@@ -1,8 +1,7 @@
//! Generated by `ast-generator`, do not edit by hand.
use super::base::Translator;
use super::mappings::TextValue;
use crate::{pre_emit,post_emit};
use super::mappings::{TextValue, HasTrapClass, Emission};
use crate::generated;
use crate::trap::{Label, TrapId};
use ra_ap_syntax::ast::{
@@ -13,29 +12,23 @@ use ra_ap_syntax::ast::{
use ra_ap_syntax::{AstNode, ast};
impl Translator<'_> {
fn emit_else_branch(&mut self, node: &ast::ElseBranch) -> Option<Label<generated::Expr>> {
match node {
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).map(Into::into),
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).map(Into::into),
}
}
{{#enums}}
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
pre_emit!({{name}}, self, node);
{{>pre_emission}}
let label = match node {
{{#variants}}
ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into),
{{/variants}}
}?;
post_emit!({{name}}, self, node, label);
{{>post_emission}}
Some(label)
}
{{/enums}}
{{#nodes}}
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
pre_emit!({{name}}, self, node);
{{>pre_emission}}
{{#has_attrs}}
if self.should_be_excluded(node) { return None; }
{{/has_attrs}}
@@ -65,9 +58,15 @@ impl Translator<'_> {
{{/fields}}
});
self.emit_location(label, node);
post_emit!({{name}}, self, node, label);
{{>post_emission}}
self.emit_tokens(node, label.into(), node.syntax().children_with_tokens());
Some(label)
}
{{/nodes}}
}
{{#enums}}
{{>trap_class_mapping}}
{{/enums}}
{{#nodes}}
{{>trap_class_mapping}}
{{/nodes}}

View File

@@ -0,0 +1,3 @@
{{#has_special_emission}}
self.post_emit(node, label);
{{/has_special_emission}}

View File

@@ -0,0 +1,5 @@
{{#has_special_emission}}
if let Some(label) = self.pre_emit(node) {
return Some(label);
}
{{/has_special_emission}}

View File

@@ -0,0 +1,6 @@
{{#has_special_emission}}
impl HasTrapClass for ast::{{ast_name}} {
type TrapClass = generated::{{name}};
}
{{/has_special_emission}}