diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/attr.rs | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 9cd0b72aa..b8d9c2682 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -122,9 +122,67 @@ impl RawAttrs { | |||
122 | } | 122 | } |
123 | 123 | ||
124 | /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. | 124 | /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. |
125 | pub(crate) fn filter(self, _db: &dyn DefDatabase, _krate: CrateId) -> Attrs { | 125 | pub(crate) fn filter(self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { |
126 | // FIXME actually implement this | 126 | let has_cfg_attrs = self.iter().any(|attr| { |
127 | Attrs(self) | 127 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]) |
128 | }); | ||
129 | if !has_cfg_attrs { | ||
130 | return Attrs(self); | ||
131 | } | ||
132 | |||
133 | let crate_graph = db.crate_graph(); | ||
134 | let new_attrs = self | ||
135 | .iter() | ||
136 | .filter_map(|attr| { | ||
137 | let attr = attr.clone(); | ||
138 | let is_cfg_attr = | ||
139 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); | ||
140 | if !is_cfg_attr { | ||
141 | return Some(attr); | ||
142 | } | ||
143 | |||
144 | let subtree = match &attr.input { | ||
145 | Some(AttrInput::TokenTree(it)) => it, | ||
146 | _ => return Some(attr), | ||
147 | }; | ||
148 | |||
149 | // Input subtree is: `(cfg, attr)` | ||
150 | // Split it up into a `cfg` and an `attr` subtree. | ||
151 | // FIXME: There should be a common API for this. | ||
152 | let mut saw_comma = false; | ||
153 | let (mut cfg, attr): (Vec<_>, Vec<_>) = | ||
154 | subtree.clone().token_trees.into_iter().partition(|tree| { | ||
155 | if saw_comma { | ||
156 | return false; | ||
157 | } | ||
158 | |||
159 | match tree { | ||
160 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
161 | saw_comma = true; | ||
162 | } | ||
163 | _ => {} | ||
164 | } | ||
165 | |||
166 | true | ||
167 | }); | ||
168 | cfg.pop(); // `,` ends up in here | ||
169 | |||
170 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg }; | ||
171 | let cfg = CfgExpr::parse(&cfg); | ||
172 | |||
173 | let cfg_options = &crate_graph[krate].cfg_options; | ||
174 | if cfg_options.check(&cfg) == Some(false) { | ||
175 | None | ||
176 | } else { | ||
177 | let attr = Subtree { delimiter: None, token_trees: attr }; | ||
178 | let attr = ast::Attr::parse(&attr.to_string()).ok()?; | ||
179 | let hygiene = Hygiene::new_unhygienic(); // FIXME | ||
180 | Attr::from_src(attr, &hygiene) | ||
181 | } | ||
182 | }) | ||
183 | .collect(); | ||
184 | |||
185 | Attrs(RawAttrs { entries: Some(new_attrs) }) | ||
128 | } | 186 | } |
129 | } | 187 | } |
130 | 188 | ||