]> git.lizzy.rs Git - rust.git/commitdiff
fix: Fix self keyword not being tagged as such in highlighting properly
authorLukas Wirth <lukastw97@gmail.com>
Sat, 4 Dec 2021 18:07:18 +0000 (19:07 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Sat, 4 Dec 2021 18:07:18 +0000 (19:07 +0100)
crates/ide/src/syntax_highlighting/highlight.rs
crates/ide/src/syntax_highlighting/test_data/highlighting.html
crates/ide/src/syntax_highlighting/tests.rs

index a5be905983f0d34471fbe045679b3f87efef10ac..88c469df2655fe59126cd1beb7d400ae04c48a22 100644 (file)
@@ -244,77 +244,71 @@ fn highlight_name_ref(
     name_ref: ast::NameRef,
 ) -> Highlight {
     let db = sema.db;
-    highlight_method_call_by_name_ref(sema, krate, &name_ref).unwrap_or_else(|| {
-        let name_class = match NameRefClass::classify(sema, &name_ref) {
-            Some(name_kind) => name_kind,
-            None => {
-                return if syntactic_name_ref_highlighting {
-                    highlight_name_ref_by_syntax(name_ref, sema, krate)
-                } else {
-                    // FIXME: Workaround for https://github.com/rust-analyzer/rust-analyzer/issues/10708
-                    //
-                    // Some popular proc macros (namely async_trait) will rewrite `self` in such a way that it no
-                    // longer resolves via NameRefClass. If we can't be resolved, but we know we're a self token,
-                    // within a function with a self param, pretend to still be `self`, rather than
-                    // an unresolved reference.
-                    if name_ref.self_token().is_some() && is_in_fn_with_self_param(&name_ref) {
-                        SymbolKind::SelfParam.into()
-                    } else {
-                        HlTag::UnresolvedReference.into()
-                    }
-                };
-            }
-        };
-        let mut h = match name_class {
-            NameRefClass::Definition(def) => {
-                if let Definition::Local(local) = &def {
-                    if let Some(name) = local.name(db) {
-                        let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
-                        *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
-                    }
-                };
+    if let Some(res) = highlight_method_call_by_name_ref(sema, krate, &name_ref) {
+        return res;
+    }
 
-                let mut h = highlight_def(sema, krate, def);
+    let name_class = match NameRefClass::classify(sema, &name_ref) {
+        Some(name_kind) => name_kind,
+        None if syntactic_name_ref_highlighting => {
+            return highlight_name_ref_by_syntax(name_ref, sema, krate)
+        }
+        // FIXME: Workaround for https://github.com/rust-analyzer/rust-analyzer/issues/10708
+        //
+        // Some popular proc macros (namely async_trait) will rewrite `self` in such a way that it no
+        // longer resolves via NameRefClass. If we can't be resolved, but we know we're a self token,
+        // within a function with a self param, pretend to still be `self`, rather than
+        // an unresolved reference.
+        None if name_ref.self_token().is_some() && is_in_fn_with_self_param(&name_ref) => {
+            return SymbolKind::SelfParam.into()
+        }
+        None => return HlTag::UnresolvedReference.into(),
+    };
+    let mut h = match name_class {
+        NameRefClass::Definition(def) => {
+            if let Definition::Local(local) = &def {
+                if let Some(name) = local.name(db) {
+                    let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
+                    *binding_hash = Some(calc_binding_hash(&name, *shadow_count))
+                }
+            };
+
+            let mut h = highlight_def(sema, krate, def);
 
-                match def {
-                    Definition::Local(local)
-                        if is_consumed_lvalue(name_ref.syntax(), &local, db) =>
+            match def {
+                Definition::Local(local) if is_consumed_lvalue(name_ref.syntax(), &local, db) => {
+                    h |= HlMod::Consuming;
+                }
+                Definition::Trait(trait_) if trait_.is_unsafe(db) => {
+                    if ast::Impl::for_trait_name_ref(&name_ref)
+                        .map_or(false, |impl_| impl_.unsafe_token().is_some())
                     {
-                        h |= HlMod::Consuming;
+                        h |= HlMod::Unsafe;
                     }
-                    Definition::Trait(trait_) if trait_.is_unsafe(db) => {
-                        if ast::Impl::for_trait_name_ref(&name_ref)
-                            .map_or(false, |impl_| impl_.unsafe_token().is_some())
-                        {
-                            h |= HlMod::Unsafe;
-                        }
-                    }
-                    Definition::Field(field) => {
-                        if let Some(parent) = name_ref.syntax().parent() {
-                            if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
-                                if let hir::VariantDef::Union(_) = field.parent_def(db) {
-                                    h |= HlMod::Unsafe;
-                                }
+                }
+                Definition::Field(field) => {
+                    if let Some(parent) = name_ref.syntax().parent() {
+                        if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
+                            if let hir::VariantDef::Union(_) = field.parent_def(db) {
+                                h |= HlMod::Unsafe;
                             }
                         }
                     }
-                    _ => (),
                 }
-
-                h
-            }
-            NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
-        };
-        if h.tag == HlTag::Symbol(SymbolKind::Module) {
-            if name_ref.self_token().is_some() {
-                return SymbolKind::SelfParam.into();
-            }
-            if name_ref.crate_token().is_some() || name_ref.super_token().is_some() {
-                h.tag = HlTag::Keyword;
+                _ => (),
             }
+
+            h
         }
-        h
-    })
+        NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
+    };
+    if name_ref.self_token().is_some() {
+        h.tag = HlTag::Symbol(SymbolKind::SelfParam);
+    }
+    if name_ref.crate_token().is_some() || name_ref.super_token().is_some() {
+        h.tag = HlTag::Keyword;
+    }
+    h
 }
 
 fn highlight_name(
index b0fbbfda2a12d59abef43f99531fedff5ca14ff9..5de621ce078cf4cc61fcb38a3778d3c4920340fd 100644 (file)
@@ -87,6 +87,7 @@ proc_macros::<span class="macro">mirror!</span> <span class="brace">{</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
 
+<span class="keyword">use</span> <span class="self_keyword crate_root">self</span><span class="operator">::</span><span class="struct">FooCopy</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="struct declaration">BarCopy</span><span class="brace">}</span><span class="semicolon">;</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
 <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="brace">{</span>
     <span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span>
index 63a1417c6aaa14f169c984ceebd21d4a36eeec24..c5834e1942192f7ee13b0830bc6feeeecf54e73e 100644 (file)
@@ -60,6 +60,7 @@ fn quop(&self) -> i32 {
     }
 }
 
+use self::FooCopy::{self as BarCopy};
 #[derive(Copy)]
 struct FooCopy {
     x: u32,