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(-) 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