From c3a4c4429de83450654795534e64e878a774a088 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Feb 2020 18:35:10 +0100 Subject: Refactor primary IDE API This introduces the new type -- Semantics. Semantics maps SyntaxNodes to various semantic info, such as type, name resolution or macro expansions. To do so, Semantics maintains a HashMap which maps every node it saw to the file from which the node originated. This is enough to get all the necessary hir bits just from syntax. --- crates/ra_ide_db/src/defs.rs | 50 +++++++++++---------------------- crates/ra_ide_db/src/imports_locator.rs | 26 +++++++---------- 2 files changed, 27 insertions(+), 49 deletions(-) (limited to 'crates/ra_ide_db/src') diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 04c214624..e10e72f71 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs @@ -6,8 +6,8 @@ // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). use hir::{ - Adt, FieldSource, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, - SourceBinder, StructField, TypeParam, + Adt, FieldSource, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef, Semantics, + StructField, TypeParam, }; use ra_prof::profile; use ra_syntax::{ @@ -68,78 +68,62 @@ impl NameDefinition { } } -pub fn classify_name( - sb: &mut SourceBinder, - name: InFile<&ast::Name>, -) -> Option { +pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option { let _p = profile("classify_name"); - let parent = name.value.syntax().parent()?; + let parent = name.syntax().parent()?; match_ast! { match parent { ast::BindPat(it) => { - let src = name.with_value(it); - let local = sb.to_def(src)?; + let local = sema.to_def(&it)?; Some(NameDefinition::Local(local)) }, ast::RecordFieldDef(it) => { - let src = name.with_value(it); - let field: hir::StructField = sb.to_def(src)?; + let field: hir::StructField = sema.to_def(&it)?; Some(from_struct_field(field)) }, ast::Module(it) => { - let def = sb.to_def(name.with_value(it))?; + let def = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::StructDef(it) => { - let src = name.with_value(it); - let def: hir::Struct = sb.to_def(src)?; + let def: hir::Struct = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::EnumDef(it) => { - let src = name.with_value(it); - let def: hir::Enum = sb.to_def(src)?; + let def: hir::Enum = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::TraitDef(it) => { - let src = name.with_value(it); - let def: hir::Trait = sb.to_def(src)?; + let def: hir::Trait = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::StaticDef(it) => { - let src = name.with_value(it); - let def: hir::Static = sb.to_def(src)?; + let def: hir::Static = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::EnumVariant(it) => { - let src = name.with_value(it); - let def: hir::EnumVariant = sb.to_def(src)?; + let def: hir::EnumVariant = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::FnDef(it) => { - let src = name.with_value(it); - let def: hir::Function = sb.to_def(src)?; + let def: hir::Function = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::ConstDef(it) => { - let src = name.with_value(it); - let def: hir::Const = sb.to_def(src)?; + let def: hir::Const = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::TypeAliasDef(it) => { - let src = name.with_value(it); - let def: hir::TypeAlias = sb.to_def(src)?; + let def: hir::TypeAlias = sema.to_def(&it)?; Some(from_module_def(def.into())) }, ast::MacroCall(it) => { - let src = name.with_value(it); - let def = sb.to_def(src.clone())?; - + let def = sema.to_def(&it)?; Some(NameDefinition::Macro(def)) }, ast::TypeParam(it) => { - let src = name.with_value(it); - let def = sb.to_def(src)?; + let def = sema.to_def(&it)?; Some(NameDefinition::TypeParam(def)) }, _ => None, diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index b8dd358a9..e590d2a5c 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs @@ -1,7 +1,7 @@ //! This module contains an import search funcionality that is provided to the ra_assists module. //! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. -use hir::{db::HirDatabase, ModuleDef, SourceBinder}; +use hir::{ModuleDef, Semantics}; use ra_prof::profile; use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; @@ -12,17 +12,17 @@ use crate::{ }; pub struct ImportsLocator<'a> { - source_binder: SourceBinder<'a, RootDatabase>, + sema: Semantics<'a, RootDatabase>, } impl<'a> ImportsLocator<'a> { pub fn new(db: &'a RootDatabase) -> Self { - Self { source_binder: SourceBinder::new(db) } + Self { sema: Semantics::new(db) } } pub fn find_imports(&mut self, name_to_import: &str) -> Vec { let _p = profile("search_for_imports"); - let db = self.source_binder.db; + let db = self.sema.db; let project_results = { let mut query = Query::new(name_to_import.to_string()); @@ -41,7 +41,7 @@ impl<'a> ImportsLocator<'a> { project_results .into_iter() .chain(lib_results.into_iter()) - .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) + .filter_map(|import_candidate| self.get_name_definition(&import_candidate)) .filter_map(|name_definition_to_import| match name_definition_to_import { NameDefinition::ModuleDef(module_def) => Some(module_def), _ => None, @@ -49,22 +49,16 @@ impl<'a> ImportsLocator<'a> { .collect() } - fn get_name_definition( - &mut self, - db: &impl HirDatabase, - import_candidate: &FileSymbol, - ) -> Option { + fn get_name_definition(&mut self, import_candidate: &FileSymbol) -> Option { let _p = profile("get_name_definition"); - let file_id = import_candidate.file_id.into(); - let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); + let file_id = import_candidate.file_id; + + let candidate_node = import_candidate.ptr.to_node(self.sema.parse(file_id).syntax()); let candidate_name_node = if candidate_node.kind() != NAME { candidate_node.children().find(|it| it.kind() == NAME)? } else { candidate_node }; - classify_name( - &mut self.source_binder, - hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, - ) + classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?) } } -- cgit v1.2.3