1- mod tags ;
1+ mod format ;
22mod html;
33mod injection;
4+ mod tags;
45#[ cfg( test) ]
56mod tests;
67
@@ -17,9 +18,8 @@ use syntax::{
1718 SyntaxNode , SyntaxToken , TextRange , WalkEvent , T ,
1819} ;
1920
20- use crate :: FileId ;
21+ use crate :: { syntax_highlighting :: format :: FormatStringHighlighter , FileId } ;
2122
22- use ast:: FormatSpecifier ;
2323pub ( crate ) use html:: highlight_as_html;
2424pub use tags:: { Highlight , HighlightModifier , HighlightModifiers , HighlightTag } ;
2525
@@ -69,7 +69,7 @@ pub(crate) fn highlight(
6969 let mut stack = HighlightedRangeStack :: new ( ) ;
7070
7171 let mut current_macro_call: Option < ( ast:: MacroCall , Option < MacroMatcherParseState > ) > = None ;
72- let mut format_string : Option < SyntaxElement > = None ;
72+ let mut format_string_highlighter = FormatStringHighlighter :: default ( ) ;
7373
7474 // Walk all nodes, keeping track of whether we are inside a macro or not.
7575 // If in macro, expand it first and highlight the expanded code.
@@ -121,7 +121,7 @@ pub(crate) fn highlight(
121121 WalkEvent :: Leave ( Some ( mc) ) => {
122122 assert ! ( current_macro_call. map( |it| it. 0 ) == Some ( mc) ) ;
123123 current_macro_call = None ;
124- format_string = None ;
124+ format_string_highlighter . reset ( ) ;
125125 }
126126 _ => ( ) ,
127127 }
@@ -173,30 +173,7 @@ pub(crate) fn highlight(
173173 let token = sema. descend_into_macros ( token. clone ( ) ) ;
174174 let parent = token. parent ( ) ;
175175
176- // Check if macro takes a format string and remember it for highlighting later.
177- // The macros that accept a format string expand to a compiler builtin macros
178- // `format_args` and `format_args_nl`.
179- if let Some ( name) = parent
180- . parent ( )
181- . and_then ( ast:: MacroCall :: cast)
182- . and_then ( |mc| mc. path ( ) )
183- . and_then ( |p| p. segment ( ) )
184- . and_then ( |s| s. name_ref ( ) )
185- {
186- match name. text ( ) . as_str ( ) {
187- "format_args" | "format_args_nl" => {
188- format_string = parent
189- . children_with_tokens ( )
190- . filter ( |t| t. kind ( ) != WHITESPACE )
191- . nth ( 1 )
192- . filter ( |e| {
193- ast:: String :: can_cast ( e. kind ( ) )
194- || ast:: RawString :: can_cast ( e. kind ( ) )
195- } )
196- }
197- _ => { }
198- }
199- }
176+ format_string_highlighter. check_for_format_string ( & parent) ;
200177
201178 // We only care Name and Name_ref
202179 match ( token. kind ( ) , parent. kind ( ) ) {
@@ -214,8 +191,6 @@ pub(crate) fn highlight(
214191 }
215192 }
216193
217- let is_format_string = format_string. as_ref ( ) == Some ( & element_to_highlight) ;
218-
219194 if let Some ( ( highlight, binding_hash) ) = highlight_element (
220195 & sema,
221196 & mut bindings_shadow_count,
@@ -226,19 +201,7 @@ pub(crate) fn highlight(
226201 if let Some ( string) =
227202 element_to_highlight. as_token ( ) . cloned ( ) . and_then ( ast:: String :: cast)
228203 {
229- if is_format_string {
230- stack. push ( ) ;
231- string. lex_format_specifier ( |piece_range, kind| {
232- if let Some ( highlight) = highlight_format_specifier ( kind) {
233- stack. add ( HighlightedRange {
234- range : piece_range + range. start ( ) ,
235- highlight : highlight. into ( ) ,
236- binding_hash : None ,
237- } ) ;
238- }
239- } ) ;
240- stack. pop ( ) ;
241- }
204+ format_string_highlighter. highlight_format_string ( & mut stack, & string, range) ;
242205 // Highlight escape sequences
243206 if let Some ( char_ranges) = string. char_ranges ( ) {
244207 stack. push ( ) ;
@@ -256,19 +219,7 @@ pub(crate) fn highlight(
256219 } else if let Some ( string) =
257220 element_to_highlight. as_token ( ) . cloned ( ) . and_then ( ast:: RawString :: cast)
258221 {
259- if is_format_string {
260- stack. push ( ) ;
261- string. lex_format_specifier ( |piece_range, kind| {
262- if let Some ( highlight) = highlight_format_specifier ( kind) {
263- stack. add ( HighlightedRange {
264- range : piece_range + range. start ( ) ,
265- highlight : highlight. into ( ) ,
266- binding_hash : None ,
267- } ) ;
268- }
269- } ) ;
270- stack. pop ( ) ;
271- }
222+ format_string_highlighter. highlight_format_string ( & mut stack, & string, range) ;
272223 }
273224 }
274225 }
@@ -436,24 +387,6 @@ impl HighlightedRangeStack {
436387 }
437388}
438389
439- fn highlight_format_specifier ( kind : FormatSpecifier ) -> Option < HighlightTag > {
440- Some ( match kind {
441- FormatSpecifier :: Open
442- | FormatSpecifier :: Close
443- | FormatSpecifier :: Colon
444- | FormatSpecifier :: Fill
445- | FormatSpecifier :: Align
446- | FormatSpecifier :: Sign
447- | FormatSpecifier :: NumberSign
448- | FormatSpecifier :: DollarSign
449- | FormatSpecifier :: Dot
450- | FormatSpecifier :: Asterisk
451- | FormatSpecifier :: QuestionMark => HighlightTag :: FormatSpecifier ,
452- FormatSpecifier :: Integer | FormatSpecifier :: Zero => HighlightTag :: NumericLiteral ,
453- FormatSpecifier :: Identifier => HighlightTag :: Local ,
454- } )
455- }
456-
457390fn macro_call_range ( macro_call : & ast:: MacroCall ) -> Option < TextRange > {
458391 let path = macro_call. path ( ) ?;
459392 let name_ref = path. segment ( ) ?. name_ref ( ) ?;
0 commit comments