diff options
Diffstat (limited to 'crates/ra_hir_def/src/body.rs')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 5f9d53ecb..eafaf48c1 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -9,11 +9,14 @@ use drop_bomb::DropBomb; | |||
9 | use either::Either; | 9 | use either::Either; |
10 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId}; | 10 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId}; |
11 | use ra_arena::{map::ArenaMap, Arena}; | 11 | use ra_arena::{map::ArenaMap, Arena}; |
12 | use ra_cfg::CfgOptions; | ||
13 | use ra_db::CrateId; | ||
12 | use ra_prof::profile; | 14 | use ra_prof::profile; |
13 | use ra_syntax::{ast, AstNode, AstPtr}; | 15 | use ra_syntax::{ast, AstNode, AstPtr}; |
14 | use rustc_hash::FxHashMap; | 16 | use rustc_hash::FxHashMap; |
15 | 17 | ||
16 | use crate::{ | 18 | use crate::{ |
19 | attr::Attrs, | ||
17 | db::DefDatabase, | 20 | db::DefDatabase, |
18 | expr::{Expr, ExprId, Pat, PatId}, | 21 | expr::{Expr, ExprId, Pat, PatId}, |
19 | item_scope::BuiltinShadowMode, | 22 | item_scope::BuiltinShadowMode, |
@@ -24,25 +27,59 @@ use crate::{ | |||
24 | AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId, | 27 | AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId, |
25 | }; | 28 | }; |
26 | 29 | ||
30 | /// A subser of Exander that only deals with cfg attributes. We only need it to | ||
31 | /// avoid cyclic queries in crate def map during enum processing. | ||
32 | pub(crate) struct CfgExpander { | ||
33 | cfg_options: CfgOptions, | ||
34 | hygiene: Hygiene, | ||
35 | } | ||
36 | |||
27 | pub(crate) struct Expander { | 37 | pub(crate) struct Expander { |
38 | cfg_expander: CfgExpander, | ||
28 | crate_def_map: Arc<CrateDefMap>, | 39 | crate_def_map: Arc<CrateDefMap>, |
29 | current_file_id: HirFileId, | 40 | current_file_id: HirFileId, |
30 | hygiene: Hygiene, | ||
31 | ast_id_map: Arc<AstIdMap>, | 41 | ast_id_map: Arc<AstIdMap>, |
32 | module: ModuleId, | 42 | module: ModuleId, |
33 | recursive_limit: usize, | 43 | recursive_limit: usize, |
34 | } | 44 | } |
35 | 45 | ||
46 | impl CfgExpander { | ||
47 | pub(crate) fn new( | ||
48 | db: &dyn DefDatabase, | ||
49 | current_file_id: HirFileId, | ||
50 | krate: CrateId, | ||
51 | ) -> CfgExpander { | ||
52 | let hygiene = Hygiene::new(db.upcast(), current_file_id); | ||
53 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); | ||
54 | CfgExpander { cfg_options, hygiene } | ||
55 | } | ||
56 | |||
57 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | ||
58 | Attrs::new(owner, &self.hygiene) | ||
59 | } | ||
60 | |||
61 | pub(crate) fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { | ||
62 | attrs.is_cfg_enabled(&self.cfg_options) | ||
63 | } | ||
64 | } | ||
65 | |||
36 | impl Expander { | 66 | impl Expander { |
37 | pub(crate) fn new( | 67 | pub(crate) fn new( |
38 | db: &dyn DefDatabase, | 68 | db: &dyn DefDatabase, |
39 | current_file_id: HirFileId, | 69 | current_file_id: HirFileId, |
40 | module: ModuleId, | 70 | module: ModuleId, |
41 | ) -> Expander { | 71 | ) -> Expander { |
72 | let cfg_expander = CfgExpander::new(db, current_file_id, module.krate); | ||
42 | let crate_def_map = db.crate_def_map(module.krate); | 73 | let crate_def_map = db.crate_def_map(module.krate); |
43 | let hygiene = Hygiene::new(db.upcast(), current_file_id); | ||
44 | let ast_id_map = db.ast_id_map(current_file_id); | 74 | let ast_id_map = db.ast_id_map(current_file_id); |
45 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module, recursive_limit: 0 } | 75 | Expander { |
76 | cfg_expander, | ||
77 | crate_def_map, | ||
78 | current_file_id, | ||
79 | ast_id_map, | ||
80 | module, | ||
81 | recursive_limit: 0, | ||
82 | } | ||
46 | } | 83 | } |
47 | 84 | ||
48 | pub(crate) fn enter_expand<T: ast::AstNode>( | 85 | pub(crate) fn enter_expand<T: ast::AstNode>( |
@@ -75,7 +112,7 @@ impl Expander { | |||
75 | ast_id_map: mem::take(&mut self.ast_id_map), | 112 | ast_id_map: mem::take(&mut self.ast_id_map), |
76 | bomb: DropBomb::new("expansion mark dropped"), | 113 | bomb: DropBomb::new("expansion mark dropped"), |
77 | }; | 114 | }; |
78 | self.hygiene = Hygiene::new(db.upcast(), file_id); | 115 | self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); |
79 | self.current_file_id = file_id; | 116 | self.current_file_id = file_id; |
80 | self.ast_id_map = db.ast_id_map(file_id); | 117 | self.ast_id_map = db.ast_id_map(file_id); |
81 | self.recursive_limit += 1; | 118 | self.recursive_limit += 1; |
@@ -91,7 +128,7 @@ impl Expander { | |||
91 | } | 128 | } |
92 | 129 | ||
93 | pub(crate) fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) { | 130 | pub(crate) fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) { |
94 | self.hygiene = Hygiene::new(db.upcast(), mark.file_id); | 131 | self.cfg_expander.hygiene = Hygiene::new(db.upcast(), mark.file_id); |
95 | self.current_file_id = mark.file_id; | 132 | self.current_file_id = mark.file_id; |
96 | self.ast_id_map = mem::take(&mut mark.ast_id_map); | 133 | self.ast_id_map = mem::take(&mut mark.ast_id_map); |
97 | self.recursive_limit -= 1; | 134 | self.recursive_limit -= 1; |
@@ -102,8 +139,16 @@ impl Expander { | |||
102 | InFile { file_id: self.current_file_id, value } | 139 | InFile { file_id: self.current_file_id, value } |
103 | } | 140 | } |
104 | 141 | ||
142 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | ||
143 | self.cfg_expander.parse_attrs(owner) | ||
144 | } | ||
145 | |||
146 | pub(crate) fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { | ||
147 | self.cfg_expander.is_cfg_enabled(attrs) | ||
148 | } | ||
149 | |||
105 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 150 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
106 | Path::from_src(path, &self.hygiene) | 151 | Path::from_src(path, &self.cfg_expander.hygiene) |
107 | } | 152 | } |
108 | 153 | ||
109 | fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> { | 154 | fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> { |
@@ -142,7 +187,7 @@ pub struct Body { | |||
142 | pub item_scope: ItemScope, | 187 | pub item_scope: ItemScope, |
143 | } | 188 | } |
144 | 189 | ||
145 | pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | 190 | pub type ExprPtr = AstPtr<ast::Expr>; |
146 | pub type ExprSource = InFile<ExprPtr>; | 191 | pub type ExprSource = InFile<ExprPtr>; |
147 | 192 | ||
148 | pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | 193 | pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; |
@@ -236,11 +281,11 @@ impl Index<PatId> for Body { | |||
236 | 281 | ||
237 | impl BodySourceMap { | 282 | impl BodySourceMap { |
238 | pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { | 283 | pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { |
239 | self.expr_map_back[expr] | 284 | self.expr_map_back[expr].clone() |
240 | } | 285 | } |
241 | 286 | ||
242 | pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> { | 287 | pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> { |
243 | let src = node.map(|it| Either::Left(AstPtr::new(it))); | 288 | let src = node.map(|it| AstPtr::new(it)); |
244 | self.expr_map.get(&src).cloned() | 289 | self.expr_map.get(&src).cloned() |
245 | } | 290 | } |
246 | 291 | ||
@@ -249,13 +294,8 @@ impl BodySourceMap { | |||
249 | self.expansions.get(&src).cloned() | 294 | self.expansions.get(&src).cloned() |
250 | } | 295 | } |
251 | 296 | ||
252 | pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> { | ||
253 | let src = node.map(|it| Either::Right(AstPtr::new(it))); | ||
254 | self.expr_map.get(&src).cloned() | ||
255 | } | ||
256 | |||
257 | pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> { | 297 | pub fn pat_syntax(&self, pat: PatId) -> Result<PatSource, SyntheticSyntax> { |
258 | self.pat_map_back[pat] | 298 | self.pat_map_back[pat].clone() |
259 | } | 299 | } |
260 | 300 | ||
261 | pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> { | 301 | pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> { |
@@ -264,6 +304,6 @@ impl BodySourceMap { | |||
264 | } | 304 | } |
265 | 305 | ||
266 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::RecordField> { | 306 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::RecordField> { |
267 | self.field_map[&(expr, field)] | 307 | self.field_map[&(expr, field)].clone() |
268 | } | 308 | } |
269 | } | 309 | } |