Forráskód Böngészése

GDScript: Add `@export_storage` annotation

Danil Alexeev 1 éve
szülő
commit
3a3a2011f4

+ 11 - 0
modules/gdscript/doc_classes/@GDScript.xml

@@ -598,6 +598,17 @@
 				[/codeblock]
 			</description>
 		</annotation>
+		<annotation name="@export_storage">
+			<return type="void" />
+			<description>
+				Export a property with [constant PROPERTY_USAGE_STORAGE] flag. The property is not displayed in the editor, but it is serialized and stored in the scene or resource file. This can be useful for [annotation @tool] scripts. Also the property value is copied when [method Resource.duplicate] or [method Node.duplicate] is called, unlike non-exported variables.
+				[codeblock]
+				var a # Not stored in the file, not displayed in the editor.
+				@export_storage var b # Stored in the file, not displayed in the editor.
+				@export var c: int # Stored in the file, displayed in the editor.
+				[/codeblock]
+			</description>
+		</annotation>
 		<annotation name="@export_subgroup">
 			<return type="void" />
 			<param index="0" name="name" type="String" />

+ 15 - 6
modules/gdscript/gdscript_parser.cpp

@@ -100,6 +100,7 @@ GDScriptParser::GDScriptParser() {
 		register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
 		// Export annotations.
 		register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
+		register_annotation(MethodInfo("@export_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
 		register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::NIL>, varray(), true);
 		register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, varray(""), true);
 		register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>);
@@ -3996,11 +3997,11 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
 		}
 		hint_string += arg_string;
 	}
-
 	variable->export_info.hint_string = hint_string;
 
 	// This is called after the analyzer is done finding the type, so this should be set here.
 	DataType export_type = variable->get_datatype();
+	bool use_default_variable_type_check = true;
 
 	if (p_annotation->name == SNAME("@export_range")) {
 		if (export_type.builtin_type == Variant::INT) {
@@ -4032,11 +4033,9 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
 
 			return true;
 		}
-	}
+	} else if (p_annotation->name == SNAME("@export")) {
+		use_default_variable_type_check = false;
 
-	// WARNING: Do not merge with the previous `else if`! Otherwise `else` (default variable type check)
-	// will not work for the above annotations. `@export` and `@export_enum` validate the type separately.
-	if (p_annotation->name == SNAME("@export")) {
 		if (variable->datatype_specifier == nullptr && variable->initializer == nullptr) {
 			push_error(R"(Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation);
 			return false;
@@ -4154,6 +4153,8 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
 			variable->export_info.type = Variant::ARRAY;
 		}
 	} else if (p_annotation->name == SNAME("@export_enum")) {
+		use_default_variable_type_check = false;
+
 		Variant::Type enum_type = Variant::INT;
 
 		if (export_type.kind == DataType::BUILTIN && export_type.builtin_type == Variant::STRING) {
@@ -4171,7 +4172,15 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
 			push_error(vformat(R"("@export_enum" annotation requires a variable of type "int" or "String" but type "%s" was given instead.)", export_type.to_string()), variable);
 			return false;
 		}
-	} else {
+	} else if (p_annotation->name == SNAME("@export_storage")) {
+		use_default_variable_type_check = false; // Can be applied to a variable of any type.
+
+		// Save the info because the compiler uses export info for overwriting member info.
+		variable->export_info = export_type.to_property_info(variable->identifier->name);
+		variable->export_info.usage |= PROPERTY_USAGE_STORAGE;
+	}
+
+	if (use_default_variable_type_check) {
 		// Validate variable type with export.
 		if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != t_type)) {
 			// Allow float/int conversion.

+ 7 - 8
modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd

@@ -4,14 +4,13 @@ enum MyEnum {A, B, C}
 
 const Utils = preload("../../utils.notest.gd")
 
-@export var x1 = MyEnum
-@export var x2 = MyEnum.A
-@export var x3 := MyEnum
-@export var x4 := MyEnum.A
-@export var x5: MyEnum
+@export var test_1 = MyEnum
+@export var test_2 = MyEnum.A
+@export var test_3 := MyEnum
+@export var test_4 := MyEnum.A
+@export var test_5: MyEnum
 
 func test():
 	for property in get_property_list():
-		if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE:
-			print(Utils.get_property_signature(property))
-			print("  ", Utils.get_property_additional_info(property))
+		if str(property.name).begins_with("test_"):
+			Utils.print_property_extended_info(property)

+ 5 - 5
modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out

@@ -1,11 +1,11 @@
 GDTEST_OK
-@export var x1: Dictionary
+var test_1: Dictionary
   hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
-@export var x2: TestExportEnumAsDictionary.MyEnum
+var test_2: TestExportEnumAsDictionary.MyEnum
   hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
-@export var x3: Dictionary
+var test_3: Dictionary
   hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
-@export var x4: TestExportEnumAsDictionary.MyEnum
+var test_4: TestExportEnumAsDictionary.MyEnum
   hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
-@export var x5: TestExportEnumAsDictionary.MyEnum
+var test_5: TestExportEnumAsDictionary.MyEnum
   hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM

+ 16 - 15
modules/gdscript/tests/scripts/parser/features/annotations.gd

@@ -1,48 +1,49 @@
 extends Node
 
-@export_enum("A", "B", "C") var a0
-@export_enum("A", "B", "C",) var a1
+const Utils = preload("../../utils.notest.gd")
+
+@export_enum("A", "B", "C") var test_1
+@export_enum("A", "B", "C",) var test_2
 
 @export_enum(
 	"A",
 	"B",
 	"C"
-) var a2
+) var test_3
 
 @export_enum(
 	"A",
 	"B",
 	"C",
-) var a3
+) var test_4
 
 @export
-var a4: int
+var test_5: int
 
 @export()
-var a5: int
+var test_6: int
 
-@export() var a6: int
-@warning_ignore("onready_with_export") @onready @export var a7: int
-@warning_ignore("onready_with_export") @onready() @export() var a8: int
+@export() var test_7: int = 42
+@warning_ignore("onready_with_export") @onready @export var test_8: int = 42
+@warning_ignore("onready_with_export") @onready() @export() var test_9: int = 42
 
 @warning_ignore("onready_with_export")
 @onready
 @export
-var a9: int
+var test_10: int = 42
 
 @warning_ignore("onready_with_export")
 @onready()
 @export()
-var a10: int
+var test_11: int = 42
 
 @warning_ignore("onready_with_export")
 @onready()
 @export()
 
-var a11: int
-
+var test_12: int = 42
 
 func test():
 	for property in get_property_list():
-		if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE:
-			print(property)
+		if str(property.name).begins_with("test_"):
+			Utils.print_property_extended_info(property, self)

+ 24 - 12
modules/gdscript/tests/scripts/parser/features/annotations.out

@@ -1,13 +1,25 @@
 GDTEST_OK
-{ "name": "a0", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
-{ "name": "a1", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
-{ "name": "a2", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
-{ "name": "a3", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
-{ "name": "a4", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a5", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a6", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a7", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a8", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a9", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a10", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "a11", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+var test_1: int = null
+  hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+var test_2: int = null
+  hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+var test_3: int = null
+  hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+var test_4: int = null
+  hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+var test_5: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_6: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_7: int = 42
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_8: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_9: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_10: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_11: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_12: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE

+ 10 - 9
modules/gdscript/tests/scripts/parser/features/export_enum.gd

@@ -1,15 +1,16 @@
-@export_enum("Red", "Green", "Blue") var untyped
+const Utils = preload("../../utils.notest.gd")
 
-@export_enum("Red", "Green", "Blue") var weak_int = 0
-@export_enum("Red", "Green", "Blue") var weak_string = ""
+@export_enum("Red", "Green", "Blue") var test_untyped
 
-@export_enum("Red", "Green", "Blue") var hard_int: int
-@export_enum("Red", "Green", "Blue") var hard_string: String
+@export_enum("Red", "Green", "Blue") var test_weak_int = 0
+@export_enum("Red", "Green", "Blue") var test_weak_string = ""
 
-@export_enum("Red:10", "Green:20", "Blue:30") var with_values
+@export_enum("Red", "Green", "Blue") var test_hard_int: int
+@export_enum("Red", "Green", "Blue") var test_hard_string: String
+
+@export_enum("Red:10", "Green:20", "Blue:30") var test_with_values
 
 func test():
 	for property in get_property_list():
-		if property.name in ["untyped", "weak_int", "weak_string", "hard_int",
-				"hard_string", "with_values"]:
-			prints(property.name, property.type, property.hint_string)
+		if str(property.name).begins_with("test_"):
+			Utils.print_property_extended_info(property, self)

+ 12 - 6
modules/gdscript/tests/scripts/parser/features/export_enum.out

@@ -1,7 +1,13 @@
 GDTEST_OK
-untyped 2 Red,Green,Blue
-weak_int 2 Red,Green,Blue
-weak_string 4 Red,Green,Blue
-hard_int 2 Red,Green,Blue
-hard_string 4 Red,Green,Blue
-with_values 2 Red:10,Green:20,Blue:30
+var test_untyped: int = null
+  hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+var test_weak_int: int = 0
+  hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+var test_weak_string: String = ""
+  hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+var test_hard_int: int = 0
+  hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+var test_hard_string: String = ""
+  hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+var test_with_values: int = null
+  hint=ENUM hint_string="Red:10,Green:20,Blue:30" usage=DEFAULT|SCRIPT_VARIABLE

+ 17 - 18
modules/gdscript/tests/scripts/parser/features/export_variable.gd

@@ -1,23 +1,22 @@
 extends Node
 
-@export var example = 99
-@export_range(0, 100) var example_range = 100
-@export_range(0, 100, 1) var example_range_step = 101
-@export_range(0, 100, 1, "or_greater") var example_range_step_or_greater = 102
+const Utils = preload("../../utils.notest.gd")
 
-@export var color: Color
-@export_color_no_alpha var color_no_alpha: Color
-@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var nodepath := ^"hello"
-@export var node: Node
-@export var node_array: Array[Node]
+@export var test_weak_int = 1
+@export var test_hard_int: int = 2
+@export_storage var test_storage_untyped
+@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`.
+@export_storage var test_storage_hard_int: int = 4
+@export_range(0, 100) var test_range = 100
+@export_range(0, 100, 1) var test_range_step = 101
+@export_range(0, 100, 1, "or_greater") var test_range_step_or_greater = 102
+@export var test_color: Color
+@export_color_no_alpha var test_color_no_alpha: Color
+@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var test_node_path := ^"hello"
+@export var test_node: Node
+@export var test_node_array: Array[Node]
 
 func test():
-	print(example)
-	print(example_range)
-	print(example_range_step)
-	print(example_range_step_or_greater)
-	print(color)
-	print(color_no_alpha)
-	print(nodepath)
-	print(node)
-	print(var_to_str(node_array))
+	for property in get_property_list():
+		if str(property.name).begins_with("test_"):
+			Utils.print_property_extended_info(property, self)

+ 26 - 9
modules/gdscript/tests/scripts/parser/features/export_variable.out

@@ -1,10 +1,27 @@
 GDTEST_OK
-99
-100
-101
-102
-(0, 0, 0, 1)
-(0, 0, 0, 1)
-hello
-<null>
-Array[Node]([])
+var test_weak_int: int = 1
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_hard_int: int = 2
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+var test_storage_untyped: Variant = null
+  hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
+var test_storage_weak_int: Variant = 3
+  hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
+var test_storage_hard_int: int = 4
+  hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE
+var test_range: int = 100
+  hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE
+var test_range_step: int = 101
+  hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE
+var test_range_step_or_greater: int = 102
+  hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE
+var test_color: Color = Color(0, 0, 0, 1)
+  hint=NONE hint_string="Color" usage=DEFAULT|SCRIPT_VARIABLE
+var test_color_no_alpha: Color = Color(0, 0, 0, 1)
+  hint=COLOR_NO_ALPHA hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
+var test_node_path: NodePath = NodePath("hello")
+  hint=NODE_PATH_VALID_TYPES hint_string="Sprite2D,Sprite3D,Control,Node" usage=DEFAULT|SCRIPT_VARIABLE
+var test_node: Node = null
+  hint=NODE_TYPE hint_string="Node" usage=DEFAULT|SCRIPT_VARIABLE
+var test_node_array: Array = Array[Node]([])
+  hint=TYPE_STRING hint_string="24/34:Node" usage=DEFAULT|SCRIPT_VARIABLE

+ 6 - 6
modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd

@@ -1,17 +1,17 @@
-extends RefCounted # TODO: Fix standalone annotations parsing.
+const Utils = preload("../../utils.notest.gd")
 
 # GH-73843
 @export_group("Resource")
 
 # GH-78252
-@export var prop_1: int
-@export_category("prop_1")
-@export var prop_2: int
+@export var test_1: int
+@export_category("test_1")
+@export var test_2: int
 
 func test():
 	var resource := Resource.new()
 	prints("Not shadowed:", resource.get_class())
 
 	for property in get_property_list():
-		if property.name in ["prop_1", "prop_2"]:
-			print(property)
+		if str(property.name).begins_with("test_"):
+			Utils.print_property_extended_info(property, self)

+ 6 - 3
modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out

@@ -1,5 +1,8 @@
 GDTEST_OK
 Not shadowed: Resource
-{ "name": "prop_1", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
-{ "name": "prop_1", "class_name": &"", "type": 0, "hint": 0, "hint_string": "", "usage": 128 }
-{ "name": "prop_2", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
+var test_1: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+@export_category("test_1")
+  hint=NONE hint_string="" usage=CATEGORY
+var test_2: int = 0
+  hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE

+ 1 - 1
modules/gdscript/tests/scripts/runtime/features/member_info.gd

@@ -60,7 +60,7 @@ func test():
 	var script: Script = get_script()
 	for property in script.get_property_list():
 		if str(property.name).begins_with("test_"):
-			print(Utils.get_property_signature(property, true))
+			print(Utils.get_property_signature(property, null, true))
 	for property in get_property_list():
 		if str(property.name).begins_with("test_"):
 			print(Utils.get_property_signature(property))

+ 3 - 3
modules/gdscript/tests/scripts/runtime/features/member_info.out

@@ -6,13 +6,13 @@ static var test_static_var_hard_int: int
 var test_var_untyped: Variant
 var test_var_weak_null: Variant
 var test_var_weak_int: Variant
-@export var test_var_weak_int_exported: int
+var test_var_weak_int_exported: int
 var test_var_weak_variant_type: Variant
-@export var test_var_weak_variant_type_exported: Variant.Type
+var test_var_weak_variant_type_exported: Variant.Type
 var test_var_hard_variant: Variant
 var test_var_hard_int: int
 var test_var_hard_variant_type: Variant.Type
-@export var test_var_hard_variant_type_exported: Variant.Type
+var test_var_hard_variant_type_exported: Variant.Type
 var test_var_hard_node_process_mode: Node.ProcessMode
 var test_var_hard_my_enum: TestMemberInfo.MyEnum
 var test_var_hard_array: Array

+ 1 - 1
modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd

@@ -30,7 +30,7 @@ func test():
 	var b := B.new()
 	for property in (B as GDScript).get_property_list():
 		if str(property.name).begins_with("test_"):
-			print(Utils.get_property_signature(property, true))
+			print(Utils.get_property_signature(property, null, true))
 	print("---")
 	for property in b.get_property_list():
 		if str(property.name).begins_with("test_"):

+ 18 - 7
modules/gdscript/tests/scripts/utils.notest.gd

@@ -20,24 +20,32 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String:
 	return type_string(property.type)
 
 
-static func get_property_signature(property: Dictionary, is_static: bool = false) -> String:
+static func get_property_signature(property: Dictionary, base: Object = null, is_static: bool = false) -> String:
+	if property.usage & PROPERTY_USAGE_CATEGORY:
+		return '@export_category("%s")' % str(property.name).c_escape()
+	if property.usage & PROPERTY_USAGE_GROUP:
+		return '@export_group("%s")' % str(property.name).c_escape()
+	if property.usage & PROPERTY_USAGE_SUBGROUP:
+		return '@export_subgroup("%s")' % str(property.name).c_escape()
+
 	var result: String = ""
 	if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
 		printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.")
-	if property.usage & PROPERTY_USAGE_DEFAULT:
-		result += "@export "
 	if is_static:
 		result += "static "
 	result += "var " + property.name + ": " + get_type(property)
+	if is_instance_valid(base):
+		result += " = " + var_to_str(base.get(property.name))
 	return result
 
 
-static func get_property_additional_info(property: Dictionary) -> String:
-	return 'hint=%s hint_string="%s" usage=%s' % [
+static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void:
+	print(get_property_signature(property, base, is_static))
+	print('  hint=%s hint_string="%s" usage=%s' % [
 		get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
 		str(property.hint_string).c_escape(),
 		get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
-	]
+	])
 
 
 static func get_method_signature(method: Dictionary, is_signal: bool = false) -> String:
@@ -153,7 +161,6 @@ static func get_property_usage_string(usage: int) -> String:
 		return "PROPERTY_USAGE_NONE"
 
 	const FLAGS: Array[Array] = [
-		[PROPERTY_USAGE_DEFAULT, "PROPERTY_USAGE_DEFAULT"],
 		[PROPERTY_USAGE_STORAGE, "PROPERTY_USAGE_STORAGE"],
 		[PROPERTY_USAGE_EDITOR, "PROPERTY_USAGE_EDITOR"],
 		[PROPERTY_USAGE_INTERNAL, "PROPERTY_USAGE_INTERNAL"],
@@ -187,6 +194,10 @@ static func get_property_usage_string(usage: int) -> String:
 
 	var result: String = ""
 
+	if (usage & PROPERTY_USAGE_DEFAULT) == PROPERTY_USAGE_DEFAULT:
+		result += "PROPERTY_USAGE_DEFAULT|"
+		usage &= ~PROPERTY_USAGE_DEFAULT
+
 	for flag in FLAGS:
 		if usage & flag[0]:
 			result += flag[1] + "|"