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,28 +2270,31 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
break;
case GDScriptTokenizer::Token::BRACKET_OPEN: {
// Array.
push_multiline(true);
advance();
pattern->pattern_type = PatternNode::PT_ARRAY;
if (!check(GDScriptTokenizer::Token::BRACKET_CLOSE)) {
do {
PatternNode *sub_pattern = parse_match_pattern(p_root_pattern != nullptr ? p_root_pattern : pattern);
if (sub_pattern == nullptr) {
continue;
}
if (pattern->rest_used) {
push_error(R"(The ".." pattern must be the last element in the pattern array.)");
} else if (sub_pattern->pattern_type == PatternNode::PT_REST) {
pattern->rest_used = true;
}
pattern->array.push_back(sub_pattern);
} while (match(GDScriptTokenizer::Token::COMMA));
}
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);
if (sub_pattern == nullptr) {
continue;
}
if (pattern->rest_used) {
push_error(R"(The ".." pattern must be the last element in the pattern array.)");
} else if (sub_pattern->pattern_type == PatternNode::PT_REST) {
pattern->rest_used = true;
}
pattern->array.push_back(sub_pattern);
} while (match(GDScriptTokenizer::Token::COMMA));
consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected "]" to close the array pattern.)");
pop_multiline();
break;
}
case GDScriptTokenizer::Token::BRACE_OPEN: {
// Dictionary.
push_multiline(true);
advance();
pattern->pattern_type = PatternNode::PT_DICTIONARY;
do {
@ -2334,6 +2337,7 @@ GDScriptParser::PatternNode *GDScriptParser::parse_match_pattern(PatternNode *p_
}
} while (match(GDScriptTokenizer::Token::COMMA));
consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected "}" to close the dictionary pattern.)");
pop_multiline();
break;
}
default: {