diff options
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index bbcd52a1c..5a4de450c 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -44,6 +44,7 @@ pub(crate) fn highlight( | |||
44 | db: &RootDatabase, | 44 | db: &RootDatabase, |
45 | file_id: FileId, | 45 | file_id: FileId, |
46 | range_to_highlight: Option<TextRange>, | 46 | range_to_highlight: Option<TextRange>, |
47 | syntactic_name_ref_highlighting: bool, | ||
47 | ) -> Vec<HighlightedRange> { | 48 | ) -> Vec<HighlightedRange> { |
48 | let _p = profile("highlight"); | 49 | let _p = profile("highlight"); |
49 | let sema = Semantics::new(db); | 50 | let sema = Semantics::new(db); |
@@ -104,6 +105,7 @@ pub(crate) fn highlight( | |||
104 | if let Some((highlight, binding_hash)) = highlight_element( | 105 | if let Some((highlight, binding_hash)) = highlight_element( |
105 | &sema, | 106 | &sema, |
106 | &mut bindings_shadow_count, | 107 | &mut bindings_shadow_count, |
108 | syntactic_name_ref_highlighting, | ||
107 | name.syntax().clone().into(), | 109 | name.syntax().clone().into(), |
108 | ) { | 110 | ) { |
109 | stack.add(HighlightedRange { | 111 | stack.add(HighlightedRange { |
@@ -200,9 +202,12 @@ pub(crate) fn highlight( | |||
200 | 202 | ||
201 | let is_format_string = format_string.as_ref() == Some(&element_to_highlight); | 203 | let is_format_string = format_string.as_ref() == Some(&element_to_highlight); |
202 | 204 | ||
203 | if let Some((highlight, binding_hash)) = | 205 | if let Some((highlight, binding_hash)) = highlight_element( |
204 | highlight_element(&sema, &mut bindings_shadow_count, element_to_highlight.clone()) | 206 | &sema, |
205 | { | 207 | &mut bindings_shadow_count, |
208 | syntactic_name_ref_highlighting, | ||
209 | element_to_highlight.clone(), | ||
210 | ) { | ||
206 | stack.add(HighlightedRange { range, highlight, binding_hash }); | 211 | stack.add(HighlightedRange { range, highlight, binding_hash }); |
207 | if let Some(string) = | 212 | if let Some(string) = |
208 | element_to_highlight.as_token().cloned().and_then(ast::String::cast) | 213 | element_to_highlight.as_token().cloned().and_then(ast::String::cast) |
@@ -410,6 +415,7 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> { | |||
410 | fn highlight_element( | 415 | fn highlight_element( |
411 | sema: &Semantics<RootDatabase>, | 416 | sema: &Semantics<RootDatabase>, |
412 | bindings_shadow_count: &mut FxHashMap<Name, u32>, | 417 | bindings_shadow_count: &mut FxHashMap<Name, u32>, |
418 | syntactic_name_ref_highlighting: bool, | ||
413 | element: SyntaxElement, | 419 | element: SyntaxElement, |
414 | ) -> Option<(Highlight, Option<u64>)> { | 420 | ) -> Option<(Highlight, Option<u64>)> { |
415 | let db = sema.db; | 421 | let db = sema.db; |
@@ -463,6 +469,7 @@ fn highlight_element( | |||
463 | } | 469 | } |
464 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | 470 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), |
465 | }, | 471 | }, |
472 | None if syntactic_name_ref_highlighting => highlight_name_ref_by_syntax(name_ref), | ||
466 | None => HighlightTag::UnresolvedReference.into(), | 473 | None => HighlightTag::UnresolvedReference.into(), |
467 | } | 474 | } |
468 | } | 475 | } |
@@ -614,3 +621,53 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
614 | 621 | ||
615 | tag.into() | 622 | tag.into() |
616 | } | 623 | } |
624 | |||
625 | fn highlight_name_ref_by_syntax(name: ast::NameRef) -> Highlight { | ||
626 | let default = HighlightTag::UnresolvedReference; | ||
627 | |||
628 | let parent = match name.syntax().parent() { | ||
629 | Some(it) => it, | ||
630 | _ => return default.into(), | ||
631 | }; | ||
632 | |||
633 | let tag = match parent.kind() { | ||
634 | METHOD_CALL_EXPR => HighlightTag::Function, | ||
635 | FIELD_EXPR => HighlightTag::Field, | ||
636 | PATH_SEGMENT => { | ||
637 | let path = match parent.parent().and_then(ast::Path::cast) { | ||
638 | Some(it) => it, | ||
639 | _ => return default.into(), | ||
640 | }; | ||
641 | let expr = match path.syntax().parent().and_then(ast::PathExpr::cast) { | ||
642 | Some(it) => it, | ||
643 | _ => { | ||
644 | // within path, decide whether it is module or adt by checking for uppercase name | ||
645 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
646 | HighlightTag::Struct | ||
647 | } else { | ||
648 | HighlightTag::Module | ||
649 | } | ||
650 | .into(); | ||
651 | } | ||
652 | }; | ||
653 | let parent = match expr.syntax().parent() { | ||
654 | Some(it) => it, | ||
655 | None => return default.into(), | ||
656 | }; | ||
657 | |||
658 | match parent.kind() { | ||
659 | CALL_EXPR => HighlightTag::Function, | ||
660 | _ => { | ||
661 | if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
662 | HighlightTag::Struct | ||
663 | } else { | ||
664 | HighlightTag::Constant | ||
665 | } | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | _ => default, | ||
670 | }; | ||
671 | |||
672 | tag.into() | ||
673 | } | ||