aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/syntax_highlighting.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-07-19 13:53:16 +0100
committerAleksey Kladov <[email protected]>2019-07-19 14:09:32 +0100
commitf9d9e0a1f75b48813fe816a1e2a6c30146a36503 (patch)
tree254e13d1f0fb3072d02ba58f918de043a5cfcded /crates/ra_ide_api/src/syntax_highlighting.rs
parente4188899962774713707629d4e15255e3bc9c85e (diff)
several highlighting cleanups
* make stuff more type-safe by using `BindPat` instead of just `Pat` * don't add `mut` into binding hash * reset shadow counter when we enter a function
Diffstat (limited to 'crates/ra_ide_api/src/syntax_highlighting.rs')
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs109
1 files changed, 60 insertions, 49 deletions
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 16a728789..0e5253025 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -4,10 +4,17 @@ use hir::{Mutability, Ty};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_prof::profile; 5use ra_prof::profile;
6use ra_syntax::{ 6use ra_syntax::{
7 ast, AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T, 7 ast::{self, NameOwner},
8 AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind,
9 SyntaxKind::*,
10 TextRange, T,
8}; 11};
9 12
10use crate::{db::RootDatabase, FileId}; 13use crate::{
14 db::RootDatabase,
15 name_ref_kind::{classify_name_ref, NameRefKind::*},
16 FileId,
17};
11 18
12#[derive(Debug)] 19#[derive(Debug)]
13pub struct HighlightedRange { 20pub struct HighlightedRange {
@@ -31,25 +38,24 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
31 } 38 }
32} 39}
33 40
34fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: ast::Pat) -> bool { 41fn is_variable_mutable(
35 let ty = analyzer.type_of_pat(db, &pat).unwrap_or(Ty::Unknown); 42 db: &RootDatabase,
36 let is_ty_mut = { 43 analyzer: &hir::SourceAnalyzer,
37 if let Some((_, mutability)) = ty.as_reference() { 44 pat: ast::BindPat,
38 match mutability { 45) -> bool {
39 Mutability::Shared => false, 46 if pat.is_mutable() {
40 Mutability::Mut => true, 47 return true;
41 } 48 }
42 } else {
43 false
44 }
45 };
46
47 let is_pat_mut = match pat.kind() {
48 ast::PatKind::BindPat(bind_pat) => bind_pat.is_mutable(),
49 _ => false,
50 };
51 49
52 is_ty_mut || is_pat_mut 50 let ty = analyzer.type_of_pat(db, &pat.into()).unwrap_or(Ty::Unknown);
51 if let Some((_, mutability)) = ty.as_reference() {
52 match mutability {
53 Mutability::Shared => false,
54 Mutability::Mut => true,
55 }
56 } else {
57 false
58 }
53} 59}
54 60
55pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 61pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
@@ -81,44 +87,45 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
81 } 87 }
82 let mut binding_hash = None; 88 let mut binding_hash = None;
83 let tag = match node.kind() { 89 let tag = match node.kind() {
90 FN_DEF => {
91 bindings_shadow_count.clear();
92 continue;
93 }
84 COMMENT => "comment", 94 COMMENT => "comment",
85 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", 95 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
86 ATTR => "attribute", 96 ATTR => "attribute",
87 NAME_REF => { 97 NAME_REF => {
88 if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) { 98 if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) {
89 // FIXME: revisit this after #1340
90 use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
91 use hir::{ImplItem, ModuleDef};
92
93 // FIXME: try to reuse the SourceAnalyzers 99 // FIXME: try to reuse the SourceAnalyzers
94 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); 100 let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
95 match classify_name_ref(db, &analyzer, &name_ref) { 101 match classify_name_ref(db, &analyzer, &name_ref) {
96 Some(Method(_)) => "function", 102 Some(Method(_)) => "function",
97 Some(Macro(_)) => "macro", 103 Some(Macro(_)) => "macro",
98 Some(FieldAccess(_)) => "field", 104 Some(FieldAccess(_)) => "field",
99 Some(AssocItem(ImplItem::Method(_))) => "function", 105 Some(AssocItem(hir::ImplItem::Method(_))) => "function",
100 Some(AssocItem(ImplItem::Const(_))) => "constant", 106 Some(AssocItem(hir::ImplItem::Const(_))) => "constant",
101 Some(AssocItem(ImplItem::TypeAlias(_))) => "type", 107 Some(AssocItem(hir::ImplItem::TypeAlias(_))) => "type",
102 Some(Def(ModuleDef::Module(_))) => "module", 108 Some(Def(hir::ModuleDef::Module(_))) => "module",
103 Some(Def(ModuleDef::Function(_))) => "function", 109 Some(Def(hir::ModuleDef::Function(_))) => "function",
104 Some(Def(ModuleDef::Struct(_))) => "type", 110 Some(Def(hir::ModuleDef::Struct(_))) => "type",
105 Some(Def(ModuleDef::Union(_))) => "type", 111 Some(Def(hir::ModuleDef::Union(_))) => "type",
106 Some(Def(ModuleDef::Enum(_))) => "type", 112 Some(Def(hir::ModuleDef::Enum(_))) => "type",
107 Some(Def(ModuleDef::EnumVariant(_))) => "constant", 113 Some(Def(hir::ModuleDef::EnumVariant(_))) => "constant",
108 Some(Def(ModuleDef::Const(_))) => "constant", 114 Some(Def(hir::ModuleDef::Const(_))) => "constant",
109 Some(Def(ModuleDef::Static(_))) => "constant", 115 Some(Def(hir::ModuleDef::Static(_))) => "constant",
110 Some(Def(ModuleDef::Trait(_))) => "type", 116 Some(Def(hir::ModuleDef::Trait(_))) => "type",
111 Some(Def(ModuleDef::TypeAlias(_))) => "type", 117 Some(Def(hir::ModuleDef::TypeAlias(_))) => "type",
112 Some(Def(ModuleDef::BuiltinType(_))) => "type", 118 Some(Def(hir::ModuleDef::BuiltinType(_))) => "type",
113 Some(SelfType(_)) => "type", 119 Some(SelfType(_)) => "type",
114 Some(Pat(ptr)) => { 120 Some(Pat(ptr)) => {
115 binding_hash = Some({ 121 let pat = ptr.to_node(&root);
116 let text = 122 if let Some(name) = pat.name() {
117 ptr.syntax_node_ptr().to_node(&root).text().to_smol_string(); 123 let text = name.text();
118 let shadow_count = 124 let shadow_count =
119 bindings_shadow_count.entry(text.clone()).or_default(); 125 bindings_shadow_count.entry(text.clone()).or_default();
120 calc_binding_hash(file_id, &text, *shadow_count) 126 binding_hash =
121 }); 127 Some(calc_binding_hash(file_id, &text, *shadow_count))
128 }
122 129
123 if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) { 130 if is_variable_mutable(db, &analyzer, ptr.to_node(&root)) {
124 "variable.mut" 131 "variable.mut"
@@ -137,14 +144,14 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
137 NAME => { 144 NAME => {
138 if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) { 145 if let Some(name) = node.as_node().cloned().and_then(ast::Name::cast) {
139 let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None); 146 let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None);
140 if let Some(pat) = name.syntax().ancestors().find_map(ast::Pat::cast) { 147 if let Some(pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) {
141 binding_hash = Some({ 148 if let Some(name) = pat.name() {
142 let text = name.syntax().text().to_smol_string(); 149 let text = name.text();
143 let shadow_count = 150 let shadow_count =
144 bindings_shadow_count.entry(text.clone()).or_insert(0); 151 bindings_shadow_count.entry(text.clone()).or_default();
145 *shadow_count += 1; 152 *shadow_count += 1;
146 calc_binding_hash(file_id, &text, *shadow_count) 153 binding_hash = Some(calc_binding_hash(file_id, &text, *shadow_count))
147 }); 154 }
148 155
149 if is_variable_mutable(db, &analyzer, pat) { 156 if is_variable_mutable(db, &analyzer, pat) {
150 "variable.mut" 157 "variable.mut"
@@ -353,6 +360,10 @@ fn main() {
353 let x = "other color please!"; 360 let x = "other color please!";
354 let y = x.to_string(); 361 let y = x.to_string();
355} 362}
363
364fn bar() {
365 let mut hello = "hello";
366}
356"# 367"#
357 .trim(), 368 .trim(),
358 ); 369 );