fix: Improve syntax highlighting in attributes
This commit is contained in:
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user