Browse Source

Merge pull request #61345 from vnen/gdscript-lambda-issues

GDScript: A few fixes for lambda issues
Rémi Verschelde 3 years ago
parent
commit
db5a86339b

+ 8 - 1
modules/gdscript/gdscript_parser.cpp

@@ -1624,6 +1624,10 @@ GDScriptParser::Node *GDScriptParser::parse_statement() {
 					case Node::AWAIT:
 					case Node::AWAIT:
 						// Fine.
 						// Fine.
 						break;
 						break;
+					case Node::LAMBDA:
+						// Standalone lambdas can't be used, so make this an error.
+						push_error("Standalone lambdas cannot be accessed. Consider assigning it to a variable.", expression);
+						break;
 					default:
 					default:
 						push_warning(expression, GDScriptWarning::STANDALONE_EXPRESSION);
 						push_warning(expression, GDScriptWarning::STANDALONE_EXPRESSION);
 				}
 				}
@@ -2099,7 +2103,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_precedence(Precedence p_pr
 	ExpressionNode *previous_operand = (this->*prefix_rule)(nullptr, p_can_assign);
 	ExpressionNode *previous_operand = (this->*prefix_rule)(nullptr, p_can_assign);
 
 
 	while (p_precedence <= get_rule(current.type)->precedence) {
 	while (p_precedence <= get_rule(current.type)->precedence) {
-		if (previous_operand == nullptr || (p_stop_on_assign && current.type == GDScriptTokenizer::Token::EQUAL)) {
+		if (previous_operand == nullptr || (p_stop_on_assign && current.type == GDScriptTokenizer::Token::EQUAL) || (previous_operand->type == Node::LAMBDA && lambda_ended)) {
 			return previous_operand;
 			return previous_operand;
 		}
 		}
 		// Also switch multiline mode on here for infix operators.
 		// Also switch multiline mode on here for infix operators.
@@ -2922,6 +2926,9 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p
 	current_function = function;
 	current_function = function;
 
 
 	SuiteNode *body = alloc_node<SuiteNode>();
 	SuiteNode *body = alloc_node<SuiteNode>();
+	body->parent_function = current_function;
+	body->parent_block = current_suite;
+
 	SuiteNode *previous_suite = current_suite;
 	SuiteNode *previous_suite = current_suite;
 	current_suite = body;
 	current_suite = body;
 
 

+ 3 - 0
modules/gdscript/tests/scripts/parser/errors/lambda_standalone.gd

@@ -0,0 +1,3 @@
+func test():
+	func standalone():
+		print("can't be accessed")

+ 2 - 0
modules/gdscript/tests/scripts/parser/errors/lambda_standalone.out

@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Standalone lambdas cannot be accessed. Consider assigning it to a variable.

+ 7 - 0
modules/gdscript/tests/scripts/parser/features/if_after_lambda.gd

@@ -0,0 +1,7 @@
+# https://github.com/godotengine/godot/issues/61231
+
+func test():
+	var my_lambda = func():
+		print("hello")
+	if 0 == 0:
+		my_lambda.call()

+ 2 - 0
modules/gdscript/tests/scripts/parser/features/if_after_lambda.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+hello

+ 7 - 0
modules/gdscript/tests/scripts/parser/features/lambda_default_parameter_capture.gd

@@ -0,0 +1,7 @@
+# https://github.com/godotengine/godot/issues/56751
+
+func test():
+	var x = "local"
+	var lambda = func(param = x):
+		print(param)
+	lambda.call()

+ 2 - 0
modules/gdscript/tests/scripts/parser/features/lambda_default_parameter_capture.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+local