Skip to content

Commit

Permalink
Rust: exclude extraction of code excluded by cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
Paolo Tranquilli committed Dec 18, 2024
1 parent a6ec51a commit 218bc80
Show file tree
Hide file tree
Showing 6 changed files with 915 additions and 823 deletions.
28 changes: 19 additions & 9 deletions rust/ast-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{fs, path::PathBuf};
pub mod codegen;
mod flags;
use codegen::grammar::ast_src::{AstNodeSrc, AstSrc, Field};
use itertools::Itertools;
use std::collections::{BTreeMap, BTreeSet};
use std::env;
use ungrammar::Grammar;
Expand Down Expand Up @@ -475,10 +476,10 @@ use ra_ap_syntax::ast::{{
use ra_ap_syntax::{{ast, AstNode}};
impl Translator<'_> {{
fn emit_else_branch(&mut self, node: ast::ElseBranch) -> Label<generated::Expr> {{
fn emit_else_branch(&mut self, node: ast::ElseBranch) -> Option<Label<generated::Expr>> {{
match node {{
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).into(),
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).into(),
ast::ElseBranch::IfExpr(inner) => self.emit_if_expr(inner).map(Into::into),
ast::ElseBranch::Block(inner) => self.emit_block_expr(inner).map(Into::into),
}}
}}\n"
)?;
Expand All @@ -488,7 +489,7 @@ impl Translator<'_> {{

writeln!(
buf,
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Label<generated::{}> {{",
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Option<Label<generated::{}>> {{",
to_lower_snake_case(type_name),
type_name,
class_name
Expand All @@ -497,7 +498,7 @@ impl Translator<'_> {{
for variant in &node.variants {
writeln!(
buf,
" ast::{}::{}(inner) => self.emit_{}(inner).into(),",
" ast::{}::{}(inner) => self.emit_{}(inner).map(Into::into),",
type_name,
variant,
to_lower_snake_case(variant)
Expand All @@ -513,7 +514,7 @@ impl Translator<'_> {{

writeln!(
buf,
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Label<generated::{}> {{",
" pub(crate) fn emit_{}(&mut self, node: ast::{}) -> Option<Label<generated::{}>> {{",
to_lower_snake_case(type_name),
type_name,
class_name
Expand All @@ -523,6 +524,15 @@ impl Translator<'_> {{
continue;
}

if field.name == "attrs" {
// special case: this means the node type implements `HasAttrs`, and we want to
// check whether it was not excluded by a `cfg` attribute
writeln!(
buf,
" if self.should_be_excluded(&node) {{ return None; }}"
)?;
}

let type_name = &field.tp;
let struct_field_name = &field.name;
let class_field_name = property_name(&node.name, &field.name);
Expand All @@ -542,15 +552,15 @@ impl Translator<'_> {{
} else if field.is_many {
writeln!(
buf,
" let {} = node.{}().map(|x| self.emit_{}(x)).collect();",
" let {} = node.{}().filter_map(|x| self.emit_{}(x)).collect();",
class_field_name,
struct_field_name,
to_lower_snake_case(type_name)
)?;
} else {
writeln!(
buf,
" let {} = node.{}().map(|x| self.emit_{}(x));",
" let {} = node.{}().and_then(|x| self.emit_{}(x));",
class_field_name,
struct_field_name,
to_lower_snake_case(type_name)
Expand Down Expand Up @@ -582,7 +592,7 @@ impl Translator<'_> {{
buf,
" self.emit_tokens(&node, label.into(), node.syntax().children_with_tokens());"
)?;
writeln!(buf, " label")?;
writeln!(buf, " Some(label)")?;

writeln!(buf, " }}\n")?;
}
Expand Down
47 changes: 30 additions & 17 deletions rust/extractor/src/translate/base.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::mappings::{AddressableAst, AddressableHir, PathAst};
use crate::generated::MacroCall;
use crate::generated::{self};
use crate::rust_analyzer::FileSemanticInformation;
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
Expand Down Expand Up @@ -267,22 +266,22 @@ impl<'a> Translator<'a> {
expanded: SyntaxNode,
) -> Option<Label<generated::AstNode>> {
match expand_to {
ra_ap_hir_expand::ExpandTo::Statements => {
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
}
ra_ap_hir_expand::ExpandTo::Items => {
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
}
ra_ap_hir_expand::ExpandTo::Statements => ast::MacroStmts::cast(expanded)
.and_then(|x| self.emit_macro_stmts(x))
.map(Into::into),
ra_ap_hir_expand::ExpandTo::Items => ast::MacroItems::cast(expanded)
.and_then(|x| self.emit_macro_items(x))
.map(Into::into),

ra_ap_hir_expand::ExpandTo::Pattern => {
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
}
ra_ap_hir_expand::ExpandTo::Type => {
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
}
ra_ap_hir_expand::ExpandTo::Expr => {
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
}
ra_ap_hir_expand::ExpandTo::Pattern => ast::Pat::cast(expanded)
.and_then(|x| self.emit_pat(x))
.map(Into::into),
ra_ap_hir_expand::ExpandTo::Type => ast::Type::cast(expanded)
.and_then(|x| self.emit_type(x))
.map(Into::into),
ra_ap_hir_expand::ExpandTo::Expr => ast::Expr::cast(expanded)
.and_then(|x| self.emit_expr(x))
.map(Into::into),
}
}
pub(crate) fn extract_macro_call_expanded(
Expand All @@ -295,7 +294,7 @@ impl<'a> Translator<'a> {
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
let kind = expanded.kind();
if let Some(value) = self.emit_expanded_as(expand_to, expanded) {
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
generated::MacroCall::emit_expanded(label, value, &mut self.trap.writer);
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(mcall, &SyntaxError::new(
Expand Down Expand Up @@ -559,4 +558,18 @@ impl<'a> Translator<'a> {
Some(())
})();
}

pub(crate) fn should_be_excluded(&self, item: &impl ast::HasAttrs) -> bool {
let Some(sema) = self.semantics else {
return false;
};
for attr in item.attrs() {
if let Some((name, tokens)) = attr.as_simple_call() {
if name == "cfg" && sema.check_cfg_attr(&tokens) == Some(false) {
return true;
}
}
}
false
}
}
Loading

0 comments on commit 218bc80

Please sign in to comment.