Sketching the resolver API

This commit is contained in:
Florian Diebold 2019-01-19 21:23:26 +01:00
parent 2b5c226e86
commit 5208c2aa93
8 changed files with 134 additions and 11 deletions

View file

@ -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);

View file

@ -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> {

View file

@ -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 {

View file

@ -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

View file

@ -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::{

View file

@ -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 {

View 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!()
}
}

View file

@ -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!()
}