diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-18 17:18:12 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-18 17:18:12 +0100 |
commit | 7b2ab597bd2d500a68e08d0546d8f72f6a013248 (patch) | |
tree | 33266be000ef9aabe1049916d9772af70a4249b5 /crates/ra_ide_api/src | |
parent | a15a278308047b160e5805dbb554a1949fcb0228 (diff) | |
parent | 4abe03879bbd11536fbb51b30342cdad74317025 (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.html | 45 | ||||
-rw-r--r-- | crates/ra_ide_api/src/snapshots/rainbow_highlighting.html | 29 | ||||
-rw-r--r-- | crates/ra_ide_api/src/syntax_highlighting.rs | 82 |
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> |
3 | body { margin: 0; } | 3 | body { margin: 0; } |
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 4 | pre { 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> |
3 | body { margin: 0; } | 3 | body { margin: 0; } |
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 4 | pre { 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 @@ | |||
1 | use rustc_hash::{FxHashMap, FxHashSet}; | 1 | use rustc_hash::{FxHashMap, FxHashSet}; |
2 | 2 | ||
3 | use hir::{Mutability, Ty}; | ||
3 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
4 | use ra_prof::profile; | 5 | use ra_prof::profile; |
5 | use ra_syntax::{ | 6 | use 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 | ||
9 | use crate::{db::RootDatabase, FileId}; | 11 | use crate::{db::RootDatabase, FileId}; |
@@ -30,6 +32,27 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { | |||
30 | } | 32 | } |
31 | } | 33 | } |
32 | 34 | ||
35 | fn 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 | |||
33 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 56 | pub(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 | ||
242 | const STYLE: &str = " | 275 | const STYLE: &str = " |
243 | <style> | 276 | <style> |
244 | body { margin: 0; } | 277 | body { margin: 0; } |
245 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | 278 | pre { 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); |