瀏覽代碼

Merge pull request #102186 from HolonProduction/completion-builtin-enum

Improve GDScript editor support for global enums
Thaddeus Crews 1 月之前
父節點
當前提交
77b680244d

+ 10 - 0
core/core_constants.cpp

@@ -863,3 +863,13 @@ void CoreConstants::get_enum_values(const StringName &p_enum, HashMap<StringName
 		(*p_values)[constant.name] = constant.value;
 	}
 }
+
+#ifdef TOOLS_ENABLED
+
+void CoreConstants::get_global_enums(List<StringName> *r_values) {
+	for (const KeyValue<StringName, Vector<_CoreConstant>> &global_enum : _global_enums) {
+		r_values->push_back(global_enum.key);
+	}
+}
+
+#endif

+ 5 - 1
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<StringName, int64_t> *p_values);
+	static void get_enum_values(const StringName &p_enum, HashMap<StringName, int64_t> *r_values);
+#ifdef TOOLS_ENABLED
+	static void get_global_enums(List<StringName> *r_values);
+#endif
 };

+ 14 - 0
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<StringName> 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<StringName> global_classes;
@@ -848,6 +856,12 @@ void GDScriptSyntaxHighlighter::_update_cache() {
 			for (const String &E : constant_list) {
 				member_keywords[E] = member_variable_color;
 			}
+
+			List<StringName> builtin_enums;
+			ClassDB::get_enum_list(instance_base, &builtin_enums);
+			for (const StringName &E : builtin_enums) {
+				member_keywords[E] = types_color;
+			}
 		}
 
 		List<PropertyInfo> scr_property_list;

+ 40 - 9
modules/gdscript/gdscript_editor.cpp

@@ -1035,6 +1035,15 @@ static void _find_built_in_variants(HashMap<String, ScriptLanguage::CodeCompleti
 	}
 }
 
+static void _find_global_enums(HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
+	List<StringName> 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<String, ScriptLanguage::CodeCompletionOption> &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<StringName, ProjectSettings::AutoloadInfo> 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<StringName> 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<StringName> 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<StringName, int64_t> enum_values;
+					CoreConstants::get_enum_values(base_type.enum_type, &enum_values);
+
+					for (const KeyValue<StringName, int64_t> &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<StringName> global_classes;
 	ScriptServer::get_global_class_list(&global_classes);

+ 9 - 0
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},
+]

+ 4 - 0
modules/gdscript/tests/scripts/completion/builtin_enum/builtin_enum_in_type_hint.gd

@@ -0,0 +1,4 @@
+extends Control
+
+func _ready():
+    var t: BaseButton.➡

+ 6 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.cfg

@@ -0,0 +1,6 @@
+[output]
+include=[
+    {"display": "Key"},
+    {"display": "KeyLocation"},
+    {"display": "Error"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_identifier.gd

@@ -0,0 +1,5 @@
+extends Object
+
+func test():
+    var t = Ke➡
+    pass

+ 6 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.cfg

@@ -0,0 +1,6 @@
+[output]
+exclude=[
+    {"display": "Key"},
+    {"display": "KeyLocation"},
+    {"display": "Error"},
+]

+ 1 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_in_extends.gd

@@ -0,0 +1 @@
+extends Ke➡

+ 6 - 0
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"},
+]

+ 5 - 0
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

+ 5 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.cfg

@@ -0,0 +1,5 @@
+[output]
+include=[
+    {"display": "KEY_A"},
+    {"display": "KEY_B"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/global_enum/global_enum_values.gd

@@ -0,0 +1,5 @@
+extends Control
+
+func test():
+    Key.➡
+    pass