GDScript: Allow variables in match patterns
To restore an ability available in 3.x and reduce compatibility changes.
This commit is contained in:
parent
218bef90af
commit
c68b2358d5
8 changed files with 59 additions and 15 deletions
|
@ -1901,11 +1901,22 @@ void GDScriptAnalyzer::resolve_match_pattern(GDScriptParser::PatternNode *p_matc
|
|||
break;
|
||||
case GDScriptParser::PatternNode::PT_EXPRESSION:
|
||||
if (p_match_pattern->expression) {
|
||||
reduce_expression(p_match_pattern->expression);
|
||||
if (!p_match_pattern->expression->is_constant) {
|
||||
push_error(R"(Expression in match pattern must be a constant.)", p_match_pattern->expression);
|
||||
GDScriptParser::ExpressionNode *expr = p_match_pattern->expression;
|
||||
reduce_expression(expr);
|
||||
result = expr->get_datatype();
|
||||
if (!expr->is_constant) {
|
||||
while (expr && expr->type == GDScriptParser::Node::SUBSCRIPT) {
|
||||
GDScriptParser::SubscriptNode *sub = static_cast<GDScriptParser::SubscriptNode *>(expr);
|
||||
if (!sub->is_attribute) {
|
||||
expr = nullptr;
|
||||
} else {
|
||||
expr = sub->base;
|
||||
}
|
||||
}
|
||||
if (!expr || expr->type != GDScriptParser::Node::IDENTIFIER) {
|
||||
push_error(R"(Expression in match pattern must be a constant expression, an identifier, or an attribute access ("A.B").)", expr);
|
||||
}
|
||||
}
|
||||
result = p_match_pattern->expression->get_datatype();
|
||||
}
|
||||
break;
|
||||
case GDScriptParser::PatternNode::PT_BIND:
|
||||
|
|
|
@ -1904,7 +1904,6 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
|
|||
#ifdef DEBUG_ENABLED
|
||||
bool all_have_return = true;
|
||||
bool have_wildcard = false;
|
||||
bool have_wildcard_without_continue = false;
|
||||
#endif
|
||||
|
||||
while (!check(GDScriptTokenizer::Token::DEDENT) && !is_at_end()) {
|
||||
|
@ -1915,19 +1914,12 @@ GDScriptParser::MatchNode *GDScriptParser::parse_match() {
|
|||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (have_wildcard_without_continue && !branch->patterns.is_empty()) {
|
||||
if (have_wildcard && !branch->patterns.is_empty()) {
|
||||
push_warning(branch->patterns[0], GDScriptWarning::UNREACHABLE_PATTERN);
|
||||
}
|
||||
|
||||
if (branch->has_wildcard) {
|
||||
have_wildcard = true;
|
||||
if (!branch->block->has_continue) {
|
||||
have_wildcard_without_continue = true;
|
||||
}
|
||||
}
|
||||
if (!branch->block->has_return) {
|
||||
all_have_return = false;
|
||||
}
|
||||
have_wildcard = have_wildcard || branch->has_wildcard;
|
||||
all_have_return = all_have_return && branch->block->has_return;
|
||||
#endif
|
||||
match->branches.push_back(branch);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
func test():
|
||||
var dict = { a = 1 }
|
||||
match 2:
|
||||
dict["a"]:
|
||||
print("not allowed")
|
|
@ -0,0 +1,2 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
Expression in match pattern must be a constant expression, an identifier, or an attribute access ("A.B").
|
|
@ -0,0 +1,5 @@
|
|||
func test():
|
||||
var a = 1
|
||||
match 2:
|
||||
a + 2:
|
||||
print("not allowed")
|
|
@ -0,0 +1,2 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
Expression in match pattern must be a constant expression, an identifier, or an attribute access ("A.B").
|
|
@ -0,0 +1,22 @@
|
|||
func test():
|
||||
var a = 1
|
||||
match 1:
|
||||
a:
|
||||
print("reach 1")
|
||||
|
||||
var dict = { b = 2 }
|
||||
match 2:
|
||||
dict.b:
|
||||
print("reach 2")
|
||||
|
||||
var nested_dict = {
|
||||
sub = { c = 3 }
|
||||
}
|
||||
match 3:
|
||||
nested_dict.sub.c:
|
||||
print("reach 3")
|
||||
|
||||
var sub_pattern = { d = 4 }
|
||||
match [4]:
|
||||
[sub_pattern.d]:
|
||||
print("reach 4")
|
|
@ -0,0 +1,5 @@
|
|||
GDTEST_OK
|
||||
reach 1
|
||||
reach 2
|
||||
reach 3
|
||||
reach 4
|
Loading…
Reference in a new issue