aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 17:18:12 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 17:18:12 +0100
commit7b2ab597bd2d500a68e08d0546d8f72f6a013248 (patch)
tree33266be000ef9aabe1049916d9772af70a4249b5 /crates/ra_ide_api/src
parenta15a278308047b160e5805dbb554a1949fcb0228 (diff)
parent4abe03879bbd11536fbb51b30342cdad74317025 (diff)
Merge #1544
1544: Highlight mutable variables differently r=matklad a=viorina ![Screenshot from 2019-07-18 19-04-57](https://user-images.githubusercontent.com/6714973/61473539-3f5d3000-a98f-11e9-99ec-a4115b2ba66b.png) Co-authored-by: Ekaterina Babshukova <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/snapshots/highlighting.html45
-rw-r--r--crates/ra_ide_api/src/snapshots/rainbow_highlighting.html29
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs82
3 files changed, 102 insertions, 54 deletions
diff --git a/crates/ra_ide_api/src/snapshots/highlighting.html b/crates/ra_ide_api/src/snapshots/highlighting.html
index d79d35bf3..709816d0d 100644
--- a/crates/ra_ide_api/src/snapshots/highlighting.html
+++ b/crates/ra_ide_api/src/snapshots/highlighting.html
@@ -1,21 +1,22 @@
1 1
2<style> 2<style>
3body { margin: 0; } 3body { margin: 0; }
4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5 5
6.comment { color: #7F9F7F; } 6.comment { color: #7F9F7F; }
7.string { color: #CC9393; } 7.string { color: #CC9393; }
8.function { color: #93E0E3; } 8.function { color: #93E0E3; }
9.parameter { color: #94BFF3; } 9.parameter { color: #94BFF3; }
10.builtin { color: #DD6718; } 10.builtin { color: #DD6718; }
11.text { color: #DCDCCC; } 11.text { color: #DCDCCC; }
12.attribute { color: #BFEBBF; } 12.attribute { color: #BFEBBF; }
13.literal { color: #DFAF8F; } 13.literal { color: #DFAF8F; }
14.macro { color: #DFAF8F; } 14.macro { color: #DFAF8F; }
15 15.variable\.mut { color: #DFAF8F; }
16.keyword { color: #F0DFAF; } 16
17.keyword\.unsafe { color: #F0DFAF; font-weight: bold; } 17.keyword { color: #F0DFAF; }
18.keyword\.control { color: #DC8CC3; } 18.keyword\.unsafe { color: #F0DFAF; font-weight: bold; }
19.keyword\.control { color: #DC8CC3; }
19</style> 20</style>
20<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> 21<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
21<span class="keyword">struct</span> <span class="type">Foo</span> { 22<span class="keyword">struct</span> <span class="type">Foo</span> {
@@ -32,9 +33,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4e
32<span class="keyword">fn</span> <span class="function">main</span>() { 33<span class="keyword">fn</span> <span class="function">main</span>() {
33 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal">92</span>); 34 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal">92</span>);
34 35
35 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable" data-binding-hash="9636295041291189729" style="color: hsl(51,57%,74%);">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>(); 36 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>();
36 <span class="keyword.control">if</span> <span class="keyword">true</span> { 37 <span class="keyword.control">if</span> <span class="keyword">true</span> {
37 <span class="variable" data-binding-hash="8496027264380925433" style="color: hsl(18,48%,55%);">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal">0</span>, <span class="field">y</span>: <span class="literal">1</span> }); 38 <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal">0</span>, <span class="field">y</span>: <span class="literal">1</span> });
38 } 39 }
39 <span class="keyword.unsafe">unsafe</span> { <span class="variable" data-binding-hash="8496027264380925433" style="color: hsl(18,48%,55%);">vec</span>.<span class="text">set_len</span>(<span class="literal">0</span>); } 40 <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal">0</span>); }
41
42 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal">42</span>;
43 <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>;
44 <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable.mut">y</span>;
45
46 <span class="variable.mut">y</span>;
40}</code></pre> \ No newline at end of file 47}</code></pre> \ No newline at end of file
diff --git a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html b/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html
index 729d129d0..ad3935b5d 100644
--- a/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide_api/src/snapshots/rainbow_highlighting.html
@@ -1,21 +1,22 @@
1 1
2<style> 2<style>
3body { margin: 0; } 3body { margin: 0; }
4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5 5
6.comment { color: #7F9F7F; } 6.comment { color: #7F9F7F; }
7.string { color: #CC9393; } 7.string { color: #CC9393; }
8.function { color: #93E0E3; } 8.function { color: #93E0E3; }
9.parameter { color: #94BFF3; } 9.parameter { color: #94BFF3; }
10.builtin { color: #DD6718; } 10.builtin { color: #DD6718; }
11.text { color: #DCDCCC; } 11.text { color: #DCDCCC; }
12.attribute { color: #BFEBBF; } 12.attribute { color: #BFEBBF; }
13.literal { color: #DFAF8F; } 13.literal { color: #DFAF8F; }
14.macro { color: #DFAF8F; } 14.macro { color: #DFAF8F; }
15.variable\.mut { color: #DFAF8F; }
15 16
16.keyword { color: #F0DFAF; } 17.keyword { color: #F0DFAF; }
17.keyword\.unsafe { color: #F0DFAF; font-weight: bold; } 18.keyword\.unsafe { color: #F0DFAF; font-weight: bold; }
18.keyword\.control { color: #DC8CC3; } 19.keyword\.control { color: #DC8CC3; }
19</style> 20</style>
20<pre><code><span class="keyword">fn</span> <span class="function">main</span>() { 21<pre><code><span class="keyword">fn</span> <span class="function">main</span>() {
21 <span class="keyword">let</span> <span class="variable" data-binding-hash="3888301305669440875" style="color: hsl(242,59%,59%);">hello</span> = <span class="string">"hello"</span>; 22 <span class="keyword">let</span> <span class="variable" data-binding-hash="3888301305669440875" style="color: hsl(242,59%,59%);">hello</span> = <span class="string">"hello"</span>;
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index d70ceb7d1..d84ae2cb2 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -1,9 +1,11 @@
1use rustc_hash::{FxHashMap, FxHashSet}; 1use rustc_hash::{FxHashMap, FxHashSet};
2 2
3use hir::{Mutability, Ty};
3use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
4use ra_prof::profile; 5use ra_prof::profile;
5use ra_syntax::{ 6use ra_syntax::{
6 ast, AstNode, Direction, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T, 7 ast, AstNode, Direction, Pat, PatKind, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::*,
8 TextRange, T,
7}; 9};
8 10
9use crate::{db::RootDatabase, FileId}; 11use crate::{db::RootDatabase, FileId};
@@ -30,6 +32,27 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
30 } 32 }
31} 33}
32 34
35fn is_variable_mutable(db: &RootDatabase, analyzer: &hir::SourceAnalyzer, pat: &Pat) -> bool {
36 let ty = analyzer.type_of_pat(db, pat).unwrap_or(Ty::Unknown);
37 let is_ty_mut = {
38 if let Some((_, mutability)) = ty.as_reference() {
39 match mutability {
40 Mutability::Shared => false,
41 Mutability::Mut => true,
42 }
43 } else {
44 false
45 }
46 };
47
48 let is_pat_mut = match pat.kind() {
49 PatKind::BindPat(bind_pat) => bind_pat.is_mutable(),
50 _ => false,
51 };
52
53 is_ty_mut || is_pat_mut
54}
55
33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 56pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
34 let _p = profile("highlight"); 57 let _p = profile("highlight");
35 let parse = db.parse(file_id); 58 let parse = db.parse(file_id);
@@ -97,7 +120,11 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
97 calc_binding_hash(file_id, &text, *shadow_count) 120 calc_binding_hash(file_id, &text, *shadow_count)
98 }); 121 });
99 122
100 "variable" 123 if is_variable_mutable(db, &analyzer, ptr.to_node(root)) {
124 "variable.mut"
125 } else {
126 "variable"
127 }
101 } 128 }
102 Some(SelfParam(_)) => "type", 129 Some(SelfParam(_)) => "type",
103 Some(GenericParam(_)) => "type", 130 Some(GenericParam(_)) => "type",
@@ -109,7 +136,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
109 } 136 }
110 NAME => { 137 NAME => {
111 if let Some(name) = node.as_node().and_then(ast::Name::cast) { 138 if let Some(name) = node.as_node().and_then(ast::Name::cast) {
112 if name.syntax().ancestors().any(|x| ast::BindPat::cast(x).is_some()) { 139 let analyzer = hir::SourceAnalyzer::new(db, file_id, name.syntax(), None);
140 if let Some(pat) = name.syntax().ancestors().find_map(Pat::cast) {
113 binding_hash = Some({ 141 binding_hash = Some({
114 let text = name.syntax().text().to_smol_string(); 142 let text = name.syntax().text().to_smol_string();
115 let shadow_count = 143 let shadow_count =
@@ -117,7 +145,12 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
117 *shadow_count += 1; 145 *shadow_count += 1;
118 calc_binding_hash(file_id, &text, *shadow_count) 146 calc_binding_hash(file_id, &text, *shadow_count)
119 }); 147 });
120 "variable" 148
149 if is_variable_mutable(db, &analyzer, pat) {
150 "variable.mut"
151 } else {
152 "variable"
153 }
121 } else if name 154 } else if name
122 .syntax() 155 .syntax()
123 .parent() 156 .parent()
@@ -241,22 +274,23 @@ fn html_escape(text: &str) -> String {
241 274
242const STYLE: &str = " 275const STYLE: &str = "
243<style> 276<style>
244body { margin: 0; } 277body { margin: 0; }
245pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 278pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
246 279
247.comment { color: #7F9F7F; } 280.comment { color: #7F9F7F; }
248.string { color: #CC9393; } 281.string { color: #CC9393; }
249.function { color: #93E0E3; } 282.function { color: #93E0E3; }
250.parameter { color: #94BFF3; } 283.parameter { color: #94BFF3; }
251.builtin { color: #DD6718; } 284.builtin { color: #DD6718; }
252.text { color: #DCDCCC; } 285.text { color: #DCDCCC; }
253.attribute { color: #BFEBBF; } 286.attribute { color: #BFEBBF; }
254.literal { color: #DFAF8F; } 287.literal { color: #DFAF8F; }
255.macro { color: #DFAF8F; } 288.macro { color: #DFAF8F; }
256 289.variable\\.mut { color: #DFAF8F; }
257.keyword { color: #F0DFAF; } 290
258.keyword\\.unsafe { color: #F0DFAF; font-weight: bold; } 291.keyword { color: #F0DFAF; }
259.keyword\\.control { color: #DC8CC3; } 292.keyword\\.unsafe { color: #F0DFAF; font-weight: bold; }
293.keyword\\.control { color: #DC8CC3; }
260</style> 294</style>
261"; 295";
262 296
@@ -289,12 +323,18 @@ fn main() {
289 vec.push(Foo { x: 0, y: 1 }); 323 vec.push(Foo { x: 0, y: 1 });
290 } 324 }
291 unsafe { vec.set_len(0); } 325 unsafe { vec.set_len(0); }
326
327 let mut x = 42;
328 let y = &mut x;
329 let z = &y;
330
331 y;
292} 332}
293"# 333"#
294 .trim(), 334 .trim(),
295 ); 335 );
296 let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html"); 336 let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html");
297 let actual_html = &analysis.highlight_as_html(file_id, true).unwrap(); 337 let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
298 let expected_html = &read_text(&dst_file); 338 let expected_html = &read_text(&dst_file);
299 std::fs::write(dst_file, &actual_html).unwrap(); 339 std::fs::write(dst_file, &actual_html).unwrap();
300 assert_eq_text!(expected_html, actual_html); 340 assert_eq_text!(expected_html, actual_html);