From a044ff0138d6bff9406b94de89fde43e7672ee1b Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Thu, 30 Jul 2020 11:07:13 -0400 Subject: Mark mutating functions with `mutable` modifier, and owning functions with `consuming`. --- crates/hir/src/code_model.rs | 15 +++++++++++ crates/hir/src/semantics.rs | 4 +-- crates/ide/src/syntax_highlighting.rs | 42 ++++++++++++++++++++++------- crates/ide/src/syntax_highlighting/tests.rs | 9 +++++++ crates/ide/test_data/highlighting.html | 15 ++++++++--- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index c442654dd..31d5276b0 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -670,6 +670,21 @@ impl Function { db.function_data(self.id).has_self_param } + pub fn mutability_of_self_param(self, db: &dyn HirDatabase) -> Option { + let func_data = db.function_data(self.id); + if !func_data.has_self_param { + return None; + } + + func_data.params.first().and_then(|param| { + if let TypeRef::Reference(_, mutability) = param { + Some(*mutability) + } else { + None + } + }) + } + pub fn params(self, db: &dyn HirDatabase) -> Vec { db.function_data(self.id).params.clone() } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index c693176fa..9f23315c3 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -267,7 +267,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.assert_contains_node(node) } - pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool { + pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool { self.imp.is_unsafe_method_call(method_call_expr) } @@ -571,7 +571,7 @@ impl<'db> SemanticsImpl<'db> { InFile::new(file_id, node) } - pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool { + pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool { method_call_expr .expr() .and_then(|expr| { diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 5d7c7e8d0..15a78a614 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -4,7 +4,7 @@ mod injection; #[cfg(test)] mod tests; -use hir::{Name, Semantics, VariantDef}; +use hir::{Mutability, Name, Semantics, VariantDef}; use ide_db::{ defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, RootDatabase, @@ -729,13 +729,23 @@ fn highlight_name( let is_unsafe = name_ref .and_then(|name_ref| name_ref.syntax().parent()) .and_then(ast::MethodCallExpr::cast) - .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) + .map(|method_call_expr| sema.is_unsafe_method_call(&method_call_expr)) .unwrap_or(false); if is_unsafe { h |= HighlightModifier::Unsafe; } } - return h; + return if func.has_self_param(db) { + match func.mutability_of_self_param(db) { + Some(mutability) => match mutability { + Mutability::Mut => h | HighlightModifier::Mutable, + Mutability::Shared => h, + }, + None => h | HighlightModifier::Consuming, + } + } else { + h + }; } hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, @@ -808,14 +818,26 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics { let mut h = Highlight::new(HighlightTag::Function); - let is_unsafe = ast::MethodCallExpr::cast(parent) - .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) - .unwrap_or(false); - if is_unsafe { - h |= HighlightModifier::Unsafe; - } + ast::MethodCallExpr::cast(parent) + .and_then(|method_call_expr| { + if sema.is_unsafe_method_call(&method_call_expr) { + h |= HighlightModifier::Unsafe; + } + + let func = sema.resolve_method_call(&method_call_expr)?; + if !func.has_self_param(sema.db) { + return Some(h); + } - h + Some(match func.mutability_of_self_param(sema.db) { + Some(mutability) => match mutability { + Mutability::Mut => h | HighlightModifier::Mutable, + Mutability::Shared => h, + }, + None => h | HighlightModifier::Consuming, + }) + }) + .unwrap_or_else(|| h) } FIELD_EXPR => { let h = HighlightTag::Field; diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 94f37d773..6cb955d29 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -36,6 +36,10 @@ impl Foo { fn qux(&mut self) { self.x = 0; } + + fn quop(&self) -> i32 { + self.x + } } static mut STATIC_MUT: i32 = 0; @@ -87,6 +91,11 @@ fn main() { let Foo { x: z, y } = Foo { x: z, y }; y; + + let mut foo = Foo { x, y: x }; + foo.quop(); + foo.qux(); + foo.baz(); } enum Option { diff --git a/crates/ide/test_data/highlighting.html b/crates/ide/test_data/highlighting.html index 8e0160eee..2aad06a92 100644 --- a/crates/ide/test_data/highlighting.html +++ b/crates/ide/test_data/highlighting.html @@ -55,13 +55,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } impl Foo { - fn baz(mut self) -> i32 { + fn baz(mut self) -> i32 { self.x } - fn qux(&mut self) { + fn qux(&mut self) { self.x = 0; } + + fn quop(&self) -> i32 { + self.x + } } static mut STATIC_MUT: i32 = 0; @@ -113,6 +117,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let Foo { x: z, y } = Foo { x: z, y }; y; + + let mut foo = Foo { x, y: x }; + foo.quop(); + foo.qux(); + foo.baz(); } enum Option<T> { @@ -122,7 +131,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd use Option::*; impl<T> Option<T> { - fn and<U>(self, other: Option<U>) -> Option<(T, U)> { + fn and<U>(self, other: Option<U>) -> Option<(T, U)> { match other { None => unimplemented!(), Nope => Nope, -- cgit v1.2.3