summaryrefslogtreecommitdiff
path: root/vala/valageniescanner.vala
diff options
context:
space:
mode:
author星外之神 <wszqkzqk@qq.com>2022-10-28 23:47:56 +0800
committerRico Tzschichholz <ricotz@ubuntu.com>2022-10-30 16:11:11 +0100
commit3c3ee793b499be959b3ed7f1f74014713382a438 (patch)
treefeb077276aa853d7d7d05659e4689c24a6f231cd /vala/valageniescanner.vala
parent2b69b8accac817f23bd51ca41d14deec131d83c5 (diff)
downloadvala-3c3ee793b499be959b3ed7f1f74014713382a438.tar.gz
vala: Add support for verbatim template string
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1373
Diffstat (limited to 'vala/valageniescanner.vala')
-rw-r--r--vala/valageniescanner.vala47
1 files changed, 36 insertions, 11 deletions
diff --git a/vala/valageniescanner.vala b/vala/valageniescanner.vala
index ef54ae7d3..286992206 100644
--- a/vala/valageniescanner.vala
+++ b/vala/valageniescanner.vala
@@ -67,7 +67,8 @@ public class Vala.Genie.Scanner {
BRACKET,
REGEX_LITERAL,
TEMPLATE,
- TEMPLATE_PART
+ TEMPLATE_PART,
+ VERBATIM_TEMPLATE
}
public Scanner (SourceFile source_file) {
@@ -97,6 +98,10 @@ public class Vala.Genie.Scanner {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE);
}
+ bool in_verbatim_template () {
+ return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.VERBATIM_TEMPLATE);
+ }
+
bool in_template_part () {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE_PART);
}
@@ -695,6 +700,7 @@ public class Vala.Genie.Scanner {
public TokenType read_template_token (out SourceLocation token_begin, out SourceLocation token_end) {
+ bool is_verbatim = in_verbatim_template ();
TokenType type;
char* begin = current;
token_begin = SourceLocation (begin, line, column);
@@ -706,9 +712,22 @@ public class Vala.Genie.Scanner {
} else {
switch (current[0]) {
case '"':
- type = TokenType.CLOSE_TEMPLATE;
- current++;
- state_stack.length--;
+ if (is_verbatim) {
+ if (current < end -2 && current[1] == '"' && current[2] == '"' && current[3] != '"') {
+ type = TokenType.CLOSE_TEMPLATE;
+ current += 3;
+ state_stack.length--;
+ } else {
+ type = TokenType.VERBATIM_TEMPLATE_STRING_LITERAL;
+ current++;
+ token_length_in_chars++;
+ state_stack += State.TEMPLATE_PART;
+ }
+ } else {
+ type = TokenType.CLOSE_TEMPLATE;
+ current++;
+ state_stack.length--;
+ }
break;
case '$':
token_begin.pos++; // $ is not part of following token
@@ -727,7 +746,7 @@ public class Vala.Genie.Scanner {
state_stack += State.PARENS;
return read_token (out token_begin, out token_end);
} else if (current[0] == '$') {
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
current++;
state_stack += State.TEMPLATE_PART;
} else {
@@ -736,10 +755,10 @@ public class Vala.Genie.Scanner {
}
break;
default:
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
token_length_in_chars = 0;
while (current < end && current[0] != '"' && current[0] != '$') {
- if (current[0] == '\\') {
+ if (current[0] == '\\' && !is_verbatim) {
current++;
token_length_in_chars++;
if (current >= end) {
@@ -842,7 +861,7 @@ public class Vala.Genie.Scanner {
return TokenType.EOF;
}
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
return read_template_token (out token_begin, out token_end);
} else if (in_template_part ()) {
state_stack.length--;
@@ -960,9 +979,15 @@ public class Vala.Genie.Scanner {
type = get_identifier_or_keyword (begin, len);
} else if (current[0] == '@') {
if (current < end - 1 && current[1] == '"') {
+ current += 1;
+ if (current < end - 5 && current[1] == '"' && current[2] == '"') {
+ current += 3;
+ state_stack += State.VERBATIM_TEMPLATE;
+ } else {
+ current += 1;
+ state_stack += State.TEMPLATE;
+ }
type = TokenType.OPEN_TEMPLATE;
- current += 2;
- state_stack += State.TEMPLATE;
} else {
token_begin.pos++; // @ is not part of the identifier
current++;
@@ -1053,7 +1078,7 @@ public class Vala.Genie.Scanner {
if (state_stack.length > 0) {
state_stack.length--;
}
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
type = TokenType.COMMA;
}
break;