Skip to content

Commit ca97baa

Browse files
committed
fix: properly handle nested strings of different types inside interpolations
1 parent 2429277 commit ca97baa

File tree

3 files changed

+44
-45
lines changed

3 files changed

+44
-45
lines changed

grammar.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,15 +1497,15 @@ module.exports = grammar({
14971497
interpolated_string_expression: $ => choice(
14981498
seq(
14991499
alias($.interpolation_regular_start, $.interpolation_start),
1500-
'"',
1500+
alias($.interpolation_start_quote, '"'),
15011501
repeat($._interpolated_string_content),
1502-
'"',
1502+
alias($.interpolation_end_quote, '"'),
15031503
),
15041504
seq(
15051505
alias($.interpolation_verbatim_start, $.interpolation_start),
1506-
'"',
1506+
alias($.interpolation_start_quote, '"'),
15071507
repeat($._interpolated_verbatim_string_content),
1508-
'"',
1508+
alias($.interpolation_end_quote, '"'),
15091509
),
15101510
seq(
15111511
alias($.interpolation_raw_start, $.interpolation_start),

src/scanner.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, co
217217
if (is_verbatim || lexer->lookahead == '@') {
218218
if (lexer->lookahead == '@') {
219219
advance(lexer);
220+
is_verbatim = true;
220221
}
221222
lexer->result_symbol = INTERPOLATION_VERBATIM_START;
222223
interpolation.string_type = VERBATIM;
@@ -246,13 +247,20 @@ bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, co
246247
if (valid_symbols[INTERPOLATION_START_QUOTE] && scanner->interpolation_stack.size > 0) {
247248
Interpolation *current_interpolation = array_back(&scanner->interpolation_stack);
248249

249-
while (lexer->lookahead == '"') {
250-
advance(lexer);
251-
current_interpolation->quote_count++;
250+
if (is_verbatim(current_interpolation) || is_regular(current_interpolation)) {
251+
if (lexer->lookahead == '"') {
252+
advance(lexer);
253+
current_interpolation->quote_count++;
254+
}
255+
} else {
256+
while (lexer->lookahead == '"') {
257+
advance(lexer);
258+
current_interpolation->quote_count++;
259+
}
252260
}
253261

254262
lexer->result_symbol = INTERPOLATION_START_QUOTE;
255-
return current_interpolation->quote_count >= 3;
263+
return current_interpolation->quote_count > 0;
256264
}
257265

258266
if (valid_symbols[INTERPOLATION_END_QUOTE] && scanner->interpolation_stack.size > 0) {
@@ -302,20 +310,6 @@ bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, co
302310

303311
if (brace_advanced == current_interpolation->open_brace_count) {
304312
current_interpolation->open_brace_count = 0;
305-
if (lexer->lookahead == '"') {
306-
if (is_regular(current_interpolation) || is_verbatim(current_interpolation)) {
307-
if (is_verbatim(current_interpolation)) {
308-
lexer->mark_end(lexer);
309-
advance(lexer);
310-
// double quote in verbatim does not signify end, unless it's a triple quote
311-
if (lexer->lookahead != '"') {
312-
array_pop(&scanner->interpolation_stack);
313-
}
314-
} else {
315-
array_pop(&scanner->interpolation_stack);
316-
}
317-
}
318-
}
319313
lexer->result_symbol = INTERPOLATION_CLOSE_BRACE;
320314
return true;
321315
}
@@ -371,9 +365,6 @@ bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, co
371365
advance(lexer);
372366
continue;
373367
}
374-
if (did_advance) {
375-
array_pop(&scanner->interpolation_stack);
376-
}
377368
return did_advance;
378369
}
379370

@@ -395,9 +386,6 @@ bool tree_sitter_c_sharp_external_scanner_scan(void *payload, TSLexer *lexer, co
395386
// finally regular
396387
else if (is_regular(current_interpolation)) {
397388
if (lexer->lookahead == '\\' || lexer->lookahead == '\n' || lexer->lookahead == '"') {
398-
if (did_advance && lexer->lookahead == '"') {
399-
array_pop(&scanner->interpolation_stack);
400-
}
401389
lexer->mark_end(lexer);
402390
return did_advance;
403391
}

test/corpus/literals.txt

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ var x = $"""The point "{X}, {Y}" is
117117

118118
var x = $"{{";
119119

120-
var x = $@"""{foo}""";
121-
122120
var x = $"""{bar}""";
123121

124122
var x = """"baz"""";
@@ -131,6 +129,10 @@ var x = $""""
131129
var x = $@" ""hi"" ";
132130
var x = @$"""Hello"" {world}!";
133131

132+
var s = $$"""
133+
{{ $" { 1 } " }}
134+
""";
135+
134136
--------------------------------------------------------------------------------
135137

136138
(compilation_unit
@@ -803,20 +805,6 @@ var x = @$"""Hello"" {world}!";
803805
(identifier)
804806
(interpolation_brace))
805807
(interpolation_quote))))))
806-
(global_statement
807-
(local_declaration_statement
808-
(variable_declaration
809-
type: (implicit_type)
810-
(variable_declarator
811-
name: (identifier)
812-
(interpolated_string_expression
813-
(interpolation_start)
814-
(interpolation_quote)
815-
(interpolation
816-
(interpolation_brace)
817-
(identifier)
818-
(interpolation_brace))
819-
(interpolation_quote))))))
820808
(global_statement
821809
(local_declaration_statement
822810
(variable_declaration
@@ -860,4 +848,27 @@ var x = @$"""Hello"" {world}!";
860848
(interpolation_brace)
861849
(identifier)
862850
(interpolation_brace))
863-
(string_content)))))))
851+
(string_content))))))
852+
(global_statement
853+
(local_declaration_statement
854+
(variable_declaration
855+
type: (implicit_type)
856+
(variable_declarator
857+
name: (identifier)
858+
(interpolated_string_expression
859+
(interpolation_start)
860+
(interpolation_quote)
861+
(string_content)
862+
(interpolation
863+
(interpolation_brace)
864+
(interpolated_string_expression
865+
(interpolation_start)
866+
(string_content)
867+
(interpolation
868+
(interpolation_brace)
869+
(integer_literal)
870+
(interpolation_brace))
871+
(string_content))
872+
(interpolation_brace))
873+
(string_content)
874+
(interpolation_quote)))))))

0 commit comments

Comments
 (0)