From 4abe03879bbd11536fbb51b30342cdad74317025 Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Thu, 18 Jul 2019 18:49:32 +0300 Subject: highlight mutable variables differently --- crates/ra_ide_api/src/syntax_highlighting.rs | 82 +++++++++++++++++++++------- 1 file changed, 61 insertions(+), 21 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 d70ceb7d1..d84ae2cb2 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -1,9 +1,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; +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, AstNode, Direction, Pat, PatKind, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*, + TextRange, T, }; use crate::{db::RootDatabase, FileId}; @@ -30,6 +32,27 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { } } +fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: &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() { + PatKind::BindPat(bind_pat) => bind_pat.is_mutable(), + _ => false, + }; + + is_ty_mut || is_pat_mut +} + pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { let _p = profile("highlight"); let parse = db.parse(file_id); @@ -97,7 +120,11 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec "type", Some(GenericParam(_)) => "type", @@ -109,7 +136,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { if let Some(name) = node.as_node().and_then(ast::Name::cast) { - if name.syntax().ancestors().any(|x| ast::BindPat::cast(x).is_some()) { + let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); + if let Some(pat) = name.syntax().ancestors().find_map(Pat::cast) { binding_hash = Some({ let text = name.syntax().text().to_smol_string(); let shadow_count = @@ -117,7 +145,12 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec String { const STYLE: &str = " "; @@ -289,12 +323,18 @@ fn main() { vec.push(Foo { x: 0, y: 1 }); } unsafe { vec.set_len(0); } + + let mut x = 42; + let y = &mut x; + let z = &y; + + y; } "# .trim(), ); let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html"); - let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); + let actual_html = &analysis.highlight_as_html(file_id, false).unwrap(); let expected_html = &read_text(&dst_file); std::fs::write(dst_file, &actual_html).unwrap(); assert_eq_text!(expected_html, actual_html); -- cgit v1.2.3