diff options
Diffstat (limited to 'modules/mono/editor')
7 files changed, 283 insertions, 176 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index 56fca6b5cb..bfc807c01a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -350,7 +350,7 @@ namespace GodotTools.Build if (_issuesListContextMenu.ItemCount > 0) { - _issuesListContextMenu.Position = (Vector2i)(_issuesList.RectGlobalPosition + atPosition); + _issuesListContextMenu.Position = (Vector2i)(_issuesList.GlobalPosition + atPosition); _issuesListContextMenu.Popup(); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 2dbc78ab77..9e8f7ef1b1 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -126,7 +126,7 @@ namespace GodotTools.Build { base._Ready(); - RectMinSize = new Vector2(0, 228) * EditorScale; + MinimumSize = new Vector2(0, 228) * EditorScale; SizeFlagsVertical = (int)SizeFlags.ExpandFill; var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill }; diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 37e6a34977..ed758cc137 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -537,7 +537,6 @@ MONO_AOT_MODE_LAST = 1000, { var iosArchs = new[] { - "armv7", "arm64" }; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 1de41821f9..272283432d 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -278,11 +278,12 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } else if (code_tag) { xml_output.append("["); pos = brk_pos + 1; - } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ")) { - String link_target = tag.substr(tag.find(" ") + 1, tag.length()); - String link_tag = tag.substr(0, tag.find(" ")); + } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ")) { + const int tag_end = tag.find(" "); + const String link_tag = tag.substr(0, tag_end); + const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); - Vector<String> link_target_parts = link_target.split("."); + const Vector<String> link_target_parts = link_target.split("."); if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) { ERR_PRINT("Invalid reference format: '" + tag + "'."); @@ -310,175 +311,18 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } if (link_tag == "method") { - if (!target_itype || !target_itype->is_object_type) { - if (OS::get_singleton()->is_stdout_verbose()) { - if (target_itype) { - OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data()); - } else { - OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", link_target.utf8().get_data()); - } - } - - // TODO Map what we can - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } else { - const MethodInterface *target_imethod = target_itype->find_method_by_name(target_cname); - - if (target_imethod) { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_itype->proxy_name); - xml_output.append("."); - xml_output.append(target_imethod->proxy_name); - xml_output.append("\"/>"); - } - } + _append_xml_method(xml_output, target_itype, target_cname, link_target, link_target_parts); } else if (link_tag == "member") { - if (!target_itype || !target_itype->is_object_type) { - if (OS::get_singleton()->is_stdout_verbose()) { - if (target_itype) { - OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data()); - } else { - OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", link_target.utf8().get_data()); - } - } - - // TODO Map what we can - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } else { - const PropertyInterface *target_iprop = target_itype->find_property_by_name(target_cname); - - if (target_iprop) { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_itype->proxy_name); - xml_output.append("."); - xml_output.append(target_iprop->proxy_name); - xml_output.append("\"/>"); - } - } + _append_xml_member(xml_output, target_itype, target_cname, link_target, link_target_parts); } else if (link_tag == "signal") { - // We do not declare signals in any way in C#, so there is nothing to reference - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); + _append_xml_signal(xml_output, target_itype, target_cname, link_target, link_target_parts); } else if (link_tag == "enum") { - StringName search_cname = !target_itype ? target_cname : StringName(target_itype->name + "." + (String)target_cname); - - const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname); - - if (!enum_match && search_cname != target_cname) { - enum_match = enum_types.find(target_cname); - } - - if (enum_match) { - const TypeInterface &target_enum_itype = enum_match->value(); - - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any - xml_output.append("\"/>"); - } else { - ERR_PRINT("Cannot resolve enum reference in documentation: '" + link_target + "'."); - - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } + _append_xml_enum(xml_output, target_itype, target_cname, link_target, link_target_parts); } else if (link_tag == "constant") { - if (!target_itype || !target_itype->is_object_type) { - if (OS::get_singleton()->is_stdout_verbose()) { - if (target_itype) { - OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", link_target.utf8().get_data()); - } else { - OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", link_target.utf8().get_data()); - } - } - - // TODO Map what we can - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } else if (!target_itype && target_cname == name_cache.type_at_GlobalScope) { - String target_name = (String)target_cname; - - // Try to find as a global constant - const ConstantInterface *target_iconst = find_constant_by_name(target_name, global_constants); - - if (target_iconst) { - // Found global constant - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "." BINDINGS_GLOBAL_SCOPE_CLASS "."); - xml_output.append(target_iconst->proxy_name); - xml_output.append("\"/>"); - } else { - // Try to find as global enum constant - const EnumInterface *target_ienum = nullptr; - - for (const EnumInterface &ienum : global_enums) { - target_ienum = &ienum; - target_iconst = find_constant_by_name(target_name, target_ienum->constants); - if (target_iconst) { - break; - } - } - - if (target_iconst) { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_ienum->cname); - xml_output.append("."); - xml_output.append(target_iconst->proxy_name); - xml_output.append("\"/>"); - } else { - ERR_PRINT("Cannot resolve global constant reference in documentation: '" + link_target + "'."); - - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } - } - } else { - String target_name = (String)target_cname; - - // Try to find the constant in the current class - const ConstantInterface *target_iconst = find_constant_by_name(target_name, target_itype->constants); - - if (target_iconst) { - // Found constant in current class - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_itype->proxy_name); - xml_output.append("."); - xml_output.append(target_iconst->proxy_name); - xml_output.append("\"/>"); - } else { - // Try to find as enum constant in the current class - const EnumInterface *target_ienum = nullptr; - - for (const EnumInterface &ienum : target_itype->enums) { - target_ienum = &ienum; - target_iconst = find_constant_by_name(target_name, target_ienum->constants); - if (target_iconst) { - break; - } - } - - if (target_iconst) { - xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); - xml_output.append(target_itype->proxy_name); - xml_output.append("."); - xml_output.append(target_ienum->cname); - xml_output.append("."); - xml_output.append(target_iconst->proxy_name); - xml_output.append("\"/>"); - } else { - ERR_PRINT("Cannot resolve constant reference in documentation: '" + link_target + "'."); - - xml_output.append("<c>"); - xml_output.append(link_target); - xml_output.append("</c>"); - } - } - } + _append_xml_constant(xml_output, target_itype, target_cname, link_target, link_target_parts); + } else if (link_tag == "theme_item") { + // We do not declare theme_items in any way in C#, so there is nothing to reference + _append_xml_undeclared(xml_output, link_target); } pos = brk_end + 1; @@ -643,6 +487,240 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf return xml_output.as_string(); } +void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { + if (p_link_target_parts[0] == name_cache.type_at_GlobalScope) { + if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print("Cannot resolve @GlobalScope method reference in documentation: %s\n", p_link_target.utf8().get_data()); + } + + // TODO Map what we can + _append_xml_undeclared(p_xml_output, p_link_target); + } else if (!p_target_itype || !p_target_itype->is_object_type) { + if (OS::get_singleton()->is_stdout_verbose()) { + if (p_target_itype) { + OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + } else { + OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", p_link_target.utf8().get_data()); + } + } + + // TODO Map what we can + _append_xml_undeclared(p_xml_output, p_link_target); + } else { + if (p_target_cname == "_init") { + // The _init method is not declared in C#, reference the constructor instead + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("()\"/>"); + } else { + const MethodInterface *target_imethod = p_target_itype->find_method_by_name(p_target_cname); + + if (target_imethod) { + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(target_imethod->proxy_name); + p_xml_output.append("\"/>"); + } else { + ERR_PRINT("Cannot resolve method reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } + } + } +} + +void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { + if (p_link_target.find("/") >= 0) { + // Properties with '/' (slash) in the name are not declared in C#, so there is nothing to reference. + _append_xml_undeclared(p_xml_output, p_link_target); + } else if (!p_target_itype || !p_target_itype->is_object_type) { + if (OS::get_singleton()->is_stdout_verbose()) { + if (p_target_itype) { + OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + } else { + OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", p_link_target.utf8().get_data()); + } + } + + // TODO Map what we can + _append_xml_undeclared(p_xml_output, p_link_target); + } else { + const TypeInterface *current_itype = p_target_itype; + const PropertyInterface *target_iprop = nullptr; + + while (target_iprop == nullptr && current_itype != nullptr) { + target_iprop = current_itype->find_property_by_name(p_target_cname); + if (target_iprop == nullptr) { + current_itype = _get_type_or_null(TypeReference(current_itype->base_name)); + } + } + + if (target_iprop) { + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(current_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(target_iprop->proxy_name); + p_xml_output.append("\"/>"); + } else { + ERR_PRINT("Cannot resolve member reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } + } +} + +void BindingsGenerator::_append_xml_signal(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { + if (!p_target_itype || !p_target_itype->is_object_type) { + if (OS::get_singleton()->is_stdout_verbose()) { + if (p_target_itype) { + OS::get_singleton()->print("Cannot resolve signal reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + } else { + OS::get_singleton()->print("Cannot resolve type from signal reference in documentation: %s\n", p_link_target.utf8().get_data()); + } + } + + // TODO Map what we can + _append_xml_undeclared(p_xml_output, p_link_target); + } else { + const SignalInterface *target_isignal = p_target_itype->find_signal_by_name(p_target_cname); + + if (target_isignal) { + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(target_isignal->proxy_name); + p_xml_output.append("\"/>"); + } else { + ERR_PRINT("Cannot resolve signal reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } + } +} + +void BindingsGenerator::_append_xml_enum(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { + const StringName search_cname = !p_target_itype ? p_target_cname : StringName(p_target_itype->name + "." + (String)p_target_cname); + + const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname); + + if (!enum_match && search_cname != p_target_cname) { + enum_match = enum_types.find(p_target_cname); + } + + if (enum_match) { + const TypeInterface &target_enum_itype = enum_match->value(); + + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any + p_xml_output.append("\"/>"); + } else { + ERR_PRINT("Cannot resolve enum reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } +} + +void BindingsGenerator::_append_xml_constant(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts) { + if (p_link_target_parts[0] == name_cache.type_at_GlobalScope) { + _append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target); + } else if (!p_target_itype || !p_target_itype->is_object_type) { + // Search in @GlobalScope as a last resort if no class was specified + if (p_link_target_parts.size() == 1) { + _append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target); + return; + } + + if (OS::get_singleton()->is_stdout_verbose()) { + if (p_target_itype) { + OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + } else { + OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", p_link_target.utf8().get_data()); + } + } + + // TODO Map what we can + _append_xml_undeclared(p_xml_output, p_link_target); + } else { + // Try to find the constant in the current class + const ConstantInterface *target_iconst = find_constant_by_name(p_target_cname, p_target_itype->constants); + + if (target_iconst) { + // Found constant in current class + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(target_iconst->proxy_name); + p_xml_output.append("\"/>"); + } else { + // Try to find as enum constant in the current class + const EnumInterface *target_ienum = nullptr; + + for (const EnumInterface &ienum : p_target_itype->enums) { + target_ienum = &ienum; + target_iconst = find_constant_by_name(p_target_cname, target_ienum->constants); + if (target_iconst) { + break; + } + } + + if (target_iconst) { + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(p_target_itype->proxy_name); + p_xml_output.append("."); + p_xml_output.append(target_ienum->cname); + p_xml_output.append("."); + p_xml_output.append(target_iconst->proxy_name); + p_xml_output.append("\"/>"); + } else if (p_link_target_parts.size() == 1) { + // Also search in @GlobalScope as a last resort if no class was specified + _append_xml_constant_in_global_scope(p_xml_output, p_target_cname, p_link_target); + } else { + ERR_PRINT("Cannot resolve constant reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } + } + } +} + +void BindingsGenerator::_append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target) { + // Try to find as a global constant + const ConstantInterface *target_iconst = find_constant_by_name(p_target_cname, global_constants); + + if (target_iconst) { + // Found global constant + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "." BINDINGS_GLOBAL_SCOPE_CLASS "."); + p_xml_output.append(target_iconst->proxy_name); + p_xml_output.append("\"/>"); + } else { + // Try to find as global enum constant + const EnumInterface *target_ienum = nullptr; + + for (const EnumInterface &ienum : global_enums) { + target_ienum = &ienum; + target_iconst = find_constant_by_name(p_target_cname, target_ienum->constants); + if (target_iconst) { + break; + } + } + + if (target_iconst) { + p_xml_output.append("<see cref=\"" BINDINGS_NAMESPACE "."); + p_xml_output.append(target_ienum->cname); + p_xml_output.append("."); + p_xml_output.append(target_iconst->proxy_name); + p_xml_output.append("\"/>"); + } else { + ERR_PRINT("Cannot resolve global constant reference in documentation: '" + p_link_target + "'."); + _append_xml_undeclared(p_xml_output, p_link_target); + } + } +} + +void BindingsGenerator::_append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target) { + p_xml_output.append("<c>"); + p_xml_output.append(p_link_target); + p_xml_output.append("</c>"); +} + int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) { CRASH_COND(p_ienum.constants.is_empty()); @@ -2122,8 +2200,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { } output.append("#ifdef TOOLS_ENABLED\n"); - for (const InternalCall &internal_call : editor_custom_icalls) + for (const InternalCall &internal_call : editor_custom_icalls) { ADD_INTERNAL_CALL_REGISTRATION(internal_call); + } output.append("#endif // TOOLS_ENABLED\n"); for (const InternalCall &internal_call : method_icalls) { diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 2e6ce3a952..f601ffde2b 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -366,6 +366,16 @@ class BindingsGenerator { return nullptr; } + const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const { + for (const MethodInterface &E : methods) { + if (E.proxy_name == p_proxy_name) { + return &E; + } + } + + return nullptr; + } + const PropertyInterface *find_property_by_name(const StringName &p_cname) const { for (const PropertyInterface &E : properties) { if (E.cname == p_cname) { @@ -386,8 +396,18 @@ class BindingsGenerator { return nullptr; } - const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const { - for (const MethodInterface &E : methods) { + const SignalInterface *find_signal_by_name(const StringName &p_cname) const { + for (const SignalInterface &E : signals_) { + if (E.cname == p_cname) { + return &E; + } + } + + return nullptr; + } + + const SignalInterface *find_signal_by_proxy_name(const String &p_proxy_name) const { + for (const SignalInterface &E : signals_) { if (E.proxy_name == p_proxy_name) { return &E; } @@ -638,6 +658,14 @@ class BindingsGenerator { String bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype); + void _append_xml_method(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts); + void _append_xml_member(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts); + void _append_xml_signal(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts); + void _append_xml_enum(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts); + void _append_xml_constant(StringBuilder &p_xml_output, const TypeInterface *p_target_itype, const StringName &p_target_cname, const String &p_link_target, const Vector<String> &p_link_target_parts); + void _append_xml_constant_in_global_scope(StringBuilder &p_xml_output, const String &p_target_cname, const String &p_link_target); + void _append_xml_undeclared(StringBuilder &p_xml_output, const String &p_link_target); + int _determine_enum_prefix(const EnumInterface &p_ienum); void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length); diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index 095fd831a3..3a41b3f6f5 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -120,7 +120,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr } break; case CompletionKind::NODE_PATHS: { { - // AutoLoads + // Autoloads. OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) { diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 3c02ea0e8e..f7f710f3f1 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -34,6 +34,7 @@ #include <unistd.h> // access #endif +#include "core/config/project_settings.h" #include "core/os/os.h" #include "core/version.h" #include "editor/debugger/editor_debugger_node.h" |