From 083986030e2a81c1135321f89e0984564ac73c41 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 10 Jan 2021 11:57:17 +0300 Subject: Replace state with function --- crates/ide/src/syntax_highlighting/format.rs | 82 ++++++++++++---------------- 1 file changed, 36 insertions(+), 46 deletions(-) (limited to 'crates/ide/src/syntax_highlighting/format.rs') diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs index d807ad0ad..a74ca844b 100644 --- a/crates/ide/src/syntax_highlighting/format.rs +++ b/crates/ide/src/syntax_highlighting/format.rs @@ -1,60 +1,48 @@ //! Syntax highlighting for format macro strings. use syntax::{ ast::{self, FormatSpecifier, HasFormatSpecifier}, - AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, + AstNode, AstToken, TextRange, }; -use crate::{HlRange, HlTag, SymbolKind}; +use crate::{syntax_highlighting::highlights::Highlights, HlRange, HlTag, SymbolKind}; -use super::highlights::Highlights; +pub(super) fn highlight_format_string( + stack: &mut Highlights, + string: &ast::String, + range: TextRange, +) { + if is_format_string(string).is_none() { + return; + } -#[derive(Default)] -pub(super) struct FormatStringHighlighter { - format_string: Option, + string.lex_format_specifier(|piece_range, kind| { + if let Some(highlight) = highlight_format_specifier(kind) { + stack.add(HlRange { + range: piece_range + range.start(), + highlight: highlight.into(), + binding_hash: None, + }); + } + }); } -impl FormatStringHighlighter { - pub(super) fn check_for_format_string(&mut self, parent: &SyntaxNode) { - // Check if macro takes a format string and remember it for highlighting later. - // The macros that accept a format string expand to a compiler builtin macros - // `format_args` and `format_args_nl`. - if let Some(name) = parent - .parent() - .and_then(ast::MacroCall::cast) - .and_then(|mc| mc.path()) - .and_then(|p| p.segment()) - .and_then(|s| s.name_ref()) - { - match name.text().as_str() { - "format_args" | "format_args_nl" => { - self.format_string = parent - .children_with_tokens() - .filter(|t| t.kind() != SyntaxKind::WHITESPACE) - .nth(1) - .filter(|e| ast::String::can_cast(e.kind())) - } - _ => {} - } - } +fn is_format_string(string: &ast::String) -> Option<()> { + let parent = string.syntax().parent(); + + let name = parent.parent().and_then(ast::MacroCall::cast)?.path()?.segment()?.name_ref()?; + if !matches!(name.text().as_str(), "format_args" | "format_args_nl") { + return None; } - pub(super) fn highlight_format_string( - &self, - stack: &mut Highlights, - string: &impl HasFormatSpecifier, - range: TextRange, - ) { - if self.format_string.as_ref() == Some(&SyntaxElement::from(string.syntax().clone())) { - string.lex_format_specifier(|piece_range, kind| { - if let Some(highlight) = highlight_format_specifier(kind) { - stack.add(HlRange { - range: piece_range + range.start(), - highlight: highlight.into(), - binding_hash: None, - }); - } - }); - } + + let first_literal = parent + .children_with_tokens() + .filter_map(|it| it.as_token().cloned().and_then(ast::String::cast)) + .next()?; + if &first_literal != string { + return None; } + + Some(()) } fn highlight_format_specifier(kind: FormatSpecifier) -> Option { @@ -70,7 +58,9 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option { | FormatSpecifier::Dot | FormatSpecifier::Asterisk | FormatSpecifier::QuestionMark => HlTag::FormatSpecifier, + FormatSpecifier::Integer | FormatSpecifier::Zero => HlTag::NumericLiteral, + FormatSpecifier::Identifier => HlTag::Symbol(SymbolKind::Local), }) } -- cgit v1.2.3