mirror of
https://github.com/godotengine/godot
synced 2024-09-05 15:29:50 +00:00
GDScript: add an optional message parameter to assert()
Before this patch, assert() only took the condition to assert on: assert(item_data) Now, it can optionally take a string that will be printed upon failure: assert(item_data, item_name + " has no item data in ItemDatabase") This makes it easier to immediately see what the issue is by being able to write informative failure messages. Thanks to @wiped1 for sharing their patch, upon which this is based. Closes #17082
This commit is contained in:
parent
750f8d4926
commit
aa8e3e7b0f
|
@ -1520,8 +1520,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
|
||||||
if (ret2 < 0)
|
if (ret2 < 0)
|
||||||
return ERR_PARSE_ERROR;
|
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(GDScriptFunction::OPCODE_ASSERT);
|
||||||
codegen.opcodes.push_back(ret2);
|
codegen.opcodes.push_back(ret2);
|
||||||
|
codegen.opcodes.push_back(message_ret);
|
||||||
#endif
|
#endif
|
||||||
} break;
|
} break;
|
||||||
case GDScriptParser::Node::TYPE_BREAKPOINT: {
|
case GDScriptParser::Node::TYPE_BREAKPOINT: {
|
||||||
|
|
|
@ -1475,20 +1475,25 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
||||||
DISPATCH_OPCODE;
|
DISPATCH_OPCODE;
|
||||||
|
|
||||||
OPCODE(OPCODE_ASSERT) {
|
OPCODE(OPCODE_ASSERT) {
|
||||||
CHECK_SPACE(2);
|
CHECK_SPACE(3);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
GET_VARIANT_PTR(test, 1);
|
GET_VARIANT_PTR(test, 1);
|
||||||
|
GET_VARIANT_PTR(message, 2);
|
||||||
bool result = test->booleanize();
|
bool result = test->booleanize();
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
const String &message_str = *message;
|
||||||
|
if (message_str.empty()) {
|
||||||
err_text = "Assertion failed.";
|
err_text = "Assertion failed.";
|
||||||
|
} else {
|
||||||
|
err_text = "Assertion failed: " + message_str;
|
||||||
|
}
|
||||||
OPCODE_BREAK;
|
OPCODE_BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
ip += 2;
|
ip += 3;
|
||||||
}
|
}
|
||||||
DISPATCH_OPCODE;
|
DISPATCH_OPCODE;
|
||||||
|
|
||||||
|
|
|
@ -3280,15 +3280,36 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
|
||||||
case GDScriptTokenizer::TK_PR_ASSERT: {
|
case GDScriptTokenizer::TK_PR_ASSERT: {
|
||||||
|
|
||||||
tokenizer->advance();
|
tokenizer->advance();
|
||||||
Node *condition = _parse_and_reduce_expression(p_block, p_static);
|
|
||||||
if (!condition) {
|
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
|
||||||
if (_recover_from_completion()) {
|
_set_error("Expected '(' after assert");
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
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>();
|
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);
|
p_block->statements.push_back(an);
|
||||||
|
|
||||||
if (!_end_statement()) {
|
if (!_end_statement()) {
|
||||||
|
|
|
@ -481,7 +481,12 @@ public:
|
||||||
|
|
||||||
struct AssertNode : public Node {
|
struct AssertNode : public Node {
|
||||||
Node *condition;
|
Node *condition;
|
||||||
AssertNode() { type = TYPE_ASSERT; }
|
Node *message;
|
||||||
|
AssertNode() :
|
||||||
|
condition(0),
|
||||||
|
message(0) {
|
||||||
|
type = TYPE_ASSERT;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BreakpointNode : public Node {
|
struct BreakpointNode : public Node {
|
||||||
|
|
Loading…
Reference in a new issue