aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs7
-rw-r--r--crates/ra_ide/src/goto_definition.rs46
-rw-r--r--crates/ra_ide/src/goto_type_definition.rs43
-rw-r--r--crates/ra_ide/src/hover.rs23
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html26
-rw-r--r--crates/ra_ide/src/snapshots/rainbow_highlighting.html2
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs98
7 files changed, 191 insertions, 54 deletions
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index ca0a483d4..981da2b79 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -188,10 +188,9 @@ impl<'a> CompletionContext<'a> {
188 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); 188 self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
189 self.has_type_args = segment.type_arg_list().is_some(); 189 self.has_type_args = segment.type_arg_list().is_some();
190 190
191 if let Some(mut path) = hir::Path::from_ast(path.clone()) { 191 if let Some(path) = hir::Path::from_ast(path.clone()) {
192 if !path.is_ident() { 192 if let Some(path_prefix) = path.qualifier() {
193 path.segments.pop().unwrap(); 193 self.path_prefix = Some(path_prefix);
194 self.path_prefix = Some(path);
195 return; 194 return;
196 } 195 }
197 } 196 }
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 2c634990d..bee8e9df2 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -3,7 +3,9 @@
3use hir::{db::AstDatabase, InFile}; 3use hir::{db::AstDatabase, InFile};
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{self, DocCommentsOwner}, 5 ast::{self, DocCommentsOwner},
6 match_ast, AstNode, SyntaxNode, 6 match_ast, AstNode,
7 SyntaxKind::*,
8 SyntaxNode, SyntaxToken, TokenAtOffset,
7}; 9};
8 10
9use crate::{ 11use crate::{
@@ -19,8 +21,7 @@ pub(crate) fn goto_definition(
19 position: FilePosition, 21 position: FilePosition,
20) -> Option<RangeInfo<Vec<NavigationTarget>>> { 22) -> Option<RangeInfo<Vec<NavigationTarget>>> {
21 let file = db.parse_or_expand(position.file_id.into())?; 23 let file = db.parse_or_expand(position.file_id.into())?;
22 let original_token = 24 let original_token = pick_best(file.token_at_offset(position.offset))?;
23 file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?;
24 let token = descend_into_macros(db, position.file_id, original_token.clone()); 25 let token = descend_into_macros(db, position.file_id, original_token.clone());
25 26
26 let nav_targets = match_ast! { 27 let nav_targets = match_ast! {
@@ -38,6 +39,17 @@ pub(crate) fn goto_definition(
38 Some(RangeInfo::new(original_token.text_range(), nav_targets)) 39 Some(RangeInfo::new(original_token.text_range(), nav_targets))
39} 40}
40 41
42fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
43 return tokens.max_by_key(priority);
44 fn priority(n: &SyntaxToken) -> usize {
45 match n.kind() {
46 IDENT | INT_NUMBER => 2,
47 kind if kind.is_trivia() => 0,
48 _ => 1,
49 }
50 }
51}
52
41#[derive(Debug)] 53#[derive(Debug)]
42pub(crate) enum ReferenceResult { 54pub(crate) enum ReferenceResult {
43 Exact(NavigationTarget), 55 Exact(NavigationTarget),
@@ -253,6 +265,18 @@ mod tests {
253 } 265 }
254 266
255 #[test] 267 #[test]
268 fn goto_definition_works_at_start_of_item() {
269 check_goto(
270 "
271 //- /lib.rs
272 struct Foo;
273 enum E { X(<|>Foo) }
274 ",
275 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
276 );
277 }
278
279 #[test]
256 fn goto_definition_resolves_correct_name() { 280 fn goto_definition_resolves_correct_name() {
257 check_goto( 281 check_goto(
258 " 282 "
@@ -453,6 +477,22 @@ mod tests {
453 } 477 }
454 478
455 #[test] 479 #[test]
480 fn goto_for_tuple_fields() {
481 check_goto(
482 "
483 //- /lib.rs
484 struct Foo(u32);
485
486 fn bar() {
487 let foo = Foo(0);
488 foo.<|>0;
489 }
490 ",
491 "TUPLE_FIELD_DEF FileId(1) [11; 14)",
492 );
493 }
494
495 #[test]
456 fn goto_definition_works_for_ufcs_inherent_methods() { 496 fn goto_definition_works_for_ufcs_inherent_methods() {
457 check_goto( 497 check_goto(
458 " 498 "
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs
index 992a08809..ce8b6c72a 100644
--- a/crates/ra_ide/src/goto_type_definition.rs
+++ b/crates/ra_ide/src/goto_type_definition.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::db::AstDatabase; 3use hir::db::AstDatabase;
4use ra_syntax::{ast, AstNode}; 4use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset};
5 5
6use crate::{ 6use crate::{
7 db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, 7 db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget,
@@ -13,7 +13,7 @@ pub(crate) fn goto_type_definition(
13 position: FilePosition, 13 position: FilePosition,
14) -> Option<RangeInfo<Vec<NavigationTarget>>> { 14) -> Option<RangeInfo<Vec<NavigationTarget>>> {
15 let file = db.parse_or_expand(position.file_id.into())?; 15 let file = db.parse_or_expand(position.file_id.into())?;
16 let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; 16 let token = pick_best(file.token_at_offset(position.offset))?;
17 let token = descend_into_macros(db, position.file_id, token); 17 let token = descend_into_macros(db, position.file_id, token);
18 18
19 let node = token.value.ancestors().find_map(|token| { 19 let node = token.value.ancestors().find_map(|token| {
@@ -41,6 +41,17 @@ pub(crate) fn goto_type_definition(
41 Some(RangeInfo::new(node.text_range(), vec![nav])) 41 Some(RangeInfo::new(node.text_range(), vec![nav]))
42} 42}
43 43
44fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
45 return tokens.max_by_key(priority);
46 fn priority(n: &SyntaxToken) -> usize {
47 match n.kind() {
48 IDENT | INT_NUMBER => 2,
49 kind if kind.is_trivia() => 0,
50 _ => 1,
51 }
52 }
53}
54
44#[cfg(test)] 55#[cfg(test)]
45mod tests { 56mod tests {
46 use crate::mock_analysis::analysis_and_position; 57 use crate::mock_analysis::analysis_and_position;
@@ -102,4 +113,32 @@ mod tests {
102 "Foo STRUCT_DEF FileId(1) [52; 65) [59; 62)", 113 "Foo STRUCT_DEF FileId(1) [52; 65) [59; 62)",
103 ); 114 );
104 } 115 }
116
117 #[test]
118 fn goto_type_definition_for_param() {
119 check_goto(
120 "
121 //- /lib.rs
122 struct Foo;
123 fn foo(<|>f: Foo) {}
124 ",
125 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
126 );
127 }
128
129 #[test]
130 fn goto_type_definition_for_tuple_field() {
131 check_goto(
132 "
133 //- /lib.rs
134 struct Foo;
135 struct Bar(Foo);
136 fn foo() {
137 let bar = Bar(Foo);
138 bar.<|>0;
139 }
140 ",
141 "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
142 );
143 }
105} 144}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index d372ca758..51e320128 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -6,6 +6,8 @@ use ra_syntax::{
6 algo::find_covering_element, 6 algo::find_covering_element,
7 ast::{self, DocCommentsOwner}, 7 ast::{self, DocCommentsOwner},
8 match_ast, AstNode, 8 match_ast, AstNode,
9 SyntaxKind::*,
10 SyntaxToken, TokenAtOffset,
9}; 11};
10 12
11use crate::{ 13use crate::{
@@ -156,7 +158,7 @@ fn hover_text_from_name_kind(
156 158
157pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { 159pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
158 let file = db.parse_or_expand(position.file_id.into())?; 160 let file = db.parse_or_expand(position.file_id.into())?;
159 let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; 161 let token = pick_best(file.token_at_offset(position.offset))?;
160 let token = descend_into_macros(db, position.file_id, token); 162 let token = descend_into_macros(db, position.file_id, token);
161 163
162 let mut res = HoverResult::new(); 164 let mut res = HoverResult::new();
@@ -218,6 +220,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
218 Some(RangeInfo::new(range, res)) 220 Some(RangeInfo::new(range, res))
219} 221}
220 222
223fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
224 return tokens.max_by_key(priority);
225 fn priority(n: &SyntaxToken) -> usize {
226 match n.kind() {
227 IDENT | INT_NUMBER => 3,
228 L_PAREN | R_PAREN => 2,
229 kind if kind.is_trivia() => 0,
230 _ => 1,
231 }
232 }
233}
234
221pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { 235pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
222 let parse = db.parse(frange.file_id); 236 let parse = db.parse(frange.file_id);
223 let leaf_node = find_covering_element(parse.tree().syntax(), frange.range); 237 let leaf_node = find_covering_element(parse.tree().syntax(), frange.range);
@@ -505,6 +519,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
505 } 519 }
506 520
507 #[test] 521 #[test]
522 fn hover_for_param_edge() {
523 let (analysis, position) = single_file_with_position("fn func(<|>foo: i32) {}");
524 let hover = analysis.hover(position).unwrap().unwrap();
525 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
526 }
527
528 #[test]
508 fn test_type_of_for_function() { 529 fn test_type_of_for_function() {
509 let (analysis, range) = single_file_with_range( 530 let (analysis, range) = single_file_with_range(
510 " 531 "
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 4166a8f90..40605d9ef 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -10,8 +10,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
10.builtin { color: #DD6718; } 10.builtin { color: #DD6718; }
11.text { color: #DCDCCC; } 11.text { color: #DCDCCC; }
12.type { color: #7CB8BB; } 12.type { color: #7CB8BB; }
13.type\.param { color: #20999D; }
13.attribute { color: #94BFF3; } 14.attribute { color: #94BFF3; }
14.literal { color: #BFEBBF; } 15.literal { color: #BFEBBF; }
16.literal\.numeric { color: #6A8759; }
15.macro { color: #94BFF3; } 17.macro { color: #94BFF3; }
16.variable { color: #DCDCCC; } 18.variable { color: #DCDCCC; }
17.variable\.mut { color: #DCDCCC; text-decoration: underline; } 19.variable\.mut { color: #DCDCCC; text-decoration: underline; }
@@ -22,36 +24,36 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
22</style> 24</style>
23<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> 25<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>
24<span class="keyword">struct</span> <span class="type">Foo</span> { 26<span class="keyword">struct</span> <span class="type">Foo</span> {
25 <span class="keyword">pub</span> <span class="field">x</span>: <span class="type">i32</span>, 27 <span class="keyword">pub</span> <span class="field">x</span>: <span class="type.builtin">i32</span>,
26 <span class="keyword">pub</span> <span class="field">y</span>: <span class="type">i32</span>, 28 <span class="keyword">pub</span> <span class="field">y</span>: <span class="type.builtin">i32</span>,
27} 29}
28 30
29<span class="keyword">fn</span> <span class="function">foo</span>&lt;<span class="type">T</span>&gt;() -&gt; <span class="type">T</span> { 31<span class="keyword">fn</span> <span class="function">foo</span>&lt;<span class="type.param">T</span>&gt;() -&gt; <span class="type.param">T</span> {
30 <span class="macro">unimplemented</span><span class="macro">!</span>(); 32 <span class="macro">unimplemented</span><span class="macro">!</span>();
31 <span class="function">foo</span>::&lt;<span class="type">i32</span>&gt;(); 33 <span class="function">foo</span>::&lt;<span class="type.builtin">i32</span>&gt;();
32} 34}
33 35
34<span class="comment">// comment</span> 36<span class="comment">// comment</span>
35<span class="keyword">fn</span> <span class="function">main</span>() { 37<span class="keyword">fn</span> <span class="function">main</span>() {
36 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal">92</span>); 38 <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal.numeric">92</span>);
37 39
38 <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>(); 40 <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>();
39 <span class="keyword.control">if</span> <span class="keyword">true</span> { 41 <span class="keyword.control">if</span> <span class="keyword">true</span> {
40 <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> }); 42 <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal.numeric">0</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> });
41 } 43 }
42 <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal">0</span>); } 44 <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); }
43 45
44 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal">42</span>; 46 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal.numeric">42</span>;
45 <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>; 47 <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>;
46 <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable.mut">y</span>; 48 <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable.mut">y</span>;
47 49
48 <span class="variable.mut">y</span>; 50 <span class="variable.mut">y</span>;
49} 51}
50 52
51<span class="keyword">enum</span> <span class="type">E</span>&lt;<span class="type">X</span>&gt; { 53<span class="keyword">enum</span> <span class="type">E</span>&lt;<span class="type.param">X</span>&gt; {
52 <span class="constant">V</span>(<span class="type">X</span>) 54 <span class="constant">V</span>(<span class="type.param">X</span>)
53} 55}
54 56
55<span class="keyword">impl</span>&lt;<span class="type">X</span>&gt; <span class="type">E</span>&lt;<span class="type">X</span>&gt; { 57<span class="keyword">impl</span>&lt;<span class="type.param">X</span>&gt; <span class="type">E</span>&lt;<span class="type.param">X</span>&gt; {
56 <span class="keyword">fn</span> <span class="function">new</span>&lt;<span class="type">T</span>&gt;() -&gt; <span class="type">E</span>&lt;<span class="type">T</span>&gt; {} 58 <span class="keyword">fn</span> <span class="function">new</span>&lt;<span class="type.param">T</span>&gt;() -&gt; <span class="type">E</span>&lt;<span class="type.param">T</span>&gt; {}
57}</code></pre> \ No newline at end of file 59}</code></pre> \ 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 9dfbc8047..ecf26c708 100644
--- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
@@ -10,8 +10,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
10.builtin { color: #DD6718; } 10.builtin { color: #DD6718; }
11.text { color: #DCDCCC; } 11.text { color: #DCDCCC; }
12.type { color: #7CB8BB; } 12.type { color: #7CB8BB; }
13.type\.param { color: #20999D; }
13.attribute { color: #94BFF3; } 14.attribute { color: #94BFF3; }
14.literal { color: #BFEBBF; } 15.literal { color: #BFEBBF; }
16.literal\.numeric { color: #6A8759; }
15.macro { color: #94BFF3; } 17.macro { color: #94BFF3; }
16.variable { color: #DCDCCC; } 18.variable { color: #DCDCCC; }
17.variable\.mut { color: #DCDCCC; text-decoration: underline; } 19.variable\.mut { color: #DCDCCC; text-decoration: underline; }
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 7ecb1a027..eb3dd1779 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -16,6 +16,34 @@ use crate::{
16 FileId, 16 FileId,
17}; 17};
18 18
19pub mod tags {
20 pub(crate) const FIELD: &'static str = "field";
21 pub(crate) const FUNCTION: &'static str = "function";
22 pub(crate) const MODULE: &'static str = "module";
23 pub(crate) const TYPE: &'static str = "type";
24 pub(crate) const CONSTANT: &'static str = "constant";
25 pub(crate) const MACRO: &'static str = "macro";
26 pub(crate) const VARIABLE: &'static str = "variable";
27 pub(crate) const VARIABLE_MUT: &'static str = "variable.mut";
28 pub(crate) const TEXT: &'static str = "text";
29
30 pub(crate) const TYPE_BUILTIN: &'static str = "type.builtin";
31 pub(crate) const TYPE_SELF: &'static str = "type.self";
32 pub(crate) const TYPE_PARAM: &'static str = "type.param";
33 pub(crate) const TYPE_LIFETIME: &'static str = "type.lifetime";
34
35 pub(crate) const LITERAL_BYTE: &'static str = "literal.byte";
36 pub(crate) const LITERAL_NUMERIC: &'static str = "literal.numeric";
37 pub(crate) const LITERAL_CHAR: &'static str = "literal.char";
38 pub(crate) const LITERAL_COMMENT: &'static str = "comment";
39 pub(crate) const LITERAL_STRING: &'static str = "string";
40 pub(crate) const LITERAL_ATTRIBUTE: &'static str = "attribute";
41
42 pub(crate) const KEYWORD_UNSAFE: &'static str = "keyword.unsafe";
43 pub(crate) const KEYWORD_CONTROL: &'static str = "keyword.control";
44 pub(crate) const KEYWORD: &'static str = "keyword";
45}
46
19#[derive(Debug)] 47#[derive(Debug)]
20pub struct HighlightedRange { 48pub struct HighlightedRange {
21 pub range: TextRange, 49 pub range: TextRange,
@@ -71,9 +99,9 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
71 bindings_shadow_count.clear(); 99 bindings_shadow_count.clear();
72 continue; 100 continue;
73 } 101 }
74 COMMENT => "comment", 102 COMMENT => tags::LITERAL_COMMENT,
75 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", 103 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => tags::LITERAL_STRING,
76 ATTR => "attribute", 104 ATTR => tags::LITERAL_ATTRIBUTE,
77 NAME_REF => { 105 NAME_REF => {
78 if node.ancestors().any(|it| it.kind() == ATTR) { 106 if node.ancestors().any(|it| it.kind() == ATTR) {
79 continue; 107 continue;
@@ -90,7 +118,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
90 } 118 }
91 }; 119 };
92 120
93 name_kind.map_or("text", |it| highlight_name(db, it)) 121 name_kind.map_or(tags::TEXT, |it| highlight_name(db, it))
94 } 122 }
95 NAME => { 123 NAME => {
96 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); 124 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap();
@@ -107,18 +135,21 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
107 135
108 match name_kind { 136 match name_kind {
109 Some(name_kind) => highlight_name(db, name_kind), 137 Some(name_kind) => highlight_name(db, name_kind),
110 None => name.syntax().parent().map_or("function", |x| match x.kind() { 138 None => name.syntax().parent().map_or(tags::FUNCTION, |x| match x.kind() {
111 TYPE_PARAM | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_ALIAS_DEF => "type", 139 STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_ALIAS_DEF => tags::TYPE,
112 RECORD_FIELD_DEF => "field", 140 TYPE_PARAM => tags::TYPE_PARAM,
113 _ => "function", 141 RECORD_FIELD_DEF => tags::FIELD,
142 _ => tags::FUNCTION,
114 }), 143 }),
115 } 144 }
116 } 145 }
117 INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", 146 INT_NUMBER | FLOAT_NUMBER => tags::LITERAL_NUMERIC,
118 LIFETIME => "parameter", 147 BYTE => tags::LITERAL_BYTE,
119 T![unsafe] => "keyword.unsafe", 148 CHAR => tags::LITERAL_CHAR,
120 k if is_control_keyword(k) => "keyword.control", 149 LIFETIME => tags::TYPE_LIFETIME,
121 k if k.is_keyword() => "keyword", 150 T![unsafe] => tags::KEYWORD_UNSAFE,
151 k if is_control_keyword(k) => tags::KEYWORD_CONTROL,
152 k if k.is_keyword() => tags::KEYWORD,
122 _ => { 153 _ => {
123 if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) { 154 if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) {
124 if let Some(path) = macro_call.path() { 155 if let Some(path) = macro_call.path() {
@@ -135,7 +166,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
135 } 166 }
136 res.push(HighlightedRange { 167 res.push(HighlightedRange {
137 range: TextRange::from_to(range_start, range_end), 168 range: TextRange::from_to(range_start, range_end),
138 tag: "macro", 169 tag: tags::MACRO,
139 binding_hash: None, 170 binding_hash: None,
140 }) 171 })
141 } 172 }
@@ -211,28 +242,29 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
211 242
212fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { 243fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str {
213 match name_kind { 244 match name_kind {
214 Macro(_) => "macro", 245 Macro(_) => tags::MACRO,
215 Field(_) => "field", 246 Field(_) => tags::FIELD,
216 AssocItem(hir::AssocItem::Function(_)) => "function", 247 AssocItem(hir::AssocItem::Function(_)) => tags::FUNCTION,
217 AssocItem(hir::AssocItem::Const(_)) => "constant", 248 AssocItem(hir::AssocItem::Const(_)) => tags::CONSTANT,
218 AssocItem(hir::AssocItem::TypeAlias(_)) => "type", 249 AssocItem(hir::AssocItem::TypeAlias(_)) => tags::TYPE,
219 Def(hir::ModuleDef::Module(_)) => "module", 250 Def(hir::ModuleDef::Module(_)) => tags::MODULE,
220 Def(hir::ModuleDef::Function(_)) => "function", 251 Def(hir::ModuleDef::Function(_)) => tags::FUNCTION,
221 Def(hir::ModuleDef::Adt(_)) => "type", 252 Def(hir::ModuleDef::Adt(_)) => tags::TYPE,
222 Def(hir::ModuleDef::EnumVariant(_)) => "constant", 253 Def(hir::ModuleDef::EnumVariant(_)) => tags::CONSTANT,
223 Def(hir::ModuleDef::Const(_)) => "constant", 254 Def(hir::ModuleDef::Const(_)) => tags::CONSTANT,
224 Def(hir::ModuleDef::Static(_)) => "constant", 255 Def(hir::ModuleDef::Static(_)) => tags::CONSTANT,
225 Def(hir::ModuleDef::Trait(_)) => "type", 256 Def(hir::ModuleDef::Trait(_)) => tags::TYPE,
226 Def(hir::ModuleDef::TypeAlias(_)) => "type", 257 Def(hir::ModuleDef::TypeAlias(_)) => tags::TYPE,
227 Def(hir::ModuleDef::BuiltinType(_)) => "type", 258 Def(hir::ModuleDef::BuiltinType(_)) => tags::TYPE_BUILTIN,
228 SelfType(_) | TypeParam(_) => "type", 259 SelfType(_) => tags::TYPE_SELF,
260 TypeParam(_) => tags::TYPE_PARAM,
229 Local(local) => { 261 Local(local) => {
230 if local.is_mut(db) { 262 if local.is_mut(db) {
231 "variable.mut" 263 tags::VARIABLE_MUT
232 } else if local.ty(db).is_mutable_reference() { 264 } else if local.ty(db).is_mutable_reference() {
233 "variable.mut" 265 tags::VARIABLE_MUT
234 } else { 266 } else {
235 "variable" 267 tags::VARIABLE
236 } 268 }
237 } 269 }
238 } 270 }
@@ -255,8 +287,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
255.builtin { color: #DD6718; } 287.builtin { color: #DD6718; }
256.text { color: #DCDCCC; } 288.text { color: #DCDCCC; }
257.type { color: #7CB8BB; } 289.type { color: #7CB8BB; }
290.type\\.param { color: #20999D; }
258.attribute { color: #94BFF3; } 291.attribute { color: #94BFF3; }
259.literal { color: #BFEBBF; } 292.literal { color: #BFEBBF; }
293.literal\\.numeric { color: #6A8759; }
260.macro { color: #94BFF3; } 294.macro { color: #94BFF3; }
261.variable { color: #DCDCCC; } 295.variable { color: #DCDCCC; }
262.variable\\.mut { color: #DCDCCC; text-decoration: underline; } 296.variable\\.mut { color: #DCDCCC; text-decoration: underline; }