summaryrefslogtreecommitdiffstats
path: root/modules/gdscript
diff options
context:
space:
mode:
authorDanil Alexeev <danil@alexeev.xyz>2023-06-30 20:40:02 +0300
committerDanil Alexeev <danil@alexeev.xyz>2023-10-16 14:09:57 +0300
commit0c2202c56e4c87c53dde17b35c8677974985ae81 (patch)
treefe7f07a9f165790d48493cbc5d922051c49c50c3 /modules/gdscript
parenta574c0296b38d5f786f249b12e6251e562c528cc (diff)
downloadredot-engine-0c2202c56e4c87c53dde17b35c8677974985ae81.tar.gz
GDScript: Fix incorrect error message for utility functions
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp34
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp11
-rw-r--r--modules/gdscript/gdscript_vm.cpp15
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.gd3
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.gd3
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.out6
11 files changed, 58 insertions, 28 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 831971c3f3..0a2dc0f87a 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -3134,12 +3134,16 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
GDScriptUtilityFunctions::get_function(function_name)(&value, (const Variant **)args.ptr(), args.size(), err);
switch (err.error) {
- case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- PropertyInfo wrong_arg = function_info.arguments[err.argument];
- push_error(vformat(R"*(Invalid argument for "%s()" function: argument %d should be "%s" but is "%s".)*", function_name, err.argument + 1,
- type_from_property(wrong_arg, true).to_string(), p_call->arguments[err.argument]->get_datatype().to_string()),
- p_call->arguments[err.argument]);
- } break;
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
+ if (value.get_type() == Variant::STRING && !value.operator String().is_empty()) {
+ push_error(vformat(R"*(Invalid argument for "%s()" function: %s)*", function_name, value), p_call->arguments[err.argument]);
+ } else {
+ // Do not use `type_from_property()` for expected type, since utility functions use their own checks.
+ push_error(vformat(R"*(Invalid argument for "%s()" function: argument %d should be "%s" but is "%s".)*", function_name, err.argument + 1,
+ Variant::get_type_name((Variant::Type)err.expected), p_call->arguments[err.argument]->get_datatype().to_string()),
+ p_call->arguments[err.argument]);
+ }
+ break;
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
push_error(vformat(R"(Invalid call for function "%s".)", function_name), p_call);
break;
@@ -3181,18 +3185,16 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
Variant::call_utility_function(function_name, &value, (const Variant **)args.ptr(), args.size(), err);
switch (err.error) {
- case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- String expected_type_name;
- if (err.argument < function_info.arguments.size()) {
- expected_type_name = type_from_property(function_info.arguments[err.argument], true).to_string();
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
+ if (value.get_type() == Variant::STRING && !value.operator String().is_empty()) {
+ push_error(vformat(R"*(Invalid argument for "%s()" function: %s)*", function_name, value), p_call->arguments[err.argument]);
} else {
- expected_type_name = Variant::get_type_name((Variant::Type)err.expected);
+ // Do not use `type_from_property()` for expected type, since utility functions use their own checks.
+ push_error(vformat(R"*(Invalid argument for "%s()" function: argument %d should be "%s" but is "%s".)*", function_name, err.argument + 1,
+ Variant::get_type_name((Variant::Type)err.expected), p_call->arguments[err.argument]->get_datatype().to_string()),
+ p_call->arguments[err.argument]);
}
-
- push_error(vformat(R"*(Invalid argument for "%s()" function: argument %d should be "%s" but is "%s".)*", function_name, err.argument + 1,
- expected_type_name, p_call->arguments[err.argument]->get_datatype().to_string()),
- p_call->arguments[err.argument]);
- } break;
+ break;
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
push_error(vformat(R"(Invalid call for function "%s".)", function_name), p_call);
break;
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index 69a0b42d89..40c564c36b 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -97,6 +97,9 @@ struct GDScriptUtilityFunctionsDefinitions {
} else {
Variant::construct(Variant::Type(type), *r_ret, p_args, 1, r_error);
+ if (r_error.error != Callable::CallError::CALL_OK) {
+ *r_ret = vformat(RTR(R"(Cannot convert "%s" to "%s".)"), Variant::get_type_name(p_args[0]->get_type()), Variant::get_type_name(Variant::Type(type)));
+ }
}
}
#endif // DISABLE_DEPRECATED
@@ -130,8 +133,8 @@ struct GDScriptUtilityFunctionsDefinitions {
}
Error err = arr.resize(count);
if (err != OK) {
+ *r_ret = RTR("Cannot resize array.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
- *r_ret = Variant();
return;
}
@@ -155,8 +158,8 @@ struct GDScriptUtilityFunctionsDefinitions {
}
Error err = arr.resize(to - from);
if (err != OK) {
+ *r_ret = RTR("Cannot resize array.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
- *r_ret = Variant();
return;
}
for (int i = from; i < to; i++) {
@@ -199,8 +202,8 @@ struct GDScriptUtilityFunctionsDefinitions {
Error err = arr.resize(count);
if (err != OK) {
+ *r_ret = RTR("Cannot resize array.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
- *r_ret = Variant();
return;
}
@@ -370,7 +373,7 @@ struct GDScriptUtilityFunctionsDefinitions {
*r_ret = gdscr->_new(nullptr, -1 /*skip initializer*/, r_error);
if (r_error.error != Callable::CallError::CALL_OK) {
- *r_ret = Variant();
+ *r_ret = RTR("Cannot instantiate GDScript class.");
return;
}
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 75dc2e4f8b..b723ecc185 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -2067,11 +2067,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (err.error != Callable::CallError::CALL_OK) {
String methodstr = function;
- if (dst->get_type() == Variant::STRING) {
+ if (dst->get_type() == Variant::STRING && !dst->operator String().is_empty()) {
// Call provided error string.
- err_text = "Error calling utility function '" + methodstr + "': " + String(*dst);
+ err_text = vformat(R"*(Error calling utility function "%s()": %s)*", methodstr, *dst);
} else {
- err_text = _get_call_error(err, "utility function '" + methodstr + "'", (const Variant **)argptrs);
+ err_text = _get_call_error(err, vformat(R"*(utility function "%s()")*", methodstr), (const Variant **)argptrs);
}
OPCODE_BREAK;
}
@@ -2123,13 +2123,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (err.error != Callable::CallError::CALL_OK) {
- // TODO: Add this information in debug.
- String methodstr = "<unknown function>";
- if (dst->get_type() == Variant::STRING) {
+ String methodstr = gds_utilities_names[_code_ptr[ip + 2]];
+ if (dst->get_type() == Variant::STRING && !dst->operator String().is_empty()) {
// Call provided error string.
- err_text = "Error calling GDScript utility function '" + methodstr + "': " + String(*dst);
+ err_text = vformat(R"*(Error calling GDScript utility function "%s()": %s)*", methodstr, *dst);
} else {
- err_text = _get_call_error(err, "GDScript utility function '" + methodstr + "'", (const Variant **)argptrs);
+ err_text = _get_call_error(err, vformat(R"*(GDScript utility function "%s()")*", methodstr), (const Variant **)argptrs);
}
OPCODE_BREAK;
}
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.gd b/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.gd
new file mode 100644
index 0000000000..c06fbd89ff
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.gd
@@ -0,0 +1,2 @@
+func test():
+ print(len(Color())) # GDScript utility function.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.out b/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.out
new file mode 100644
index 0000000000..9cb04f6240
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/gd_utility_function_wrong_arg.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Invalid argument for "len()" function: Value of type 'Color' can't provide a length.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.gd b/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.gd
new file mode 100644
index 0000000000..dc6e26e682
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.gd
@@ -0,0 +1,2 @@
+func test():
+ print(floor(Color())) # Built-in utility function.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.out b/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.out
new file mode 100644
index 0000000000..27d2504dd0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/utility_function_wrong_arg.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Invalid argument for "floor()" function: Argument "x" must be "int", "float", "Vector2", "Vector2i", "Vector3", "Vector3i", "Vector4", or "Vector4i".
diff --git a/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.gd b/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.gd
new file mode 100644
index 0000000000..340fc8c150
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.gd
@@ -0,0 +1,3 @@
+func test():
+ var x = Color()
+ print(len(x)) # GDScript utility function.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.out b/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.out
new file mode 100644
index 0000000000..6d2938dcf3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/gd_utility_function_wrong_arg.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/gd_utility_function_wrong_arg.gd
+>> 3
+>> Error calling GDScript utility function "len()": Value of type 'Color' can't provide a length.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.gd b/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.gd
new file mode 100644
index 0000000000..6568155bae
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.gd
@@ -0,0 +1,3 @@
+func test():
+ var x = Color()
+ print(floor(x)) # Built-in utility function.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.out b/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.out
new file mode 100644
index 0000000000..b311bfa38a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/utility_function_wrong_arg.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/utility_function_wrong_arg.gd
+>> 3
+>> Error calling utility function "floor()": Argument "x" must be "int", "float", "Vector2", "Vector2i", "Vector3", "Vector3i", "Vector4", or "Vector4i".