aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-01-19 20:23:26 +0000
committerFlorian Diebold <[email protected]>2019-02-01 21:14:34 +0000
commit5208c2aa930ae452e062dcdc2563c1bbb67d2e4a (patch)
tree9d6c6868485a8013c420a7ba74a29930d9c85737 /crates
parent2b5c226e86892113bcab478cdf4c9adaf1e7b2f6 (diff)
Sketching the resolver API
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model_api.rs15
-rw-r--r--crates/ra_hir/src/code_model_impl/function.rs6
-rw-r--r--crates/ra_hir/src/expr.rs11
-rw-r--r--crates/ra_hir/src/expr/scope.rs2
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs2
-rw-r--r--crates/ra_hir/src/resolve.rs100
-rw-r--r--crates/ra_hir/src/source_binder.rs7
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
186impl Docs for Module { 193impl 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};
5use crate::{ 5use 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
12impl Function { 12impl 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
12use crate::{ 12use 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};
17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; 17use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
18 18
19pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; 19pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
20 20
21mod scope; 21pub(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)]
24pub struct ExprId(RawId); 24pub 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
67impl Index<ExprId> for Body { 72impl 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;
36mod expr; 36mod expr;
37mod generics; 37mod generics;
38mod docs; 38mod docs;
39mod resolve;
39 40
40mod code_model_api; 41mod code_model_api;
41mod code_model_impl; 42mod 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
65pub use self::code_model_api::{ 67pub 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)]
36pub struct ItemMap { 36pub 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.
3use std::sync::Arc;
4
5use rustc_hash::FxHashMap;
6
7use 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)]
19pub 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)]
25pub(crate) struct ModuleItemMap {
26 item_map: Arc<ItemMap>,
27 module_id: ModuleId,
28}
29
30#[derive(Debug, Clone)]
31pub(crate) struct ExprScope {
32 expr_scopes: Arc<ExprScopes>,
33 scope_id: ScopeId,
34}
35
36#[derive(Debug, Clone)]
37pub(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)]
51pub 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
64impl 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
84impl 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
96impl 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
15use crate::{ 15use 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)]
206pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
207 unimplemented!()
208}