From b4e08eb752cca0135208ed0729479e1d9c87773d Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 17 Jan 2024 11:27:40 -0300 Subject: [PATCH] Allow `free()` to be used as Callable This method is registered in a special way so ClassDB doesn't naturally know about its existence. Here it is hardcoded if any other option fail to check if it is about the `free()` method and, if so, say it exists and return a Callable. --- core/object/class_db.cpp | 7 +++++++ modules/gdscript/gdscript_compiler.cpp | 3 ++- .../tests/scripts/runtime/features/free_is_callable.gd | 10 ++++++++++ .../scripts/runtime/features/free_is_callable.out | 3 +++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd create mode 100644 modules/gdscript/tests/scripts/runtime/features/free_is_callable.out diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index bf1bd0de93a..45fbb19f88b 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -31,6 +31,7 @@ #include "class_db.h" #include "core/config/engine.h" +#include "core/core_string_names.h" #include "core/io/resource_loader.h" #include "core/object/script_language.h" #include "core/os/mutex.h" @@ -1299,6 +1300,12 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia check = check->inherits_ptr; } + // The "free()" method is special, so we assume it exists and return a Callable. + if (p_property == CoreStringNames::get_singleton()->_free) { + r_value = Callable(p_object, p_property); + return true; + } + return false; } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index f6633f8bf68..edba6340b95 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -37,6 +37,7 @@ #include "core/config/engine.h" #include "core/config/project_settings.h" +#include "core/core_string_names.h" bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) { if (codegen.function_node && codegen.function_node->is_static) { @@ -345,7 +346,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code scr = scr->_base; } - if (nc && (ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { + if (nc && (identifier == CoreStringNames::get_singleton()->_free || ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { // Get like it was a property. GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); diff --git a/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd new file mode 100644 index 00000000000..b9746a8207b --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd @@ -0,0 +1,10 @@ +func test(): + var node := Node.new() + var callable: Callable = node.free + callable.call() + print(node) + + node = Node.new() + callable = node["free"] + callable.call() + print(node) diff --git a/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out new file mode 100644 index 00000000000..97bfc46d968 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out @@ -0,0 +1,3 @@ +GDTEST_OK + +