Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion misc/codegen/lib/schemadefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def __getitem__(self, item):

use_for_null = _ClassPragma("null")

qltest.add(_ClassPragma("skip"))
qltest.add(_Pragma("skip"))
Comment thread
hvitved marked this conversation as resolved.
Resolved
qltest.add(_ClassPragma("collapse_hierarchy"))
qltest.add(_ClassPragma("uncollapse_hierarchy"))
qltest.add(
Expand Down
25 changes: 23 additions & 2 deletions rust/ast-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ fn should_enum_be_skipped(name: &str) -> bool {
fn should_node_be_skipped(name: &str) -> bool {
name == "TypeAnchor" // we flatten TypeAnchor into PathSegment in the extractor
|| name == "MacroStmts" // we workaround a getter bug in the extractor
|| name == "ParenExpr" // parenthesized expressions are extracted as their inner expression
|| name == "ParenPat" // parenthesized patterns are extracted as their inner pattern
}

fn should_node_be_skipped_in_extractor(name: &str) -> bool {
Expand Down Expand Up @@ -133,6 +135,7 @@ fn get_additional_fields(node_name: &str) -> Vec<FieldInfo> {
FieldInfo::body("body", "TokenTree"),
],
"MacroCall" => vec![FieldInfo::body("token_tree", "TokenTree")],
"MacroExpr" | "RecordExpr" => vec![FieldInfo::list("attrs", "AnyAttr")],
"FormatArgsExpr" => vec![FieldInfo::list("args", "FormatArgsArg")],
"ArgList" => vec![FieldInfo::list("args", "Expr")],
"Fn" => vec![FieldInfo::body("body", "BlockExpr")],
Expand Down Expand Up @@ -349,6 +352,7 @@ struct EnumVariantInfo {
name: String,
snake_case_name: String,
variant_ast_name: String,
emission: String,
}

#[derive(Serialize)]
Expand All @@ -365,6 +369,8 @@ struct ExtractorNodeFieldInfo {
name: String,
method: String,
snake_case_ty: String,
attributes: bool,
parenthesized_attrs: bool,
string: bool,
predicate: bool,
optional: bool,
Expand Down Expand Up @@ -399,10 +405,16 @@ fn enum_to_extractor_info(node: &AstEnumSrc) -> ExtractorEnumInfo {
.map(|v| {
let name = class_name(v);
let snake_case_name = to_lower_snake_case(v);
let emission = match v.as_str() {
"ParenExpr" => "self.emit_parenthesized_expr(inner)".to_owned(),
"ParenPat" => "self.emit_parenthesized_pat(inner)".to_owned(),
_ => format!("self.emit_{snake_case_name}(inner).map(Into::into)"),
};
EnumVariantInfo {
name,
snake_case_name,
variant_ast_name: v.to_string(),
emission,
}
})
.collect(),
Expand All @@ -412,6 +424,7 @@ fn enum_to_extractor_info(node: &AstEnumSrc) -> ExtractorEnumInfo {

fn field_info_to_extractor_info(name: &str, field: &FieldInfo) -> ExtractorNodeFieldInfo {
let name = property_name(name, &field.name);
let attributes = name == "attrs";
match &field.ty {
FieldType::String => ExtractorNodeFieldInfo {
name,
Expand Down Expand Up @@ -440,6 +453,7 @@ fn field_info_to_extractor_info(name: &str, field: &FieldInfo) -> ExtractorNodeF
},
FieldType::List(ty) => ExtractorNodeFieldInfo {
name,
attributes,
method: if ty == "AnyAttr" {
"attrs_with_doc".to_owned()
} else {
Expand All @@ -453,12 +467,19 @@ fn field_info_to_extractor_info(name: &str, field: &FieldInfo) -> ExtractorNodeF
}
fn node_to_extractor_info(node: &AstNodeSrc) -> ExtractorNodeInfo {
let fields = get_fields(node);
let has_attrs = fields.iter().any(|f| f.name == "attrs");
let parenthesized_attrs = matches!(node.name.as_str(), "MacroExpr" | "RecordExpr");
let name = class_name(&node.name);
let fields = fields
let fields: Vec<_> = fields
.iter()
.map(|f| field_info_to_extractor_info(&name, f))
.map(|mut f| {
f.parenthesized_attrs = parenthesized_attrs && f.name == "attrs";
f
})
.collect();
let has_attrs = fields
.iter()
.any(|f| f.name == "attrs" && !f.parenthesized_attrs);
ExtractorNodeInfo {
name,
snake_case_name: to_lower_snake_case(&node.name),
Expand Down
20 changes: 19 additions & 1 deletion rust/ast-generator/templates/extractor.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Translator<'_> {
{{>pre_emission}}
let label = match node {
{{#variants}}
ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into),
ast::{{ast_name}}::{{variant_ast_name}}(inner) => {{{emission}}},
{{/variants}}
}?;
{{>post_emission}}
Expand All @@ -33,6 +33,18 @@ impl Translator<'_> {
if self.should_be_excluded(node) { return None; }
{{/has_attrs}}
{{#fields}}
{{#attributes}}
{{#parenthesized_attrs}}
let attrs = self.take_parenthesized_expr_attrs(node.syntax());
{{/parenthesized_attrs}}
{{^parenthesized_attrs}}
let mut attrs = self.take_parenthesized_expr_attrs(node.syntax());
attrs.extend(node.{{method}}().filter_map(|x| self.emit_{{snake_case_ty}}(&x)));
{{/parenthesized_attrs}}
{{/attributes}}
{{/fields}}
{{#fields}}
{{^attributes}}
let {{name}} =
{{#predicate}}
node.{{method}}().is_some()
Expand All @@ -50,11 +62,17 @@ impl Translator<'_> {
if self.should_skip_bodies() { None } else { node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(&x)) }
{{/body}}
;
{{/attributes}}
{{/fields}}
let label = self.trap.emit(generated::{{name}} {
id: TrapId::Star,
{{#fields}}
{{#attributes}}
attrs,
{{/attributes}}
{{^attributes}}
{{name}},
{{/attributes}}
{{/fields}}
});
self.emit_location(label, node);
Expand Down
Loading
Loading