From 209eb32796c6fd56d1b378690c807cf73ce54235 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Feb 2020 15:27:52 +0100 Subject: Classify name takes const patterns into account --- crates/ra_ide/src/goto_definition.rs | 13 +++---------- crates/ra_ide/src/hover.rs | 6 +++--- crates/ra_ide/src/references.rs | 2 +- crates/ra_ide/src/syntax_highlighting.rs | 16 +++++++++------- crates/ra_ide_db/src/defs.rs | 27 ++++++++++++++++++++++++++- crates/ra_ide_db/src/imports_locator.rs | 3 ++- 6 files changed, 44 insertions(+), 23 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 6053c1bb6..621ab982c 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs @@ -30,7 +30,9 @@ pub(crate) fn goto_definition( reference_definition(&sema, &name_ref).to_vec() }, ast::Name(name) => { - name_definition(&sema, &name)? + let def = classify_name(&sema, &name)?.definition(); + let nav = def.try_to_nav(sema.db)?; + vec![nav] }, _ => return None, } @@ -88,15 +90,6 @@ pub(crate) fn reference_definition( Approximate(navs) } -fn name_definition( - sema: &Semantics, - name: &ast::Name, -) -> Option> { - let def = classify_name(sema, name)?; - let nav = def.try_to_nav(sema.db)?; - Some(vec![nav]) -} - #[cfg(test)] mod tests { use test_utils::{assert_eq_text, covers}; diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 7ba4bfcac..1e4fcdefb 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -156,7 +156,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option { - classify_name(&sema, &name).map(|d| (name.syntax().clone(), d)) + classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition())) }, _ => None, } @@ -761,13 +761,13 @@ fn func(foo: i32) { if true { <|>foo; }; } fn test_hover_through_literal_string_in_builtin_macro() { check_hover_no_result( r#" - //- /lib.rs + //- /lib.rs #[rustc_builtin_macro] macro_rules! assert { ($cond:expr) => {{ /* compiler built-in */ }}; ($cond:expr,) => {{ /* compiler built-in */ }}; ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; - } + } fn foo() { assert!("hel<|>lo"); diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index baa8a4d29..f763013ae 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs @@ -155,7 +155,7 @@ fn find_name( opt_name: Option, ) -> Option> { if let Some(name) = opt_name { - let def = classify_name(sema, &name)?; + let def = classify_name(sema, &name)?.definition(); let range = name.syntax().text_range(); return Some(RangeInfo::new(range, (name.text().to_string(), def))); } diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index c0f7c1c9f..6312bcb83 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -7,7 +7,7 @@ mod tests; use hir::{Name, Semantics}; use ra_ide_db::{ - defs::{classify_name, NameDefinition}, + defs::{classify_name, NameClass, NameDefinition}, RootDatabase, }; use ra_prof::profile; @@ -169,7 +169,7 @@ fn highlight_element( let name = element.into_node().and_then(ast::Name::cast).unwrap(); let name_kind = classify_name(sema, &name); - if let Some(NameDefinition::Local(local)) = &name_kind { + if let Some(NameClass::NameDefinition(NameDefinition::Local(local))) = &name_kind { if let Some(name) = local.name(db) { let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); *shadow_count += 1; @@ -177,11 +177,13 @@ fn highlight_element( } }; - let h = match name_kind { - Some(name_kind) => highlight_name(db, name_kind), - None => highlight_name_by_syntax(name), - }; - h | HighlightModifier::Definition + match name_kind { + Some(NameClass::NameDefinition(def)) => { + highlight_name(db, def) | HighlightModifier::Definition + } + Some(NameClass::ConstReference(def)) => highlight_name(db, def), + None => highlight_name_by_syntax(name) | HighlightModifier::Definition, + } } // Highlight references like the definitions they resolve to diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 484755158..3079d1197 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs @@ -68,7 +68,32 @@ impl NameDefinition { } } -pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option { +pub enum NameClass { + NameDefinition(NameDefinition), + /// `None` in `if let None = Some(82) {}` + ConstReference(NameDefinition), +} + +impl NameClass { + pub fn into_definition(self) -> Option { + match self { + NameClass::NameDefinition(it) => Some(it), + NameClass::ConstReference(_) => None, + } + } + + pub fn definition(self) -> NameDefinition { + match self { + NameClass::NameDefinition(it) | NameClass::ConstReference(it) => it, + } + } +} + +pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option { + classify_name_inner(sema, name).map(NameClass::NameDefinition) +} + +fn classify_name_inner(sema: &Semantics, name: &ast::Name) -> Option { let _p = profile("classify_name"); let parent = name.syntax().parent()?; diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index e590d2a5c..e5fc3c470 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs @@ -59,6 +59,7 @@ impl<'a> ImportsLocator<'a> { } else { candidate_node }; - classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?) + let name = ast::Name::cast(candidate_name_node)?; + classify_name(&self.sema, &name)?.into_definition() } } -- cgit v1.2.3 From 5ebfcb9cb757ece936f631cf69136e1d38cb6afc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Feb 2020 16:36:14 +0100 Subject: Fix highlighting of const patterns --- crates/ra_hir/src/semantics.rs | 8 +++++-- crates/ra_hir/src/source_analyzer.rs | 31 +++++++++++++++++++++----- crates/ra_ide/src/snapshots/highlighting.html | 15 +++++++++---- crates/ra_ide/src/syntax_highlighting/tests.rs | 17 +++++++++----- crates/ra_ide_db/src/defs.rs | 6 +++++ 5 files changed, 61 insertions(+), 16 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index c3d8ee1ae..154adedb3 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -18,8 +18,8 @@ use crate::{ db::HirDatabase, source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer}, source_binder::{ChildContainer, SourceBinder}, - Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution, - ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, + Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path, + PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, }; use ra_prof::profile; @@ -129,6 +129,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.analyze(path.syntax()).resolve_path(self.db, path) } + pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option { + self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) + } + // FIXME: use this instead? // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option; diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index b655e2c32..c650a9e08 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs @@ -11,9 +11,9 @@ use either::Either; use hir_def::{ body::{ scope::{ExprScopes, ScopeId}, - BodySourceMap, + Body, BodySourceMap, }, - expr::{ExprId, PatId}, + expr::{ExprId, Pat, PatId}, resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, AsMacroCall, DefWithBodyId, }; @@ -25,8 +25,8 @@ use ra_syntax::{ }; use crate::{ - db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, Path, Static, Struct, - Trait, Type, TypeAlias, TypeParam, + db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static, + Struct, Trait, Type, TypeAlias, TypeParam, }; /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of @@ -35,6 +35,7 @@ use crate::{ pub(crate) struct SourceAnalyzer { file_id: HirFileId, pub(crate) resolver: Resolver, + body: Option>, body_source_map: Option>, infer: Option>, scopes: Option>, @@ -66,7 +67,7 @@ impl SourceAnalyzer { node: InFile<&SyntaxNode>, offset: Option, ) -> SourceAnalyzer { - let (_body, source_map) = db.body_with_source_map(def); + let (body, source_map) = db.body_with_source_map(def); let scopes = db.expr_scopes(def); let scope = match offset { None => scope_for(&scopes, &source_map, node), @@ -75,6 +76,7 @@ impl SourceAnalyzer { let resolver = resolver_for_scope(db, def, scope); SourceAnalyzer { resolver, + body: Some(body), body_source_map: Some(source_map), infer: Some(db.infer(def)), scopes: Some(scopes), @@ -88,6 +90,7 @@ impl SourceAnalyzer { ) -> SourceAnalyzer { SourceAnalyzer { resolver, + body: None, body_source_map: None, infer: None, scopes: None, @@ -197,6 +200,24 @@ impl SourceAnalyzer { self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) } + pub(crate) fn resolve_bind_pat_to_const( + &self, + db: &impl HirDatabase, + pat: &ast::BindPat, + ) -> Option { + let pat_id = self.pat_id(&pat.clone().into())?; + let body = self.body.as_ref()?; + let path = match &body[pat_id] { + Pat::Path(path) => path, + _ => return None, + }; + let res = resolve_hir_path(db, &self.resolver, &path)?; + match res { + PathResolution::Def(def) => Some(def), + _ => None, + } + } + pub(crate) fn resolve_path( &self, db: &impl HirDatabase, diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index 8c372ad27..cb4097e05 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html @@ -65,10 +65,17 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd y; } -enum E<X> { - V(X) +enum Option<T> { + Some(T), + None, } +use Option::*; -impl<X> E<X> { - fn new<T>() -> E<T> {} +impl<T> Option<T> { + fn and<U>(self, other: Option<U>) -> Option<(T, U)> { + match other { + None => todo!(), + Nope => Nope, + } + } } \ No newline at end of file diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 2d90a072f..21c4dd818 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs @@ -50,12 +50,19 @@ fn main() { y; } -enum E { - V(X) +enum Option { + Some(T), + None, } - -impl E { - fn new() -> E {} +use Option::*; + +impl Option { + fn and(self, other: Option) -> Option<(T, U)> { + match other { + None => todo!(), + Nope => Nope, + } + } } "# .trim(), diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 3079d1197..93f32ba85 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs @@ -90,6 +90,12 @@ impl NameClass { } pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option { + if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) { + if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) { + return Some(NameClass::ConstReference(NameDefinition::ModuleDef(def))); + } + } + classify_name_inner(sema, name).map(NameClass::NameDefinition) } -- cgit v1.2.3 From 56ce34c6a7ec0b4426d4cb25e10512c7efaf6f06 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Feb 2020 16:49:46 +0100 Subject: Correctly flag 'lifetime definitions as definitions --- crates/ra_ide/src/snapshots/highlighting.html | 41 +++++++++++----------- .../ra_ide/src/snapshots/rainbow_highlighting.html | 18 +++++----- crates/ra_ide/src/syntax_highlighting.rs | 9 +++-- crates/ra_ide/src/syntax_highlighting/html.rs | 2 +- crates/ra_ide/src/syntax_highlighting/tags.rs | 8 +++-- crates/ra_ide/src/syntax_highlighting/tests.rs | 9 +++-- 6 files changed, 47 insertions(+), 40 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index cb4097e05..495b07f69 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html @@ -3,7 +3,7 @@ body { margin: 0; } pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } - +.lifetime { color: #DFAF8F; font-style: italic; } .comment { color: #7F9F7F; } .struct, .enum { color: #7CB8BB; } .enum_variant { color: #BDE0F3; } @@ -27,14 +27,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .control { font-style: italic; }
#[derive(Clone, Debug)]
-struct Foo {
-    pub x: i32,
-    pub y: i32,
+struct Foo {
+    pub x: i32,
+    pub y: i32,
 }
 
-fn foo<T>() -> T {
-    unimplemented!();
-    foo::<i32>();
+fn foo<'a, T>() -> T {
+    foo::<'a, i32>()
 }
 
 macro_rules! def_fn {
@@ -42,40 +41,40 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 }
 
 def_fn! {
-    fn bar() -> u32 {
+    fn bar() -> u32 {
         100
     }
 }
 
 // comment
-fn main() {
+fn main() {
     println!("Hello, {}!", 92);
 
-    let mut vec = Vec::new();
+    let mut vec = Vec::new();
     if true {
-        let x = 92;
+        let x = 92;
         vec.push(Foo { x, y: 1 });
     }
     unsafe { vec.set_len(0); }
 
-    let mut x = 42;
-    let y = &mut x;
-    let z = &y;
+    let mut x = 42;
+    let y = &mut x;
+    let z = &y;
 
     y;
 }
 
-enum Option<T> {
-    Some(T),
-    None,
+enum Option<T> {
+    Some(T),
+    None,
 }
 use Option::*;
 
-impl<T> Option<T> {
-    fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
+impl<T> Option<T> {
+    fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
         match other {
-            None => todo!(),
-            Nope => Nope,
+            None => unimplemented!(),
+            Nope => Nope,
         }
     }
 }
\ No newline at end of file diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html index f63e64b6d..dddbfc0dd 100644 --- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html @@ -3,7 +3,7 @@ body { margin: 0; } pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } - +.lifetime { color: #DFAF8F; font-style: italic; } .comment { color: #7F9F7F; } .struct, .enum { color: #7CB8BB; } .enum_variant { color: #BDE0F3; } @@ -26,15 +26,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .keyword.unsafe { color: #BC8383; font-weight: bold; } .control { font-style: italic; } -
fn main() {
-    let hello = "hello";
-    let x = hello.to_string();
-    let y = hello.to_string();
+
fn main() {
+    let hello = "hello";
+    let x = hello.to_string();
+    let y = hello.to_string();
 
-    let x = "other color please!";
-    let y = x.to_string();
+    let x = "other color please!";
+    let y = x.to_string();
 }
 
-fn bar() {
-    let mut hello = "hello";
+fn bar() {
+    let mut hello = "hello";
 }
\ No newline at end of file diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 6312bcb83..b94b6a022 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -214,8 +214,13 @@ fn highlight_element( INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), BYTE => HighlightTag::ByteLiteral.into(), CHAR => HighlightTag::CharLiteral.into(), - // FIXME: set Declaration for decls - LIFETIME => HighlightTag::Lifetime.into(), + LIFETIME => { + let h = Highlight::new(HighlightTag::Lifetime); + dbg!(match element.parent().map(|it| it.kind()) { + Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, + _ => h, + }) + } k if k.is_keyword() => { let h = Highlight::new(HighlightTag::Keyword); diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs index 54678c278..e13766c9d 100644 --- a/crates/ra_ide/src/syntax_highlighting/html.rs +++ b/crates/ra_ide/src/syntax_highlighting/html.rs @@ -80,7 +80,7 @@ const STYLE: &str = " body { margin: 0; } pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } - +.lifetime { color: #DFAF8F; font-style: italic; } .comment { color: #7F9F7F; } .struct, .enum { color: #7CB8BB; } .enum_variant { color: #BDE0F3; } diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs index 9da80823c..8835a5de2 100644 --- a/crates/ra_ide/src/syntax_highlighting/tags.rs +++ b/crates/ra_ide/src/syntax_highlighting/tags.rs @@ -90,8 +90,12 @@ impl fmt::Display for HighlightTag { } impl HighlightModifier { - const ALL: &'static [HighlightModifier] = - &[HighlightModifier::Mutable, HighlightModifier::Unsafe, HighlightModifier::Control]; + const ALL: &'static [HighlightModifier] = &[ + HighlightModifier::Control, + HighlightModifier::Definition, + HighlightModifier::Mutable, + HighlightModifier::Unsafe, + ]; fn as_str(self) -> &'static str { match self { diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 21c4dd818..98c030791 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs @@ -17,9 +17,8 @@ struct Foo { pub y: i32, } -fn foo() -> T { - unimplemented!(); - foo::(); +fn foo<'a, T>() -> T { + foo::<'a, i32>() } macro_rules! def_fn { @@ -59,7 +58,7 @@ use Option::*; impl Option { fn and(self, other: Option) -> Option<(T, U)> { match other { - None => todo!(), + None => unimplemented!(), Nope => Nope, } } @@ -130,5 +129,5 @@ fn test_ranges() { .highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) }) .unwrap(); - assert_eq!(&highlights[0].highlight.to_string(), "field"); + assert_eq!(&highlights[0].highlight.to_string(), "field.declaration"); } -- cgit v1.2.3