Skip to content

Commit 218bc80

Browse files
author
Paolo Tranquilli
committed
Rust: exclude extraction of code excluded by cfg
1 parent a6ec51a commit 218bc80

File tree

6 files changed

+915
-823
lines changed

6 files changed

+915
-823
lines changed

rust/ast-generator/src/main.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{fs, path::PathBuf};
44
pub mod codegen;
55
mod flags;
66
use codegen::grammar::ast_src::{AstNodeSrc, AstSrc, Field};
7+
use itertools::Itertools;
78
use std::collections::{BTreeMap, BTreeSet};
89
use std::env;
910
use ungrammar::Grammar;
@@ -475,10 +476,10 @@ use ra_ap_syntax::ast::{{
475476
use ra_ap_syntax::{{ast, AstNode}};
476477
477478
impl Translator<'_> {{
478-
fn emit_else_branch(&mut self, node: ast::ElseBranch) -> Label<generated::Expr> {{
479+
fn emit_else_branch(&mut self, node: ast::ElseBranch) -> Option<Label<generated::Expr>> {{
479480
match node {{
480-
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).into(),
481-
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).into(),
481+
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).map(Into::into),
482+
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).map(Into::into),
482483
}}
483484
}}\n"
484485
)?;
@@ -488,7 +489,7 @@ impl Translator<'_> {{
488489

489490
writeln!(
490491
buf,
491-
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Label<generated::{}> {{",
492+
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Option<Label<generated::{}>> {{",
492493
to_lower_snake_case(type_name),
493494
type_name,
494495
class_name
@@ -497,7 +498,7 @@ impl Translator<'_> {{
497498
for variant in &node.variants {
498499
writeln!(
499500
buf,
500-
" ast::{}::{}(inner) => self.emit_{}(inner).into(),",
501+
" ast::{}::{}(inner) => self.emit_{}(inner).map(Into::into),",
501502
type_name,
502503
variant,
503504
to_lower_snake_case(variant)
@@ -513,7 +514,7 @@ impl Translator<'_> {{
513514

514515
writeln!(
515516
buf,
516-
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Label<generated::{}> {{",
517+
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Option<Label<generated::{}>> {{",
517518
to_lower_snake_case(type_name),
518519
type_name,
519520
class_name
@@ -523,6 +524,15 @@ impl Translator<'_> {{
523524
continue;
524525
}
525526

527+
if field.name == "attrs" {
528+
// special case: this means the node type implements `HasAttrs`, and we want to
529+
// check whether it was not excluded by a `cfg` attribute
530+
writeln!(
531+
buf,
532+
" if self.should_be_excluded(&node) {{ return None; }}"
533+
)?;
534+
}
535+
526536
let type_name = &field.tp;
527537
let struct_field_name = &field.name;
528538
let class_field_name = property_name(&node.name, &field.name);
@@ -542,15 +552,15 @@ impl Translator<'_> {{
542552
} else if field.is_many {
543553
writeln!(
544554
buf,
545-
" let {} = node.{}().map(|x| self.emit_{}(x)).collect();",
555+
" let {} = node.{}().filter_map(|x| self.emit_{}(x)).collect();",
546556
class_field_name,
547557
struct_field_name,
548558
to_lower_snake_case(type_name)
549559
)?;
550560
} else {
551561
writeln!(
552562
buf,
553-
" let {} = node.{}().map(|x| self.emit_{}(x));",
563+
" let {} = node.{}().and_then(|x| self.emit_{}(x));",
554564
class_field_name,
555565
struct_field_name,
556566
to_lower_snake_case(type_name)
@@ -582,7 +592,7 @@ impl Translator<'_> {{
582592
buf,
583593
" self.emit_tokens(&node, label.into(), node.syntax().children_with_tokens());"
584594
)?;
585-
writeln!(buf, " label")?;
595+
writeln!(buf, " Some(label)")?;
586596

587597
writeln!(buf, " }}\n")?;
588598
}

rust/extractor/src/translate/base.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::mappings::{AddressableAst, AddressableHir, PathAst};
2-
use crate::generated::MacroCall;
32
use crate::generated::{self};
43
use crate::rust_analyzer::FileSemanticInformation;
54
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
@@ -267,22 +266,22 @@ impl<'a> Translator<'a> {
267266
expanded: SyntaxNode,
268267
) -> Option<Label<generated::AstNode>> {
269268
match expand_to {
270-
ra_ap_hir_expand::ExpandTo::Statements => {
271-
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
272-
}
273-
ra_ap_hir_expand::ExpandTo::Items => {
274-
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
275-
}
269+
ra_ap_hir_expand::ExpandTo::Statements => ast::MacroStmts::cast(expanded)
270+
.and_then(|x| self.emit_macro_stmts(x))
271+
.map(Into::into),
272+
ra_ap_hir_expand::ExpandTo::Items => ast::MacroItems::cast(expanded)
273+
.and_then(|x| self.emit_macro_items(x))
274+
.map(Into::into),
276275

277-
ra_ap_hir_expand::ExpandTo::Pattern => {
278-
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
279-
}
280-
ra_ap_hir_expand::ExpandTo::Type => {
281-
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
282-
}
283-
ra_ap_hir_expand::ExpandTo::Expr => {
284-
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
285-
}
276+
ra_ap_hir_expand::ExpandTo::Pattern => ast::Pat::cast(expanded)
277+
.and_then(|x| self.emit_pat(x))
278+
.map(Into::into),
279+
ra_ap_hir_expand::ExpandTo::Type => ast::Type::cast(expanded)
280+
.and_then(|x| self.emit_type(x))
281+
.map(Into::into),
282+
ra_ap_hir_expand::ExpandTo::Expr => ast::Expr::cast(expanded)
283+
.and_then(|x| self.emit_expr(x))
284+
.map(Into::into),
286285
}
287286
}
288287
pub(crate) fn extract_macro_call_expanded(
@@ -295,7 +294,7 @@ impl<'a> Translator<'a> {
295294
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
296295
let kind = expanded.kind();
297296
if let Some(value) = self.emit_expanded_as(expand_to, expanded) {
298-
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
297+
generated::MacroCall::emit_expanded(label, value, &mut self.trap.writer);
299298
} else {
300299
let range = self.text_range_for_node(mcall);
301300
self.emit_parse_error(mcall, &SyntaxError::new(
@@ -559,4 +558,18 @@ impl<'a> Translator<'a> {
559558
Some(())
560559
})();
561560
}
561+
562+
pub(crate) fn should_be_excluded(&self, item: &impl ast::HasAttrs) -> bool {
563+
let Some(sema) = self.semantics else {
564+
return false;
565+
};
566+
for attr in item.attrs() {
567+
if let Some((name, tokens)) = attr.as_simple_call() {
568+
if name == "cfg" && sema.check_cfg_attr(&tokens) == Some(false) {
569+
return true;
570+
}
571+
}
572+
}
573+
false
574+
}
562575
}

0 commit comments

Comments
 (0)