You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
GDScript: fix subclass methods not inheriting RPC info
This commit is contained in:
@@ -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
|
#ifdef DEBUG_ENABLED
|
||||||
String GDScript::debug_get_script_name(const Ref<Script> &p_script) {
|
String GDScript::debug_get_script_name(const Ref<Script> &p_script) {
|
||||||
if (p_script.is_valid()) {
|
if (p_script.is_valid()) {
|
||||||
|
|||||||
@@ -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);
|
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 _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_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;
|
void _get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const;
|
||||||
|
|||||||
@@ -2503,7 +2503,10 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
|
|||||||
return err;
|
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)) {
|
if (parsed_classes.has(p_script)) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -2562,6 +2565,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri
|
|||||||
p_script->implicit_initializer = nullptr;
|
p_script->implicit_initializer = nullptr;
|
||||||
p_script->implicit_ready = nullptr;
|
p_script->implicit_ready = nullptr;
|
||||||
p_script->static_initializer = nullptr;
|
p_script->static_initializer = nullptr;
|
||||||
|
p_script->rpc_config.clear();
|
||||||
|
|
||||||
p_script->clearing = false;
|
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())) {
|
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) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2611,7 +2615,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri
|
|||||||
return ERR_COMPILATION_FAILED;
|
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) {
|
if (err) {
|
||||||
_set_error(vformat(R"(Could not populate class members of base class "%s" in "%s".)", base->fully_qualified_name, base->path), nullptr);
|
_set_error(vformat(R"(Could not populate class members of base class "%s" in "%s".)", base->fully_qualified_name, base->path), nullptr);
|
||||||
return err;
|
return err;
|
||||||
@@ -2628,6 +2632,12 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri
|
|||||||
} break;
|
} 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++) {
|
for (int i = 0; i < p_class->members.size(); i++) {
|
||||||
const GDScriptParser::ClassNode::Member &member = p_class->members[i];
|
const GDScriptParser::ClassNode::Member &member = p_class->members[i];
|
||||||
switch (member.type) {
|
switch (member.type) {
|
||||||
@@ -2746,6 +2756,14 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri
|
|||||||
p_script->members.insert(Variant());
|
p_script->members.insert(Variant());
|
||||||
} break;
|
} 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:
|
default:
|
||||||
break; // Nothing to do here.
|
break; // Nothing to do here.
|
||||||
}
|
}
|
||||||
@@ -2756,7 +2774,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri
|
|||||||
parsed_classes.insert(p_script);
|
parsed_classes.insert(p_script);
|
||||||
parsing_classes.erase(p_script);
|
parsing_classes.erase(p_script);
|
||||||
|
|
||||||
// Populate sub-classes.
|
// Populate inner classes.
|
||||||
for (int i = 0; i < p_class->members.size(); i++) {
|
for (int i = 0; i < p_class->members.size(); i++) {
|
||||||
const GDScriptParser::ClassNode::Member &member = p_class->members[i];
|
const GDScriptParser::ClassNode::Member &member = p_class->members[i];
|
||||||
if (member.type != member.CLASS) {
|
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
|
// Subclass might still be parsing, just skip it
|
||||||
if (!parsing_classes.has(subclass_ptr)) {
|
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) {
|
if (err) {
|
||||||
return 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;
|
has_static_data = has_static_data || inner_class->has_static_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_script->_init_rpc_methods_properties();
|
|
||||||
|
|
||||||
p_script->valid = true;
|
p_script->valid = true;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -2979,7 +2995,7 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri
|
|||||||
make_scripts(p_script, root, p_keep_state);
|
make_scripts(p_script, root, p_keep_state);
|
||||||
|
|
||||||
main_script->_owner = nullptr;
|
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) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -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 *_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);
|
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 _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);
|
Error _compile_class(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
|
||||||
int err_line = 0;
|
int err_line = 0;
|
||||||
int err_column = 0;
|
int err_column = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user