@@ -29,6 +29,7 @@ typedef enum {
29
29
Format = 1 << 4 ,
30
30
Triple = 1 << 5 ,
31
31
Bytes = 1 << 6 ,
32
+ Template = 1 << 7 ,
32
33
} Flags ;
33
34
34
35
typedef struct {
@@ -45,6 +46,8 @@ static inline bool is_triple(Delimiter *delimiter) { return delimiter->flags & T
45
46
46
47
static inline bool is_bytes (Delimiter * delimiter ) { return delimiter -> flags & Bytes ; }
47
48
49
+ static inline bool is_template (Delimiter * delimiter ) { return delimiter -> flags & Template ; }
50
+
48
51
static inline int32_t end_character (Delimiter * delimiter ) {
49
52
if (delimiter -> flags & SingleQuote ) {
50
53
return '\'' ;
@@ -66,6 +69,8 @@ static inline void set_triple(Delimiter *delimiter) { delimiter->flags |= Triple
66
69
67
70
static inline void set_bytes (Delimiter * delimiter ) { delimiter -> flags |= Bytes ; }
68
71
72
+ static inline void set_template (Delimiter * delimiter ) { delimiter -> flags |= (Template | Format ); }
73
+
69
74
static inline void set_end_character (Delimiter * delimiter , int32_t character ) {
70
75
switch (character ) {
71
76
case '\'' :
@@ -85,7 +90,7 @@ static inline void set_end_character(Delimiter *delimiter, int32_t character) {
85
90
typedef struct {
86
91
Array (uint16_t ) indents ;
87
92
Array (Delimiter ) delimiters ;
88
- bool inside_f_string ;
93
+ bool inside_interpolated_string ;
89
94
} Scanner ;
90
95
91
96
static inline void advance (TSLexer * lexer ) { lexer -> advance (lexer , false); }
@@ -102,7 +107,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
102
107
if (valid_symbols [ESCAPE_INTERPOLATION ] && scanner -> delimiters .size > 0 &&
103
108
(lexer -> lookahead == '{' || lexer -> lookahead == '}' ) && !error_recovery_mode ) {
104
109
Delimiter * delimiter = array_back (& scanner -> delimiters );
105
- if (is_format (delimiter )) {
110
+ if (is_format (delimiter ) || is_template ( delimiter ) ) {
106
111
lexer -> mark_end (lexer );
107
112
bool is_left_brace = lexer -> lookahead == '{' ;
108
113
advance (lexer );
@@ -122,7 +127,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
122
127
int32_t end_char = end_character (delimiter );
123
128
bool has_content = advanced_once ;
124
129
while (lexer -> lookahead ) {
125
- if ((advanced_once || lexer -> lookahead == '{' || lexer -> lookahead == '}' ) && is_format (delimiter )) {
130
+ if ((advanced_once || lexer -> lookahead == '{' || lexer -> lookahead == '}' ) && ( is_format (delimiter ) || is_template ( delimiter ) )) {
126
131
lexer -> mark_end (lexer );
127
132
lexer -> result_symbol = STRING_CONTENT ;
128
133
return has_content ;
@@ -177,7 +182,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
177
182
lexer -> mark_end (lexer );
178
183
array_pop (& scanner -> delimiters );
179
184
lexer -> result_symbol = STRING_END ;
180
- scanner -> inside_f_string = false;
185
+ scanner -> inside_interpolated_string = false;
181
186
}
182
187
return true;
183
188
}
@@ -195,7 +200,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
195
200
advance (lexer );
196
201
array_pop (& scanner -> delimiters );
197
202
lexer -> result_symbol = STRING_END ;
198
- scanner -> inside_f_string = false;
203
+ scanner -> inside_interpolated_string = false;
199
204
}
200
205
lexer -> mark_end (lexer );
201
206
return true;
@@ -280,7 +285,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
280
285
if ((valid_symbols [DEDENT ] ||
281
286
(!valid_symbols [NEWLINE ] && !(valid_symbols [STRING_START ] && next_tok_is_string_start ) &&
282
287
!within_brackets )) &&
283
- indent_length < current_indent_length && !scanner -> inside_f_string &&
288
+ indent_length < current_indent_length && !scanner -> inside_interpolated_string &&
284
289
285
290
// Wait to create a dedent token until we've consumed any
286
291
// comments
@@ -309,6 +314,8 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
309
314
set_raw (& delimiter );
310
315
} else if (lexer -> lookahead == 'b' || lexer -> lookahead == 'B' ) {
311
316
set_bytes (& delimiter );
317
+ } else if (lexer -> lookahead == 't' || lexer -> lookahead == 'T' ) {
318
+ set_template (& delimiter );
312
319
} else if (lexer -> lookahead != 'u' && lexer -> lookahead != 'U' ) {
313
320
break ;
314
321
}
@@ -349,7 +356,7 @@ bool tree_sitter_python_external_scanner_scan(void *payload, TSLexer *lexer, con
349
356
if (end_character (& delimiter )) {
350
357
array_push (& scanner -> delimiters , delimiter );
351
358
lexer -> result_symbol = STRING_START ;
352
- scanner -> inside_f_string = is_format (& delimiter );
359
+ scanner -> inside_interpolated_string = is_format ( & delimiter ) || is_template (& delimiter );
353
360
return true;
354
361
}
355
362
if (has_flags ) {
@@ -365,7 +372,7 @@ unsigned tree_sitter_python_external_scanner_serialize(void *payload, char *buff
365
372
366
373
size_t size = 0 ;
367
374
368
- buffer [size ++ ] = (char )scanner -> inside_f_string ;
375
+ buffer [size ++ ] = (char )scanner -> inside_interpolated_string ;
369
376
370
377
size_t delimiter_count = scanner -> delimiters .size ;
371
378
if (delimiter_count > UINT8_MAX ) {
@@ -398,7 +405,7 @@ void tree_sitter_python_external_scanner_deserialize(void *payload, const char *
398
405
if (length > 0 ) {
399
406
size_t size = 0 ;
400
407
401
- scanner -> inside_f_string = (bool )buffer [size ++ ];
408
+ scanner -> inside_interpolated_string = (bool )buffer [size ++ ];
402
409
403
410
size_t delimiter_count = (uint8_t )buffer [size ++ ];
404
411
if (delimiter_count > 0 ) {
0 commit comments