diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 19ba1b740f..3138a9c80c 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2860,9 +2860,11 @@ Error GDScriptCompiler::_prepare_compilation(GDScript *p_script, const GDScriptP } break; } - minfo.data_type = _gdtype_from_datatype(variable->get_datatype(), p_script); - PropertyInfo prop_info = variable->get_datatype().to_property_info(name); + const GDScriptParser::DataType variable_type = variable->get_datatype(); + minfo.data_type = _gdtype_from_datatype(variable_type, p_script); + + PropertyInfo prop_info = variable_type.to_property_info(name); PropertyInfo export_info = variable->export_info; if (variable->exported) { @@ -2873,6 +2875,28 @@ Error GDScriptCompiler::_prepare_compilation(GDScript *p_script, const GDScriptP prop_info.hint = export_info.hint; prop_info.hint_string = export_info.hint_string; prop_info.usage = export_info.usage; + } else { + // Enum hint doesn't really belong to the data type information, so we don't want to add it to + // `GDScriptParser::DataType::to_property_info()`. However, we still want to add this metadata + // for unexported properties so they display nicely in the Remote Tree Inspector. + if (variable_type.kind == GDScriptParser::DataType::ENUM && !variable_type.is_meta_type) { + prop_info.hint = PROPERTY_HINT_ENUM; + + String enum_hint_string; + bool first = true; + for (const KeyValue &E : variable_type.enum_values) { + if (first) { + first = false; + } else { + enum_hint_string += ","; + } + enum_hint_string += E.key.operator String().capitalize().xml_escape(); + enum_hint_string += ":"; + enum_hint_string += String::num_int64(E.value).xml_escape(); + } + + prop_info.hint_string = enum_hint_string; + } } prop_info.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; minfo.property_info = prop_info; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 5e874814d0..13a5361484 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4815,10 +4815,10 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta String enum_hint_string; bool first = true; for (const KeyValue &E : export_type.enum_values) { - if (!first) { - enum_hint_string += ","; - } else { + if (first) { first = false; + } else { + enum_hint_string += ","; } enum_hint_string += E.key.operator String().capitalize().xml_escape(); enum_hint_string += ":"; @@ -4892,10 +4892,10 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta String enum_hint_string; bool first = true; for (const KeyValue &E : export_type.enum_values) { - if (!first) { - enum_hint_string += ","; - } else { + if (first) { first = false; + } else { + enum_hint_string += ","; } enum_hint_string += E.key.operator String().capitalize().xml_escape(); enum_hint_string += ":"; diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd index 8aa449f602..0d3cfc55da 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd @@ -5,6 +5,8 @@ extends Node const PreloadedGlobalClass = preload("./export_variable_global.notest.gd") const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd") +enum CustomEnum {A, B, C} + # Built-in types. @export var test_weak_int = 1 @export var test_hard_int: int = 2 @@ -16,8 +18,21 @@ const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd") @export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var test_node_path := ^"hello" # Enums. -@export var test_side: Side -@export var test_atm: AutoTranslateMode +@export var test_side_weak = SIDE_LEFT +@export var test_atm_weak = AUTO_TRANSLATE_MODE_INHERIT +@export var test_custom_enum_weak = CustomEnum.A + +@export var test_side_hard: Side +@export var test_atm_hard: AutoTranslateMode +@export var test_custom_enum_hard: CustomEnum + +var test_side_weak_no_export = SIDE_LEFT +var test_atm_weak_no_export = AUTO_TRANSLATE_MODE_INHERIT +var test_custom_enum_weak_no_export = CustomEnum.A + +var test_side_hard_no_export: Side +var test_atm_hard_no_export: AutoTranslateMode +var test_custom_enum_hard_no_export: CustomEnum # Resources and nodes. @export var test_image: Image diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out index c0bf4d6e06..00dbe74f1e 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.out +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out @@ -15,10 +15,30 @@ var test_color_no_alpha: Color = Color(0, 0, 0, 1) hint=COLOR_NO_ALPHA hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" var test_node_path: NodePath = NodePath("hello") hint=NODE_PATH_VALID_TYPES hint_string="Sprite2D,Sprite3D,Control,Node" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" -var test_side: Side = 0 +var test_side_weak: Side = 0 hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side" -var test_atm: Node.AutoTranslateMode = 0 +var test_atm_weak: Node.AutoTranslateMode = 0 hint=ENUM hint_string="Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.AutoTranslateMode" +var test_custom_enum_weak: ExportVariableTest.CustomEnum = 0 + hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"ExportVariableTest.CustomEnum" +var test_side_hard: Side = 0 + hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side" +var test_atm_hard: Node.AutoTranslateMode = 0 + hint=ENUM hint_string="Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.AutoTranslateMode" +var test_custom_enum_hard: ExportVariableTest.CustomEnum = 0 + hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"ExportVariableTest.CustomEnum" +var test_side_weak_no_export: Variant = 0 + hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=SCRIPT_VARIABLE|NIL_IS_VARIANT class_name=&"" +var test_atm_weak_no_export: Variant = 0 + hint=ENUM hint_string="Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=SCRIPT_VARIABLE|NIL_IS_VARIANT class_name=&"" +var test_custom_enum_weak_no_export: Variant = 0 + hint=ENUM hint_string="A:0,B:1,C:2" usage=SCRIPT_VARIABLE|NIL_IS_VARIANT class_name=&"" +var test_side_hard_no_export: Side = 0 + hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side" +var test_atm_hard_no_export: Node.AutoTranslateMode = 0 + hint=ENUM hint_string="Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.AutoTranslateMode" +var test_custom_enum_hard_no_export: ExportVariableTest.CustomEnum = 0 + hint=ENUM hint_string="A:0,B:1,C:2" usage=SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"ExportVariableTest.CustomEnum" var test_image: Image = null hint=RESOURCE_TYPE hint_string="Image" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Image" var test_timer: Timer = null diff --git a/scene/debugger/scene_debugger_object.cpp b/scene/debugger/scene_debugger_object.cpp index 0323f727aa..e922d1e573 100644 --- a/scene/debugger/scene_debugger_object.cpp +++ b/scene/debugger/scene_debugger_object.cpp @@ -109,6 +109,7 @@ void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInsta } HashSet exported_members; + HashMap non_exported_members; if (p_instance) { List pinfo; @@ -116,6 +117,10 @@ void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInsta for (const PropertyInfo &E : pinfo) { if (E.usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { exported_members.insert(E.name); + } else { + PropertyInfo pi = E; + pi.usage |= PROPERTY_USAGE_EDITOR; + non_exported_members.insert(E.name, pi); } } } @@ -132,8 +137,17 @@ void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInsta Variant m; if (p_instance->get(E, m)) { - String script_path = sm.key == p_script ? "" : sm.key->get_path().get_file() + "/"; - PropertyInfo pi(m.get_type(), "Members/" + script_path + E); + const String script_path = sm.key == p_script ? "" : sm.key->get_path().get_file() + "/"; + + PropertyInfo pi; + const PropertyInfo *pi_ptr = non_exported_members.getptr(E); + if (pi_ptr == nullptr) { + pi.type = m.get_type(); + } else { + pi = *pi_ptr; + } + pi.name = "Members/" + script_path + E; + properties.push_back(SceneDebuggerProperty(pi, m)); } }