diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 112a76ffa7..89d8a08d5c 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -863,3 +863,13 @@ void CoreConstants::get_enum_values(const StringName &p_enum, HashMap *r_values) { + for (const KeyValue> &global_enum : _global_enums) { + r_values->push_back(global_enum.key); + } +} + +#endif diff --git a/core/core_constants.h b/core/core_constants.h index c432fdca3b..8e58241c1e 100644 --- a/core/core_constants.h +++ b/core/core_constants.h @@ -32,6 +32,7 @@ #include "core/string/string_name.h" #include "core/templates/hash_map.h" +#include "core/templates/list.h" class CoreConstants { public: @@ -44,5 +45,8 @@ public: static bool is_global_constant(const StringName &p_name); static int get_global_constant_index(const StringName &p_name); static bool is_global_enum(const StringName &p_enum); - static void get_enum_values(const StringName &p_enum, HashMap *p_values); + static void get_enum_values(const StringName &p_enum, HashMap *r_values); +#ifdef TOOLS_ENABLED + static void get_global_enums(List *r_values); +#endif }; diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 9bcb21909f..a3cb4e5c07 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -34,6 +34,7 @@ #include "../gdscript_tokenizer.h" #include "core/config/project_settings.h" +#include "core/core_constants.h" #include "editor/editor_settings.h" #include "editor/themes/editor_theme_manager.h" #include "scene/gui/text_edit.h" @@ -722,6 +723,13 @@ void GDScriptSyntaxHighlighter::_update_cache() { } } + /* Global enums. */ + List global_enums; + CoreConstants::get_global_enums(&global_enums); + for (const StringName &enum_name : global_enums) { + class_names[enum_name] = types_color; + } + /* User types. */ const Color usertype_color = EDITOR_GET("text_editor/theme/highlighting/user_type_color"); List global_classes; @@ -848,6 +856,12 @@ void GDScriptSyntaxHighlighter::_update_cache() { for (const String &E : constant_list) { member_keywords[E] = member_variable_color; } + + List builtin_enums; + ClassDB::get_enum_list(instance_base, &builtin_enums); + for (const StringName &E : builtin_enums) { + member_keywords[E] = types_color; + } } List scr_property_list; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 3b23ce53fc..2533e8ad69 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1035,6 +1035,15 @@ static void _find_built_in_variants(HashMap &r_result) { + List global_enums; + CoreConstants::get_global_enums(&global_enums); + for (const StringName &enum_name : global_enums) { + ScriptLanguage::CodeCompletionOption option(enum_name, ScriptLanguage::CODE_COMPLETION_KIND_ENUM, ScriptLanguage::LOCATION_OTHER); + r_result.insert(option.display, option); + } +} + static void _list_available_types(bool p_inherit_only, GDScriptParser::CompletionContext &p_context, HashMap &r_result) { // Built-in Variant Types _find_built_in_variants(r_result, true); @@ -1096,6 +1105,11 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio r_result.insert(option.display, option); } + // Global enums + if (!p_inherit_only) { + _find_global_enums(r_result); + } + // Autoload singletons HashMap autoloads = ProjectSettings::get_singleton()->get_autoload_list(); @@ -1396,15 +1410,29 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base } break; case GDScriptParser::DataType::ENUM: { String type_str = base_type.native_type; - StringName type = type_str.get_slicec('.', 0); - StringName type_enum = base_type.enum_type; - List enum_values; - ClassDB::get_enum_constants(type, type_enum, &enum_values); - for (const StringName &E : enum_values) { - int location = p_recursion_depth + _get_enum_constant_location(type, E); - ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location); - r_result.insert(option.display, option); + if (type_str.contains_char('.')) { + StringName type = type_str.get_slicec('.', 0); + StringName type_enum = base_type.enum_type; + + List enum_values; + + ClassDB::get_enum_constants(type, type_enum, &enum_values); + + for (const StringName &E : enum_values) { + int location = p_recursion_depth + _get_enum_constant_location(type, E); + ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location); + r_result.insert(option.display, option); + } + } else if (CoreConstants::is_global_enum(base_type.enum_type)) { + HashMap enum_values; + CoreConstants::get_enum_values(base_type.enum_type, &enum_values); + + for (const KeyValue &enum_value : enum_values) { + int location = p_recursion_depth + ScriptLanguage::LOCATION_OTHER; + ScriptLanguage::CodeCompletionOption option(enum_value.key, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location); + r_result.insert(option.display, option); + } } } [[fallthrough]]; @@ -1585,6 +1613,9 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context r_result.insert(option.display, option); } + // Global enums + _find_global_enums(r_result); + // Global classes List global_classes; ScriptServer::get_global_class_list(&global_classes); diff --git a/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.cfg b/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.cfg new file mode 100644 index 0000000000..7c7b465f26 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.cfg @@ -0,0 +1,9 @@ +[output] +include=[ + {"display": "DrawMode", + "location": 256}, + {"display": "Anchor", + "location": 257}, + {"display": "TextureRepeat", + "location": 258}, +] diff --git a/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.gd b/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.gd new file mode 100644 index 0000000000..1cdab92c55 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.gd @@ -0,0 +1,4 @@ +extends Control + +func _ready(): + var t: BaseButton.➡ diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.cfg b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.cfg new file mode 100644 index 0000000000..acbcad3018 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.cfg @@ -0,0 +1,6 @@ +[output] +include=[ + {"display": "Key"}, + {"display": "KeyLocation"}, + {"display": "Error"}, +] diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.gd b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.gd new file mode 100644 index 0000000000..426b41babb --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.gd @@ -0,0 +1,5 @@ +extends Object + +func test(): + var t = Ke➡ + pass diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.cfg b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.cfg new file mode 100644 index 0000000000..918ba54338 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.cfg @@ -0,0 +1,6 @@ +[output] +exclude=[ + {"display": "Key"}, + {"display": "KeyLocation"}, + {"display": "Error"}, +] diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.gd b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.gd new file mode 100644 index 0000000000..dee35277da --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.gd @@ -0,0 +1 @@ +extends Ke➡ diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.cfg b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.cfg new file mode 100644 index 0000000000..acbcad3018 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.cfg @@ -0,0 +1,6 @@ +[output] +include=[ + {"display": "Key"}, + {"display": "KeyLocation"}, + {"display": "Error"}, +] diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.gd b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.gd new file mode 100644 index 0000000000..0d1bf0980d --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_type_hint.gd @@ -0,0 +1,5 @@ +extends Control + +func _ready(): + var t: Ke➡ + pass diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.cfg b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.cfg new file mode 100644 index 0000000000..a265ae4401 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.cfg @@ -0,0 +1,5 @@ +[output] +include=[ + {"display": "KEY_A"}, + {"display": "KEY_B"}, +] diff --git a/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.gd b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.gd new file mode 100644 index 0000000000..972aaa0e63 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.gd @@ -0,0 +1,5 @@ +extends Control + +func test(): + Key.➡ + pass