Sketching the resolver API
This commit is contained in:
parent
2b5c226e86
commit
5208c2aa93
8 changed files with 134 additions and 11 deletions
|
@ -9,14 +9,15 @@ use crate::{
|
|||
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 @@ impl Module {
|
|||
}
|
||||
|
||||
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 @@ impl Function {
|
|||
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);
|
||||
|
|
|
@ -5,14 +5,12 @@ use ra_syntax::ast::{self, NameOwner};
|
|||
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> {
|
||||
|
|
|
@ -10,15 +10,15 @@ use ra_syntax::{
|
|||
};
|
||||
|
||||
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 @@ impl Body {
|
|||
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 {
|
||||
|
|
|
@ -73,6 +73,7 @@ impl ExprScopes {
|
|||
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 @@ impl ScopesWithSyntaxMapping {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -36,6 +36,7 @@ mod impl_block;
|
|||
mod expr;
|
||||
mod generics;
|
||||
mod docs;
|
||||
mod resolve;
|
||||
|
||||
mod code_model_api;
|
||||
mod code_model_impl;
|
||||
|
@ -60,6 +61,7 @@ pub use self::{
|
|||
docs::{Docs, Documentation},
|
||||
adt::AdtDef,
|
||||
expr::{ExprScopes, ScopesWithSyntaxMapping},
|
||||
resolve::Resolver,
|
||||
};
|
||||
|
||||
pub use self::code_model_api::{
|
||||
|
|
|
@ -30,7 +30,7 @@ use crate::{
|
|||
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 {
|
||||
|
|
100
crates/ra_hir/src/resolve.rs
Normal file
100
crates/ra_hir/src/resolve.rs
Normal file
|
@ -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!()
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ use ra_syntax::{
|
|||
|
||||
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!()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue