Skip to content

Commit 8f31924

Browse files
committed
Cleanup string handling in syntax highlighting
1 parent 9200f77 commit 8f31924

File tree

4 files changed

+27
-58
lines changed

4 files changed

+27
-58
lines changed

crates/ide/src/syntax_highlighting.rs

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod tests;
1414

1515
use std::ops::ControlFlow;
1616

17-
use hir::{InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics};
17+
use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics};
1818
use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind};
1919
use span::EditionedFileId;
2020
use syntax::{
@@ -371,8 +371,7 @@ fn traverse(
371371
InFile::new(file_id.into(), element)
372372
};
373373

374-
// string highlight injections, note this does not use the descended element as proc-macros
375-
// can rewrite string literals which invalidates our indices
374+
// string highlight injections
376375
if let (Some(original_token), Some(descended_token)) =
377376
(original_token, descended_element.value.as_token())
378377
{
@@ -390,6 +389,7 @@ fn traverse(
390389
}
391390
}
392391

392+
let edition = descended_element.file_id.edition(sema.db);
393393
let element = match descended_element.value {
394394
NodeOrToken::Node(name_like) => {
395395
let hl = highlight::name_like(
@@ -398,7 +398,7 @@ fn traverse(
398398
&mut bindings_shadow_count,
399399
config.syntactic_name_ref_highlighting,
400400
name_like,
401-
file_id.edition(),
401+
edition,
402402
);
403403
if hl.is_some() && !in_macro {
404404
// skip highlighting the contained token of our name-like node
@@ -408,7 +408,7 @@ fn traverse(
408408
hl
409409
}
410410
NodeOrToken::Token(token) => {
411-
highlight::token(sema, token, file_id.edition(), tt_level > 0).zip(Some(None))
411+
highlight::token(sema, token, edition, tt_level > 0).zip(Some(None))
412412
}
413413
};
414414
if let Some((mut highlight, binding_hash)) = element {
@@ -448,10 +448,11 @@ fn string_injections(
448448
token: SyntaxToken,
449449
descended_token: &SyntaxToken,
450450
) -> ControlFlow<()> {
451-
if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind()) {
452-
let string = ast::String::cast(token);
453-
let string_to_highlight = ast::String::cast(descended_token.clone());
454-
if let Some((string, descended_string)) = string.zip(string_to_highlight) {
451+
if !matches!(token.kind(), STRING | BYTE_STRING | BYTE | CHAR | C_STRING) {
452+
return ControlFlow::Continue(());
453+
}
454+
if let Some(string) = ast::String::cast(token.clone()) {
455+
if let Some(descended_string) = ast::String::cast(descended_token.clone()) {
455456
if string.is_raw()
456457
&& inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some()
457458
{
@@ -463,32 +464,17 @@ fn string_injections(
463464
highlight_escape_string(hl, &string);
464465
}
465466
}
466-
} else if ast::ByteString::can_cast(token.kind())
467-
&& ast::ByteString::can_cast(descended_token.kind())
468-
{
469-
if let Some(byte_string) = ast::ByteString::cast(token) {
470-
if !byte_string.is_raw() {
471-
highlight_escape_string(hl, &byte_string);
472-
}
467+
} else if let Some(byte_string) = ast::ByteString::cast(token.clone()) {
468+
if !byte_string.is_raw() {
469+
highlight_escape_string(hl, &byte_string);
473470
}
474-
} else if ast::CString::can_cast(token.kind()) && ast::CString::can_cast(descended_token.kind())
475-
{
476-
if let Some(c_string) = ast::CString::cast(token) {
477-
if !c_string.is_raw() {
478-
highlight_escape_string(hl, &c_string);
479-
}
471+
} else if let Some(c_string) = ast::CString::cast(token.clone()) {
472+
if !c_string.is_raw() {
473+
highlight_escape_string(hl, &c_string);
480474
}
481-
} else if ast::Char::can_cast(token.kind()) && ast::Char::can_cast(descended_token.kind()) {
482-
let Some(char) = ast::Char::cast(token) else {
483-
return ControlFlow::Break(());
484-
};
485-
475+
} else if let Some(char) = ast::Char::cast(token.clone()) {
486476
highlight_escape_char(hl, &char)
487-
} else if ast::Byte::can_cast(token.kind()) && ast::Byte::can_cast(descended_token.kind()) {
488-
let Some(byte) = ast::Byte::cast(token) else {
489-
return ControlFlow::Break(());
490-
};
491-
477+
} else if let Some(byte) = ast::Byte::cast(token) {
492478
highlight_escape_byte(hl, &byte)
493479
}
494480
ControlFlow::Continue(())
@@ -536,10 +522,10 @@ fn descend_token(
536522
token.map(|token| match token.parent().and_then(ast::NameLike::cast) {
537523
// Remap the token into the wrapping single token nodes
538524
Some(parent) => match (token.kind(), parent.syntax().kind()) {
539-
(T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent),
540-
(T![self] | T![super] | T![crate] | T![Self], NAME_REF) => NodeOrToken::Node(parent),
541-
(INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent),
542-
(LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
525+
(T![ident] | T![self], NAME)
526+
| (T![ident] | T![self] | T![super] | T![crate] | T![Self], NAME_REF)
527+
| (INT_NUMBER, NAME_REF)
528+
| (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
543529
_ => NodeOrToken::Token(token),
544530
},
545531
None => NodeOrToken::Token(token),

crates/ide/src/syntax_highlighting/highlight.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub(super) fn name_like(
8989
Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => {
9090
highlight_def(sema, krate, def, edition)
9191
}
92-
// FIXME: Fallback for 'static and '_, as we do not resolve these yet
92+
// FIXME: Fallback for '_, as we do not resolve these yet
9393
_ => SymbolKind::LifetimeParam.into(),
9494
},
9595
};

crates/parser/src/syntax_kind/generated.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ pub enum SyntaxKind {
147147
C_STRING,
148148
FLOAT_NUMBER,
149149
INT_NUMBER,
150-
RAW_BYTE_STRING,
151-
RAW_C_STRING,
152-
RAW_STRING,
153150
STRING,
154151
COMMENT,
155152
ERROR,
@@ -343,9 +340,6 @@ impl SyntaxKind {
343340
| C_STRING
344341
| FLOAT_NUMBER
345342
| INT_NUMBER
346-
| RAW_BYTE_STRING
347-
| RAW_C_STRING
348-
| RAW_STRING
349343
| STRING
350344
| ABI
351345
| ADT
@@ -898,18 +892,7 @@ impl SyntaxKind {
898892
)
899893
}
900894
pub fn is_literal(self) -> bool {
901-
matches!(
902-
self,
903-
BYTE | BYTE_STRING
904-
| CHAR
905-
| C_STRING
906-
| FLOAT_NUMBER
907-
| INT_NUMBER
908-
| RAW_BYTE_STRING
909-
| RAW_C_STRING
910-
| RAW_STRING
911-
| STRING
912-
)
895+
matches!(self, BYTE | BYTE_STRING | CHAR | C_STRING | FLOAT_NUMBER | INT_NUMBER | STRING)
913896
}
914897
pub fn from_keyword(ident: &str, edition: Edition) -> Option<SyntaxKind> {
915898
let kw = match ident {

crates/syntax/rust.ungram

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ MacroExpr =
438438
Literal =
439439
Attr* value:(
440440
'@int_number' | '@float_number'
441-
| '@string' | '@raw_string'
442-
| '@byte_string' | '@raw_byte_string'
443-
| '@c_string' | '@raw_c_string'
441+
| '@string'
442+
| '@byte_string'
443+
| '@c_string'
444444
| '@char' | '@byte'
445445
| 'true' | 'false'
446446
)

0 commit comments

Comments
 (0)