diff options
author | Florian Diebold <[email protected]> | 2019-01-19 20:23:26 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-02-01 21:14:34 +0000 |
commit | 5208c2aa930ae452e062dcdc2563c1bbb67d2e4a (patch) | |
tree | 9d6c6868485a8013c420a7ba74a29930d9c85737 /crates | |
parent | 2b5c226e86892113bcab478cdf4c9adaf1e7b2f6 (diff) |
Sketching the resolver API
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/function.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/scope.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 100 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 7 |
8 files changed, 134 insertions, 11 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 71123a698..73541a8c3 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -9,14 +9,15 @@ use crate::{ | |||
9 | type_ref::TypeRef, | 9 | type_ref::TypeRef, |
10 | nameres::{ModuleScope, lower::ImportId}, | 10 | nameres::{ModuleScope, lower::ImportId}, |
11 | HirDatabase, PersistentHirDatabase, | 11 | HirDatabase, PersistentHirDatabase, |
12 | expr::BodySyntaxMapping, | 12 | expr::{Body, BodySyntaxMapping}, |
13 | ty::{InferenceResult}, | 13 | ty::InferenceResult, |
14 | adt::{EnumVariantId, StructFieldId, VariantDef}, | 14 | adt::{EnumVariantId, StructFieldId, VariantDef}, |
15 | generics::GenericParams, | 15 | generics::GenericParams, |
16 | docs::{Documentation, Docs, docs_from_ast}, | 16 | docs::{Documentation, Docs, docs_from_ast}, |
17 | module_tree::ModuleId, | 17 | module_tree::ModuleId, |
18 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, | 18 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, |
19 | impl_block::ImplId, | 19 | impl_block::ImplId, |
20 | resolve::Resolver, | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | /// hir::Crate describes a single crate. It's the main interface with which | 23 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -175,12 +176,18 @@ impl Module { | |||
175 | } | 176 | } |
176 | 177 | ||
177 | pub fn resolve_path(&self, db: &impl PersistentHirDatabase, path: &Path) -> PerNs<ModuleDef> { | 178 | pub fn resolve_path(&self, db: &impl PersistentHirDatabase, path: &Path) -> PerNs<ModuleDef> { |
179 | // TODO replace by Resolver::resolve_path | ||
178 | db.item_map(self.krate).resolve_path(db, *self, path) | 180 | db.item_map(self.krate).resolve_path(db, *self, path) |
179 | } | 181 | } |
180 | 182 | ||
181 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | 183 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { |
182 | self.problems_impl(db) | 184 | self.problems_impl(db) |
183 | } | 185 | } |
186 | |||
187 | #[allow(unused_variables)] | ||
188 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | ||
189 | unimplemented!() | ||
190 | } | ||
184 | } | 191 | } |
185 | 192 | ||
186 | impl Docs for Module { | 193 | impl Docs for Module { |
@@ -449,6 +456,10 @@ impl Function { | |||
449 | db.body_syntax_mapping(*self) | 456 | db.body_syntax_mapping(*self) |
450 | } | 457 | } |
451 | 458 | ||
459 | pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> { | ||
460 | db.body_hir(*self) | ||
461 | } | ||
462 | |||
452 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { | 463 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { |
453 | let scopes = db.expr_scopes(*self); | 464 | let scopes = db.expr_scopes(*self); |
454 | let syntax_mapping = db.body_syntax_mapping(*self); | 465 | let syntax_mapping = db.body_syntax_mapping(*self); |
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 5b0b31b1d..8326c02c7 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -5,14 +5,12 @@ use ra_syntax::ast::{self, NameOwner}; | |||
5 | use crate::{ | 5 | use crate::{ |
6 | HirDatabase, Name, AsName, Function, FnSignature, | 6 | HirDatabase, Name, AsName, Function, FnSignature, |
7 | type_ref::{TypeRef, Mutability}, | 7 | type_ref::{TypeRef, Mutability}, |
8 | expr::Body, PersistentHirDatabase, | 8 | PersistentHirDatabase, |
9 | impl_block::ImplBlock, | 9 | impl_block::ImplBlock, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | impl Function { | 12 | impl Function { |
13 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> { | 13 | // TODO impl_block should probably also be part of the code model API? |
14 | db.body_hir(*self) | ||
15 | } | ||
16 | 14 | ||
17 | /// The containing impl block, if this is a method. | 15 | /// The containing impl block, if this is a method. |
18 | pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Option<ImplBlock> { | 16 | pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Option<ImplBlock> { |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index f4a950418..6d124fe2f 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -10,15 +10,15 @@ use ra_syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Path, Name, Function, | 13 | Path, Name, HirDatabase, Function, Resolver, |
14 | name::AsName, HirDatabase, | 14 | name::AsName, |
15 | type_ref::{Mutability, TypeRef}, | 15 | type_ref::{Mutability, TypeRef}, |
16 | }; | 16 | }; |
17 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; | 17 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; |
18 | 18 | ||
19 | pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; | 19 | pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; |
20 | 20 | ||
21 | mod scope; | 21 | pub(crate) mod scope; |
22 | 22 | ||
23 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 23 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
24 | pub struct ExprId(RawId); | 24 | pub struct ExprId(RawId); |
@@ -62,6 +62,11 @@ impl Body { | |||
62 | pub fn body_expr(&self) -> ExprId { | 62 | pub fn body_expr(&self) -> ExprId { |
63 | self.body_expr | 63 | self.body_expr |
64 | } | 64 | } |
65 | |||
66 | #[allow(unused_variables)] | ||
67 | pub fn resolver_for_expr(&self, expr_id: ExprId) -> Resolver { | ||
68 | unimplemented!() | ||
69 | } | ||
65 | } | 70 | } |
66 | 71 | ||
67 | impl Index<ExprId> for Body { | 72 | impl Index<ExprId> for Body { |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index b7971088d..504a087a3 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -73,6 +73,7 @@ impl ExprScopes { | |||
73 | context_expr: ExprId, | 73 | context_expr: ExprId, |
74 | name: Name, | 74 | name: Name, |
75 | ) -> Option<&'a ScopeEntry> { | 75 | ) -> Option<&'a ScopeEntry> { |
76 | // TODO replace by Resolver::resolve_name | ||
76 | let mut shadowed = FxHashSet::default(); | 77 | let mut shadowed = FxHashSet::default(); |
77 | let ret = self | 78 | let ret = self |
78 | .scope_chain_for(context_expr) | 79 | .scope_chain_for(context_expr) |
@@ -179,6 +180,7 @@ impl ScopesWithSyntaxMapping { | |||
179 | 180 | ||
180 | // XXX: during completion, cursor might be outside of any particular | 181 | // XXX: during completion, cursor might be outside of any particular |
181 | // expression. Try to figure out the correct scope... | 182 | // expression. Try to figure out the correct scope... |
183 | // TODO: move this to source binder? | ||
182 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { | 184 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { |
183 | let r = ptr.range(); | 185 | let r = ptr.range(); |
184 | let child_scopes = self | 186 | let child_scopes = self |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 905c53c7d..e58658378 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -36,6 +36,7 @@ mod impl_block; | |||
36 | mod expr; | 36 | mod expr; |
37 | mod generics; | 37 | mod generics; |
38 | mod docs; | 38 | mod docs; |
39 | mod resolve; | ||
39 | 40 | ||
40 | mod code_model_api; | 41 | mod code_model_api; |
41 | mod code_model_impl; | 42 | mod code_model_impl; |
@@ -60,6 +61,7 @@ pub use self::{ | |||
60 | docs::{Docs, Documentation}, | 61 | docs::{Docs, Documentation}, |
61 | adt::AdtDef, | 62 | adt::AdtDef, |
62 | expr::{ExprScopes, ScopesWithSyntaxMapping}, | 63 | expr::{ExprScopes, ScopesWithSyntaxMapping}, |
64 | resolve::Resolver, | ||
63 | }; | 65 | }; |
64 | 66 | ||
65 | pub use self::code_model_api::{ | 67 | pub use self::code_model_api::{ |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index f8627acbe..e825ec089 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -30,7 +30,7 @@ use crate::{ | |||
30 | nameres::lower::{ImportId, LoweredModule, ImportData}, | 30 | nameres::lower::{ImportId, LoweredModule, ImportData}, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | /// `ItemMap` is the result of name resolution. It contains, for each | 33 | /// `ItemMap` is the result of module name resolution. It contains, for each |
34 | /// module, the set of visible items. | 34 | /// module, the set of visible items. |
35 | #[derive(Default, Debug, PartialEq, Eq)] | 35 | #[derive(Default, Debug, PartialEq, Eq)] |
36 | pub struct ItemMap { | 36 | pub struct ItemMap { |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs new file mode 100644 index 000000000..41fcb35bc --- /dev/null +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -0,0 +1,100 @@ | |||
1 | #![allow(unused_variables, dead_code)] | ||
2 | //! Name resolution. | ||
3 | use std::sync::Arc; | ||
4 | |||
5 | use rustc_hash::FxHashMap; | ||
6 | |||
7 | use crate::{ | ||
8 | ModuleDef, | ||
9 | name::Name, | ||
10 | nameres::{PerNs, lower::ImportId, ItemMap}, | ||
11 | module_tree::ModuleId, | ||
12 | generics::GenericParams, | ||
13 | expr::{Body, scope::{ExprScopes, ScopeId}, PatId}, | ||
14 | impl_block::ImplBlock, | ||
15 | path::Path, | ||
16 | }; | ||
17 | |||
18 | #[derive(Debug, Clone)] | ||
19 | pub struct Resolver { | ||
20 | scopes: Vec<Scope>, // maybe a 'linked list' of scopes? or allow linking a Resolver to a parent Resolver? that's an optimization that might not be necessary, though | ||
21 | } | ||
22 | |||
23 | // TODO how to store these best | ||
24 | #[derive(Debug, Clone)] | ||
25 | pub(crate) struct ModuleItemMap { | ||
26 | item_map: Arc<ItemMap>, | ||
27 | module_id: ModuleId, | ||
28 | } | ||
29 | |||
30 | #[derive(Debug, Clone)] | ||
31 | pub(crate) struct ExprScope { | ||
32 | expr_scopes: Arc<ExprScopes>, | ||
33 | scope_id: ScopeId, | ||
34 | } | ||
35 | |||
36 | #[derive(Debug, Clone)] | ||
37 | pub(crate) enum Scope { | ||
38 | /// All the items and imported names of a module | ||
39 | ModuleScope(ModuleItemMap), | ||
40 | /// Brings the generic parameters of an item into scope | ||
41 | GenericParams(Arc<GenericParams>), | ||
42 | /// Brings the function parameters into scope | ||
43 | FunctionParams(Arc<Body>), | ||
44 | /// Brings `Self` into scope | ||
45 | ImplBlockScope(ImplBlock), | ||
46 | /// Local bindings | ||
47 | ExprScope(ExprScope), | ||
48 | } | ||
49 | |||
50 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
51 | pub enum Resolution { | ||
52 | /// An item | ||
53 | Def { | ||
54 | def: ModuleDef, | ||
55 | import: Option<ImportId>, | ||
56 | }, | ||
57 | /// A local binding (only value namespace) | ||
58 | LocalBinding { pat: PatId }, | ||
59 | /// A generic parameter | ||
60 | GenericParam { idx: u32 }, | ||
61 | // TODO how does `Self` resolve? | ||
62 | } | ||
63 | |||
64 | impl Resolver { | ||
65 | pub fn resolve_name(&self, name: &Name) -> PerNs<Resolution> { | ||
66 | for scope in self.scopes.iter().rev() { | ||
67 | let resolution = scope.resolve_name(name); | ||
68 | if !resolution.is_none() { | ||
69 | return resolution; | ||
70 | } | ||
71 | } | ||
72 | PerNs::none() | ||
73 | } | ||
74 | |||
75 | pub fn resolve_path(&self, path: &Path) -> PerNs<Resolution> { | ||
76 | unimplemented!() | ||
77 | } | ||
78 | |||
79 | pub fn all_names(&self) -> FxHashMap<Name, Resolution> { | ||
80 | unimplemented!() | ||
81 | } | ||
82 | } | ||
83 | |||
84 | impl Resolver { | ||
85 | pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver { | ||
86 | self.scopes.push(scope); | ||
87 | self | ||
88 | } | ||
89 | |||
90 | pub(crate) fn pop_scope(mut self) -> Resolver { | ||
91 | self.scopes.pop(); | ||
92 | self | ||
93 | } | ||
94 | } | ||
95 | |||
96 | impl Scope { | ||
97 | fn resolve_name(&self, name: &Name) -> PerNs<Resolution> { | ||
98 | unimplemented!() | ||
99 | } | ||
100 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a1b94ed9c..1fdd7d087 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -14,7 +14,7 @@ use ra_syntax::{ | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, ModuleDef, Struct, Enum, | 16 | HirDatabase, Function, ModuleDef, Struct, Enum, |
17 | AsName, Module, HirFileId, Crate, Trait, | 17 | AsName, Module, HirFileId, Crate, Trait, Resolver, |
18 | ids::{LocationCtx, SourceFileItemId}, | 18 | ids::{LocationCtx, SourceFileItemId}, |
19 | }; | 19 | }; |
20 | 20 | ||
@@ -201,3 +201,8 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te | |||
201 | 201 | ||
202 | res | 202 | res |
203 | } | 203 | } |
204 | |||
205 | #[allow(unused_variables)] | ||
206 | pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver { | ||
207 | unimplemented!() | ||
208 | } | ||