From f9d9e0a1f75b48813fe816a1e2a6c30146a36503 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 19 Jul 2019 15:53:16 +0300 Subject: several highlighting cleanups * make stuff more type-safe by using `BindPat` instead of just `Pat` * don't add `mut` into binding hash * reset shadow counter when we enter a function --- crates/ra_ide_api/src/syntax_highlighting.rs | 109 +++++++++++++++------------ 1 file changed, 60 insertions(+), 49 deletions(-) (limited to 'crates/ra_ide_api/src/syntax_highlighting.rs') diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 16a728789..0e5253025 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -4,10 +4,17 @@ use hir::{Mutability, Ty}; use ra_db::SourceDatabase; use ra_prof::profile; use ra_syntax::{ - ast, AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T, + ast::{self, NameOwner}, + AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, + SyntaxKind::*, + TextRange, T, }; -use crate::{db::RootDatabase, FileId}; +use crate::{ + db::RootDatabase, + name_ref_kind::{classify_name_ref, NameRefKind::*}, + FileId, +}; #[derive(Debug)] pub struct HighlightedRange { @@ -31,25 +38,24 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { } } -fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: ast::Pat) -> bool { - let ty = analyzer.type_of_pat(db, &pat).unwrap_or(Ty::Unknown); - let is_ty_mut = { - if let Some((_, mutability)) = ty.as_reference() { - match mutability { - Mutability::Shared => false, - Mutability::Mut => true, - } - } else { - false - } - }; - - let is_pat_mut = match pat.kind() { - ast::PatKind::BindPat(bind_pat) => bind_pat.is_mutable(), - _ => false, - }; +fn is_variable_mutable( + db: &RootDatabase, + analyzer: &hir::SourceAnalyzer, + pat: ast::BindPat, +) -> bool { + if pat.is_mutable() { + return true; + } - is_ty_mut || is_pat_mut + let ty = analyzer.type_of_pat(db, &pat.into()).unwrap_or(Ty::Unknown); + if let Some((_, mutability)) = ty.as_reference() { + match mutability { + Mutability::Shared => false, + Mutability::Mut => true, + } + } else { + false + } } pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { @@ -81,44 +87,45 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { + bindings_shadow_count.clear(); + continue; + } COMMENT => "comment", STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", ATTR => "attribute", NAME_REF => { if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) { - // FIXME: revisit this after #1340 - use crate::name_ref_kind::{classify_name_ref, NameRefKind::*}; - use hir::{ImplItem, ModuleDef}; - // FIXME: try to reuse the SourceAnalyzers let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); match classify_name_ref(db, &analyzer, &name_ref) { Some(Method(_)) => "function", Some(Macro(_)) => "macro", Some(FieldAccess(_)) => "field", - Some(AssocItem(ImplItem::Method(_))) => "function", - Some(AssocItem(ImplItem::Const(_))) => "constant", - Some(AssocItem(ImplItem::TypeAlias(_))) => "type", - Some(Def(ModuleDef::Module(_))) => "module", - Some(Def(ModuleDef::Function(_))) => "function", - Some(Def(ModuleDef::Struct(_))) => "type", - Some(Def(ModuleDef::Union(_))) => "type", - Some(Def(ModuleDef::Enum(_))) => "type", - Some(Def(ModuleDef::EnumVariant(_))) => "constant", - Some(Def(ModuleDef::Const(_))) => "constant", - Some(Def(ModuleDef::Static(_))) => "constant", - Some(Def(ModuleDef::Trait(_))) => "type", - Some(Def(ModuleDef::TypeAlias(_))) => "type", - Some(Def(ModuleDef::BuiltinType(_))) => "type", + Some(AssocItem(hir::ImplItem::Method(_))) => "function", + Some(AssocItem(hir::ImplItem::Const(_))) => "constant", + Some(AssocItem(hir::ImplItem::TypeAlias(_))) => "type", + Some(Def(hir::ModuleDef::Module(_))) => "module", + Some(Def(hir::ModuleDef::Function(_))) => "function", + Some(Def(hir::ModuleDef::Struct(_))) => "type", + Some(Def(hir::ModuleDef::Union(_))) => "type", + Some(Def(hir::ModuleDef::Enum(_))) => "type", + Some(Def(hir::ModuleDef::EnumVariant(_))) => "constant", + Some(Def(hir::ModuleDef::Const(_))) => "constant", + Some(Def(hir::ModuleDef::Static(_))) => "constant", + Some(Def(hir::ModuleDef::Trait(_))) => "type", + Some(Def(hir::ModuleDef::TypeAlias(_))) => "type", + Some(Def(hir::ModuleDef::BuiltinType(_))) => "type", Some(SelfType(_)) => "type", Some(Pat(ptr)) => { - binding_hash = Some({ - let text = - ptr.syntax_node_ptr().to_node(&root).text().to_smol_string(); + let pat = ptr.to_node(&root); + if let Some(name) = pat.name() { + let text = name.text(); let shadow_count = bindings_shadow_count.entry(text.clone()).or_default(); - calc_binding_hash(file_id, &text, *shadow_count) - }); + binding_hash = + Some(calc_binding_hash(file_id, &text, *shadow_count)) + } if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) { "variable.mut" @@ -137,14 +144,14 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) { let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); - if let Some(pat) = name.syntax().ancestors().find_map(ast::Pat::cast) { - binding_hash = Some({ - let text = name.syntax().text().to_smol_string(); + if let Some(pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) { + if let Some(name) = pat.name() { + let text = name.text(); let shadow_count = - bindings_shadow_count.entry(text.clone()).or_insert(0); + bindings_shadow_count.entry(text.clone()).or_default(); *shadow_count += 1; - calc_binding_hash(file_id, &text, *shadow_count) - }); + binding_hash = Some(calc_binding_hash(file_id, &text, *shadow_count)) + } if is_variable_mutable(db, &analyzer, pat) { "variable.mut" @@ -353,6 +360,10 @@ fn main() { let x = "other color please!"; let y = x.to_string(); } + +fn bar() { + let mut hello = "hello"; +} "# .trim(), ); -- cgit v1.2.3