Skip to content

Commit e15e81e

Browse files
committed
Rust: refactor pre_emit! and post_emit! to a trait
1 parent 5162d2c commit e15e81e

File tree

5 files changed

+1192
-442
lines changed

5 files changed

+1192
-442
lines changed

rust/ast-generator/src/main.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,31 @@ fn property_name(type_name: &str, field_name: &str) -> String {
5252
name.to_owned()
5353
}
5454

55+
fn has_special_emission(type_name: &str) -> bool {
56+
matches!(
57+
type_name,
58+
"Item"
59+
| "AssocItem"
60+
| "ExternItem"
61+
| "Meta"
62+
| "MacroCall"
63+
| "Fn"
64+
| "Struct"
65+
| "Enum"
66+
| "Union"
67+
| "Module"
68+
| "Variant"
69+
| "PathExpr"
70+
| "RecordExpr"
71+
| "PathPat"
72+
| "RecordPat"
73+
| "TupleStructPat"
74+
| "MethodCallExpr"
75+
| "PathSegment"
76+
| "Const"
77+
)
78+
}
79+
5580
fn to_lower_snake_case(s: &str) -> String {
5681
let mut buf = String::with_capacity(s.len());
5782
let mut prev = false;
@@ -355,6 +380,7 @@ struct ExtractorEnumInfo {
355380
snake_case_name: String,
356381
ast_name: String,
357382
variants: Vec<EnumVariantInfo>,
383+
has_special_emission: bool,
358384
}
359385

360386
#[derive(Serialize, Default)]
@@ -376,6 +402,7 @@ struct ExtractorNodeInfo {
376402
ast_name: String,
377403
fields: Vec<ExtractorNodeFieldInfo>,
378404
has_attrs: bool,
405+
has_special_emission: bool,
379406
}
380407

381408
#[derive(Serialize)]
@@ -406,6 +433,7 @@ fn enum_to_extractor_info(node: &AstEnumSrc) -> Option<ExtractorEnumInfo> {
406433
}
407434
})
408435
.collect(),
436+
has_special_emission: has_special_emission(&node.name),
409437
})
410438
}
411439

@@ -460,6 +488,7 @@ fn node_to_extractor_info(node: &AstNodeSrc) -> ExtractorNodeInfo {
460488
ast_name: node.name.clone(),
461489
fields,
462490
has_attrs,
491+
has_special_emission: has_special_emission(&node.name),
463492
}
464493
}
465494

rust/ast-generator/templates/extractor.mustache

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Generated by `ast-generator`, do not edit by hand.
22

33
use super::base::Translator;
4-
use super::mappings::TextValue;
5-
use crate::{pre_emit,post_emit};
4+
use super::mappings::{TextValue, MappedToTrapClass, Emission};
65
use crate::generated;
76
use crate::trap::{Label, TrapId};
87
use ra_ap_syntax::ast::{
@@ -22,20 +21,20 @@ impl Translator<'_> {
2221
{{#enums}}
2322

2423
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
25-
pre_emit!({{name}}, self, node);
24+
node.pre_emit(self);
2625
let label = match node {
2726
{{#variants}}
2827
ast::{{ast_name}}::{{variant_ast_name}}(inner) => self.emit_{{snake_case_name}}(inner).map(Into::into),
2928
{{/variants}}
3029
}?;
31-
post_emit!({{name}}, self, node, label);
30+
node.post_emit(self, label);
3231
Some(label)
3332
}
3433
{{/enums}}
3534
{{#nodes}}
3635

3736
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
38-
pre_emit!({{name}}, self, node);
37+
node.pre_emit(self);
3938
{{#has_attrs}}
4039
if self.should_be_excluded(node) { return None; }
4140
{{/has_attrs}}
@@ -65,9 +64,29 @@ impl Translator<'_> {
6564
{{/fields}}
6665
});
6766
self.emit_location(label, node);
68-
post_emit!({{name}}, self, node, label);
67+
node.post_emit(self, label);
6968
self.emit_tokens(node, label.into(), node.syntax().children_with_tokens());
7069
Some(label)
7170
}
7271
{{/nodes}}
7372
}
73+
{{#enums}}
74+
75+
impl MappedToTrapClass for ast::{{ast_name}} {
76+
type TrapClass = generated::{{name}};
77+
}
78+
79+
{{^has_special_emission}}
80+
impl Emission for ast::{{ast_name}} {}
81+
{{/has_special_emission}}
82+
{{/enums}}
83+
{{#nodes}}
84+
85+
impl MappedToTrapClass for ast::{{ast_name}} {
86+
type TrapClass = generated::{{name}};
87+
}
88+
89+
{{^has_special_emission}}
90+
impl Emission for ast::{{ast_name}} {}
91+
{{/has_special_emission}}
92+
{{/nodes}}

rust/extractor/src/translate/base.rs

Lines changed: 140 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::mappings::{AddressableAst, AddressableHir, PathAst};
1+
use super::mappings::{AddressableAst, AddressableHir, Emission, PathAst};
22
use crate::generated::{self};
33
use crate::rust_analyzer::FileSemanticInformation;
44
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
@@ -22,121 +22,161 @@ use ra_ap_syntax::{
2222
ast,
2323
};
2424

25-
#[macro_export]
26-
macro_rules! pre_emit {
27-
(Item, $self:ident, $node:ident) => {
28-
if let Some(label) = $self.prepare_item_expansion($node) {
29-
return Some(label.into());
30-
}
31-
};
32-
(AssocItem, $self:ident, $node:ident) => {
33-
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
34-
return Some(label.into());
35-
}
36-
};
37-
(ExternItem, $self:ident, $node:ident) => {
38-
if let Some(label) = $self.prepare_item_expansion(&$node.clone().into()) {
39-
return Some(label.into());
40-
}
41-
};
42-
(Meta, $self:ident, $node:ident) => {
43-
// rust-analyzer doesn't expand macros in this context
44-
$self.macro_context_depth += 1;
45-
};
46-
($($_:tt)*) => {};
25+
impl Emission for ast::Item {
26+
fn pre_emit(&self, translator: &mut Translator) -> Option<Label<Self::TrapClass>> {
27+
translator.prepare_item_expansion(self).map(Into::into)
28+
}
29+
30+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
31+
translator.emit_item_expansion(self, label);
32+
}
33+
}
34+
35+
impl Emission for ast::AssocItem {
36+
fn pre_emit(&self, translator: &mut Translator) -> Option<Label<Self::TrapClass>> {
37+
translator
38+
.prepare_item_expansion(&self.clone().into())
39+
.map(Into::into)
40+
}
41+
42+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
43+
translator.emit_item_expansion(&self.clone().into(), label.into());
44+
}
45+
}
46+
47+
impl Emission for ast::ExternItem {
48+
fn pre_emit(&self, translator: &mut Translator) -> Option<Label<Self::TrapClass>> {
49+
translator
50+
.prepare_item_expansion(&self.clone().into())
51+
.map(Into::into)
52+
}
53+
54+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
55+
translator.emit_item_expansion(&self.clone().into(), label.into());
56+
}
57+
}
58+
59+
impl Emission for ast::Meta {
60+
fn pre_emit(&self, translator: &mut Translator) -> Option<Label<Self::TrapClass>> {
61+
translator.macro_context_depth += 1;
62+
None
63+
}
64+
65+
fn post_emit(&self, translator: &mut Translator, _label: Label<Self::TrapClass>) {
66+
translator.macro_context_depth -= 1;
67+
}
68+
}
69+
70+
impl Emission for ast::Fn {
71+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
72+
translator.emit_function_has_implementation(self, label);
73+
translator.extract_canonical_origin(self, label.into());
74+
}
75+
}
76+
77+
impl Emission for ast::Struct {
78+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
79+
translator.emit_derive_expansion(self, label);
80+
translator.extract_canonical_origin(self, label.into());
81+
}
82+
}
83+
84+
impl Emission for ast::Enum {
85+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
86+
translator.emit_derive_expansion(self, label);
87+
translator.extract_canonical_origin(self, label.into());
88+
}
89+
}
90+
91+
impl Emission for ast::Union {
92+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
93+
translator.emit_derive_expansion(self, label);
94+
translator.extract_canonical_origin(self, label.into());
95+
}
96+
}
97+
98+
impl Emission for ast::Module {
99+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
100+
translator.extract_canonical_origin(self, label.into());
101+
}
102+
}
103+
104+
impl Emission for ast::Variant {
105+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
106+
translator.extract_canonical_origin_of_enum_variant(self, label);
107+
}
108+
}
109+
110+
impl Emission for ast::PathExpr {
111+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
112+
translator.extract_path_canonical_destination(self, label.into());
113+
}
47114
}
48115

49-
// TODO: remove the mannually written Label conversions. These can be auto-generated by
116+
impl Emission for ast::RecordExpr {
117+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
118+
translator.extract_path_canonical_destination(self, label.into());
119+
}
120+
}
121+
122+
impl Emission for ast::PathPat {
123+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
124+
translator.extract_path_canonical_destination(self, label.into());
125+
}
126+
}
127+
128+
impl Emission for ast::RecordPat {
129+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
130+
translator.extract_path_canonical_destination(self, label.into());
131+
}
132+
}
133+
134+
impl Emission for ast::TupleStructPat {
135+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
136+
translator.extract_path_canonical_destination(self, label.into());
137+
}
138+
}
139+
140+
impl Emission for ast::MethodCallExpr {
141+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
142+
translator.extract_method_canonical_destination(self, label);
143+
}
144+
}
145+
146+
impl Emission for ast::PathSegment {
147+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
148+
translator.extract_types_from_path_segment(self, label);
149+
}
150+
}
151+
152+
impl Emission for ast::Const {
153+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
154+
translator.emit_const_has_implementation(self, label);
155+
}
156+
}
157+
158+
impl Emission for ast::MacroCall {
159+
fn post_emit(&self, translator: &mut Translator, label: Label<Self::TrapClass>) {
160+
translator.extract_macro_call_expanded(self, label);
161+
}
162+
}
163+
164+
// TODO: remove the manually written Label conversions. These can be auto-generated by
50165
// changing the base class of AssocItem from AstNode to Item
51166
impl From<crate::trap::Label<generated::AssocItem>> for crate::trap::Label<generated::Item> {
52167
fn from(value: crate::trap::Label<generated::AssocItem>) -> Self {
53168
// SAFETY: this is safe because every concrete instance of `@assoc_item` is also an instance of `@item`
54169
unsafe { Self::from_untyped(value.as_untyped()) }
55170
}
56171
}
57-
// TODO: remove the mannually written Label conversions. These can be auto-generated by
172+
// TODO: remove the manually written Label conversions. These can be auto-generated by
58173
// changing the base class of ExternItem from AstNode to Item
59174
impl From<crate::trap::Label<generated::ExternItem>> for crate::trap::Label<generated::Item> {
60175
fn from(value: crate::trap::Label<generated::ExternItem>) -> Self {
61176
// SAFETY: this is safe because every concrete instance of `@extern_item` is also an instance of `@item`
62177
unsafe { Self::from_untyped(value.as_untyped()) }
63178
}
64179
}
65-
#[macro_export]
66-
macro_rules! post_emit {
67-
(Meta, $self:ident, $node:ident, $label:ident) => {
68-
$self.macro_context_depth -= 1;
69-
};
70-
(MacroCall, $self:ident, $node:ident, $label:ident) => {
71-
$self.extract_macro_call_expanded($node, $label);
72-
};
73-
(Function, $self:ident, $node:ident, $label:ident) => {
74-
$self.emit_function_has_implementation($node, $label);
75-
$self.extract_canonical_origin($node, $label.into());
76-
};
77-
(Trait, $self:ident, $node:ident, $label:ident) => {
78-
$self.extract_canonical_origin($node, $label.into());
79-
};
80-
(Struct, $self:ident, $node:ident, $label:ident) => {
81-
$self.emit_derive_expansion($node, $label);
82-
$self.extract_canonical_origin($node, $label.into());
83-
};
84-
(Enum, $self:ident, $node:ident, $label:ident) => {
85-
$self.emit_derive_expansion($node, $label);
86-
$self.extract_canonical_origin($node, $label.into());
87-
};
88-
(Union, $self:ident, $node:ident, $label:ident) => {
89-
$self.emit_derive_expansion($node, $label);
90-
$self.extract_canonical_origin($node, $label.into());
91-
};
92-
(Module, $self:ident, $node:ident, $label:ident) => {
93-
$self.extract_canonical_origin($node, $label.into());
94-
};
95-
(Variant, $self:ident, $node:ident, $label:ident) => {
96-
$self.extract_canonical_origin_of_enum_variant($node, $label);
97-
};
98-
(Item, $self:ident, $node:ident, $label:ident) => {
99-
$self.emit_item_expansion($node, $label);
100-
};
101-
(AssocItem, $self:ident, $node:ident, $label:ident) => {
102-
$self.emit_item_expansion(
103-
&$node.clone().into(),
104-
From::<Label<generated::AssocItem>>::from($label),
105-
);
106-
};
107-
(ExternItem, $self:ident, $node:ident, $label:ident) => {
108-
$self.emit_item_expansion(
109-
&$node.clone().into(),
110-
From::<Label<generated::ExternItem>>::from($label),
111-
);
112-
};
113-
// TODO canonical origin of other items
114-
(PathExpr, $self:ident, $node:ident, $label:ident) => {
115-
$self.extract_path_canonical_destination($node, $label.into());
116-
};
117-
(StructExpr, $self:ident, $node:ident, $label:ident) => {
118-
$self.extract_path_canonical_destination($node, $label.into());
119-
};
120-
(PathPat, $self:ident, $node:ident, $label:ident) => {
121-
$self.extract_path_canonical_destination($node, $label.into());
122-
};
123-
(StructPat, $self:ident, $node:ident, $label:ident) => {
124-
$self.extract_path_canonical_destination($node, $label.into());
125-
};
126-
(TupleStructPat, $self:ident, $node:ident, $label:ident) => {
127-
$self.extract_path_canonical_destination($node, $label.into());
128-
};
129-
(MethodCallExpr, $self:ident, $node:ident, $label:ident) => {
130-
$self.extract_method_canonical_destination($node, $label);
131-
};
132-
(PathSegment, $self:ident, $node:ident, $label:ident) => {
133-
$self.extract_types_from_path_segment($node, $label.into());
134-
};
135-
(Const, $self:ident, $node:ident, $label:ident) => {
136-
$self.emit_const_has_implementation($node, $label);
137-
};
138-
($($_:tt)*) => {};
139-
}
140180

141181
// see https://github.com/tokio-rs/tracing/issues/2730
142182
macro_rules! dispatch_to_tracing {

0 commit comments

Comments
 (0)