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
}
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 {
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);
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> {
};
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);
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 {
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)
// 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
mod expr;
mod generics;
mod docs;
+mod resolve;
mod code_model_api;
mod code_model_impl;
docs::{Docs, Documentation},
adt::AdtDef,
expr::{ExprScopes, ScopesWithSyntaxMapping},
+ resolve::Resolver,
};
pub use self::code_model_api::{
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 {
--- /dev/null
+#![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!()
+ }
+}
use crate::{
HirDatabase, Function, ModuleDef, Struct, Enum,
- AsName, Module, HirFileId, Crate, Trait,
+ AsName, Module, HirFileId, Crate, Trait, Resolver,
ids::{LocationCtx, SourceFileItemId},
};
res
}
+
+#[allow(unused_variables)]
+pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
+ unimplemented!()
+}