Skip to content

Commit 86415f1

Browse files
committed
Merge pull request godotengine#99150 from dalexeev/gds-fix-callable-call-errror-text
GDScript: Fix `Callable` call error text
2 parents 18b849c + 2b30f23 commit 86415f1

File tree

7 files changed

+48
-15
lines changed

7 files changed

+48
-15
lines changed

core/variant/variant_callable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ uint32_t VariantCallable::hash() const {
4545
}
4646

4747
String VariantCallable::get_as_text() const {
48-
return vformat("%s::%s (Callable)", Variant::get_type_name(variant.get_type()), method);
48+
return vformat("%s::%s", Variant::get_type_name(variant.get_type()), method);
4949
}
5050

5151
CallableCustom::CompareEqualFunc VariantCallable::get_compare_equal_func() const {

modules/gdscript/gdscript_function.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ class GDScriptFunction {
551551
} profile;
552552
#endif
553553

554-
_FORCE_INLINE_ String _get_call_error(const String &p_where, const Variant **p_argptrs, const Variant &p_ret, const Callable::CallError &p_err) const;
554+
String _get_call_error(const String &p_where, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const;
555+
String _get_callable_call_error(const String &p_where, const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const;
555556
Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type);
556557

557558
public:

modules/gdscript/gdscript_utility_callable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ String GDScriptUtilityCallable::get_as_text() const {
5555
scope = "@GDScript";
5656
break;
5757
}
58-
return vformat("%s::%s (Callable)", scope, function_name);
58+
return vformat("%s::%s", scope, function_name);
5959
}
6060

6161
CallableCustom::CompareEqualFunc GDScriptUtilityCallable::get_compare_equal_func() const {

modules/gdscript/gdscript_vm.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ Variant GDScriptFunction::_get_default_variant_for_data_type(const GDScriptDataT
150150
return Variant();
151151
}
152152

153-
String GDScriptFunction::_get_call_error(const String &p_where, const Variant **p_argptrs, const Variant &p_ret, const Callable::CallError &p_err) const {
153+
String GDScriptFunction::_get_call_error(const String &p_where, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const {
154154
switch (p_err.error) {
155155
case Callable::CallError::CALL_OK:
156156
return String();
@@ -160,7 +160,8 @@ String GDScriptFunction::_get_call_error(const String &p_where, const Variant **
160160
}
161161
return "Invalid call. Nonexistent " + p_where + ".";
162162
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
163-
ERR_FAIL_COND_V_MSG(p_err.argument < 0 || p_argptrs[p_err.argument] == nullptr, "Bug: Invalid CallError argument index or null pointer.", "Bug: Invalid CallError argument index or null pointer.");
163+
ERR_FAIL_INDEX_V_MSG(p_err.argument, p_argcount, "Bug: Invalid call error argument index.", "Bug: Invalid call error argument index.");
164+
ERR_FAIL_NULL_V_MSG(p_argptrs[p_err.argument], "Bug: Argument is null pointer.", "Bug: Argument is null pointer.");
164165
// Handle the Object to Object case separately as we don't have further class details.
165166
#ifdef DEBUG_ENABLED
166167
if (p_err.expected == Variant::OBJECT && p_argptrs[p_err.argument]->get_type() == p_err.expected) {
@@ -185,6 +186,27 @@ String GDScriptFunction::_get_call_error(const String &p_where, const Variant **
185186
return "Bug: Invalid call error code " + itos(p_err.error) + ".";
186187
}
187188

189+
String GDScriptFunction::_get_callable_call_error(const String &p_where, const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const {
190+
Vector<Variant> binds;
191+
p_callable.get_bound_arguments_ref(binds);
192+
193+
int args_unbound = p_callable.get_unbound_arguments_count();
194+
195+
if (p_argcount - args_unbound < 0) {
196+
return "Callable unbinds " + itos(args_unbound) + " arguments, but called with " + itos(p_argcount);
197+
} else {
198+
Vector<const Variant *> argptrs;
199+
argptrs.resize(p_argcount - args_unbound + binds.size());
200+
for (int i = 0; i < p_argcount - args_unbound; i++) {
201+
argptrs.write[i] = p_argptrs[i];
202+
}
203+
for (int i = 0; i < binds.size(); i++) {
204+
argptrs.write[i + p_argcount - args_unbound] = &binds[i];
205+
}
206+
return _get_call_error(p_where, (const Variant **)argptrs.ptr(), argptrs.size(), p_ret, p_err);
207+
}
208+
}
209+
188210
void (*type_init_function_table[])(Variant *) = {
189211
nullptr, // NIL (shouldn't be called).
190212
&VariantInitializer<bool>::init, // BOOL.
@@ -1703,7 +1725,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
17031725

17041726
#ifdef DEBUG_ENABLED
17051727
if (err.error != Callable::CallError::CALL_OK) {
1706-
err_text = _get_call_error("'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs, *dst, err);
1728+
err_text = _get_call_error("'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs, argc, *dst, err);
17071729
OPCODE_BREAK;
17081730
}
17091731
#endif
@@ -1957,7 +1979,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
19571979
}
19581980
}
19591981
}
1960-
err_text = _get_call_error("function '" + methodstr + (is_callable ? "" : "' in base '" + basestr) + "'", (const Variant **)argptrs, temp_ret, err);
1982+
1983+
if (is_callable) {
1984+
err_text = _get_callable_call_error(vformat("function '%s'", methodstr), *base, (const Variant **)argptrs, argc, temp_ret, err);
1985+
} else {
1986+
err_text = _get_call_error(vformat("function '%s' in base '%s'", methodstr, basestr), (const Variant **)argptrs, argc, temp_ret, err);
1987+
}
19611988
OPCODE_BREAK;
19621989
}
19631990
#endif // DEBUG_ENABLED
@@ -2043,7 +2070,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
20432070
}
20442071
}
20452072
}
2046-
err_text = _get_call_error("function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs, temp_ret, err);
2073+
err_text = _get_call_error("function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs, argc, temp_ret, err);
20472074
OPCODE_BREAK;
20482075
}
20492076
#endif
@@ -2076,7 +2103,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
20762103

20772104
#ifdef DEBUG_ENABLED
20782105
if (err.error != Callable::CallError::CALL_OK) {
2079-
err_text = _get_call_error("static function '" + methodname->operator String() + "' in type '" + Variant::get_type_name(builtin_type) + "'", argptrs, *ret, err);
2106+
err_text = _get_call_error("static function '" + methodname->operator String() + "' in type '" + Variant::get_type_name(builtin_type) + "'", argptrs, argc, *ret, err);
20802107
OPCODE_BREAK;
20812108
}
20822109
#endif
@@ -2120,7 +2147,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
21202147
#endif
21212148

21222149
if (err.error != Callable::CallError::CALL_OK) {
2123-
err_text = _get_call_error("static function '" + method->get_name().operator String() + "' in type '" + method->get_instance_class().operator String() + "'", argptrs, *ret, err);
2150+
err_text = _get_call_error("static function '" + method->get_name().operator String() + "' in type '" + method->get_instance_class().operator String() + "'", argptrs, argc, *ret, err);
21242151
OPCODE_BREAK;
21252152
}
21262153

@@ -2351,7 +2378,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
23512378
// Call provided error string.
23522379
err_text = vformat(R"*(Error calling utility function "%s()": %s)*", methodstr, *dst);
23532380
} else {
2354-
err_text = _get_call_error(vformat(R"*(utility function "%s()")*", methodstr), (const Variant **)argptrs, *dst, err);
2381+
err_text = _get_call_error(vformat(R"*(utility function "%s()")*", methodstr), (const Variant **)argptrs, argc, *dst, err);
23552382
}
23562383
OPCODE_BREAK;
23572384
}
@@ -2408,7 +2435,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
24082435
// Call provided error string.
24092436
err_text = vformat(R"*(Error calling GDScript utility function "%s()": %s)*", methodstr, *dst);
24102437
} else {
2411-
err_text = _get_call_error(vformat(R"*(GDScript utility function "%s()")*", methodstr), (const Variant **)argptrs, *dst, err);
2438+
err_text = _get_call_error(vformat(R"*(GDScript utility function "%s()")*", methodstr), (const Variant **)argptrs, argc, *dst, err);
24122439
}
24132440
OPCODE_BREAK;
24142441
}
@@ -2475,7 +2502,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
24752502

24762503
if (err.error != Callable::CallError::CALL_OK) {
24772504
String methodstr = *methodname;
2478-
err_text = _get_call_error("function '" + methodstr + "'", (const Variant **)argptrs, *dst, err);
2505+
err_text = _get_call_error("function '" + methodstr + "'", (const Variant **)argptrs, argc, *dst, err);
24792506

24802507
OPCODE_BREAK;
24812508
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#debug-only
2+
func test():
3+
print(load.bind([]).call())
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
GDTEST_RUNTIME_ERROR
2+
>> SCRIPT ERROR at runtime/errors/callable_call_invalid_arg_type.gd:3 on test(): Invalid type in function '@GDScript::load (Callable)'. Cannot convert argument 1 from Array to String.

modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
GDTEST_OK
2-
@GlobalScope::print (Callable)
3-
@GDScript::len (Callable)
2+
@GlobalScope::print
3+
@GDScript::len
44
1 2 3
55
1
66
3

0 commit comments

Comments
 (0)