diff options
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 114 |
1 files changed, 84 insertions, 30 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 028b55902..e3a96f9d5 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -464,7 +464,7 @@ fn highlight_element( | |||
464 | let db = sema.db; | 464 | let db = sema.db; |
465 | let mut binding_hash = None; | 465 | let mut binding_hash = None; |
466 | let highlight: Highlight = match element.kind() { | 466 | let highlight: Highlight = match element.kind() { |
467 | FN_DEF => { | 467 | FN => { |
468 | bindings_shadow_count.clear(); | 468 | bindings_shadow_count.clear(); |
469 | return None; | 469 | return None; |
470 | } | 470 | } |
@@ -539,20 +539,52 @@ fn highlight_element( | |||
539 | _ => h, | 539 | _ => h, |
540 | } | 540 | } |
541 | } | 541 | } |
542 | T![*] => { | 542 | p if p.is_punct() => match p { |
543 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | 543 | T![::] | T![->] | T![=>] | T![&] | T![..] | T![=] | T![@] => { |
544 | 544 | HighlightTag::Operator.into() | |
545 | let expr = prefix_expr.expr()?; | ||
546 | let ty = sema.type_of_expr(&expr)?; | ||
547 | if !ty.is_raw_ptr() { | ||
548 | return None; | ||
549 | } else { | ||
550 | HighlightTag::Operator | HighlightModifier::Unsafe | ||
551 | } | 545 | } |
552 | } | 546 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { |
553 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | 547 | HighlightTag::Macro.into() |
554 | Highlight::new(HighlightTag::Macro) | 548 | } |
555 | } | 549 | T![*] if element.parent().and_then(ast::PointerType::cast).is_some() => { |
550 | HighlightTag::Keyword.into() | ||
551 | } | ||
552 | T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
553 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | ||
554 | |||
555 | let expr = prefix_expr.expr()?; | ||
556 | let ty = sema.type_of_expr(&expr)?; | ||
557 | if ty.is_raw_ptr() { | ||
558 | HighlightTag::Operator | HighlightModifier::Unsafe | ||
559 | } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { | ||
560 | HighlightTag::Operator.into() | ||
561 | } else { | ||
562 | HighlightTag::Punctuation.into() | ||
563 | } | ||
564 | } | ||
565 | T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
566 | HighlightTag::NumericLiteral.into() | ||
567 | } | ||
568 | _ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
569 | HighlightTag::Operator.into() | ||
570 | } | ||
571 | _ if element.parent().and_then(ast::BinExpr::cast).is_some() => { | ||
572 | HighlightTag::Operator.into() | ||
573 | } | ||
574 | _ if element.parent().and_then(ast::RangeExpr::cast).is_some() => { | ||
575 | HighlightTag::Operator.into() | ||
576 | } | ||
577 | _ if element.parent().and_then(ast::RangePat::cast).is_some() => { | ||
578 | HighlightTag::Operator.into() | ||
579 | } | ||
580 | _ if element.parent().and_then(ast::DotDotPat::cast).is_some() => { | ||
581 | HighlightTag::Operator.into() | ||
582 | } | ||
583 | _ if element.parent().and_then(ast::Attr::cast).is_some() => { | ||
584 | HighlightTag::Attribute.into() | ||
585 | } | ||
586 | _ => HighlightTag::Punctuation.into(), | ||
587 | }, | ||
556 | 588 | ||
557 | k if k.is_keyword() => { | 589 | k if k.is_keyword() => { |
558 | let h = Highlight::new(HighlightTag::Keyword); | 590 | let h = Highlight::new(HighlightTag::Keyword); |
@@ -566,10 +598,31 @@ fn highlight_element( | |||
566 | | T![return] | 598 | | T![return] |
567 | | T![while] | 599 | | T![while] |
568 | | T![in] => h | HighlightModifier::ControlFlow, | 600 | | T![in] => h | HighlightModifier::ControlFlow, |
569 | T![for] if !is_child_of_impl(element) => h | HighlightModifier::ControlFlow, | 601 | T![for] if !is_child_of_impl(&element) => h | HighlightModifier::ControlFlow, |
570 | T![unsafe] => h | HighlightModifier::Unsafe, | 602 | T![unsafe] => h | HighlightModifier::Unsafe, |
571 | T![true] | T![false] => HighlightTag::BoolLiteral.into(), | 603 | T![true] | T![false] => HighlightTag::BoolLiteral.into(), |
572 | T![self] => HighlightTag::SelfKeyword.into(), | 604 | T![self] => { |
605 | let self_param_is_mut = element | ||
606 | .parent() | ||
607 | .and_then(ast::SelfParam::cast) | ||
608 | .and_then(|p| p.mut_token()) | ||
609 | .is_some(); | ||
610 | // closure to enforce lazyness | ||
611 | let self_path = || { | ||
612 | sema.resolve_path(&element.parent()?.parent().and_then(ast::Path::cast)?) | ||
613 | }; | ||
614 | if self_param_is_mut | ||
615 | || matches!(self_path(), | ||
616 | Some(hir::PathResolution::Local(local)) | ||
617 | if local.is_self(db) | ||
618 | && (local.is_mut(db) || local.ty(db).is_mutable_reference()) | ||
619 | ) | ||
620 | { | ||
621 | HighlightTag::SelfKeyword | HighlightModifier::Mutable | ||
622 | } else { | ||
623 | HighlightTag::SelfKeyword.into() | ||
624 | } | ||
625 | } | ||
573 | _ => h, | 626 | _ => h, |
574 | } | 627 | } |
575 | } | 628 | } |
@@ -592,9 +645,9 @@ fn highlight_element( | |||
592 | } | 645 | } |
593 | } | 646 | } |
594 | 647 | ||
595 | fn is_child_of_impl(element: SyntaxElement) -> bool { | 648 | fn is_child_of_impl(element: &SyntaxElement) -> bool { |
596 | match element.parent() { | 649 | match element.parent() { |
597 | Some(e) => e.kind() == IMPL_DEF, | 650 | Some(e) => e.kind() == IMPL, |
598 | _ => false, | 651 | _ => false, |
599 | } | 652 | } |
600 | } | 653 | } |
@@ -630,9 +683,10 @@ fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight { | |||
630 | }, | 683 | }, |
631 | Definition::SelfType(_) => HighlightTag::SelfType, | 684 | Definition::SelfType(_) => HighlightTag::SelfType, |
632 | Definition::TypeParam(_) => HighlightTag::TypeParam, | 685 | Definition::TypeParam(_) => HighlightTag::TypeParam, |
633 | // FIXME: distinguish between locals and parameters | ||
634 | Definition::Local(local) => { | 686 | Definition::Local(local) => { |
635 | let mut h = Highlight::new(HighlightTag::Local); | 687 | let tag = |
688 | if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local }; | ||
689 | let mut h = Highlight::new(tag); | ||
636 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { | 690 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { |
637 | h |= HighlightModifier::Mutable; | 691 | h |= HighlightModifier::Mutable; |
638 | } | 692 | } |
@@ -651,18 +705,18 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
651 | }; | 705 | }; |
652 | 706 | ||
653 | let tag = match parent.kind() { | 707 | let tag = match parent.kind() { |
654 | STRUCT_DEF => HighlightTag::Struct, | 708 | STRUCT => HighlightTag::Struct, |
655 | ENUM_DEF => HighlightTag::Enum, | 709 | ENUM => HighlightTag::Enum, |
656 | UNION_DEF => HighlightTag::Union, | 710 | UNION => HighlightTag::Union, |
657 | TRAIT_DEF => HighlightTag::Trait, | 711 | TRAIT => HighlightTag::Trait, |
658 | TYPE_ALIAS_DEF => HighlightTag::TypeAlias, | 712 | TYPE_ALIAS => HighlightTag::TypeAlias, |
659 | TYPE_PARAM => HighlightTag::TypeParam, | 713 | TYPE_PARAM => HighlightTag::TypeParam, |
660 | RECORD_FIELD_DEF => HighlightTag::Field, | 714 | RECORD_FIELD => HighlightTag::Field, |
661 | MODULE => HighlightTag::Module, | 715 | MODULE => HighlightTag::Module, |
662 | FN_DEF => HighlightTag::Function, | 716 | FN => HighlightTag::Function, |
663 | CONST_DEF => HighlightTag::Constant, | 717 | CONST => HighlightTag::Constant, |
664 | STATIC_DEF => HighlightTag::Static, | 718 | STATIC => HighlightTag::Static, |
665 | ENUM_VARIANT => HighlightTag::EnumVariant, | 719 | VARIANT => HighlightTag::EnumVariant, |
666 | BIND_PAT => HighlightTag::Local, | 720 | BIND_PAT => HighlightTag::Local, |
667 | _ => default, | 721 | _ => default, |
668 | }; | 722 | }; |