aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/syntax_highlighting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/syntax_highlighting.rs')
-rw-r--r--crates/ide/src/syntax_highlighting.rs126
1 files changed, 72 insertions, 54 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 488969f1a..67ad7c63d 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -23,7 +23,7 @@ use crate::{
23 syntax_highlighting::{ 23 syntax_highlighting::{
24 format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, 24 format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight,
25 }, 25 },
26 FileId, HighlightModifier, HighlightTag, 26 FileId, HighlightModifier, HighlightTag, SymbolKind,
27}; 27};
28 28
29pub(crate) use html::highlight_as_html; 29pub(crate) use html::highlight_as_html;
@@ -103,7 +103,7 @@ pub(crate) fn highlight(
103 if let Some(range) = macro_call_range(&mc) { 103 if let Some(range) = macro_call_range(&mc) {
104 stack.add(HighlightedRange { 104 stack.add(HighlightedRange {
105 range, 105 range,
106 highlight: HighlightTag::Macro.into(), 106 highlight: HighlightTag::Symbol(SymbolKind::Macro).into(),
107 binding_hash: None, 107 binding_hash: None,
108 }); 108 });
109 } 109 }
@@ -470,13 +470,13 @@ fn highlight_element(
470 }; 470 };
471 471
472 match name_kind { 472 match name_kind {
473 Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(), 473 Some(NameClass::ExternCrate(_)) => HighlightTag::Symbol(SymbolKind::Module).into(),
474 Some(NameClass::Definition(def)) => { 474 Some(NameClass::Definition(def)) => {
475 highlight_def(db, def) | HighlightModifier::Definition 475 highlight_def(db, def) | HighlightModifier::Definition
476 } 476 }
477 Some(NameClass::ConstReference(def)) => highlight_def(db, def), 477 Some(NameClass::ConstReference(def)) => highlight_def(db, def),
478 Some(NameClass::PatFieldShorthand { field_ref, .. }) => { 478 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
479 let mut h = HighlightTag::Field.into(); 479 let mut h = HighlightTag::Symbol(SymbolKind::Field).into();
480 if let Definition::Field(field) = field_ref { 480 if let Definition::Field(field) = field_ref {
481 if let VariantDef::Union(_) = field.parent_def(db) { 481 if let VariantDef::Union(_) = field.parent_def(db) {
482 h |= HighlightModifier::Unsafe; 482 h |= HighlightModifier::Unsafe;
@@ -493,14 +493,16 @@ fn highlight_element(
493 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { 493 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => {
494 // even though we track whether we are in an attribute or not we still need this special case 494 // even though we track whether we are in an attribute or not we still need this special case
495 // as otherwise we would emit unresolved references for name refs inside attributes 495 // as otherwise we would emit unresolved references for name refs inside attributes
496 Highlight::from(HighlightTag::Function) 496 Highlight::from(HighlightTag::Symbol(SymbolKind::Function))
497 } 497 }
498 NAME_REF => { 498 NAME_REF => {
499 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 499 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
500 highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { 500 highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| {
501 match NameRefClass::classify(sema, &name_ref) { 501 match NameRefClass::classify(sema, &name_ref) {
502 Some(name_kind) => match name_kind { 502 Some(name_kind) => match name_kind {
503 NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), 503 NameRefClass::ExternCrate(_) => {
504 HighlightTag::Symbol(SymbolKind::Module).into()
505 }
504 NameRefClass::Definition(def) => { 506 NameRefClass::Definition(def) => {
505 if let Definition::Local(local) = &def { 507 if let Definition::Local(local) = &def {
506 if let Some(name) = local.name(db) { 508 if let Some(name) = local.name(db) {
@@ -530,7 +532,9 @@ fn highlight_element(
530 532
531 h 533 h
532 } 534 }
533 NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), 535 NameRefClass::FieldShorthand { .. } => {
536 HighlightTag::Symbol(SymbolKind::Field).into()
537 }
534 }, 538 },
535 None if syntactic_name_ref_highlighting => { 539 None if syntactic_name_ref_highlighting => {
536 highlight_name_ref_by_syntax(name_ref, sema) 540 highlight_name_ref_by_syntax(name_ref, sema)
@@ -556,7 +560,7 @@ fn highlight_element(
556 CHAR => HighlightTag::CharLiteral.into(), 560 CHAR => HighlightTag::CharLiteral.into(),
557 QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow, 561 QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow,
558 LIFETIME => { 562 LIFETIME => {
559 let h = Highlight::new(HighlightTag::Lifetime); 563 let h = Highlight::new(HighlightTag::Symbol(SymbolKind::LifetimeParam));
560 match element.parent().map(|it| it.kind()) { 564 match element.parent().map(|it| it.kind()) {
561 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, 565 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition,
562 _ => h, 566 _ => h,
@@ -580,7 +584,7 @@ fn highlight_element(
580 HighlightTag::Operator.into() 584 HighlightTag::Operator.into()
581 } 585 }
582 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 586 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
583 HighlightTag::Macro.into() 587 HighlightTag::Symbol(SymbolKind::Macro).into()
584 } 588 }
585 T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { 589 T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => {
586 HighlightTag::BuiltinType.into() 590 HighlightTag::BuiltinType.into()
@@ -659,7 +663,7 @@ fn highlight_element(
659 .and_then(SyntaxNode::parent) 663 .and_then(SyntaxNode::parent)
660 .and_then(ast::Path::cast) 664 .and_then(ast::Path::cast)
661 .and_then(|p| sema.resolve_path(&p)); 665 .and_then(|p| sema.resolve_path(&p));
662 let mut h = HighlightTag::SelfKeyword.into(); 666 let mut h = HighlightTag::Symbol(SymbolKind::SelfParam).into();
663 if self_param_is_mut 667 if self_param_is_mut
664 || matches!(self_path, 668 || matches!(self_path,
665 Some(hir::PathResolution::Local(local)) 669 Some(hir::PathResolution::Local(local))
@@ -732,7 +736,8 @@ fn highlight_method_call(
732 method_call: &ast::MethodCallExpr, 736 method_call: &ast::MethodCallExpr,
733) -> Option<Highlight> { 737) -> Option<Highlight> {
734 let func = sema.resolve_method_call(&method_call)?; 738 let func = sema.resolve_method_call(&method_call)?;
735 let mut h = HighlightTag::Method.into(); 739 let mut h = HighlightTag::Symbol(SymbolKind::Function).into();
740 h |= HighlightModifier::Associated;
736 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { 741 if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) {
737 h |= HighlightModifier::Unsafe; 742 h |= HighlightModifier::Unsafe;
738 } 743 }
@@ -756,35 +761,45 @@ fn highlight_method_call(
756 761
757fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { 762fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
758 match def { 763 match def {
759 Definition::Macro(_) => HighlightTag::Macro, 764 Definition::Macro(_) => HighlightTag::Symbol(SymbolKind::Macro),
760 Definition::Field(_) => HighlightTag::Field, 765 Definition::Field(_) => HighlightTag::Symbol(SymbolKind::Field),
761 Definition::ModuleDef(def) => match def { 766 Definition::ModuleDef(def) => match def {
762 hir::ModuleDef::Module(_) => HighlightTag::Module, 767 hir::ModuleDef::Module(_) => HighlightTag::Symbol(SymbolKind::Module),
763 hir::ModuleDef::Function(func) => { 768 hir::ModuleDef::Function(func) => {
764 let mut h = if func.as_assoc_item(db).is_some() { 769 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Function));
770 if func.as_assoc_item(db).is_some() {
771 h |= HighlightModifier::Associated;
765 if func.self_param(db).is_none() { 772 if func.self_param(db).is_none() {
766 Highlight::from(HighlightTag::Method) | HighlightModifier::Static 773 h |= HighlightModifier::Static
767 } else {
768 HighlightTag::Method.into()
769 } 774 }
770 } else { 775 }
771 HighlightTag::Function.into()
772 };
773 if func.is_unsafe(db) { 776 if func.is_unsafe(db) {
774 h |= HighlightModifier::Unsafe; 777 h |= HighlightModifier::Unsafe;
775 } 778 }
776 return h; 779 return h;
777 } 780 }
778 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, 781 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct),
779 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, 782 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum),
780 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, 783 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union),
781 hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant, 784 hir::ModuleDef::EnumVariant(_) => HighlightTag::Symbol(SymbolKind::Variant),
782 hir::ModuleDef::Const(_) => HighlightTag::Constant, 785 hir::ModuleDef::Const(konst) => {
783 hir::ModuleDef::Trait(_) => HighlightTag::Trait, 786 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const));
784 hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, 787 if konst.as_assoc_item(db).is_some() {
788 h |= HighlightModifier::Associated
789 }
790 return h;
791 }
792 hir::ModuleDef::Trait(_) => HighlightTag::Symbol(SymbolKind::Trait),
793 hir::ModuleDef::TypeAlias(type_) => {
794 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::TypeAlias));
795 if type_.as_assoc_item(db).is_some() {
796 h |= HighlightModifier::Associated
797 }
798 return h;
799 }
785 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, 800 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType,
786 hir::ModuleDef::Static(s) => { 801 hir::ModuleDef::Static(s) => {
787 let mut h = Highlight::new(HighlightTag::Static); 802 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Static));
788 if s.is_mut(db) { 803 if s.is_mut(db) {
789 h |= HighlightModifier::Mutable; 804 h |= HighlightModifier::Mutable;
790 h |= HighlightModifier::Unsafe; 805 h |= HighlightModifier::Unsafe;
@@ -792,11 +807,14 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
792 return h; 807 return h;
793 } 808 }
794 }, 809 },
795 Definition::SelfType(_) => HighlightTag::SelfType, 810 Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl),
796 Definition::TypeParam(_) => HighlightTag::TypeParam, 811 Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam),
797 Definition::Local(local) => { 812 Definition::Local(local) => {
798 let tag = 813 let tag = if local.is_param(db) {
799 if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local }; 814 HighlightTag::Symbol(SymbolKind::ValueParam)
815 } else {
816 HighlightTag::Symbol(SymbolKind::Local)
817 };
800 let mut h = Highlight::new(tag); 818 let mut h = Highlight::new(tag);
801 if local.is_mut(db) || local.ty(db).is_mutable_reference() { 819 if local.is_mut(db) || local.ty(db).is_mutable_reference() {
802 h |= HighlightModifier::Mutable; 820 h |= HighlightModifier::Mutable;
@@ -806,7 +824,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
806 } 824 }
807 return h; 825 return h;
808 } 826 }
809 Definition::LifetimeParam(_) => HighlightTag::Lifetime, 827 Definition::LifetimeParam(_) => HighlightTag::Symbol(SymbolKind::LifetimeParam),
810 } 828 }
811 .into() 829 .into()
812} 830}
@@ -820,19 +838,19 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
820 }; 838 };
821 839
822 let tag = match parent.kind() { 840 let tag = match parent.kind() {
823 STRUCT => HighlightTag::Struct, 841 STRUCT => HighlightTag::Symbol(SymbolKind::Struct),
824 ENUM => HighlightTag::Enum, 842 ENUM => HighlightTag::Symbol(SymbolKind::Enum),
825 UNION => HighlightTag::Union, 843 VARIANT => HighlightTag::Symbol(SymbolKind::Variant),
826 TRAIT => HighlightTag::Trait, 844 UNION => HighlightTag::Symbol(SymbolKind::Union),
827 TYPE_ALIAS => HighlightTag::TypeAlias, 845 TRAIT => HighlightTag::Symbol(SymbolKind::Trait),
828 TYPE_PARAM => HighlightTag::TypeParam, 846 TYPE_ALIAS => HighlightTag::Symbol(SymbolKind::TypeAlias),
829 RECORD_FIELD => HighlightTag::Field, 847 TYPE_PARAM => HighlightTag::Symbol(SymbolKind::TypeParam),
830 MODULE => HighlightTag::Module, 848 RECORD_FIELD => HighlightTag::Symbol(SymbolKind::Field),
831 FN => HighlightTag::Function, 849 MODULE => HighlightTag::Symbol(SymbolKind::Module),
832 CONST => HighlightTag::Constant, 850 FN => HighlightTag::Symbol(SymbolKind::Function),
833 STATIC => HighlightTag::Static, 851 CONST => HighlightTag::Symbol(SymbolKind::Const),
834 VARIANT => HighlightTag::EnumVariant, 852 STATIC => HighlightTag::Symbol(SymbolKind::Static),
835 IDENT_PAT => HighlightTag::Local, 853 IDENT_PAT => HighlightTag::Symbol(SymbolKind::Local),
836 _ => default, 854 _ => default,
837 }; 855 };
838 856
@@ -851,10 +869,10 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
851 METHOD_CALL_EXPR => { 869 METHOD_CALL_EXPR => {
852 return ast::MethodCallExpr::cast(parent) 870 return ast::MethodCallExpr::cast(parent)
853 .and_then(|method_call| highlight_method_call(sema, &method_call)) 871 .and_then(|method_call| highlight_method_call(sema, &method_call))
854 .unwrap_or_else(|| HighlightTag::Function.into()); 872 .unwrap_or_else(|| HighlightTag::Symbol(SymbolKind::Function).into());
855 } 873 }
856 FIELD_EXPR => { 874 FIELD_EXPR => {
857 let h = HighlightTag::Field; 875 let h = HighlightTag::Symbol(SymbolKind::Field);
858 let is_union = ast::FieldExpr::cast(parent) 876 let is_union = ast::FieldExpr::cast(parent)
859 .and_then(|field_expr| { 877 .and_then(|field_expr| {
860 let field = sema.resolve_field(&field_expr)?; 878 let field = sema.resolve_field(&field_expr)?;
@@ -881,9 +899,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
881 _ => { 899 _ => {
882 // within path, decide whether it is module or adt by checking for uppercase name 900 // within path, decide whether it is module or adt by checking for uppercase name
883 return if name.text().chars().next().unwrap_or_default().is_uppercase() { 901 return if name.text().chars().next().unwrap_or_default().is_uppercase() {
884 HighlightTag::Struct 902 HighlightTag::Symbol(SymbolKind::Struct)
885 } else { 903 } else {
886 HighlightTag::Module 904 HighlightTag::Symbol(SymbolKind::Module)
887 } 905 }
888 .into(); 906 .into();
889 } 907 }
@@ -894,11 +912,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
894 }; 912 };
895 913
896 match parent.kind() { 914 match parent.kind() {
897 CALL_EXPR => HighlightTag::Function.into(), 915 CALL_EXPR => HighlightTag::Symbol(SymbolKind::Function).into(),
898 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { 916 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() {
899 HighlightTag::Struct.into() 917 HighlightTag::Symbol(SymbolKind::Struct)
900 } else { 918 } else {
901 HighlightTag::Constant 919 HighlightTag::Symbol(SymbolKind::Const)
902 } 920 }
903 .into(), 921 .into(),
904 } 922 }