Fix multiline array/dictionary match statements

Currently array and dictionary expressions cannot be spread over
multiple lines in match statements.

Adding mutliline push/pop while parsing the pattern for bracket and
brace enables the ability for these to be multiline. This enables more
complex patterns to be matched without exceeding line limits.

Fixes #90372
This commit is contained in:
Aiden Storey 2024-04-07 22:13:10 -04:00 committed by Rémi Verschelde
parent b2f425fe68
commit 74177d79c9
No known key found for this signature in database
GPG key ID: C3336907360768E1
5 changed files with 82 additions and 15 deletions

View file

@ -2270,11 +2270,13 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
break; break;
case GDScriptTokenizer::Token::BRACKET_OPEN: { case GDScriptTokenizer::Token::BRACKET_OPEN: {
// Array. // Array.
push_multiline(true);
advance(); advance();
pattern->pattern_type = PatternNode::PT_ARRAY; pattern->pattern_type = PatternNode::PT_ARRAY;
if (!check(GDScriptTokenizer::Token::BRACKET_CLOSE)) {
do { do {
if (is_at_end() || check(GDScriptTokenizer::Token::BRACKET_CLOSE)) {
break;
}
PatternNode *sub_pattern = parse_match_pattern(p_root_pattern != nullptr ? p_root_pattern : pattern); PatternNode *sub_pattern = parse_match_pattern(p_root_pattern != nullptr ? p_root_pattern : pattern);
if (sub_pattern == nullptr) { if (sub_pattern == nullptr) {
continue; continue;
@ -2286,12 +2288,13 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
} }
pattern->array.push_back(sub_pattern); pattern->array.push_back(sub_pattern);
} while (match(GDScriptTokenizer::Token::COMMA)); } while (match(GDScriptTokenizer::Token::COMMA));
}
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected "]" to close the array pattern.)"); consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected "]" to close the array pattern.)");
pop_multiline();
break; break;
} }
case GDScriptTokenizer::Token::BRACE_OPEN: { case GDScriptTokenizer::Token::BRACE_OPEN: {
// Dictionary. // Dictionary.
push_multiline(true);
advance(); advance();
pattern->pattern_type = PatternNode::PT_DICTIONARY; pattern->pattern_type = PatternNode::PT_DICTIONARY;
do { do {
@ -2334,6 +2337,7 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
} }
} while (match(GDScriptTokenizer::Token::COMMA)); } while (match(GDScriptTokenizer::Token::COMMA));
consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected "}" to close the dictionary pattern.)"); consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected "}" to close the dictionary pattern.)");
pop_multiline();
break; break;
} }
default: { default: {

View file

@ -0,0 +1,33 @@
func foo(x):
match x:
["value1"]:
print('["value1"]')
["value1", "value2"]:
print('["value1", "value2"]')
func bar(x):
match x:
[
"value1"
]:
print('multiline ["value1"]')
[
"value1",
"value2",
]:
print('multiline ["value1", "value2",]')
[
"value1",
[
"value2",
..,
],
]:
print('multiline ["value1", ["value2", ..,],]')
func test():
foo(["value1"])
foo(["value1", "value2"])
bar(["value1"])
bar(["value1", "value2"])
bar(["value1", ["value2", "value3"]])

View file

@ -0,0 +1,6 @@
GDTEST_OK
["value1"]
["value1", "value2"]
multiline ["value1"]
multiline ["value1", "value2",]
multiline ["value1", ["value2", ..,],]

View file

@ -26,6 +26,24 @@ func bar(x):
_: _:
print("wildcard") print("wildcard")
func baz(x):
match x:
{
"key1": "value1"
}:
print('multiline {"key1": "value1"}')
{
"key2": "value2",
}:
print('multiline {"key2": "value2",}')
{
"key3": {
"key1",
..,
},
}:
print('multiline {"key3": {"key1", ..,},}')
func test(): func test():
foo({"key1": "value1", "key2": "value2"}) foo({"key1": "value1", "key2": "value2"})
foo({"key1": "value1", "key2": ""}) foo({"key1": "value1", "key2": ""})
@ -41,3 +59,6 @@ func test():
bar({1: "1"}) bar({1: "1"})
bar({2: "2"}) bar({2: "2"})
bar({3: "3"}) bar({3: "3"})
baz({"key1": "value1"})
baz({"key2": "value2"})
baz({"key3": {"key1": "value1", "key2": "value2"}})

View file

@ -13,3 +13,6 @@ wildcard
1 1
2 2
wildcard wildcard
multiline {"key1": "value1"}
multiline {"key2": "value2",}
multiline {"key3": {"key1", ..,},}