@@ -1076,7 +1076,7 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static) {
10761076 return parse_variable (p_is_static, true );
10771077}
10781078
1079- GDScriptParser::VariableNode *GDScriptParser::parse_variable (bool p_is_static, bool p_allow_property) {
1079+ GDScriptParser::VariableNode *GDScriptParser::parse_variable (bool p_is_static, bool p_allow_property, bool p_is_if_condition ) {
10801080 VariableNode *variable = alloc_node<VariableNode>();
10811081
10821082 if (!consume (GDScriptTokenizer::Token::IDENTIFIER, R"( Expected variable name after "var".)" )) {
@@ -1135,7 +1135,10 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_is_static, b
11351135 }
11361136
11371137 complete_extents (variable);
1138- end_statement (" variable declaration" );
1138+
1139+ if (p_is_if_condition == false ) {
1140+ end_statement (" variable declaration" );
1141+ }
11391142
11401143 return variable;
11411144}
@@ -2087,21 +2090,68 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
20872090}
20882091
20892092GDScriptParser::IfNode *GDScriptParser::parse_if (const String &p_token) {
2090- IfNode *n_if = alloc_node<IfNode>();
2093+ SuiteNode *condition_block = alloc_node<SuiteNode>();
2094+ condition_block->parent_block = current_suite;
2095+ condition_block->parent_function = current_function;
2096+ SuiteNode *saved_suite = current_suite;
2097+ current_suite = condition_block;
2098+
2099+ VariableNode *variable = nullptr ;
2100+ ExpressionNode *condition = nullptr ;
2101+ if (match (GDScriptTokenizer::Token::VAR)) {
2102+ // Variable declaration
2103+ variable = parse_variable (false , false , true );
2104+ if (variable == nullptr ) {
2105+ push_error (vformat (R"( Expected variable definition after "%s".)" , p_token));
2106+ } else if (variable->initializer == nullptr ) {
2107+ push_error (R"( Expected expression for variable initial value.)" );
2108+ } else {
2109+ const SuiteNode::Local &local = current_suite->get_local (variable->identifier ->name );
2110+ if (local.type != SuiteNode::Local::UNDEFINED) {
2111+ push_error (vformat (R"( There is already a %s named "%s" declared in this scope.)" , local.get_name (), variable->identifier ->name ), variable->identifier );
2112+ }
2113+ condition_block->add_local (variable, current_function);
2114+
2115+ IdentifierNode *identifier = alloc_node<IdentifierNode>();
2116+ identifier->name = variable->identifier ->name ;
2117+ identifier->suite = condition_block;
2118+ identifier->source = IdentifierNode::Source::LOCAL_VARIABLE;
2119+ const SuiteNode::Local &declaration = condition_block->get_local (identifier->name );
2120+ identifier->variable_source = declaration.variable ;
2121+ declaration.variable ->usages ++;
2122+ complete_extents (identifier);
2123+
2124+ condition_block->statements .push_back (variable);
20912125
2092- n_if->condition = parse_expression (false );
2093- if (n_if->condition == nullptr ) {
2094- push_error (vformat (R"( Expected conditional expression after "%s".)" , p_token));
2126+ condition = identifier;
2127+ }
2128+ } else {
2129+ // Expression
2130+ ExpressionNode *expression = parse_expression (false );
2131+ if (expression == nullptr ) {
2132+ push_error (vformat (R"( Expected conditional expression after "%s".)" , p_token));
2133+ } else {
2134+ condition = expression;
2135+ }
20952136 }
20962137
20972138 consume (GDScriptTokenizer::Token::COLON, vformat (R"( Expected ":" after "%s" condition.)" , p_token));
20982139
2099- n_if->true_block = parse_suite (vformat (R"( "%s" block)" , p_token));
2100- n_if->true_block ->parent_if = n_if;
2140+ SuiteNode *true_block = parse_suite (vformat (R"( "%s" block)" , p_token));
21012141
2102- if (n_if->true_block ->has_continue ) {
2103- current_suite->has_continue = true ;
2104- }
2142+ complete_extents (condition_block);
2143+ current_suite = saved_suite;
2144+
2145+ IfNode *n_if = alloc_node<IfNode>();
2146+
2147+ true_block->parent_function = current_function;
2148+ true_block->parent_block = condition_block;
2149+ true_block->parent_if = n_if;
2150+
2151+ n_if->variable = variable;
2152+ n_if->condition = condition;
2153+ n_if->condition_block = condition_block;
2154+ n_if->true_block = true_block;
21052155
21062156 if (match (GDScriptTokenizer::Token::ELIF)) {
21072157 SuiteNode *else_block = alloc_node<SuiteNode>();
@@ -2123,10 +2173,10 @@ GDScriptParser::IfNode *GDScriptParser::parse_if(const String &p_token) {
21232173 }
21242174 complete_extents (n_if);
21252175
2126- if (n_if->false_block != nullptr && n_if->false_block ->has_return && n_if->true_block ->has_return ) {
2176+ if (( n_if->false_block != nullptr && n_if->false_block ->has_return ) && n_if->true_block ->has_return ) {
21272177 current_suite->has_return = true ;
21282178 }
2129- if (n_if->false_block != nullptr && n_if->false_block ->has_continue ) {
2179+ if (( n_if->false_block != nullptr && n_if->false_block -> has_continue ) || n_if-> true_block ->has_continue ) {
21302180 current_suite->has_continue = true ;
21312181 }
21322182
@@ -4787,11 +4837,25 @@ bool GDScriptParser::warning_annotations(AnnotationNode *p_annotation, Node *p_t
47874837
47884838 // Contain bodies.
47894839 SIMPLE_CASE (Node::FOR, ForNode, list)
4790- SIMPLE_CASE (Node::IF, IfNode, condition)
47914840 SIMPLE_CASE (Node::MATCH, MatchNode, test)
47924841 SIMPLE_CASE (Node::WHILE, WhileNode, condition)
47934842#undef SIMPLE_CASE
47944843
4844+ case Node::IF: {
4845+ IfNode *if_n = static_cast <IfNode *>(p_target);
4846+ if (if_n->variable ) {
4847+ if (if_n->variable ->initializer ) {
4848+ end_line = if_n->variable ->initializer ->end_line ;
4849+ } else {
4850+ end_line = if_n->start_line ;
4851+ }
4852+ } else if (if_n->condition ) {
4853+ end_line = if_n->condition ->end_line ;
4854+ } else {
4855+ end_line = if_n->start_line ;
4856+ }
4857+ } break ;
4858+
47954859 case Node::CLASS: {
47964860 end_line = p_target->start_line ;
47974861 for (const AnnotationNode *annotation : p_target->annotations ) {
@@ -5744,7 +5808,11 @@ void GDScriptParser::TreePrinter::print_if(IfNode *p_if, bool p_is_elif) {
57445808 } else {
57455809 push_text (" If " );
57465810 }
5747- print_expression (p_if->condition );
5811+ if (p_if->variable ) {
5812+ print_variable (p_if->variable );
5813+ } else {
5814+ print_expression (p_if->condition );
5815+ }
57485816 push_line (" :" );
57495817
57505818 increase_indent ();
0 commit comments