mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Cleanup string handling in syntax highlighting
This commit is contained in:
parent
9200f77068
commit
8f319240b4
@ -14,7 +14,7 @@ mod tests;
|
|||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics};
|
use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics};
|
||||||
use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind};
|
use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind};
|
||||||
use span::EditionedFileId;
|
use span::EditionedFileId;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
@ -371,8 +371,7 @@ fn traverse(
|
|||||||
InFile::new(file_id.into(), element)
|
InFile::new(file_id.into(), element)
|
||||||
};
|
};
|
||||||
|
|
||||||
// string highlight injections, note this does not use the descended element as proc-macros
|
// string highlight injections
|
||||||
// can rewrite string literals which invalidates our indices
|
|
||||||
if let (Some(original_token), Some(descended_token)) =
|
if let (Some(original_token), Some(descended_token)) =
|
||||||
(original_token, descended_element.value.as_token())
|
(original_token, descended_element.value.as_token())
|
||||||
{
|
{
|
||||||
@ -390,6 +389,7 @@ fn traverse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let edition = descended_element.file_id.edition(sema.db);
|
||||||
let element = match descended_element.value {
|
let element = match descended_element.value {
|
||||||
NodeOrToken::Node(name_like) => {
|
NodeOrToken::Node(name_like) => {
|
||||||
let hl = highlight::name_like(
|
let hl = highlight::name_like(
|
||||||
@ -398,7 +398,7 @@ fn traverse(
|
|||||||
&mut bindings_shadow_count,
|
&mut bindings_shadow_count,
|
||||||
config.syntactic_name_ref_highlighting,
|
config.syntactic_name_ref_highlighting,
|
||||||
name_like,
|
name_like,
|
||||||
file_id.edition(),
|
edition,
|
||||||
);
|
);
|
||||||
if hl.is_some() && !in_macro {
|
if hl.is_some() && !in_macro {
|
||||||
// skip highlighting the contained token of our name-like node
|
// skip highlighting the contained token of our name-like node
|
||||||
@ -408,7 +408,7 @@ fn traverse(
|
|||||||
hl
|
hl
|
||||||
}
|
}
|
||||||
NodeOrToken::Token(token) => {
|
NodeOrToken::Token(token) => {
|
||||||
highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None))
|
highlight::token(sema, token, edition, tt_level > 0).zip(Some(None))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some((mut highlight, binding_hash)) = element {
|
if let Some((mut highlight, binding_hash)) = element {
|
||||||
@ -448,10 +448,11 @@ fn string_injections(
|
|||||||
token: SyntaxToken,
|
token: SyntaxToken,
|
||||||
descended_token: &SyntaxToken,
|
descended_token: &SyntaxToken,
|
||||||
) -> ControlFlow<()> {
|
) -> ControlFlow<()> {
|
||||||
if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) {
|
if !matches!(token.kind(), STRING | BYTE_STRING | BYTE | CHAR | C_STRING) {
|
||||||
let string = ast::String::cast(token);
|
return ControlFlow::Continue(());
|
||||||
let string_to_highlight = ast::String::cast(descended_token.clone());
|
}
|
||||||
if let Some((string, descended_string)) = string.zip(string_to_highlight) {
|
if let Some(string) = ast::String::cast(token.clone()) {
|
||||||
|
if let Some(descended_string) = ast::String::cast(descended_token.clone()) {
|
||||||
if string.is_raw()
|
if string.is_raw()
|
||||||
&& inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some()
|
&& inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some()
|
||||||
{
|
{
|
||||||
@ -463,32 +464,17 @@ fn string_injections(
|
|||||||
highlight_escape_string(hl, &string);
|
highlight_escape_string(hl, &string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ast::ByteString::can_cast(token.kind())
|
} else if let Some(byte_string) = ast::ByteString::cast(token.clone()) {
|
||||||
&& ast::ByteString::can_cast(descended_token.kind())
|
|
||||||
{
|
|
||||||
if let Some(byte_string) = ast::ByteString::cast(token) {
|
|
||||||
if !byte_string.is_raw() {
|
if !byte_string.is_raw() {
|
||||||
highlight_escape_string(hl, &byte_string);
|
highlight_escape_string(hl, &byte_string);
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(c_string) = ast::CString::cast(token.clone()) {
|
||||||
} else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind())
|
|
||||||
{
|
|
||||||
if let Some(c_string) = ast::CString::cast(token) {
|
|
||||||
if !c_string.is_raw() {
|
if !c_string.is_raw() {
|
||||||
highlight_escape_string(hl, &c_string);
|
highlight_escape_string(hl, &c_string);
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(char) = ast::Char::cast(token.clone()) {
|
||||||
} else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) {
|
|
||||||
let Some(char) = ast::Char::cast(token) else {
|
|
||||||
return ControlFlow::Break(());
|
|
||||||
};
|
|
||||||
|
|
||||||
highlight_escape_char(hl, &char)
|
highlight_escape_char(hl, &char)
|
||||||
} else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) {
|
} else if let Some(byte) = ast::Byte::cast(token) {
|
||||||
let Some(byte) = ast::Byte::cast(token) else {
|
|
||||||
return ControlFlow::Break(());
|
|
||||||
};
|
|
||||||
|
|
||||||
highlight_escape_byte(hl, &byte)
|
highlight_escape_byte(hl, &byte)
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
@ -536,10 +522,10 @@ fn descend_token(
|
|||||||
token.map(|token| match token.parent().and_then(ast::NameLike::cast) {
|
token.map(|token| match token.parent().and_then(ast::NameLike::cast) {
|
||||||
// Remap the token into the wrapping single token nodes
|
// Remap the token into the wrapping single token nodes
|
||||||
Some(parent) => match (token.kind(), parent.syntax().kind()) {
|
Some(parent) => match (token.kind(), parent.syntax().kind()) {
|
||||||
(T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent),
|
(T![ident] | T![self], NAME)
|
||||||
(T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent),
|
| (T![ident] | T![self] | T![super] | T![crate] | T![Self], NAME_REF)
|
||||||
(INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent),
|
| (INT_NUMBER, NAME_REF)
|
||||||
(LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
|
| (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
|
||||||
_ => NodeOrToken::Token(token),
|
_ => NodeOrToken::Token(token),
|
||||||
},
|
},
|
||||||
None => NodeOrToken::Token(token),
|
None => NodeOrToken::Token(token),
|
||||||
|
@ -89,7 +89,7 @@ pub(super) fn name_like(
|
|||||||
Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => {
|
Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => {
|
||||||
highlight_def(sema, krate, def, edition)
|
highlight_def(sema, krate, def, edition)
|
||||||
}
|
}
|
||||||
// FIXME: Fallback for 'static and '_, as we do not resolve these yet
|
// FIXME: Fallback for '_, as we do not resolve these yet
|
||||||
_ => SymbolKind::LifetimeParam.into(),
|
_ => SymbolKind::LifetimeParam.into(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -147,9 +147,6 @@ pub enum SyntaxKind {
|
|||||||
C_STRING,
|
C_STRING,
|
||||||
FLOAT_NUMBER,
|
FLOAT_NUMBER,
|
||||||
INT_NUMBER,
|
INT_NUMBER,
|
||||||
RAW_BYTE_STRING,
|
|
||||||
RAW_C_STRING,
|
|
||||||
RAW_STRING,
|
|
||||||
STRING,
|
STRING,
|
||||||
COMMENT,
|
COMMENT,
|
||||||
ERROR,
|
ERROR,
|
||||||
@ -343,9 +340,6 @@ impl SyntaxKind {
|
|||||||
| C_STRING
|
| C_STRING
|
||||||
| FLOAT_NUMBER
|
| FLOAT_NUMBER
|
||||||
| INT_NUMBER
|
| INT_NUMBER
|
||||||
| RAW_BYTE_STRING
|
|
||||||
| RAW_C_STRING
|
|
||||||
| RAW_STRING
|
|
||||||
| STRING
|
| STRING
|
||||||
| ABI
|
| ABI
|
||||||
| ADT
|
| ADT
|
||||||
@ -898,18 +892,7 @@ impl SyntaxKind {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn is_literal(self) -> bool {
|
pub fn is_literal(self) -> bool {
|
||||||
matches!(
|
matches!(self, BYTE | BYTE_STRING | CHAR | C_STRING | FLOAT_NUMBER | INT_NUMBER | STRING)
|
||||||
self,
|
|
||||||
BYTE | BYTE_STRING
|
|
||||||
| CHAR
|
|
||||||
| C_STRING
|
|
||||||
| FLOAT_NUMBER
|
|
||||||
| INT_NUMBER
|
|
||||||
| RAW_BYTE_STRING
|
|
||||||
| RAW_C_STRING
|
|
||||||
| RAW_STRING
|
|
||||||
| STRING
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
pub fn from_keyword(ident: &str, edition: Edition) -> Option<SyntaxKind> {
|
pub fn from_keyword(ident: &str, edition: Edition) -> Option<SyntaxKind> {
|
||||||
let kw = match ident {
|
let kw = match ident {
|
||||||
|
@ -438,9 +438,9 @@ MacroExpr =
|
|||||||
Literal =
|
Literal =
|
||||||
Attr* value:(
|
Attr* value:(
|
||||||
'@int_number' | '@float_number'
|
'@int_number' | '@float_number'
|
||||||
| '@string' | '@raw_string'
|
| '@string'
|
||||||
| '@byte_string' | '@raw_byte_string'
|
| '@byte_string'
|
||||||
| '@c_string' | '@raw_c_string'
|
| '@c_string'
|
||||||
| '@char' | '@byte'
|
| '@char' | '@byte'
|
||||||
| 'true' | 'false'
|
| 'true' | 'false'
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user