diff options
author | ocean (they/them) <anvilfolk@gmail.com> | 2023-08-31 13:49:04 -0400 |
---|---|---|
committer | ocean (they/them) <anvilfolk@gmail.com> | 2023-09-11 11:10:07 -0400 |
commit | 711ffabcfe28d7ca7de03a65e8cd37fbc601ef33 (patch) | |
tree | c29b978206cf2b0dc0a1601aa8e52c90826c63e8 | |
parent | 0bca4242392992840b0b891acde6422c49712e3e (diff) | |
download | redot-engine-711ffabcfe28d7ca7de03a65e8cd37fbc601ef33.tar.gz |
GDScript: fix subclass methods not inheriting RPC info
-rw-r--r-- | modules/gdscript/gdscript.cpp | 16 | ||||
-rw-r--r-- | modules/gdscript/gdscript.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 32 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.h | 2 |
4 files changed, 25 insertions, 26 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index ccbcb3ee96..6623f96c2a 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1399,22 +1399,6 @@ void GDScript::_save_orphaned_subclasses(ClearData *p_clear_data) { } } -void GDScript::_init_rpc_methods_properties() { - // Copy the base rpc methods so we don't mask their IDs. - rpc_config.clear(); - if (base.is_valid()) { - rpc_config = base->rpc_config.duplicate(); - } - - // RPC Methods - for (KeyValue<StringName, GDScriptFunction *> &E : member_functions) { - Variant config = E.value->get_rpc_config(); - if (config.get_type() != Variant::NIL) { - rpc_config[E.value->get_name()] = config; - } - } -} - #ifdef DEBUG_ENABLED String GDScript::debug_get_script_name(const Ref<Script> &p_script) { if (p_script.is_valid()) { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 0ba007683c..4ea3a2302d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -168,7 +168,6 @@ class GDScript : public Script { bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false, PlaceHolderScriptInstance *p_instance_to_update = nullptr); void _save_orphaned_subclasses(GDScript::ClearData *p_clear_data); - void _init_rpc_methods_properties(); void _get_script_property_list(List<PropertyInfo> *r_list, bool p_include_base) const; void _get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 985eb97b29..120e845ae1 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2503,7 +2503,10 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP return err; } -Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { +// Prepares given script, and inner class scripts, for compilation. It populates class members and initializes method +// RPC info for its base classes first, then for itself, then for inner classes. +// Warning: this function cannot initiate compilation of other classes, or it will result in cyclic dependency issues. +Error GDScriptCompiler::_prepare_compilation(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { if (parsed_classes.has(p_script)) { return OK; } @@ -2562,6 +2565,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri p_script->implicit_initializer = nullptr; p_script->implicit_ready = nullptr; p_script->static_initializer = nullptr; + p_script->rpc_config.clear(); p_script->clearing = false; @@ -2592,7 +2596,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri } if (main_script->has_class(base.ptr())) { - Error err = _populate_class_members(base.ptr(), p_class->base_type.class_type, p_keep_state); + Error err = _prepare_compilation(base.ptr(), p_class->base_type.class_type, p_keep_state); if (err) { return err; } @@ -2611,7 +2615,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri return ERR_COMPILATION_FAILED; } - err = _populate_class_members(base.ptr(), p_class->base_type.class_type, p_keep_state); + err = _prepare_compilation(base.ptr(), p_class->base_type.class_type, p_keep_state); if (err) { _set_error(vformat(R"(Could not populate class members of base class "%s" in "%s".)", base->fully_qualified_name, base->path), nullptr); return err; @@ -2628,6 +2632,12 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri } break; } + // Duplicate RPC information from base GDScript + // Base script isn't valid because it should not have been compiled yet, but the reference contains relevant info. + if (base_type.kind == GDScriptDataType::GDSCRIPT && p_script->base.is_valid()) { + p_script->rpc_config = p_script->base->rpc_config.duplicate(); + } + for (int i = 0; i < p_class->members.size(); i++) { const GDScriptParser::ClassNode::Member &member = p_class->members[i]; switch (member.type) { @@ -2746,6 +2756,14 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri p_script->members.insert(Variant()); } break; + case GDScriptParser::ClassNode::Member::FUNCTION: { + const GDScriptParser::FunctionNode *function_n = member.function; + + Variant config = function_n->rpc_config; + if (config.get_type() != Variant::NIL) { + p_script->rpc_config[function_n->identifier->name] = config; + } + } break; default: break; // Nothing to do here. } @@ -2756,7 +2774,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri parsed_classes.insert(p_script); parsing_classes.erase(p_script); - // Populate sub-classes. + // Populate inner classes. for (int i = 0; i < p_class->members.size(); i++) { const GDScriptParser::ClassNode::Member &member = p_class->members[i]; if (member.type != member.CLASS) { @@ -2769,7 +2787,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri // Subclass might still be parsing, just skip it if (!parsing_classes.has(subclass_ptr)) { - Error err = _populate_class_members(subclass_ptr, inner_class, p_keep_state); + Error err = _prepare_compilation(subclass_ptr, inner_class, p_keep_state); if (err) { return err; } @@ -2905,8 +2923,6 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser: has_static_data = has_static_data || inner_class->has_static_data; } - p_script->_init_rpc_methods_properties(); - p_script->valid = true; return OK; } @@ -2979,7 +2995,7 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri make_scripts(p_script, root, p_keep_state); main_script->_owner = nullptr; - Error err = _populate_class_members(main_script, parser->get_tree(), p_keep_state); + Error err = _prepare_compilation(main_script, parser->get_tree(), p_keep_state); if (err) { return err; diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 2f522da4ea..1882471331 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -135,7 +135,7 @@ class GDScriptCompiler { GDScriptFunction *_parse_function(Error &r_error, GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false, bool p_for_lambda = false); GDScriptFunction *_make_static_initializer(Error &r_error, GDScript *p_script, const GDScriptParser::ClassNode *p_class); Error _parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter); - Error _populate_class_members(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); + Error _prepare_compilation(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); Error _compile_class(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); int err_line = 0; int err_column = 0; |