summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-02-07 16:28:52 +0100
committerRémi Verschelde <rverschelde@gmail.com>2023-02-07 16:28:52 +0100
commit98921d8fbaa83f53f0205ea77f522e37ba30ead2 (patch)
tree44689c21648c131e7a37c853185b8054e4df7519
parentbdad9770d64914da3b77bee49916419b5df87d1c (diff)
Revert "Remove script class checks when getting function signature"
This reverts commit 0fef203b1f39c3373f9f25b8e75e75f6b03f7c88. This introduced some other issues, as discussed in #72144.
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp12
-rw-r--r--modules/gdscript/gdscript_compiler.cpp3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate_class.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.out1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate_class.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/parser/features/super_class_check.gd13
-rw-r--r--modules/gdscript/tests/scripts/parser/features/super_class_check.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd19
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/static_duplicate.out9
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/static_duplicate_preload.notest.gd5
13 files changed, 13 insertions, 65 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 78e437b42a..cd1dcf9a78 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -3017,7 +3017,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
push_error(vformat(R"*(Cannot call non-static function "%s()" from static function "%s()".)*", p_call->function_name, parent_function->identifier->name), p_call);
} else if (!is_self && base_type.is_meta_type && !is_static) {
base_type.is_meta_type = false; // For `to_string()`.
- push_error(vformat(R"*(Cannot call non-static function "%s()" on a class directly. Make an instance instead.)*", p_call->function_name), p_call);
+ push_error(vformat(R"*(Cannot call non-static function "%s()" on the class "%s" directly. Make an instance instead.)*", p_call->function_name, base_type.to_string()), p_call);
} else if (is_self && !is_static) {
mark_lambda_use_self();
}
@@ -4564,6 +4564,16 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
base_script = base_script->get_base_script();
}
+ // If the base is a script, it might be trying to access members of the Script class itself.
+ if (p_base_type.is_meta_type && !p_is_constructor && (p_base_type.kind == GDScriptParser::DataType::SCRIPT || p_base_type.kind == GDScriptParser::DataType::CLASS)) {
+ MethodInfo info;
+ StringName script_class = p_base_type.kind == GDScriptParser::DataType::SCRIPT ? p_base_type.script_type->get_class_name() : StringName(GDScript::get_class_static());
+
+ if (ClassDB::get_method_info(script_class, function_name, &info)) {
+ return function_signature_from_info(info, r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg);
+ }
+ }
+
if (p_is_constructor) {
// Native types always have a default constructor.
r_return_type = p_base_type;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 210550a674..46cd4b0d55 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -591,6 +591,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
}
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee);
+
if (subscript->is_attribute) {
// May be static built-in method call.
if (!call->is_super && subscript->base->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name) < Variant::VARIANT_MAX) {
@@ -614,7 +615,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
} else {
class_name = base.type.native_type == StringName() ? base.type.script_type->get_instance_base_type() : base.type.native_type;
}
- if (!subscript->base->is_constant && ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) {
+ if (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) {
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
if (_can_use_ptrcall(method, arguments)) {
// Exact arguments, use ptrcall.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.gd b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.gd
deleted file mode 100644
index 966d2b0aa2..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.gd
+++ /dev/null
@@ -1,5 +0,0 @@
-const TestClass = preload("gdscript_duplicate_class.notest.gd")
-
-func test():
- # (TestClass as GDScript).duplicate() exists
- TestClass.duplicate()
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.out b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.out
deleted file mode 100644
index b2c7fec86e..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.out
+++ /dev/null
@@ -1,2 +0,0 @@
-GDTEST_ANALYZER_ERROR
-Cannot call non-static function "duplicate()" on a class directly. Make an instance instead.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate_class.notest.gd b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate_class.notest.gd
deleted file mode 100644
index 61510e14cd..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate_class.notest.gd
+++ /dev/null
@@ -1 +0,0 @@
-extends Node
diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd
deleted file mode 100644
index 030daf502c..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd
+++ /dev/null
@@ -1,6 +0,0 @@
-const TestClass = preload("gdscript_duplicate_class.notest.gd")
-
-func test():
- # TestClass.duplicate() fails
- @warning_ignore("return_value_discarded")
- (TestClass as GDScript).duplicate()
diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.out b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.out
deleted file mode 100644
index d73c5eb7cd..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.out
+++ /dev/null
@@ -1 +0,0 @@
-GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate_class.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate_class.notest.gd
deleted file mode 100644
index 61510e14cd..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate_class.notest.gd
+++ /dev/null
@@ -1 +0,0 @@
-extends Node
diff --git a/modules/gdscript/tests/scripts/parser/features/super_class_check.gd b/modules/gdscript/tests/scripts/parser/features/super_class_check.gd
deleted file mode 100644
index edfc45a8d8..0000000000
--- a/modules/gdscript/tests/scripts/parser/features/super_class_check.gd
+++ /dev/null
@@ -1,13 +0,0 @@
-# https://github.com/godotengine/godot/issues/71994
-
-func test():
- pass
-
-class A extends RefCounted:
- pass
-
-class B extends A:
- # Parsing `duplicate()` here would throw this error:
- # Parse Error: The function signature doesn't match the parent. Parent signature is "duplicate(bool = default) -> Resource".
- func duplicate():
- pass
diff --git a/modules/gdscript/tests/scripts/parser/features/super_class_check.out b/modules/gdscript/tests/scripts/parser/features/super_class_check.out
deleted file mode 100644
index d73c5eb7cd..0000000000
--- a/modules/gdscript/tests/scripts/parser/features/super_class_check.out
+++ /dev/null
@@ -1 +0,0 @@
-GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd b/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd
deleted file mode 100644
index 418501dcc5..0000000000
--- a/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd
+++ /dev/null
@@ -1,19 +0,0 @@
-const PreloadClass = preload("static_duplicate_preload.notest.gd")
-const PreloadClassAlias = PreloadClass
-
-func test():
- var dup_preload_one = PreloadClass.duplicate()
- print(dup_preload_one == Vector2.ONE)
-
- var dup_preload_two = (PreloadClass as GDScript).duplicate()
- print(dup_preload_two is GDScript)
-
- var dup_preload_alias_one = PreloadClassAlias.duplicate()
- print(dup_preload_alias_one == Vector2.ONE)
-
- var dup_preload_alias_two = (PreloadClassAlias as GDScript).duplicate()
- print(dup_preload_alias_two is GDScript)
-
- var PreloadClassAsGDScript = PreloadClass as GDScript
- var dup_preload_class_as_gdscript_one = PreloadClassAsGDScript.duplicate()
- print(dup_preload_class_as_gdscript_one is GDScript)
diff --git a/modules/gdscript/tests/scripts/runtime/features/static_duplicate.out b/modules/gdscript/tests/scripts/runtime/features/static_duplicate.out
deleted file mode 100644
index 34cd5c7652..0000000000
--- a/modules/gdscript/tests/scripts/runtime/features/static_duplicate.out
+++ /dev/null
@@ -1,9 +0,0 @@
-GDTEST_OK
-preload duplicate
-true
-true
-preload duplicate
-true
-true
-preload duplicate
-false
diff --git a/modules/gdscript/tests/scripts/runtime/features/static_duplicate_preload.notest.gd b/modules/gdscript/tests/scripts/runtime/features/static_duplicate_preload.notest.gd
deleted file mode 100644
index 291ffc2c0b..0000000000
--- a/modules/gdscript/tests/scripts/runtime/features/static_duplicate_preload.notest.gd
+++ /dev/null
@@ -1,5 +0,0 @@
-extends RefCounted
-
-static func duplicate() -> Vector2:
- print("preload duplicate")
- return Vector2.ONE