From 164b34a734a2d38b6ed264112277a6f6e8018adf Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Thu, 4 Apr 2024 21:15:17 +0000 Subject: [PATCH] Don't pass `self` when calling a static function from a non-static context --- modules/gdscript/gdscript_analyzer.cpp | 7 ++++--- modules/gdscript/gdscript_compiler.cpp | 2 +- modules/gdscript/gdscript_parser.h | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 6af6460b315..f67f4913c34 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3293,6 +3293,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a if (get_function_signature(p_call, is_constructor, base_type, p_call->function_name, return_type, par_types, default_arg_count, method_flags)) { // If the method is implemented in the class hierarchy, the virtual flag will not be set for that MethodInfo and the search stops there. // Virtual check only possible for super() calls because class hierarchy is known. Node/Objects may have scripts attached we don't know of at compile-time. + p_call->is_static = method_flags.has_flag(METHOD_FLAG_STATIC); if (p_call->is_super && method_flags.has_flag(METHOD_FLAG_VIRTUAL)) { push_error(vformat(R"*(Cannot call the parent class' virtual function "%s()" because it hasn't been defined.)*", p_call->function_name), p_call); } @@ -3311,7 +3312,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a base_type.is_meta_type = false; } - if (is_self && static_context && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + if (is_self && static_context && !p_call->is_static) { // Get the parent function above any lambda. GDScriptParser::FunctionNode *parent_function = parser->current_function; while (parent_function && parent_function->source_lambda) { @@ -3323,10 +3324,10 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a } else { push_error(vformat(R"*(Cannot call non-static function "%s()" from a static variable initializer.)*", p_call->function_name), p_call); } - } else if (!is_self && base_type.is_meta_type && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + } else if (!is_self && base_type.is_meta_type && !p_call->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); - } else if (is_self && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + } else if (is_self && !p_call->is_static) { mark_lambda_use_self(); } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 13ed66710c9..d706c1b101a 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -648,7 +648,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code // Not exact arguments, but still can use method bind call. gen->write_call_method_bind(result, self, method, arguments); } - } else if (codegen.is_static || (codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { + } else if (call->is_static || codegen.is_static || (codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { GDScriptCodeGenerator::Address self; self.mode = GDScriptCodeGenerator::Address::CLASS; if (is_awaited) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index ea67f1eaffb..d047fa8e46f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -498,6 +498,7 @@ public: Vector arguments; StringName function_name; bool is_super = false; + bool is_static = false; CallNode() { type = CALL;