diff options
author | Adam Scott <ascott.ca@gmail.com> | 2023-01-26 17:15:51 -0500 |
---|---|---|
committer | RĂ©mi Verschelde <rverschelde@gmail.com> | 2023-02-07 11:48:10 +0100 |
commit | 0fef203b1f39c3373f9f25b8e75e75f6b03f7c88 (patch) | |
tree | 586dadacddae2e031a65c5fd69eaaef9c65b2a22 | |
parent | 3f02cf7ced320f25ac5f4f72d7a57d98296bfcd1 (diff) |
Remove script class checks when getting function signature
13 files changed, 65 insertions, 13 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index cd1dcf9a78..78e437b42a 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 the class "%s" directly. Make an instance instead.)*", p_call->function_name, base_type.to_string()), p_call); + push_error(vformat(R"*(Cannot call non-static function "%s()" on a class directly. Make an instance instead.)*", p_call->function_name), p_call); } else if (is_self && !is_static) { mark_lambda_use_self(); } @@ -4564,16 +4564,6 @@ 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 46cd4b0d55..210550a674 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -591,7 +591,6 @@ 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) { @@ -615,7 +614,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 (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) { + if (!subscript->base->is_constant && 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 new file mode 100644 index 0000000000..966d2b0aa2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.gd @@ -0,0 +1,5 @@ +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 new file mode 100644 index 0000000000..b2c7fec86e --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate.out @@ -0,0 +1,2 @@ +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 new file mode 100644 index 0000000000..61510e14cd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/gdscript_duplicate_class.notest.gd @@ -0,0 +1 @@ +extends Node diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd new file mode 100644 index 0000000000..030daf502c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.gd @@ -0,0 +1,6 @@ +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 new file mode 100644 index 0000000000..d73c5eb7cd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate.out @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000..61510e14cd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/gdscript_duplicate_class.notest.gd @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000000..edfc45a8d8 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/super_class_check.gd @@ -0,0 +1,13 @@ +# 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 new file mode 100644 index 0000000000..d73c5eb7cd --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/super_class_check.out @@ -0,0 +1 @@ +GDTEST_OK diff --git a/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd b/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd new file mode 100644 index 0000000000..418501dcc5 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/static_duplicate.gd @@ -0,0 +1,19 @@ +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 new file mode 100644 index 0000000000..34cd5c7652 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/static_duplicate.out @@ -0,0 +1,9 @@ +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 new file mode 100644 index 0000000000..291ffc2c0b --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/static_duplicate_preload.notest.gd @@ -0,0 +1,5 @@ +extends RefCounted + +static func duplicate() -> Vector2: + print("preload duplicate") + return Vector2.ONE |