From c640c2ea114f21bc6e4913dac38cdc451c41ceae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 14 Jan 2020 17:24:00 +0100 Subject: Make syntax highlighting linear --- crates/ra_ide/src/references.rs | 6 +- crates/ra_ide/src/references/classify.rs | 109 ++++++++++++++++++------------- crates/ra_ide/src/syntax_highlighting.rs | 12 ++-- 3 files changed, 73 insertions(+), 54 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 2c753dade..2b74d7653 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs @@ -29,7 +29,7 @@ use crate::{ }; pub(crate) use self::{ - classify::{classify_name, classify_name_ref}, + classify::{classify_name, classify_name2, classify_name_ref, classify_name_ref2}, name_definition::{NameDefinition, NameKind}, rename::rename, }; @@ -309,7 +309,7 @@ mod tests { } impl Foo { fn f() -> i32 { 42 } - } + } fn main() { let f: Foo; f = Foo {a: Foo::f()}; @@ -319,7 +319,7 @@ mod tests { check_result( refs, "Foo STRUCT_DEF FileId(1) [5; 39) [12; 15) Other", - &["FileId(1) [142; 145) StructLiteral"], + &["FileId(1) [138; 141) StructLiteral"], ); } diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index 3483a7176..9778ca536 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs @@ -1,6 +1,6 @@ //! Functions that are used to classify an element from its definition or reference. -use hir::{FromSource, InFile, Module, ModuleSource, PathResolution, SourceAnalyzer}; +use hir::{FromSource, InFile, Module, ModuleSource, PathResolution, SourceBinder}; use ra_prof::profile; use ra_syntax::{ast, match_ast, AstNode}; use test_utils::tested_by; @@ -12,6 +12,14 @@ use super::{ use crate::db::RootDatabase; pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Option { + let mut sb = SourceBinder::new(db); + classify_name2(&mut sb, name) +} + +pub(crate) fn classify_name2( + sb: &mut SourceBinder, + name: InFile<&ast::Name>, +) -> Option { let _p = profile("classify_name"); let parent = name.value.syntax().parent()?; @@ -19,90 +27,89 @@ pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Opti match parent { ast::BindPat(it) => { let src = name.with_value(it); - let local = hir::Local::from_source(db, src)?; + let local = hir::Local::from_source(sb.db, src)?; Some(NameDefinition { visibility: None, - container: local.module(db), + container: local.module(sb.db), kind: NameKind::Local(local), }) }, ast::RecordFieldDef(it) => { - let ast = hir::FieldSource::Named(it); - let src = name.with_value(ast); - let field = hir::StructField::from_source(db, src)?; - Some(from_struct_field(db, field)) + let src = name.with_value(it); + let field: hir::StructField = sb.to_def(src)?; + Some(from_struct_field(sb.db, field)) }, ast::Module(it) => { let def = { if !it.has_semi() { let ast = hir::ModuleSource::Module(it); let src = name.with_value(ast); - hir::Module::from_definition(db, src) + hir::Module::from_definition(sb.db, src) } else { let src = name.with_value(it); - hir::Module::from_declaration(db, src) + hir::Module::from_declaration(sb.db, src) } }?; - Some(from_module_def(db, def.into(), None)) + Some(from_module_def(sb.db, def.into(), None)) }, ast::StructDef(it) => { let src = name.with_value(it); - let def = hir::Struct::from_source(db, src)?; - Some(from_module_def(db, def.into(), None)) + let def: hir::Struct = sb.to_def(src)?; + Some(from_module_def(sb.db, def.into(), None)) }, ast::EnumDef(it) => { let src = name.with_value(it); - let def = hir::Enum::from_source(db, src)?; - Some(from_module_def(db, def.into(), None)) + let def: hir::Enum = sb.to_def(src)?; + Some(from_module_def(sb.db, def.into(), None)) }, ast::TraitDef(it) => { let src = name.with_value(it); - let def = hir::Trait::from_source(db, src)?; - Some(from_module_def(db, def.into(), None)) + let def: hir::Trait = sb.to_def(src)?; + Some(from_module_def(sb.db, def.into(), None)) }, ast::StaticDef(it) => { let src = name.with_value(it); - let def = hir::Static::from_source(db, src)?; - Some(from_module_def(db, def.into(), None)) + let def: hir::Static = sb.to_def(src)?; + Some(from_module_def(sb.db, def.into(), None)) }, ast::EnumVariant(it) => { let src = name.with_value(it); - let def = hir::EnumVariant::from_source(db, src)?; - Some(from_module_def(db, def.into(), None)) + let def: hir::EnumVariant = sb.to_def(src)?; + Some(from_module_def(sb.db, def.into(), None)) }, ast::FnDef(it) => { let src = name.with_value(it); - let def = hir::Function::from_source(db, src)?; + let def: hir::Function = sb.to_def(src)?; if parent.parent().and_then(ast::ItemList::cast).is_some() { - Some(from_assoc_item(db, def.into())) + Some(from_assoc_item(sb.db, def.into())) } else { - Some(from_module_def(db, def.into(), None)) + Some(from_module_def(sb.db, def.into(), None)) } }, ast::ConstDef(it) => { let src = name.with_value(it); - let def = hir::Const::from_source(db, src)?; + let def: hir::Const = sb.to_def(src)?; if parent.parent().and_then(ast::ItemList::cast).is_some() { - Some(from_assoc_item(db, def.into())) + Some(from_assoc_item(sb.db, def.into())) } else { - Some(from_module_def(db, def.into(), None)) + Some(from_module_def(sb.db, def.into(), None)) } }, ast::TypeAliasDef(it) => { let src = name.with_value(it); - let def = hir::TypeAlias::from_source(db, src)?; + let def: hir::TypeAlias = sb.to_def(src)?; if parent.parent().and_then(ast::ItemList::cast).is_some() { - Some(from_assoc_item(db, def.into())) + Some(from_assoc_item(sb.db, def.into())) } else { - Some(from_module_def(db, def.into(), None)) + Some(from_module_def(sb.db, def.into(), None)) } }, ast::MacroCall(it) => { let src = name.with_value(it); - let def = hir::MacroDef::from_source(db, src.clone())?; + let def = hir::MacroDef::from_source(sb.db, src.clone())?; - let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); - let module = Module::from_definition(db, src.with_value(module_src))?; + let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax())); + let module = Module::from_definition(sb.db, src.with_value(module_src))?; Some(NameDefinition { visibility: None, @@ -112,10 +119,10 @@ pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Opti }, ast::TypeParam(it) => { let src = name.with_value(it); - let def = hir::TypeParam::from_source(db, src)?; + let def = hir::TypeParam::from_source(sb.db, src)?; Some(NameDefinition { visibility: None, - container: def.module(db), + container: def.module(sb.db), kind: NameKind::TypeParam(def), }) }, @@ -127,23 +134,31 @@ pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Opti pub(crate) fn classify_name_ref( db: &RootDatabase, name_ref: InFile<&ast::NameRef>, +) -> Option { + let mut sb = SourceBinder::new(db); + classify_name_ref2(&mut sb, name_ref) +} + +pub(crate) fn classify_name_ref2( + sb: &mut SourceBinder, + name_ref: InFile<&ast::NameRef>, ) -> Option { let _p = profile("classify_name_ref"); let parent = name_ref.value.syntax().parent()?; - let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); + let analyzer = sb.analyze(name_ref.map(|it| it.syntax()), None); if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { tested_by!(goto_def_for_methods); if let Some(func) = analyzer.resolve_method_call(&method_call) { - return Some(from_assoc_item(db, func.into())); + return Some(from_assoc_item(sb.db, func.into())); } } if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { tested_by!(goto_def_for_fields); if let Some(field) = analyzer.resolve_field(&field_expr) { - return Some(from_struct_field(db, field)); + return Some(from_struct_field(sb.db, field)); } } @@ -151,30 +166,32 @@ pub(crate) fn classify_name_ref( tested_by!(goto_def_for_record_fields); tested_by!(goto_def_for_field_init_shorthand); if let Some(field_def) = analyzer.resolve_record_field(&record_field) { - return Some(from_struct_field(db, field_def)); + return Some(from_struct_field(sb.db, field_def)); } } - let ast = ModuleSource::from_child_node(db, name_ref.with_value(&parent)); + let ast = ModuleSource::from_child_node(sb.db, name_ref.with_value(&parent)); // FIXME: find correct container and visibility for each case - let container = Module::from_definition(db, name_ref.with_value(ast))?; + let container = Module::from_definition(sb.db, name_ref.with_value(ast))?; let visibility = None; if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { tested_by!(goto_def_for_macros); - if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { + if let Some(macro_def) = + analyzer.resolve_macro_call(sb.db, name_ref.with_value(¯o_call)) + { let kind = NameKind::Macro(macro_def); return Some(NameDefinition { kind, container, visibility }); } } let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; - let resolved = analyzer.resolve_path(db, &path)?; + let resolved = analyzer.resolve_path(sb.db, &path)?; match resolved { - PathResolution::Def(def) => Some(from_module_def(db, def, Some(container))), - PathResolution::AssocItem(item) => Some(from_assoc_item(db, item)), + PathResolution::Def(def) => Some(from_module_def(sb.db, def, Some(container))), + PathResolution::AssocItem(item) => Some(from_assoc_item(sb.db, item)), PathResolution::Local(local) => { - let container = local.module(db); + let container = local.module(sb.db); let kind = NameKind::Local(local); Some(NameDefinition { kind, container, visibility: None }) } @@ -188,7 +205,7 @@ pub(crate) fn classify_name_ref( } PathResolution::SelfType(impl_block) => { let kind = NameKind::SelfType(impl_block); - let container = impl_block.module(db); + let container = impl_block.module(sb.db); Some(NameDefinition { kind, container, visibility }) } } diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index f06a8933e..fd422d07c 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -2,7 +2,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; -use hir::{InFile, Name}; +use hir::{InFile, Name, SourceBinder}; use ra_db::SourceDatabase; use ra_prof::profile; use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; @@ -10,7 +10,7 @@ use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind:: use crate::{ db::RootDatabase, references::{ - classify_name, classify_name_ref, + classify_name2, classify_name_ref2, NameKind::{self, *}, }, FileId, @@ -84,6 +84,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec = FxHashSet::default(); @@ -108,8 +110,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec continue, NAME_REF => { let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); - let name_kind = - classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind); + let name_kind = classify_name_ref2(&mut sb, InFile::new(file_id.into(), &name_ref)) + .map(|d| d.kind); match name_kind { Some(name_kind) => { if let Local(local) = &name_kind { @@ -129,7 +131,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); let name_kind = - classify_name(db, InFile::new(file_id.into(), &name)).map(|d| d.kind); + classify_name2(&mut sb, InFile::new(file_id.into(), &name)).map(|d| d.kind); if let Some(Local(local)) = &name_kind { if let Some(name) = local.name(db) { -- cgit v1.2.3