Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/syntax_highlighting.rs')
| -rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 9fb6a30263..d7ad6a7579 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -206,6 +206,19 @@ fn traverse( let is_unlinked = sema.to_module_def(file_id).is_none(); let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default(); + enum AttrOrDerive { + Attr(ast::Item), + Derive(ast::Item), + } + + impl AttrOrDerive { + fn item(&self) -> &ast::Item { + match self { + AttrOrDerive::Attr(item) | AttrOrDerive::Derive(item) => item, + } + } + } + let mut tt_level = 0; let mut attr_or_derive_item = None; let mut current_macro: Option<ast::Macro> = None; @@ -260,7 +273,7 @@ fn traverse( if attr_or_derive_item.is_none() { if sema.is_attr_macro_call(&item) { - attr_or_derive_item = Some(item); + attr_or_derive_item = Some(AttrOrDerive::Attr(item)); } else { let adt = match item { ast::Item::Enum(it) => Some(ast::Adt::Enum(it)), @@ -270,7 +283,8 @@ fn traverse( }; match adt { Some(adt) if sema.is_derive_annotated(&adt) => { - attr_or_derive_item = Some(ast::Item::from(adt)); + attr_or_derive_item = + Some(AttrOrDerive::Derive(ast::Item::from(adt))); } _ => (), } @@ -292,7 +306,9 @@ fn traverse( current_macro = None; macro_highlighter = MacroHighlighter::default(); } - Some(item) if attr_or_derive_item.as_ref().map_or(false, |it| *it == item) => { + Some(item) + if attr_or_derive_item.as_ref().map_or(false, |it| *it.item() == item) => + { attr_or_derive_item = None; } _ => (), @@ -330,15 +346,26 @@ fn traverse( // Descending tokens into macros is expensive even if no descending occurs, so make sure // that we actually are in a position where descending is possible. - let in_macro = tt_level > 0 || attr_or_derive_item.is_some(); + let in_macro = tt_level > 0 + || match attr_or_derive_item { + Some(AttrOrDerive::Attr(_)) => true, + Some(AttrOrDerive::Derive(_)) => inside_attribute, + None => false, + }; let descended_element = if in_macro { // Attempt to descend tokens into macro-calls. match element { NodeOrToken::Token(token) if token.kind() != COMMENT => { - let token = sema.descend_into_macros_single(token); + let token = match attr_or_derive_item { + Some(AttrOrDerive::Attr(_)) => { + sema.descend_into_macros_with_kind_preference(token) + } + Some(AttrOrDerive::Derive(_)) | None => { + sema.descend_into_macros_single(token) + } + }; match token.parent().and_then(ast::NameLike::cast) { // Remap the token into the wrapping single token nodes - // FIXME: if the node doesn't resolve, we also won't do token based highlighting! Some(parent) => match (token.kind(), parent.syntax().kind()) { (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent), (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => { |