diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-10-05 15:25:59 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-10-05 15:25:59 +0100 |
commit | ae6305b90c80eb919cfde985cba66975b6222ed2 (patch) | |
tree | de601daf3714c4bda937e7cad05d048b69d16e71 /crates/ra_hir/src/nameres/collector.rs | |
parent | dbf869b4d2dac09df17609edf6e67c1611b71dc5 (diff) | |
parent | c6303d9fee98232ac83a77f943c39d65c9c6b6db (diff) |
Merge #1928
1928: Support `#[cfg(..)]` r=matklad a=oxalica
This PR implement `#[cfg(..)]` conditional compilation. It read default cfg options from `rustc --print cfg` with also hard-coded `test` and `debug_assertion` enabled.
Front-end settings are **not** included in this PR.
There is also a known issue that inner control attributes are totally ignored. I think it is **not** a part of `cfg` and create a separated issue for it. #1949
Fixes #1920
Related: #1073
Co-authored-by: uHOOCCOOHu <[email protected]>
Co-authored-by: oxalica <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index a568fdabd..cef2dc9d2 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_cfg::CfgOptions; | ||
3 | use ra_db::FileId; | 4 | use ra_db::FileId; |
4 | use ra_syntax::{ast, SmolStr}; | 5 | use ra_syntax::{ast, SmolStr}; |
5 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
@@ -35,6 +36,9 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C | |||
35 | } | 36 | } |
36 | } | 37 | } |
37 | 38 | ||
39 | let crate_graph = db.crate_graph(); | ||
40 | let cfg_options = crate_graph.cfg_options(def_map.krate().crate_id()); | ||
41 | |||
38 | let mut collector = DefCollector { | 42 | let mut collector = DefCollector { |
39 | db, | 43 | db, |
40 | def_map, | 44 | def_map, |
@@ -42,6 +46,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C | |||
42 | unresolved_imports: Vec::new(), | 46 | unresolved_imports: Vec::new(), |
43 | unexpanded_macros: Vec::new(), | 47 | unexpanded_macros: Vec::new(), |
44 | macro_stack_monitor: MacroStackMonitor::default(), | 48 | macro_stack_monitor: MacroStackMonitor::default(), |
49 | cfg_options, | ||
45 | }; | 50 | }; |
46 | collector.collect(); | 51 | collector.collect(); |
47 | collector.finish() | 52 | collector.finish() |
@@ -76,8 +81,8 @@ impl MacroStackMonitor { | |||
76 | } | 81 | } |
77 | 82 | ||
78 | /// Walks the tree of module recursively | 83 | /// Walks the tree of module recursively |
79 | struct DefCollector<DB> { | 84 | struct DefCollector<'a, DB> { |
80 | db: DB, | 85 | db: &'a DB, |
81 | def_map: CrateDefMap, | 86 | def_map: CrateDefMap, |
82 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, | 87 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, |
83 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, | 88 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, |
@@ -86,9 +91,11 @@ struct DefCollector<DB> { | |||
86 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly | 91 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly |
87 | /// To prevent stack overflow, we add a deep counter here for prevent that. | 92 | /// To prevent stack overflow, we add a deep counter here for prevent that. |
88 | macro_stack_monitor: MacroStackMonitor, | 93 | macro_stack_monitor: MacroStackMonitor, |
94 | |||
95 | cfg_options: &'a CfgOptions, | ||
89 | } | 96 | } |
90 | 97 | ||
91 | impl<'a, DB> DefCollector<&'a DB> | 98 | impl<DB> DefCollector<'_, DB> |
92 | where | 99 | where |
93 | DB: DefDatabase, | 100 | DB: DefDatabase, |
94 | { | 101 | { |
@@ -506,7 +513,7 @@ struct ModCollector<'a, D> { | |||
506 | parent_module: Option<ParentModule<'a>>, | 513 | parent_module: Option<ParentModule<'a>>, |
507 | } | 514 | } |
508 | 515 | ||
509 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> | 516 | impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> |
510 | where | 517 | where |
511 | DB: DefDatabase, | 518 | DB: DefDatabase, |
512 | { | 519 | { |
@@ -523,24 +530,27 @@ where | |||
523 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 530 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
524 | // any other items. | 531 | // any other items. |
525 | for item in items { | 532 | for item in items { |
526 | if let raw::RawItem::Import(import_id) = *item { | 533 | if self.is_cfg_enabled(&item.attrs) { |
527 | let import = self.raw_items[import_id].clone(); | 534 | if let raw::RawItemKind::Import(import_id) = item.kind { |
528 | if import.is_extern_crate && import.is_macro_use { | 535 | let import = self.raw_items[import_id].clone(); |
529 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); | 536 | if import.is_extern_crate && import.is_macro_use { |
537 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); | ||
538 | } | ||
530 | } | 539 | } |
531 | } | 540 | } |
532 | } | 541 | } |
533 | 542 | ||
534 | for item in items { | 543 | for item in items { |
535 | match *item { | 544 | if self.is_cfg_enabled(&item.attrs) { |
536 | raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]), | 545 | match item.kind { |
537 | raw::RawItem::Import(import_id) => self.def_collector.unresolved_imports.push(( | 546 | raw::RawItemKind::Module(m) => self.collect_module(&self.raw_items[m]), |
538 | self.module_id, | 547 | raw::RawItemKind::Import(import_id) => self |
539 | import_id, | 548 | .def_collector |
540 | self.raw_items[import_id].clone(), | 549 | .unresolved_imports |
541 | )), | 550 | .push((self.module_id, import_id, self.raw_items[import_id].clone())), |
542 | raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]), | 551 | raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]), |
543 | raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]), | 552 | raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]), |
553 | } | ||
544 | } | 554 | } |
545 | } | 555 | } |
546 | } | 556 | } |
@@ -703,6 +713,14 @@ where | |||
703 | self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); | 713 | self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); |
704 | } | 714 | } |
705 | } | 715 | } |
716 | |||
717 | fn is_cfg_enabled(&self, attrs: &raw::Attrs) -> bool { | ||
718 | attrs.as_ref().map_or(true, |attrs| { | ||
719 | attrs | ||
720 | .iter() | ||
721 | .all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) | ||
722 | }) | ||
723 | } | ||
706 | } | 724 | } |
707 | 725 | ||
708 | fn is_macro_rules(path: &Path) -> bool { | 726 | fn is_macro_rules(path: &Path) -> bool { |
@@ -730,6 +748,7 @@ mod tests { | |||
730 | unresolved_imports: Vec::new(), | 748 | unresolved_imports: Vec::new(), |
731 | unexpanded_macros: Vec::new(), | 749 | unexpanded_macros: Vec::new(), |
732 | macro_stack_monitor: monitor, | 750 | macro_stack_monitor: monitor, |
751 | cfg_options: &CfgOptions::default(), | ||
733 | }; | 752 | }; |
734 | collector.collect(); | 753 | collector.collect(); |
735 | collector.finish() | 754 | collector.finish() |