Prechádzať zdrojové kódy

Core: Fix `Object::has_method()` for script static methods

Danil Alexeev 1 rok pred
rodič
commit
ed0b3c08e1

+ 9 - 1
core/object/object.cpp

@@ -666,8 +666,16 @@ bool Object::has_method(const StringName &p_method) const {
 	}
 
 	MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
+	if (method != nullptr) {
+		return true;
+	}
 
-	return method != nullptr;
+	const Script *scr = Object::cast_to<Script>(this);
+	if (scr != nullptr) {
+		return scr->has_static_method(p_method);
+	}
+
+	return false;
 }
 
 Variant Object::getvar(const Variant &p_key, bool *r_valid) const {

+ 3 - 0
core/object/script_language.h

@@ -145,7 +145,10 @@ public:
 	virtual PropertyInfo get_class_category() const;
 #endif // TOOLS_ENABLED
 
+	// TODO: In the next compat breakage rename to `*_script_*` to disambiguate from `Object::has_method()`.
 	virtual bool has_method(const StringName &p_method) const = 0;
+	virtual bool has_static_method(const StringName &p_method) const { return false; }
+
 	virtual MethodInfo get_method_info(const StringName &p_method) const = 0;
 
 	virtual bool is_tool() const = 0;

+ 1 - 0
core/object/script_language_extension.cpp

@@ -55,6 +55,7 @@ void ScriptExtension::_bind_methods() {
 	GDVIRTUAL_BIND(_get_class_icon_path);
 
 	GDVIRTUAL_BIND(_has_method, "method");
+	GDVIRTUAL_BIND(_has_static_method, "method");
 	GDVIRTUAL_BIND(_get_method_info, "method");
 
 	GDVIRTUAL_BIND(_is_tool);

+ 1 - 0
core/object/script_language_extension.h

@@ -99,6 +99,7 @@ public:
 #endif // TOOLS_ENABLED
 
 	EXBIND1RC(bool, has_method, const StringName &)
+	EXBIND1RC(bool, has_static_method, const StringName &)
 
 	GDVIRTUAL1RC(Dictionary, _get_method_info, const StringName &)
 	virtual MethodInfo get_method_info(const StringName &p_method) const override {

+ 6 - 0
doc/classes/ScriptExtension.xml

@@ -123,6 +123,12 @@
 			<description>
 			</description>
 		</method>
+		<method name="_has_static_method" qualifiers="virtual const">
+			<return type="bool" />
+			<param index="0" name="method" type="StringName" />
+			<description>
+			</description>
+		</method>
 		<method name="_inherits_script" qualifiers="virtual const">
 			<return type="bool" />
 			<param index="0" name="script" type="Script" />

+ 4 - 0
modules/gdscript/gdscript.cpp

@@ -346,6 +346,10 @@ bool GDScript::has_method(const StringName &p_method) const {
 	return member_functions.has(p_method);
 }
 
+bool GDScript::has_static_method(const StringName &p_method) const {
+	return member_functions.has(p_method) && member_functions[p_method]->is_static();
+}
+
 MethodInfo GDScript::get_method_info(const StringName &p_method) const {
 	HashMap<StringName, GDScriptFunction *>::ConstIterator E = member_functions.find(p_method);
 	if (!E) {

+ 1 - 0
modules/gdscript/gdscript.h

@@ -266,6 +266,7 @@ public:
 
 	virtual void get_script_method_list(List<MethodInfo> *p_list) const override;
 	virtual bool has_method(const StringName &p_method) const override;
+	virtual bool has_static_method(const StringName &p_method) const override;
 	virtual MethodInfo get_method_info(const StringName &p_method) const override;
 
 	virtual void get_script_property_list(List<PropertyInfo> *p_list) const override;

+ 12 - 0
modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.gd

@@ -0,0 +1,12 @@
+# GH-79521
+
+class_name TestStaticMethodAsCallable
+
+static func static_func() -> String:
+	return "Test"
+
+func test():
+	var a: Callable = TestStaticMethodAsCallable.static_func
+	var b: Callable = static_func
+	prints(a.call(), a.is_valid())
+	prints(b.call(), b.is_valid())

+ 3 - 0
modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.out

@@ -0,0 +1,3 @@
+GDTEST_OK
+Test true
+Test true