diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 28f6867672c0..375da1f454ea 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -440,12 +440,14 @@ impl Analysis { /// Computes syntax highlighting for the given file pub fn highlight(&self, file_id: FileId) -> Cancelable> { - self.with_db(|db| syntax_highlighting::highlight(db, file_id, None)) + self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false)) } /// Computes syntax highlighting for the given file range. pub fn highlight_range(&self, frange: FileRange) -> Cancelable> { - self.with_db(|db| syntax_highlighting::highlight(db, frange.file_id, Some(frange.range))) + self.with_db(|db| { + syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false) + }) } /// Computes syntax highlighting for the given file. diff --git a/crates/ra_ide/src/prime_caches.rs b/crates/ra_ide/src/prime_caches.rs index 90bf7d25f20c..c5ab5a1d87ba 100644 --- a/crates/ra_ide/src/prime_caches.rs +++ b/crates/ra_ide/src/prime_caches.rs @@ -7,6 +7,6 @@ use crate::{FileId, RootDatabase}; pub(crate) fn prime_caches(db: &RootDatabase, files: Vec) { for file in files { - let _ = crate::syntax_highlighting::highlight(db, file, None); + let _ = crate::syntax_highlighting::highlight(db, file, None, false); } } diff --git a/crates/ra_ide/src/snapshots/highlight_doctest.html b/crates/ra_ide/src/snapshots/highlight_doctest.html index 0ae8c7efcd6b..5228df2674bc 100644 --- a/crates/ra_ide/src/snapshots/highlight_doctest.html +++ b/crates/ra_ide/src/snapshots/highlight_doctest.html @@ -25,22 +25,29 @@ .variable { color: #DCDCCC; } .format_specifier { color: #CC696B; } .mutable { text-decoration: underline; } +.unresolved_reference { color: #FC5555; } .keyword { color: #F0DFAF; font-weight: bold; } .keyword.unsafe { color: #BC8383; font-weight: bold; } .control { font-style: italic; } -
impl Foo {
+
struct Foo {
+    bar: bool,
+}
+
+impl Foo {
+    pub const bar: bool = true;
+
     /// Constructs a new `Foo`.
     ///
     /// # Examples
     ///
     /// ```
     /// # #![allow(unused_mut)]
-    /// let mut foo: Foo = Foo::new();
+    /// let mut foo: Foo = Foo::new();
     /// ```
-    pub const fn new() -> Foo {
-        Foo { }
+    pub const fn new() -> Foo {
+        Foo { bar: true }
     }
 
     /// `bar` method on `Foo`.
@@ -48,11 +55,15 @@
     /// # Examples
     ///
     /// ```
-    /// let foo = Foo::new();
+    /// use x::y;
+    ///
+    /// let foo = Foo::new();
     ///
     /// // calls bar on foo
     /// assert!(foo.bar());
     ///
+    /// let bar = foo.bar || Foo::bar;
+    ///
     /// /* multi-line
     ///        comment */
     ///
@@ -63,7 +74,7 @@
     /// ```
     ///
     /// ```
-    /// let foobar = Foo::new().bar();
+    /// let foobar = Foo::new().bar();
     /// ```
     pub fn foo(&self) -> bool {
         true
diff --git a/crates/ra_ide/src/snapshots/highlight_injection.html b/crates/ra_ide/src/snapshots/highlight_injection.html
index dec06eb518f5..e1c9d35233f1 100644
--- a/crates/ra_ide/src/snapshots/highlight_injection.html
+++ b/crates/ra_ide/src/snapshots/highlight_injection.html
@@ -25,6 +25,7 @@
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/snapshots/highlight_strings.html b/crates/ra_ide/src/snapshots/highlight_strings.html
index 849eb3b7349b..666b48fd0744 100644
--- a/crates/ra_ide/src/snapshots/highlight_strings.html
+++ b/crates/ra_ide/src/snapshots/highlight_strings.html
@@ -25,6 +25,7 @@
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/snapshots/highlight_unsafe.html b/crates/ra_ide/src/snapshots/highlight_unsafe.html
index bd24e6e381ef..e1540499b4d7 100644
--- a/crates/ra_ide/src/snapshots/highlight_unsafe.html
+++ b/crates/ra_ide/src/snapshots/highlight_unsafe.html
@@ -25,6 +25,7 @@
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 5c2ff6ab5a47..52912dc93f94 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -25,6 +25,7 @@
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
index 1ab06182c040..1d7f04882078 100644
--- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
@@ -25,6 +25,7 @@
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index bbcd52a1c1f8..5a4de450c6de 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -44,6 +44,7 @@ pub(crate) fn highlight(
     db: &RootDatabase,
     file_id: FileId,
     range_to_highlight: Option,
+    syntactic_name_ref_highlighting: bool,
 ) -> Vec {
     let _p = profile("highlight");
     let sema = Semantics::new(db);
@@ -104,6 +105,7 @@ pub(crate) fn highlight(
                     if let Some((highlight, binding_hash)) = highlight_element(
                         &sema,
                         &mut bindings_shadow_count,
+                        syntactic_name_ref_highlighting,
                         name.syntax().clone().into(),
                     ) {
                         stack.add(HighlightedRange {
@@ -200,9 +202,12 @@ pub(crate) fn highlight(
 
         let is_format_string = format_string.as_ref() == Some(&element_to_highlight);
 
-        if let Some((highlight, binding_hash)) =
-            highlight_element(&sema, &mut bindings_shadow_count, element_to_highlight.clone())
-        {
+        if let Some((highlight, binding_hash)) = highlight_element(
+            &sema,
+            &mut bindings_shadow_count,
+            syntactic_name_ref_highlighting,
+            element_to_highlight.clone(),
+        ) {
             stack.add(HighlightedRange { range, highlight, binding_hash });
             if let Some(string) =
                 element_to_highlight.as_token().cloned().and_then(ast::String::cast)
@@ -410,6 +415,7 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option {
 fn highlight_element(
     sema: &Semantics,
     bindings_shadow_count: &mut FxHashMap,
+    syntactic_name_ref_highlighting: bool,
     element: SyntaxElement,
 ) -> Option<(Highlight, Option)> {
     let db = sema.db;
@@ -463,6 +469,7 @@ fn highlight_element(
                     }
                     NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(),
                 },
+                None if syntactic_name_ref_highlighting => highlight_name_ref_by_syntax(name_ref),
                 None => HighlightTag::UnresolvedReference.into(),
             }
         }
@@ -614,3 +621,53 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
 
     tag.into()
 }
+
+fn highlight_name_ref_by_syntax(name: ast::NameRef) -> Highlight {
+    let default = HighlightTag::UnresolvedReference;
+
+    let parent = match name.syntax().parent() {
+        Some(it) => it,
+        _ => return default.into(),
+    };
+
+    let tag = match parent.kind() {
+        METHOD_CALL_EXPR => HighlightTag::Function,
+        FIELD_EXPR => HighlightTag::Field,
+        PATH_SEGMENT => {
+            let path = match parent.parent().and_then(ast::Path::cast) {
+                Some(it) => it,
+                _ => return default.into(),
+            };
+            let expr = match path.syntax().parent().and_then(ast::PathExpr::cast) {
+                Some(it) => it,
+                _ => {
+                    // within path, decide whether it is module or adt by checking for uppercase name
+                    return if name.text().chars().next().unwrap_or_default().is_uppercase() {
+                        HighlightTag::Struct
+                    } else {
+                        HighlightTag::Module
+                    }
+                    .into();
+                }
+            };
+            let parent = match expr.syntax().parent() {
+                Some(it) => it,
+                None => return default.into(),
+            };
+
+            match parent.kind() {
+                CALL_EXPR => HighlightTag::Function,
+                _ => {
+                    if name.text().chars().next().unwrap_or_default().is_uppercase() {
+                        HighlightTag::Struct
+                    } else {
+                        HighlightTag::Constant
+                    }
+                }
+            }
+        }
+        _ => default,
+    };
+
+    tag.into()
+}
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs
index 5bada6252c0f..853b4a20f11c 100644
--- a/crates/ra_ide/src/syntax_highlighting/html.rs
+++ b/crates/ra_ide/src/syntax_highlighting/html.rs
@@ -19,7 +19,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
         )
     }
 
-    let ranges = highlight(db, file_id, None);
+    let ranges = highlight(db, file_id, None, false);
     let text = parse.tree().syntax().to_string();
     let mut prev_pos = TextSize::from(0);
     let mut buf = String::new();
@@ -84,6 +84,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .variable           { color: #DCDCCC; }
 .format_specifier   { color: #CC696B; }
 .mutable            { text-decoration: underline; }
+.unresolved_reference { color: #FC5555; }
 
 .keyword            { color: #F0DFAF; font-weight: bold; }
 .keyword.unsafe     { color: #BC8383; font-weight: bold; }
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs
index 3575a0fc6e9f..a02ffe59ee29 100644
--- a/crates/ra_ide/src/syntax_highlighting/injection.rs
+++ b/crates/ra_ide/src/syntax_highlighting/injection.rs
@@ -137,7 +137,7 @@ pub(super) fn highlight_doc_comment(
     let (analysis, tmp_file_id) = Analysis::from_single_file(text);
 
     stack.push();
-    for mut h in analysis.highlight(tmp_file_id).unwrap() {
+    for mut h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() {
         // Determine start offset and end offset in case of multi-line ranges
         let mut start_offset = None;
         let mut end_offset = None;
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 070b24f4551b..062b3ff4ae4f 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -287,7 +287,13 @@ fn main() {
 fn test_highlight_doctest() {
     check_highlighting(
         r#"
+struct Foo {
+    bar: bool,
+}
+
 impl Foo {
+    pub const bar: bool = true;
+
     /// Constructs a new `Foo`.
     ///
     /// # Examples
@@ -297,7 +303,7 @@ impl Foo {
     /// let mut foo: Foo = Foo::new();
     /// ```
     pub const fn new() -> Foo {
-        Foo { }
+        Foo { bar: true }
     }
 
     /// `bar` method on `Foo`.
@@ -305,11 +311,15 @@ impl Foo {
     /// # Examples
     ///
     /// ```
+    /// use x::y;
+    ///
     /// let foo = Foo::new();
     ///
     /// // calls bar on foo
     /// assert!(foo.bar());
     ///
+    /// let bar = foo.bar || Foo::bar;
+    ///
     /// /* multi-line
     ///        comment */
     ///
@@ -330,7 +340,7 @@ impl Foo {
         .trim(),
         "crates/ra_ide/src/snapshots/highlight_doctest.html",
         false,
-    )
+    );
 }
 
 /// Highlights the code given by the `ra_fixture` argument, renders the