Skip to content

Commit 7c8fc79

Browse files
committed
Rust: extract getExpended on Items
1 parent 7e108a8 commit 7c8fc79

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2108
-1320
lines changed

rust/ast-generator/BUILD.bazel

+1-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ codeql_rust_binary(
4646
) + [":codegen"],
4747
aliases = aliases(),
4848
args = ["$(rlocationpath :rust.ungram)"],
49-
compile_data = glob(["src/templates/*.mustache"]),
50-
data = [":rust.ungram"],
49+
data = [":rust.ungram"] + glob(["templates/*.mustache"]),
5150
proc_macro_deps = all_crate_deps(
5251
proc_macro = True,
5352
),

rust/ast-generator/src/main.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ fn fix_blank_lines(s: &str) -> String {
142142
fn write_schema(
143143
grammar: &AstSrc,
144144
super_types: BTreeMap<String, BTreeSet<String>>,
145+
mustache_ctx: &mustache::Context,
145146
) -> mustache::Result<String> {
146147
let mut schema = Schema::default();
147148
schema.classes.extend(
@@ -156,7 +157,7 @@ fn write_schema(
156157
.iter()
157158
.map(|node| node_src_to_schema_class(node, &super_types)),
158159
);
159-
let template = mustache::compile_str(include_str!("templates/schema.mustache"))?;
160+
let template = mustache_ctx.compile_path("schema")?;
160161
let res = template.render_to_string(&schema)?;
161162
Ok(fix_blank_lines(&res))
162163
}
@@ -541,7 +542,7 @@ fn node_to_extractor_info(node: &AstNodeSrc) -> ExtractorNodeInfo {
541542
}
542543
}
543544

544-
fn write_extractor(grammar: &AstSrc) -> mustache::Result<String> {
545+
fn write_extractor(grammar: &AstSrc, mustache_ctx: &mustache::Context) -> mustache::Result<String> {
545546
let extractor_info = ExtractorInfo {
546547
enums: grammar
547548
.enums
@@ -550,7 +551,7 @@ fn write_extractor(grammar: &AstSrc) -> mustache::Result<String> {
550551
.collect(),
551552
nodes: grammar.nodes.iter().map(node_to_extractor_info).collect(),
552553
};
553-
let template = mustache::compile_str(include_str!("templates/extractor.mustache"))?;
554+
let template = mustache_ctx.compile_path("extractor")?;
554555
let res = template.render_to_string(&extractor_info)?;
555556
Ok(fix_blank_lines(&res))
556557
}
@@ -578,16 +579,21 @@ fn main() -> anyhow::Result<()> {
578579
let super_class_y = super_types.get(&y.name).into_iter().flatten().max();
579580
super_class_x.cmp(&super_class_y).then(x.name.cmp(&y.name))
580581
});
581-
let schema = write_schema(&grammar, super_types)?;
582-
let schema_path = project_root().join("schema/ast.py");
582+
let root = project_root();
583+
let mustache_ctx = mustache::Context {
584+
template_path: root.join("ast-generator").join("templates"),
585+
template_extension: "mustache".to_string(),
586+
};
587+
let schema = write_schema(&grammar, super_types, &mustache_ctx)?;
588+
let schema_path = root.join("schema/ast.py");
583589
codegen::ensure_file_contents(
584590
crate::flags::CodegenType::Grammar,
585591
&schema_path,
586592
&schema,
587593
false,
588594
);
589595

590-
let extractor = write_extractor(&grammar)?;
596+
let extractor = write_extractor(&grammar, &mustache_ctx)?;
591597
let extractor_path = project_root().join("extractor/src/translate/generated.rs");
592598
codegen::ensure_file_contents(
593599
crate::flags::CodegenType::Grammar,

rust/ast-generator/src/templates/extractor.mustache renamed to rust/ast-generator/templates/extractor.mustache

+18-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! Generated by `ast-generator`, do not edit by hand.
2-
{{! <- denotes empty line that should be kept, all blank lines are removed otherwise}}
3-
#![cfg_attr(any(), rustfmt::skip)]
4-
2+
53
use super::base::Translator;
64
use super::mappings::TextValue;
75
use crate::emit_detached;
@@ -11,30 +9,33 @@ use ra_ap_syntax::ast::{
119
HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasModuleItem, HasName,
1210
HasTypeBounds, HasVisibility, RangeItem,
1311
};
14-
use ra_ap_syntax::{ast, AstNode};
15-
12+
#[rustfmt::skip]
13+
use ra_ap_syntax::{AstNode, ast};
14+
1615
impl Translator<'_> {
17-
fn emit_else_branch(&mut self, node: ast::ElseBranch) -> Option<Label<generated::Expr>> {
16+
fn emit_else_branch(&mut self, node: &ast::ElseBranch) -> Option<Label<generated::Expr>> {
1817
match node {
1918
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).map(Into::into),
2019
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).map(Into::into),
2120
}
2221
}
2322
{{#enums}}
24-
25-
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
26-
match node {
23+
24+
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
25+
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}}
30-
}
29+
}?;
30+
emit_detached!({{name}}, self, node, label);
31+
Some(label)
3132
}
3233
{{/enums}}
3334
{{#nodes}}
34-
35-
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
35+
36+
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
3637
{{#has_attrs}}
37-
if self.should_be_excluded(&node) { return None; }
38+
if self.should_be_excluded(node) { return None; }
3839
{{/has_attrs}}
3940
{{#fields}}
4041
{{#predicate}}
@@ -44,10 +45,10 @@ impl Translator<'_> {
4445
let {{name}} = node.try_get_text();
4546
{{/string}}
4647
{{#list}}
47-
let {{name}} = node.{{method}}().filter_map(|x| self.emit_{{snake_case_ty}}(x)).collect();
48+
let {{name}} = node.{{method}}().filter_map(|x| self.emit_{{snake_case_ty}}(&x)).collect();
4849
{{/list}}
4950
{{#optional}}
50-
let {{name}} = node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(x));
51+
let {{name}} = node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(&x));
5152
{{/optional}}
5253
{{/fields}}
5354
let label = self.trap.emit(generated::{{name}} {
@@ -56,9 +57,9 @@ impl Translator<'_> {
5657
{{name}},
5758
{{/fields}}
5859
});
59-
self.emit_location(label, &node);
60+
self.emit_location(label, node);
6061
emit_detached!({{name}}, self, node, label);
61-
self.emit_tokens(&node, label.into(), node.syntax().children_with_tokens());
62+
self.emit_tokens(node, label.into(), node.syntax().children_with_tokens());
6263
Some(label)
6364
}
6465
{{/nodes}}

rust/codegen/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ _args = [
77
"//rust/ast-generator:Cargo.toml",
88
"//misc/codegen",
99
"//rust:codegen-conf",
10+
"@rules_rust//tools/rustfmt:upstream_rustfmt",
1011
]
1112

1213
sh_binary(

rust/codegen/codegen.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ grammar_file="$(rlocation "$2")"
99
ast_generator_manifest="$(rlocation "$3")"
1010
codegen="$(rlocation "$4")"
1111
codegen_conf="$(rlocation "$5")"
12-
shift 5
12+
rustfmt="$(rlocation "$6")"
13+
shift 6
1314

1415
CARGO_MANIFEST_DIR="$(dirname "$ast_generator_manifest")" "$ast_generator" "$grammar_file"
16+
"$rustfmt" "$(dirname "$ast_generator_manifest")/../extractor/src/translate/generated.rs"
1517
"$codegen" --configuration-file="$codegen_conf" "$@"

rust/extractor/src/generated/.generated.list

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/extractor/src/generated/top.rs

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/extractor/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a> Extractor<'a> {
8989
no_location,
9090
);
9191
}
92-
translator.emit_source_file(ast);
92+
translator.emit_source_file(&ast);
9393
translator.trap.commit().unwrap_or_else(|err| {
9494
error!(
9595
"Failed to write trap file for: {}: {}",

rust/extractor/src/translate/base.rs

+48-27
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ra_ap_hir::{
1111
};
1212
use ra_ap_hir_def::ModuleId;
1313
use ra_ap_hir_def::type_ref::Mutability;
14-
use ra_ap_hir_expand::ExpandTo;
14+
use ra_ap_hir_expand::{ExpandResult, ExpandTo};
1515
use ra_ap_ide_db::RootDatabase;
1616
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
1717
use ra_ap_parser::SyntaxKind;
@@ -25,50 +25,53 @@ use ra_ap_syntax::{
2525
#[macro_export]
2626
macro_rules! emit_detached {
2727
(MacroCall, $self:ident, $node:ident, $label:ident) => {
28-
$self.extract_macro_call_expanded(&$node, $label);
28+
$self.extract_macro_call_expanded($node, $label);
2929
};
3030
(Function, $self:ident, $node:ident, $label:ident) => {
31-
$self.extract_canonical_origin(&$node, $label.into());
31+
$self.extract_canonical_origin($node, $label.into());
3232
};
3333
(Trait, $self:ident, $node:ident, $label:ident) => {
34-
$self.extract_canonical_origin(&$node, $label.into());
34+
$self.extract_canonical_origin($node, $label.into());
3535
};
3636
(Struct, $self:ident, $node:ident, $label:ident) => {
37-
$self.extract_canonical_origin(&$node, $label.into());
37+
$self.extract_canonical_origin($node, $label.into());
3838
};
3939
(Enum, $self:ident, $node:ident, $label:ident) => {
40-
$self.extract_canonical_origin(&$node, $label.into());
40+
$self.extract_canonical_origin($node, $label.into());
4141
};
4242
(Union, $self:ident, $node:ident, $label:ident) => {
43-
$self.extract_canonical_origin(&$node, $label.into());
43+
$self.extract_canonical_origin($node, $label.into());
4444
};
4545
(Module, $self:ident, $node:ident, $label:ident) => {
46-
$self.extract_canonical_origin(&$node, $label.into());
46+
$self.extract_canonical_origin($node, $label.into());
4747
};
4848
(Variant, $self:ident, $node:ident, $label:ident) => {
49-
$self.extract_canonical_origin_of_enum_variant(&$node, $label);
49+
$self.extract_canonical_origin_of_enum_variant($node, $label);
50+
};
51+
(Item, $self:ident, $node:ident, $label:ident) => {
52+
$self.emit_item_expansion($node, $label);
5053
};
5154
// TODO canonical origin of other items
5255
(PathExpr, $self:ident, $node:ident, $label:ident) => {
53-
$self.extract_path_canonical_destination(&$node, $label.into());
56+
$self.extract_path_canonical_destination($node, $label.into());
5457
};
5558
(StructExpr, $self:ident, $node:ident, $label:ident) => {
56-
$self.extract_path_canonical_destination(&$node, $label.into());
59+
$self.extract_path_canonical_destination($node, $label.into());
5760
};
5861
(PathPat, $self:ident, $node:ident, $label:ident) => {
59-
$self.extract_path_canonical_destination(&$node, $label.into());
62+
$self.extract_path_canonical_destination($node, $label.into());
6063
};
6164
(StructPat, $self:ident, $node:ident, $label:ident) => {
62-
$self.extract_path_canonical_destination(&$node, $label.into());
65+
$self.extract_path_canonical_destination($node, $label.into());
6366
};
6467
(TupleStructPat, $self:ident, $node:ident, $label:ident) => {
65-
$self.extract_path_canonical_destination(&$node, $label.into());
68+
$self.extract_path_canonical_destination($node, $label.into());
6669
};
6770
(MethodCallExpr, $self:ident, $node:ident, $label:ident) => {
68-
$self.extract_method_canonical_destination(&$node, $label);
71+
$self.extract_method_canonical_destination($node, $label);
6972
};
7073
(PathSegment, $self:ident, $node:ident, $label:ident) => {
71-
$self.extract_types_from_path_segment(&$node, $label.into());
74+
$self.extract_types_from_path_segment($node, $label.into());
7275
};
7376
($($_:tt)*) => {};
7477
}
@@ -252,7 +255,11 @@ impl<'a> Translator<'a> {
252255
}
253256
}
254257
}
255-
fn emit_macro_expansion_parse_errors(&mut self, mcall: &ast::MacroCall, expanded: &SyntaxNode) {
258+
fn emit_macro_expansion_parse_errors(
259+
&mut self,
260+
node: &impl ast::AstNode,
261+
expanded: &SyntaxNode,
262+
) {
256263
let semantics = self.semantics.as_ref().unwrap();
257264
if let Some(value) = semantics
258265
.hir_file_for(expanded)
@@ -266,19 +273,19 @@ impl<'a> Translator<'a> {
266273
if let Some(err) = &value.err {
267274
let error = err.render_to_string(semantics.db);
268275

269-
if err.span().anchor.file_id == semantics.hir_file_for(mcall.syntax()) {
276+
if err.span().anchor.file_id == semantics.hir_file_for(node.syntax()) {
270277
let location = err.span().range
271278
+ semantics
272279
.db
273280
.ast_id_map(err.span().anchor.file_id.into())
274281
.get_erased(err.span().anchor.ast_id)
275282
.text_range()
276283
.start();
277-
self.emit_parse_error(mcall, &SyntaxError::new(error.message, location));
284+
self.emit_parse_error(node, &SyntaxError::new(error.message, location));
278285
};
279286
}
280287
for err in value.value.iter() {
281-
self.emit_parse_error(mcall, err);
288+
self.emit_parse_error(node, err);
282289
}
283290
}
284291
}
@@ -290,20 +297,20 @@ impl<'a> Translator<'a> {
290297
) -> Option<Label<generated::AstNode>> {
291298
match expand_to {
292299
ra_ap_hir_expand::ExpandTo::Statements => ast::MacroStmts::cast(expanded)
293-
.and_then(|x| self.emit_macro_stmts(x))
300+
.and_then(|x| self.emit_macro_stmts(&x))
294301
.map(Into::into),
295302
ra_ap_hir_expand::ExpandTo::Items => ast::MacroItems::cast(expanded)
296-
.and_then(|x| self.emit_macro_items(x))
303+
.and_then(|x| self.emit_macro_items(&x))
297304
.map(Into::into),
298305

299306
ra_ap_hir_expand::ExpandTo::Pattern => ast::Pat::cast(expanded)
300-
.and_then(|x| self.emit_pat(x))
307+
.and_then(|x| self.emit_pat(&x))
301308
.map(Into::into),
302309
ra_ap_hir_expand::ExpandTo::Type => ast::Type::cast(expanded)
303-
.and_then(|x| self.emit_type(x))
310+
.and_then(|x| self.emit_type(&x))
304311
.map(Into::into),
305312
ra_ap_hir_expand::ExpandTo::Expr => ast::Expr::cast(expanded)
306-
.and_then(|x| self.emit_expr(x))
313+
.and_then(|x| self.emit_expr(&x))
307314
.map(Into::into),
308315
}
309316
}
@@ -626,17 +633,31 @@ impl<'a> Translator<'a> {
626633
if let Some(t) = type_refs
627634
.next()
628635
.and_then(ast::Type::cast)
629-
.and_then(|t| self.emit_type(t))
636+
.and_then(|t| self.emit_type(&t))
630637
{
631638
generated::PathSegment::emit_type_repr(label, t, &mut self.trap.writer)
632639
}
633640
if let Some(t) = type_refs
634641
.next()
635642
.and_then(ast::PathType::cast)
636-
.and_then(|t| self.emit_path_type(t))
643+
.and_then(|t| self.emit_path_type(&t))
637644
{
638645
generated::PathSegment::emit_trait_type_repr(label, t, &mut self.trap.writer)
639646
}
640647
}
641648
}
649+
650+
pub(crate) fn emit_item_expansion(&mut self, node: &ast::Item, label: Label<generated::Item>) {
651+
(|| {
652+
let semantics = self.semantics?;
653+
let ExpandResult {
654+
value: expanded, ..
655+
} = semantics.expand_attr_macro(node)?;
656+
// TODO emit err?
657+
self.emit_macro_expansion_parse_errors(node, &expanded);
658+
let expanded = self.emit_expanded_as(ExpandTo::Items, expanded)?;
659+
generated::Item::emit_expanded(label, expanded, &mut self.trap.writer);
660+
Some(())
661+
})();
662+
}
642663
}

0 commit comments

Comments
 (0)