]> git.lizzy.rs Git - rust.git/commitdiff
Sketching the resolver API
authorFlorian Diebold <flodiebold@gmail.com>
Sat, 19 Jan 2019 20:23:26 +0000 (21:23 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 1 Feb 2019 21:14:34 +0000 (22:14 +0100)
crates/ra_hir/src/code_model_api.rs
crates/ra_hir/src/code_model_impl/function.rs
crates/ra_hir/src/expr.rs
crates/ra_hir/src/expr/scope.rs
crates/ra_hir/src/lib.rs
crates/ra_hir/src/nameres.rs
crates/ra_hir/src/resolve.rs [new file with mode: 0644]
crates/ra_hir/src/source_binder.rs

index 71123a69832de065cd72aa75e13cbc2d3caa2eb3..73541a8c38aff988786173ff57baaedfa5173302 100644 (file)
@@ -9,14 +9,15 @@
     type_ref::TypeRef,
     nameres::{ModuleScope, lower::ImportId},
     HirDatabase, PersistentHirDatabase,
-    expr::BodySyntaxMapping,
-    ty::{InferenceResult},
+    expr::{Body, BodySyntaxMapping},
+    ty::InferenceResult,
     adt::{EnumVariantId, StructFieldId, VariantDef},
     generics::GenericParams,
     docs::{Documentation, Docs, docs_from_ast},
     module_tree::ModuleId,
     ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
     impl_block::ImplId,
+    resolve::Resolver,
 };
 
 /// hir::Crate describes a single crate. It's the main interface with which
@@ -175,12 +176,18 @@ pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope {
     }
 
     pub fn resolve_path(&self, db: &impl PersistentHirDatabase, path: &Path) -> PerNs<ModuleDef> {
+        // TODO replace by Resolver::resolve_path
         db.item_map(self.krate).resolve_path(db, *self, path)
     }
 
     pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
         self.problems_impl(db)
     }
+
+    #[allow(unused_variables)]
+    pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
+        unimplemented!()
+    }
 }
 
 impl Docs for Module {
@@ -449,6 +456,10 @@ pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMappin
         db.body_syntax_mapping(*self)
     }
 
+    pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
+        db.body_hir(*self)
+    }
+
     pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping {
         let scopes = db.expr_scopes(*self);
         let syntax_mapping = db.body_syntax_mapping(*self);
index 5b0b31b1d597775843e58ac25a9bcfc56ac90c74..8326c02c783b5a22f155afdf765cbebc39157d7d 100644 (file)
@@ -5,14 +5,12 @@
 use crate::{
     HirDatabase, Name, AsName, Function, FnSignature,
     type_ref::{TypeRef, Mutability},
-    expr::Body, PersistentHirDatabase,
+    PersistentHirDatabase,
     impl_block::ImplBlock,
 };
 
 impl Function {
-    pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
-        db.body_hir(*self)
-    }
+    // TODO impl_block should probably also be part of the code model API?
 
     /// The containing impl block, if this is a method.
     pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Option<ImplBlock> {
index f4a95041848b6ca6924efde02e9b6db71a7fb0ec..6d124fe2f728be8b7cbda841ff546bd8f53ee642 100644 (file)
 };
 
 use crate::{
-    Path, Name, Function,
-    name::AsName, HirDatabase,
+    Path, Name, HirDatabase, Function, Resolver,
+    name::AsName,
     type_ref::{Mutability, TypeRef},
 };
 use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
 
 pub use self::scope::{ExprScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
 
-mod scope;
+pub(crate) mod scope;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct ExprId(RawId);
@@ -62,6 +62,11 @@ pub fn params(&self) -> &[PatId] {
     pub fn body_expr(&self) -> ExprId {
         self.body_expr
     }
+
+    #[allow(unused_variables)]
+    pub fn resolver_for_expr(&self, expr_id: ExprId) -> Resolver {
+        unimplemented!()
+    }
 }
 
 impl Index<ExprId> for Body {
index b7971088d05d9d8f5c3148d8082d0e93803bc249..504a087a3901731e6729f5a3106cb0334283dc41 100644 (file)
@@ -73,6 +73,7 @@ pub fn resolve_local_name<'a>(
         context_expr: ExprId,
         name: Name,
     ) -> Option<&'a ScopeEntry> {
+        // TODO replace by Resolver::resolve_name
         let mut shadowed = FxHashSet::default();
         let ret = self
             .scope_chain_for(context_expr)
@@ -179,6 +180,7 @@ pub fn scope_chain_for_offset<'a>(
 
     // XXX: during completion, cursor might be outside of any particular
     // expression. Try to figure out the correct scope...
+    // TODO: move this to source binder?
     fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
         let r = ptr.range();
         let child_scopes = self
index 905c53c7dd4bdfacdb5e14ba0e77bfba1fc57182..e58658378a7e4ad0288d1095868444b8894786d3 100644 (file)
@@ -36,6 +36,7 @@ fn from(it: $v) -> $e {
 mod expr;
 mod generics;
 mod docs;
+mod resolve;
 
 mod code_model_api;
 mod code_model_impl;
@@ -60,6 +61,7 @@ fn from(it: $v) -> $e {
     docs::{Docs, Documentation},
     adt::AdtDef,
     expr::{ExprScopes, ScopesWithSyntaxMapping},
+    resolve::Resolver,
 };
 
 pub use self::code_model_api::{
index f8627acbe063ccf661580569172a23be52e659c2..e825ec089670f60dd167c8a5498e0266aa583c28 100644 (file)
@@ -30,7 +30,7 @@
     nameres::lower::{ImportId, LoweredModule, ImportData},
 };
 
-/// `ItemMap` is the result of name resolution. It contains, for each
+/// `ItemMap` is the result of module name resolution. It contains, for each
 /// module, the set of visible items.
 #[derive(Default, Debug, PartialEq, Eq)]
 pub struct ItemMap {
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
new file mode 100644 (file)
index 0000000..41fcb35
--- /dev/null
@@ -0,0 +1,100 @@
+#![allow(unused_variables, dead_code)]
+//! Name resolution.
+use std::sync::Arc;
+
+use rustc_hash::FxHashMap;
+
+use crate::{
+    ModuleDef,
+    name::Name,
+    nameres::{PerNs, lower::ImportId, ItemMap},
+    module_tree::ModuleId,
+    generics::GenericParams,
+    expr::{Body, scope::{ExprScopes, ScopeId}, PatId},
+    impl_block::ImplBlock,
+    path::Path,
+};
+
+#[derive(Debug, Clone)]
+pub struct Resolver {
+    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
+}
+
+// TODO how to store these best
+#[derive(Debug, Clone)]
+pub(crate) struct ModuleItemMap {
+    item_map: Arc<ItemMap>,
+    module_id: ModuleId,
+}
+
+#[derive(Debug, Clone)]
+pub(crate) struct ExprScope {
+    expr_scopes: Arc<ExprScopes>,
+    scope_id: ScopeId,
+}
+
+#[derive(Debug, Clone)]
+pub(crate) enum Scope {
+    /// All the items and imported names of a module
+    ModuleScope(ModuleItemMap),
+    /// Brings the generic parameters of an item into scope
+    GenericParams(Arc<GenericParams>),
+    /// Brings the function parameters into scope
+    FunctionParams(Arc<Body>),
+    /// Brings `Self` into scope
+    ImplBlockScope(ImplBlock),
+    /// Local bindings
+    ExprScope(ExprScope),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum Resolution {
+    /// An item
+    Def {
+        def: ModuleDef,
+        import: Option<ImportId>,
+    },
+    /// A local binding (only value namespace)
+    LocalBinding { pat: PatId },
+    /// A generic parameter
+    GenericParam { idx: u32 },
+    // TODO how does `Self` resolve?
+}
+
+impl Resolver {
+    pub fn resolve_name(&self, name: &Name) -> PerNs<Resolution> {
+        for scope in self.scopes.iter().rev() {
+            let resolution = scope.resolve_name(name);
+            if !resolution.is_none() {
+                return resolution;
+            }
+        }
+        PerNs::none()
+    }
+
+    pub fn resolve_path(&self, path: &Path) -> PerNs<Resolution> {
+        unimplemented!()
+    }
+
+    pub fn all_names(&self) -> FxHashMap<Name, Resolution> {
+        unimplemented!()
+    }
+}
+
+impl Resolver {
+    pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver {
+        self.scopes.push(scope);
+        self
+    }
+
+    pub(crate) fn pop_scope(mut self) -> Resolver {
+        self.scopes.pop();
+        self
+    }
+}
+
+impl Scope {
+    fn resolve_name(&self, name: &Name) -> PerNs<Resolution> {
+        unimplemented!()
+    }
+}
index a1b94ed9c9cfed493c299531dffa4bd212b44e9d..1fdd7d087a33fd480270cd8b2ffbd714a5faf7b3 100644 (file)
@@ -14,7 +14,7 @@
 
 use crate::{
     HirDatabase, Function, ModuleDef, Struct, Enum,
-    AsName, Module, HirFileId, Crate, Trait,
+    AsName, Module, HirFileId, Crate, Trait, Resolver,
     ids::{LocationCtx, SourceFileItemId},
 };
 
@@ -201,3 +201,8 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
 
     res
 }
+
+#[allow(unused_variables)]
+pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
+    unimplemented!()
+}