diff options
author | George Marques <george@gmarqu.es> | 2023-01-30 14:50:08 -0300 |
---|---|---|
committer | George Marques <george@gmarqu.es> | 2023-02-02 10:20:35 -0300 |
commit | 5fc79185943e0d3eeb5645ca6d44457170abe809 (patch) | |
tree | 192d3d0eb8d3be1338f56aa532b065f85bd20b9e /modules/gdscript/gdscript_vm.cpp | |
parent | 315d3c4d21e4ee7df1e45593205e35d7a034aa6d (diff) | |
download | redot-engine-5fc79185943e0d3eeb5645ca6d44457170abe809.tar.gz |
GDScript: Improve usability of setter chains
- Consider PackedArrays non-shared since they are copied on C++/script
boundaries.
- Add error messages in the analyzer when assigning to read-only
properties.
- Add specific error message at runtime when assignment fails because
the property is read-only.
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index e18a4a6190..b99f5d2685 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -811,13 +811,22 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { + Object *obj = dst->get_validated_object(); String v = index->operator String(); - if (!v.is_empty()) { - v = "'" + v + "'"; + bool read_only_property = false; + if (obj) { + read_only_property = ClassDB::has_property(obj->get_class_name(), v) && (ClassDB::get_property_setter(obj->get_class_name(), v) == StringName()); + } + if (read_only_property) { + err_text = vformat(R"(Cannot set value into property "%s" (on base "%s") because it is read-only.)", v, _get_var_type(dst)); } else { - v = "of type '" + _get_var_type(index) + "'"; + if (!v.is_empty()) { + v = "'" + v + "'"; + } else { + v = "of type '" + _get_var_type(index) + "'"; + } + err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'"; } - err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'"; OPCODE_BREAK; } #endif @@ -1003,8 +1012,16 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (!valid) { - String err_type; - err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'."; + Object *obj = dst->get_validated_object(); + bool read_only_property = false; + if (obj) { + read_only_property = ClassDB::has_property(obj->get_class_name(), *index) && (ClassDB::get_property_setter(obj->get_class_name(), *index) == StringName()); + } + if (read_only_property) { + err_text = vformat(R"(Cannot set value into property "%s" (on base "%s") because it is read-only.)", String(*index), _get_var_type(dst)); + } else { + err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'."; + } OPCODE_BREAK; } #endif |