From 3baa526fb07184ce9804a06c8e0251971eea3b49 Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self --- crates/hir/src/code_model.rs | 4 ++ crates/ide/src/syntax_highlighting.rs | 15 ++++++ crates/ide/src/syntax_highlighting/tags.rs | 4 ++ .../test_data/highlight_assoc_functions.html | 56 ++++++++++++++++++++++ .../test_data/highlight_doctest.html | 2 +- .../test_data/highlight_injection.html | 2 +- crates/ide/src/syntax_highlighting/tests.rs | 28 +++++++++++ crates/rust-analyzer/src/to_proto.rs | 1 + 8 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 30a5e4580..afb849b4d 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -787,6 +787,10 @@ impl Function { pub fn has_body(self, db: &dyn HirDatabase) -> bool { db.function_data(self.id).has_body } + + pub fn source(self, db: &dyn HirDatabase) -> InFile { + self.id.lookup(db.upcast()).source(db.upcast()) + } } // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index efcc8ecfe..c28ff849a 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -746,6 +746,21 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_unsafe(db) { h |= HighlightModifier::Unsafe; } + if let None = func.self_param(db) { + // if enclosing IMPL or TRAIT exists, this is a static method + let fn_parent_kind = func + .source(db) + .value + .syntax() + .parent() + .and_then(|s| s.parent()) + .and_then(|s| Some(s.kind())); + if let Some(SyntaxKind::IMPL) = fn_parent_kind { + h |= HighlightModifier::Static; + } else if let Some(SyntaxKind::TRAIT) = fn_parent_kind { + h |= HighlightModifier::Static; + } + } return h; } hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index e8f78ad52..65e0671a5 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -65,6 +65,8 @@ pub enum HighlightModifier { Consuming, Unsafe, Callable, + /// Used for associated functions + Static, } impl HighlightTag { @@ -124,6 +126,7 @@ impl HighlightModifier { HighlightModifier::Consuming, HighlightModifier::Unsafe, HighlightModifier::Callable, + HighlightModifier::Static, ]; fn as_str(self) -> &'static str { @@ -137,6 +140,7 @@ impl HighlightModifier { HighlightModifier::Consuming => "consuming", HighlightModifier::Unsafe => "unsafe", HighlightModifier::Callable => "callable", + HighlightModifier::Static => "static", } } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html new file mode 100644 index 000000000..cd80d72b7 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html @@ -0,0 +1,56 @@ + + +
fn not_static() {}
+
+struct foo {}
+
+impl foo {
+    pub fn is_static() {}
+    pub fn is_not_static(&self) {}
+}
+
+trait t {
+    fn t_is_static() {}
+    fn t_is_not_static(&self) {}
+}
+
+impl t for foo {
+    pub fn is_static() {}
+    pub fn is_not_static(&self) {}
+}
+        
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 6322d404f..65fba8b02 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -53,7 +53,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// # #![allow(unused_mut)] /// let mut foo: Foo = Foo::new(); /// ``` - pub const fn new() -> Foo { + pub const fn new() -> Foo { Foo { bar: true } } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 18addd00d..57c178916 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html @@ -40,7 +40,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fn main() { fixture(r#" trait Foo { - fn foo() { + fn foo() { println!("2 + 2 = {}", 4); } }"# diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 2b667b0d4..5c22e2fce 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -513,6 +513,34 @@ fn test_extern_crate() { ); } +#[test] +fn test_associated_function() { + check_highlighting( + r#" +fn not_static() {} + +struct foo {} + +impl foo { + pub fn is_static() {} + pub fn is_not_static(&self) {} +} + +trait t { + fn t_is_static() {} + fn t_is_not_static(&self) {} +} + +impl t for foo { + pub fn is_static() {} + pub fn is_not_static(&self) {} +} + "#, + expect_file!["./test_data/highlight_assoc_functions.html"], + false, + ) +} + /// Highlights the code given by the `ra_fixture` argument, renders the /// result as HTML, and compares it with the HTML file given as `snapshot`. /// Note that the `snapshot` file is overwritten by the rendered HTML. diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 92b7c7b68..f8ecd8e83 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -426,6 +426,7 @@ fn semantic_token_type_and_modifiers( HighlightModifier::Consuming => semantic_tokens::CONSUMING, HighlightModifier::Unsafe => semantic_tokens::UNSAFE, HighlightModifier::Callable => semantic_tokens::CALLABLE, + HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC, }; mods |= modifier; } -- cgit v1.2.3 From 771c0d8c083e9c86a309a4380039602817e09fc8 Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self refactor logic into code_model.rs --- crates/hir/src/code_model.rs | 23 ++++++++++++++++++++--- crates/ide/src/syntax_highlighting.rs | 16 ++-------------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index afb849b4d..d04de053f 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -41,7 +41,7 @@ use rustc_hash::FxHashSet; use stdx::impl_from; use syntax::{ ast::{self, AttrsOwner, NameOwner}, - AstNode, SmolStr, + AstNode, SmolStr, SyntaxKind, }; use tt::{Ident, Leaf, Literal, TokenTree}; @@ -788,8 +788,25 @@ impl Function { db.function_data(self.id).has_body } - pub fn source(self, db: &dyn HirDatabase) -> InFile { - self.id.lookup(db.upcast()).source(db.upcast()) + /// whether this function is associated with some trait/impl + pub fn is_associated(self, db: &dyn HirDatabase) -> bool { + if let Some(_) = self.self_param(db) { + return false; + } + + let fn_parent_kind = self + .source(db) + .value + .syntax() + .parent() + .and_then(|s| s.parent()) + .and_then(|s| Some(s.kind())); + + match fn_parent_kind { + Some(SyntaxKind::IMPL) => true, + Some(SyntaxKind::TRAIT) => true, + _ => false, + } } } diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index c28ff849a..3fcdb5e52 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -746,20 +746,8 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_unsafe(db) { h |= HighlightModifier::Unsafe; } - if let None = func.self_param(db) { - // if enclosing IMPL or TRAIT exists, this is a static method - let fn_parent_kind = func - .source(db) - .value - .syntax() - .parent() - .and_then(|s| s.parent()) - .and_then(|s| Some(s.kind())); - if let Some(SyntaxKind::IMPL) = fn_parent_kind { - h |= HighlightModifier::Static; - } else if let Some(SyntaxKind::TRAIT) = fn_parent_kind { - h |= HighlightModifier::Static; - } + if func.is_associated(db) { + h |= HighlightModifier::Static; } return h; } -- cgit v1.2.3 From 14b38e198cbf6413eb52d61671c904014ed6037d Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self refactor logic into code_model.rs --- crates/hir/src/code_model.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index d04de053f..1319eb9cb 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -790,7 +790,7 @@ impl Function { /// whether this function is associated with some trait/impl pub fn is_associated(self, db: &dyn HirDatabase) -> bool { - if let Some(_) = self.self_param(db) { + if self.self_param(db).is_some() { return false; } -- cgit v1.2.3 From 3aa0e40726b44564e5f68612517d0d65d519275a Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self refactor logic into code_model.rs address comments --- crates/hir/src/code_model.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 1319eb9cb..3277597c6 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -802,11 +802,7 @@ impl Function { .and_then(|s| s.parent()) .and_then(|s| Some(s.kind())); - match fn_parent_kind { - Some(SyntaxKind::IMPL) => true, - Some(SyntaxKind::TRAIT) => true, - _ => false, - } + matches!(fn_parent_kind, Some(SyntaxKind::IMPL) | Some(SyntaxKind::TRAIT)) } } -- cgit v1.2.3 From 90031a267a2ea510cede2ab5c3164bb8605a69ac Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self refactor logic into code_model.rs address comments --- crates/hir/src/code_model.rs | 6 +----- crates/ide/src/syntax_highlighting.rs | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 3277597c6..fadd010e2 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -789,11 +789,7 @@ impl Function { } /// whether this function is associated with some trait/impl - pub fn is_associated(self, db: &dyn HirDatabase) -> bool { - if self.self_param(db).is_some() { - return false; - } - + pub fn is_assoc_item(self, db: &dyn HirDatabase) -> bool { let fn_parent_kind = self .source(db) .value diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 3fcdb5e52..41fd36edf 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -746,7 +746,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_unsafe(db) { h |= HighlightModifier::Unsafe; } - if func.is_associated(db) { + if func.is_assoc_item(db) && func.self_param(db).is_none() { h |= HighlightModifier::Static; } return h; -- cgit v1.2.3 From 6b950d24d44c6de4de3486832676359b2dfcb7c8 Mon Sep 17 00:00:00 2001 From: Anatol Liu Date: Wed, 4 Nov 2020 20:08:46 -0800 Subject: Add static semantic token modifier for associated functions with no &self refactor logic into code_model.rs address comments --- crates/hir/src/code_model.rs | 15 +-------------- crates/ide/src/syntax_highlighting.rs | 4 ++-- 2 files changed, 3 insertions(+), 16 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index fadd010e2..30a5e4580 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -41,7 +41,7 @@ use rustc_hash::FxHashSet; use stdx::impl_from; use syntax::{ ast::{self, AttrsOwner, NameOwner}, - AstNode, SmolStr, SyntaxKind, + AstNode, SmolStr, }; use tt::{Ident, Leaf, Literal, TokenTree}; @@ -787,19 +787,6 @@ impl Function { pub fn has_body(self, db: &dyn HirDatabase) -> bool { db.function_data(self.id).has_body } - - /// whether this function is associated with some trait/impl - pub fn is_assoc_item(self, db: &dyn HirDatabase) -> bool { - let fn_parent_kind = self - .source(db) - .value - .syntax() - .parent() - .and_then(|s| s.parent()) - .and_then(|s| Some(s.kind())); - - matches!(fn_parent_kind, Some(SyntaxKind::IMPL) | Some(SyntaxKind::TRAIT)) - } } // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 41fd36edf..4a01097df 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -6,7 +6,7 @@ pub(crate) mod tags; #[cfg(test)] mod tests; -use hir::{Local, Name, Semantics, VariantDef}; +use hir::{AsAssocItem, Local, Name, Semantics, VariantDef}; use ide_db::{ defs::{Definition, NameClass, NameRefClass}, RootDatabase, @@ -746,7 +746,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_unsafe(db) { h |= HighlightModifier::Unsafe; } - if func.is_assoc_item(db) && func.self_param(db).is_none() { + if func.as_assoc_item(db).is_some() && func.self_param(db).is_none() { h |= HighlightModifier::Static; } return h; -- cgit v1.2.3