diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-11 11:48:02 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-11 11:48:02 +0000 |
commit | a599147b4232c0d4f6b071a3a96e86f903f4cf52 (patch) | |
tree | fc8ddd1428c4be2babbdd713c852b31276a315f2 /crates/ra_hir/src/source_binder.rs | |
parent | ef2a9aedb6ac7f0b79e636cff7947935fecb909d (diff) | |
parent | 8b7f853cc19d0940ec542e10bc23aa78455bbb3b (diff) |
Merge #2200
2200: Add variables to HIR r=matklad a=matklad
Introduce a `hir::Variable`, which should cover locals, parameters and `self`. Unlike `PatId`, variable knows it's owner so it is self-contained, and should be more convenient to use from `ra_ide_api`.
The goal here is to hide more details about `Body` from hir, which should make it easier to move `Body` into `hir_def`. I don't think that `ra_ide_api` intrracts with bodies directly at the moment anyway, but the glue layer is based basically on `ast::BindPat`, which seems pretty brittle.
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 66cb4b357..c5fdf3bab 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -28,7 +28,7 @@ use crate::{ | |||
28 | ids::LocationCtx, | 28 | ids::LocationCtx, |
29 | resolve::{ScopeDef, TypeNs, ValueNs}, | 29 | resolve::{ScopeDef, TypeNs, ValueNs}, |
30 | ty::method_resolution::{self, implements_trait}, | 30 | ty::method_resolution::{self, implements_trait}, |
31 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, | 31 | AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId, Local, |
32 | MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, | 32 | MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, |
33 | }; | 33 | }; |
34 | 34 | ||
@@ -94,6 +94,7 @@ fn def_with_body_from_child_node( | |||
94 | #[derive(Debug)] | 94 | #[derive(Debug)] |
95 | pub struct SourceAnalyzer { | 95 | pub struct SourceAnalyzer { |
96 | resolver: Resolver, | 96 | resolver: Resolver, |
97 | body_owner: Option<DefWithBody>, | ||
97 | body_source_map: Option<Arc<BodySourceMap>>, | 98 | body_source_map: Option<Arc<BodySourceMap>>, |
98 | infer: Option<Arc<crate::ty::InferenceResult>>, | 99 | infer: Option<Arc<crate::ty::InferenceResult>>, |
99 | scopes: Option<Arc<crate::expr::ExprScopes>>, | 100 | scopes: Option<Arc<crate::expr::ExprScopes>>, |
@@ -104,7 +105,7 @@ pub enum PathResolution { | |||
104 | /// An item | 105 | /// An item |
105 | Def(crate::ModuleDef), | 106 | Def(crate::ModuleDef), |
106 | /// A local binding (only value namespace) | 107 | /// A local binding (only value namespace) |
107 | LocalBinding(Either<AstPtr<ast::BindPat>, AstPtr<ast::SelfParam>>), | 108 | Local(Local), |
108 | /// A generic parameter | 109 | /// A generic parameter |
109 | GenericParam(u32), | 110 | GenericParam(u32), |
110 | SelfType(crate::ImplBlock), | 111 | SelfType(crate::ImplBlock), |
@@ -152,6 +153,7 @@ impl SourceAnalyzer { | |||
152 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); | 153 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); |
153 | SourceAnalyzer { | 154 | SourceAnalyzer { |
154 | resolver, | 155 | resolver, |
156 | body_owner: Some(def), | ||
155 | body_source_map: Some(source_map), | 157 | body_source_map: Some(source_map), |
156 | infer: Some(def.infer(db)), | 158 | infer: Some(def.infer(db)), |
157 | scopes: Some(scopes), | 159 | scopes: Some(scopes), |
@@ -162,6 +164,7 @@ impl SourceAnalyzer { | |||
162 | .ancestors() | 164 | .ancestors() |
163 | .find_map(|node| try_get_resolver_for_node(db, file_id, &node)) | 165 | .find_map(|node| try_get_resolver_for_node(db, file_id, &node)) |
164 | .unwrap_or_default(), | 166 | .unwrap_or_default(), |
167 | body_owner: None, | ||
165 | body_source_map: None, | 168 | body_source_map: None, |
166 | infer: None, | 169 | infer: None, |
167 | scopes: None, | 170 | scopes: None, |
@@ -233,16 +236,9 @@ impl SourceAnalyzer { | |||
233 | }); | 236 | }); |
234 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { | 237 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { |
235 | let res = match val { | 238 | let res = match val { |
236 | ValueNs::LocalBinding(it) => { | 239 | ValueNs::LocalBinding(pat_id) => { |
237 | // We get a `PatId` from resolver, but it actually can only | 240 | let var = Local { parent: self.body_owner?, pat_id }; |
238 | // point at `BindPat`, and not at the arbitrary pattern. | 241 | PathResolution::Local(var) |
239 | let pat_ptr = self | ||
240 | .body_source_map | ||
241 | .as_ref()? | ||
242 | .pat_syntax(it)? | ||
243 | .ast // FIXME: ignoring file_id here is definitelly wrong | ||
244 | .map_a(|ptr| ptr.cast::<ast::BindPat>().unwrap()); | ||
245 | PathResolution::LocalBinding(pat_ptr) | ||
246 | } | 242 | } |
247 | ValueNs::Function(it) => PathResolution::Def(it.into()), | 243 | ValueNs::Function(it) => PathResolution::Def(it.into()), |
248 | ValueNs::Const(it) => PathResolution::Def(it.into()), | 244 | ValueNs::Const(it) => PathResolution::Def(it.into()), |