Skip to content

Commit 33282c7

Browse files
committed
Merge branch 'cfg_attr' of https://github.com/wyatt-herkamp/rust-analyzer into cfg_attr
2 parents 2cfbaed + f45b080 commit 33282c7

File tree

5 files changed

+84
-2
lines changed

5 files changed

+84
-2
lines changed

crates/cfg/src/cfg_attr.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use std::{
2+
fmt::{self, Debug},
3+
slice::Iter as SliceIter,
4+
};
5+
6+
use crate::{cfg_expr::next_cfg_expr, CfgAtom, CfgExpr};
7+
use tt::{Delimiter, SmolStr, Span};
8+
/// Represents a `#[cfg_attr(.., my_attr)]` attribute.
9+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10+
pub struct CfgAttr<S> {
11+
/// Expression in `cfg_attr` attribute.
12+
pub cfg_expr: CfgExpr,
13+
/// Inner attribute.
14+
pub attr: tt::Subtree<S>,
15+
}
16+
17+
impl<S: Clone + Span + Debug> CfgAttr<S> {
18+
/// Parses a sub tree in the form of (cfg_expr, inner_attribute)
19+
pub fn parse(tt: &tt::Subtree<S>) -> Option<CfgAttr<S>> {
20+
let mut iter = tt.token_trees.iter();
21+
let cfg_expr = next_cfg_expr(&mut iter).unwrap_or(CfgExpr::Invalid);
22+
// FIXME: This is probably not the right way to do this
23+
// Get's the span of the next token tree
24+
let first_span = iter.as_slice().first().map(|tt| tt.first_span())?;
25+
let attr = tt::Subtree {
26+
delimiter: Delimiter::invisible_spanned(first_span),
27+
token_trees: iter.cloned().collect(),
28+
};
29+
Some(CfgAttr { cfg_expr, attr: attr })
30+
}
31+
}
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use expect_test::{expect, Expect};
36+
use mbe::{syntax_node_to_token_tree, DummyTestSpanMap, DUMMY};
37+
use syntax::{ast, AstNode};
38+
39+
use crate::{CfgAttr, DnfExpr};
40+
41+
fn check_dnf(input: &str, expected_dnf: Expect, expected_attrs: Expect) {
42+
let source_file = ast::SourceFile::parse(input).ok().unwrap();
43+
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
44+
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap, DUMMY);
45+
let Some(CfgAttr { cfg_expr, attr }) = CfgAttr::parse(&tt) else {
46+
assert!(false, "failed to parse cfg_attr");
47+
return;
48+
};
49+
50+
let actual = format!("#![cfg({})]", DnfExpr::new(cfg_expr));
51+
expected_dnf.assert_eq(&actual);
52+
let actual_attrs = format!("#![{}]", attr);
53+
expected_attrs.assert_eq(&actual_attrs);
54+
}
55+
56+
#[test]
57+
fn smoke() {
58+
check_dnf(
59+
r#"#![cfg_attr(feature = "nightly", feature(slice_split_at_unchecked))]"#,
60+
expect![[r#"#![cfg(feature = "nightly")]"#]],
61+
expect![r#"#![feature (slice_split_at_unchecked)]"#],
62+
);
63+
64+
check_dnf(
65+
r#"#![cfg_attr(not(feature = "std"), no_std)]"#,
66+
expect![[r#"#![cfg(not(feature = "std"))]"#]],
67+
expect![r#"#![no_std]"#],
68+
);
69+
}
70+
}

crates/cfg/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
#![warn(rust_2018_idioms, unused_lifetimes)]
44

5-
pub mod cfg_expr;
5+
mod cfg_expr;
66
mod dnf;
77
#[cfg(test)]
88
mod tests;
@@ -12,6 +12,7 @@ use std::fmt;
1212
use rustc_hash::FxHashSet;
1313
use tt::SmolStr;
1414

15+
pub use cfg_attr::CfgAttr;
1516
pub use cfg_expr::{CfgAtom, CfgExpr};
1617
pub use dnf::DnfExpr;
1718

crates/hir-expand/src/db.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use syntax::{
1010
ast::{self, HasAttrs},
1111
AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T,
1212
};
13+
use tracing::info;
1314
use triomphe::Arc;
1415

1516
use crate::{
@@ -461,7 +462,14 @@ fn macro_arg(
461462
}
462463
}
463464
}
464-
465+
fn censor_cfg_elements(
466+
node: &SyntaxNode,
467+
loc: &MacroCallLoc,
468+
span_map: &SpanMap,
469+
db: &dyn ExpandDatabase,
470+
) -> FxHashSet<SyntaxElement> {
471+
cfg_process::process_cfg_attrs(node, loc, span_map, db).unwrap_or_default()
472+
}
465473
// FIXME: Censoring info should be calculated by the caller! Namely by name resolution
466474
/// Certain macro calls expect some nodes in the input to be preprocessed away, namely:
467475
/// - derives expect all `#[derive(..)]` invocations up to the currently invoked one to be stripped

crates/hir-expand/src/fixup.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub(crate) fn fixup_syntax(
5252
) -> SyntaxFixups {
5353
let mut append = FxHashMap::<SyntaxElement, _>::default();
5454
let mut remove = FxHashSet::<SyntaxElement>::default();
55+
let mut remove = FxHashSet::<SyntaxElement>::default();
5556
let mut preorder = node.preorder();
5657
let mut original = Vec::new();
5758
let dummy_range = FIXUP_DUMMY_RANGE;
@@ -68,6 +69,7 @@ pub(crate) fn fixup_syntax(
6869

6970
let node_range = node.text_range();
7071
if can_handle_error(&node) && has_error_to_handle(&node) {
72+
remove.insert(node.clone().into());
7173
remove.insert(node.clone().into());
7274
// the node contains an error node, we have to completely replace it by something valid
7375
let original_tree = mbe::syntax_node_to_token_tree(&node, span_map, call_site);

crates/mbe/src/syntax_bridge.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use syntax::{
99
SyntaxKind::{self, *},
1010
SyntaxNode, SyntaxToken, SyntaxTreeBuilder, TextRange, TextSize, WalkEvent, T,
1111
};
12+
use tracing::info;
1213
use tt::{
1314
buffer::{Cursor, TokenBuffer},
1415
Span,

0 commit comments

Comments
 (0)