Browse Source

Merge pull request #31142 from mitchcurtis/assert-message

GDScript: add an optional message parameter to assert()
Rémi Verschelde 6 năm trước cách đây
mục cha
commit
318ac6ee13

+ 8 - 0
modules/gdscript/gdscript_compiler.cpp

@@ -1520,8 +1520,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
 				if (ret2 < 0)
 					return ERR_PARSE_ERROR;
 
+				int message_ret = 0;
+				if (as->message) {
+					message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
+					if (message_ret < 0)
+						return ERR_PARSE_ERROR;
+				}
+
 				codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
 				codegen.opcodes.push_back(ret2);
+				codegen.opcodes.push_back(message_ret);
 #endif
 			} break;
 			case GDScriptParser::Node::TYPE_BREAKPOINT: {

+ 9 - 4
modules/gdscript/gdscript_function.cpp

@@ -1475,20 +1475,25 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 			DISPATCH_OPCODE;
 
 			OPCODE(OPCODE_ASSERT) {
-				CHECK_SPACE(2);
+				CHECK_SPACE(3);
 
 #ifdef DEBUG_ENABLED
 				GET_VARIANT_PTR(test, 1);
+				GET_VARIANT_PTR(message, 2);
 				bool result = test->booleanize();
 
 				if (!result) {
-
-					err_text = "Assertion failed.";
+					const String &message_str = *message;
+					if (message_str.empty()) {
+						err_text = "Assertion failed.";
+					} else {
+						err_text = "Assertion failed: " + message_str;
+					}
 					OPCODE_BREAK;
 				}
 
 #endif
-				ip += 2;
+				ip += 3;
 			}
 			DISPATCH_OPCODE;
 

+ 27 - 6
modules/gdscript/gdscript_parser.cpp

@@ -3280,15 +3280,36 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
 			case GDScriptTokenizer::TK_PR_ASSERT: {
 
 				tokenizer->advance();
-				Node *condition = _parse_and_reduce_expression(p_block, p_static);
-				if (!condition) {
-					if (_recover_from_completion()) {
-						break;
-					}
+
+				if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
+					_set_error("Expected '(' after assert");
+					return;
+				}
+
+				tokenizer->advance();
+
+				Vector<Node *> args;
+				const bool result = _parse_arguments(p_block, args, p_static);
+				if (!result) {
+					return;
+				}
+
+				if (args.empty() || args.size() > 2) {
+					_set_error("Wrong number of arguments, expected 1 or 2");
 					return;
 				}
+
 				AssertNode *an = alloc_node<AssertNode>();
-				an->condition = condition;
+				an->condition = _reduce_expression(args[0], p_static);
+
+				if (args.size() == 2) {
+					an->message = _reduce_expression(args[1], p_static);
+				} else {
+					ConstantNode *message_node = alloc_node<ConstantNode>();
+					message_node->value = String();
+					an->message = message_node;
+				}
+
 				p_block->statements.push_back(an);
 
 				if (!_end_statement()) {

+ 6 - 1
modules/gdscript/gdscript_parser.h

@@ -481,7 +481,12 @@ public:
 
 	struct AssertNode : public Node {
 		Node *condition;
-		AssertNode() { type = TYPE_ASSERT; }
+		Node *message;
+		AssertNode() :
+				condition(0),
+				message(0) {
+			type = TYPE_ASSERT;
+		}
 	};
 
 	struct BreakpointNode : public Node {