aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/syntax_highlighting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting.rs')
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs63
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> {
410fn highlight_element( 415fn 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
625fn 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}