From 8960a0895126d1e964cb7488233b2c665a5bd0db Mon Sep 17 00:00:00 2001
From: Aramis Razzaghipour <aramisnoah@gmail.com>
Date: Wed, 26 May 2021 09:12:59 +1000
Subject: Fix bug where library functions were not highlighted as such

---
 crates/ide/src/syntax_highlighting/highlight.rs    | 23 ++++++++++++++++------
 .../test_data/highlighting.html                    |  2 +-
 crates/ide/src/syntax_highlighting/tests.rs        |  8 +++++++-
 3 files changed, 25 insertions(+), 8 deletions(-)

(limited to 'crates/ide/src')

diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index b4a3d39c9..9503c936d 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -71,7 +71,7 @@ pub(super) fn element(
         }
         NAME_REF => {
             let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
-            highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| {
+            highlight_func_by_name_ref(sema, krate, &name_ref).unwrap_or_else(|| {
                 let is_self = name_ref.self_token().is_some();
                 let h = match NameRefClass::classify(sema, &name_ref) {
                     Some(name_kind) => match name_kind {
@@ -108,7 +108,7 @@ pub(super) fn element(
                         NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
                     },
                     None if syntactic_name_ref_highlighting => {
-                        highlight_name_ref_by_syntax(name_ref, sema)
+                        highlight_name_ref_by_syntax(name_ref, sema, krate)
                     }
                     None => HlTag::UnresolvedReference.into(),
                 };
@@ -434,19 +434,23 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
 
 fn highlight_func_by_name_ref(
     sema: &Semantics<RootDatabase>,
+    krate: Option<hir::Crate>,
     name_ref: &ast::NameRef,
 ) -> Option<Highlight> {
     let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?;
-    highlight_method_call(sema, &mc)
+    highlight_method_call(sema, krate, &mc)
 }
 
 fn highlight_method_call(
     sema: &Semantics<RootDatabase>,
+    krate: Option<hir::Crate>,
     method_call: &ast::MethodCallExpr,
 ) -> Option<Highlight> {
     let func = sema.resolve_method_call(&method_call)?;
+
     let mut h = SymbolKind::Function.into();
     h |= HlMod::Associated;
+
     if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) {
         h |= HlMod::Unsafe;
     }
@@ -454,7 +458,10 @@ fn highlight_method_call(
         h |= HlMod::Async;
     }
     if func.as_assoc_item(sema.db).and_then(|it| it.containing_trait(sema.db)).is_some() {
-        h |= HlMod::Trait
+        h |= HlMod::Trait;
+    }
+    if Some(func.module(sema.db).krate()) != krate {
+        h |= HlMod::Library;
     }
 
     if let Some(self_param) = func.self_param(sema.db) {
@@ -503,7 +510,11 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
     tag.into()
 }
 
-fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight {
+fn highlight_name_ref_by_syntax(
+    name: ast::NameRef,
+    sema: &Semantics<RootDatabase>,
+    krate: Option<hir::Crate>,
+) -> Highlight {
     let default = HlTag::UnresolvedReference;
 
     let parent = match name.syntax().parent() {
@@ -514,7 +525,7 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
     match parent.kind() {
         METHOD_CALL_EXPR => {
             return ast::MethodCallExpr::cast(parent)
-                .and_then(|it| highlight_method_call(sema, &it))
+                .and_then(|it| highlight_method_call(sema, krate, &it))
                 .unwrap_or_else(|| SymbolKind::Function.into());
         }
         FIELD_EXPR => {
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 055d21109..0264e39a3 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -258,7 +258,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
     <span class="keyword">let</span> <span class="variable declaration">control_flow</span> <span class="operator">=</span> <span class="module library">foo</span><span class="operator">::</span><span class="function library">identity</span><span class="parenthesis">(</span><span class="module library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Continue</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
-    <span class="keyword control">if</span> <span class="keyword">let</span> <span class="module library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Die</span> <span class="operator">=</span> <span class="variable">control_flow</span> <span class="brace">{</span>
+    <span class="keyword control">if</span> <span class="variable">control_flow</span><span class="operator">.</span><span class="function associated consuming library">should_die</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
         foo::<span class="macro">die!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index be4447ebb..662b53481 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -232,7 +232,7 @@ fn use_foo_items() {
 
     let control_flow = foo::identity(foo::ControlFlow::Continue);
 
-    if let foo::ControlFlow::Die = control_flow {
+    if control_flow.should_die() {
         foo::die!();
     }
 }
@@ -249,6 +249,12 @@ pub enum ControlFlow {
     Die,
 }
 
+impl ControlFlow {
+    pub fn should_die(self) -> bool {
+        matches!(self, ControlFlow::Die)
+    }
+}
+
 pub fn identity<T>(x: T) -> T { x }
 
 pub mod consts {
-- 
cgit v1.2.3