Merge pull request #82122 from dalexeev/gds-add-export-hidden-annotation
GDScript: Add `@export_storage` annotation
This commit is contained in:
commit
21ee3716c2
16 changed files with 178 additions and 109 deletions
|
@ -597,6 +597,17 @@
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
</description>
|
</description>
|
||||||
</annotation>
|
</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">
|
<annotation name="@export_subgroup">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="name" type="String" />
|
<param index="0" name="name" type="String" />
|
||||||
|
|
|
@ -101,6 +101,7 @@ GDScriptParser::GDScriptParser() {
|
||||||
register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
|
register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
|
||||||
// Export annotations.
|
// Export annotations.
|
||||||
register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
|
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_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_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>);
|
register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>);
|
||||||
|
@ -4085,11 +4086,11 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
|
||||||
}
|
}
|
||||||
hint_string += arg_string;
|
hint_string += arg_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable->export_info.hint_string = hint_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.
|
// This is called after the analyzer is done finding the type, so this should be set here.
|
||||||
DataType export_type = variable->get_datatype();
|
DataType export_type = variable->get_datatype();
|
||||||
|
bool use_default_variable_type_check = true;
|
||||||
|
|
||||||
if (p_annotation->name == SNAME("@export_range")) {
|
if (p_annotation->name == SNAME("@export_range")) {
|
||||||
if (export_type.builtin_type == Variant::INT) {
|
if (export_type.builtin_type == Variant::INT) {
|
||||||
|
@ -4121,11 +4122,9 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
|
||||||
|
|
||||||
return true;
|
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) {
|
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);
|
push_error(R"(Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation);
|
||||||
return false;
|
return false;
|
||||||
|
@ -4243,6 +4242,8 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
|
||||||
variable->export_info.type = Variant::ARRAY;
|
variable->export_info.type = Variant::ARRAY;
|
||||||
}
|
}
|
||||||
} else if (p_annotation->name == SNAME("@export_enum")) {
|
} else if (p_annotation->name == SNAME("@export_enum")) {
|
||||||
|
use_default_variable_type_check = false;
|
||||||
|
|
||||||
Variant::Type enum_type = Variant::INT;
|
Variant::Type enum_type = Variant::INT;
|
||||||
|
|
||||||
if (export_type.kind == DataType::BUILTIN && export_type.builtin_type == Variant::STRING) {
|
if (export_type.kind == DataType::BUILTIN && export_type.builtin_type == Variant::STRING) {
|
||||||
|
@ -4260,7 +4261,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);
|
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;
|
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.
|
// Validate variable type with export.
|
||||||
if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != t_type)) {
|
if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != t_type)) {
|
||||||
// Allow float/int conversion.
|
// Allow float/int conversion.
|
||||||
|
|
|
@ -4,14 +4,13 @@ enum MyEnum {A, B, C}
|
||||||
|
|
||||||
const Utils = preload("../../utils.notest.gd")
|
const Utils = preload("../../utils.notest.gd")
|
||||||
|
|
||||||
@export var x1 = MyEnum
|
@export var test_1 = MyEnum
|
||||||
@export var x2 = MyEnum.A
|
@export var test_2 = MyEnum.A
|
||||||
@export var x3 := MyEnum
|
@export var test_3 := MyEnum
|
||||||
@export var x4 := MyEnum.A
|
@export var test_4 := MyEnum.A
|
||||||
@export var x5: MyEnum
|
@export var test_5: MyEnum
|
||||||
|
|
||||||
func test():
|
func test():
|
||||||
for property in get_property_list():
|
for property in get_property_list():
|
||||||
if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE:
|
if str(property.name).begins_with("test_"):
|
||||||
print(Utils.get_property_signature(property))
|
Utils.print_property_extended_info(property)
|
||||||
print(" ", Utils.get_property_additional_info(property))
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
@export var x1: Dictionary
|
var test_1: Dictionary
|
||||||
hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
|
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
|
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
|
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
|
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
|
hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
|
||||||
|
|
|
@ -1,48 +1,49 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
@export_enum("A", "B", "C") var a0
|
const Utils = preload("../../utils.notest.gd")
|
||||||
@export_enum("A", "B", "C",) var a1
|
|
||||||
|
@export_enum("A", "B", "C") var test_1
|
||||||
|
@export_enum("A", "B", "C",) var test_2
|
||||||
|
|
||||||
@export_enum(
|
@export_enum(
|
||||||
"A",
|
"A",
|
||||||
"B",
|
"B",
|
||||||
"C"
|
"C"
|
||||||
) var a2
|
) var test_3
|
||||||
|
|
||||||
@export_enum(
|
@export_enum(
|
||||||
"A",
|
"A",
|
||||||
"B",
|
"B",
|
||||||
"C",
|
"C",
|
||||||
) var a3
|
) var test_4
|
||||||
|
|
||||||
@export
|
@export
|
||||||
var a4: int
|
var test_5: int
|
||||||
|
|
||||||
@export()
|
@export()
|
||||||
var a5: int
|
var test_6: int
|
||||||
|
|
||||||
@export() var a6: int
|
@export() var test_7: int = 42
|
||||||
@warning_ignore("onready_with_export") @onready @export var a7: int
|
@warning_ignore("onready_with_export") @onready @export var test_8: int = 42
|
||||||
@warning_ignore("onready_with_export") @onready() @export() var a8: int
|
@warning_ignore("onready_with_export") @onready() @export() var test_9: int = 42
|
||||||
|
|
||||||
@warning_ignore("onready_with_export")
|
@warning_ignore("onready_with_export")
|
||||||
@onready
|
@onready
|
||||||
@export
|
@export
|
||||||
var a9: int
|
var test_10: int = 42
|
||||||
|
|
||||||
@warning_ignore("onready_with_export")
|
@warning_ignore("onready_with_export")
|
||||||
@onready()
|
@onready()
|
||||||
@export()
|
@export()
|
||||||
var a10: int
|
var test_11: int = 42
|
||||||
|
|
||||||
@warning_ignore("onready_with_export")
|
@warning_ignore("onready_with_export")
|
||||||
@onready()
|
@onready()
|
||||||
@export()
|
@export()
|
||||||
|
|
||||||
var a11: int
|
var test_12: int = 42
|
||||||
|
|
||||||
|
|
||||||
func test():
|
func test():
|
||||||
for property in get_property_list():
|
for property in get_property_list():
|
||||||
if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE:
|
if str(property.name).begins_with("test_"):
|
||||||
print(property)
|
Utils.print_property_extended_info(property, self)
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
{ "name": "a0", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
|
var test_1: int = null
|
||||||
{ "name": "a1", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
|
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "a2", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
|
var test_2: int = null
|
||||||
{ "name": "a3", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 }
|
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "a4", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
var test_3: int = null
|
||||||
{ "name": "a5", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "a6", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
var test_4: int = null
|
||||||
{ "name": "a7", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "a8", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
var test_5: int = 0
|
||||||
{ "name": "a9", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "a10", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
var test_6: int = 0
|
||||||
{ "name": "a11", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
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
|
||||||
|
|
|
@ -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 test_untyped
|
||||||
@export_enum("Red", "Green", "Blue") var weak_string = ""
|
|
||||||
|
|
||||||
@export_enum("Red", "Green", "Blue") var hard_int: int
|
@export_enum("Red", "Green", "Blue") var test_weak_int = 0
|
||||||
@export_enum("Red", "Green", "Blue") var hard_string: String
|
@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():
|
func test():
|
||||||
for property in get_property_list():
|
for property in get_property_list():
|
||||||
if property.name in ["untyped", "weak_int", "weak_string", "hard_int",
|
if str(property.name).begins_with("test_"):
|
||||||
"hard_string", "with_values"]:
|
Utils.print_property_extended_info(property, self)
|
||||||
prints(property.name, property.type, property.hint_string)
|
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
untyped 2 Red,Green,Blue
|
var test_untyped: int = null
|
||||||
weak_int 2 Red,Green,Blue
|
hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
weak_string 4 Red,Green,Blue
|
var test_weak_int: int = 0
|
||||||
hard_int 2 Red,Green,Blue
|
hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
hard_string 4 Red,Green,Blue
|
var test_weak_string: String = ""
|
||||||
with_values 2 Red:10,Green:20,Blue:30
|
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
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
@export var example = 99
|
const Utils = preload("../../utils.notest.gd")
|
||||||
@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
|
|
||||||
|
|
||||||
@export var color: Color
|
@export var test_weak_int = 1
|
||||||
@export_color_no_alpha var color_no_alpha: Color
|
@export var test_hard_int: int = 2
|
||||||
@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var nodepath := ^"hello"
|
@export_storage var test_storage_untyped
|
||||||
@export var node: Node
|
@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`.
|
||||||
@export var node_array: Array[Node]
|
@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():
|
func test():
|
||||||
print(example)
|
for property in get_property_list():
|
||||||
print(example_range)
|
if str(property.name).begins_with("test_"):
|
||||||
print(example_range_step)
|
Utils.print_property_extended_info(property, self)
|
||||||
print(example_range_step_or_greater)
|
|
||||||
print(color)
|
|
||||||
print(color_no_alpha)
|
|
||||||
print(nodepath)
|
|
||||||
print(node)
|
|
||||||
print(var_to_str(node_array))
|
|
||||||
|
|
|
@ -1,10 +1,27 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
99
|
var test_weak_int: int = 1
|
||||||
100
|
hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
101
|
var test_hard_int: int = 2
|
||||||
102
|
hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
(0, 0, 0, 1)
|
var test_storage_untyped: Variant = null
|
||||||
(0, 0, 0, 1)
|
hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
|
||||||
hello
|
var test_storage_weak_int: Variant = 3
|
||||||
<null>
|
hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
|
||||||
Array[Node]([])
|
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
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
extends RefCounted # TODO: Fix standalone annotations parsing.
|
const Utils = preload("../../utils.notest.gd")
|
||||||
|
|
||||||
# GH-73843
|
# GH-73843
|
||||||
@export_group("Resource")
|
@export_group("Resource")
|
||||||
|
|
||||||
# GH-78252
|
# GH-78252
|
||||||
@export var prop_1: int
|
@export var test_1: int
|
||||||
@export_category("prop_1")
|
@export_category("test_1")
|
||||||
@export var prop_2: int
|
@export var test_2: int
|
||||||
|
|
||||||
func test():
|
func test():
|
||||||
var resource := Resource.new()
|
var resource := Resource.new()
|
||||||
prints("Not shadowed:", resource.get_class())
|
prints("Not shadowed:", resource.get_class())
|
||||||
|
|
||||||
for property in get_property_list():
|
for property in get_property_list():
|
||||||
if property.name in ["prop_1", "prop_2"]:
|
if str(property.name).begins_with("test_"):
|
||||||
print(property)
|
Utils.print_property_extended_info(property, self)
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
GDTEST_OK
|
GDTEST_OK
|
||||||
Not shadowed: Resource
|
Not shadowed: Resource
|
||||||
{ "name": "prop_1", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
var test_1: int = 0
|
||||||
{ "name": "prop_1", "class_name": &"", "type": 0, "hint": 0, "hint_string": "", "usage": 128 }
|
hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
{ "name": "prop_2", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 }
|
@export_category("test_1")
|
||||||
|
hint=NONE hint_string="" usage=CATEGORY
|
||||||
|
var test_2: int = 0
|
||||||
|
hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
|
||||||
|
|
|
@ -60,7 +60,7 @@ func test():
|
||||||
var script: Script = get_script()
|
var script: Script = get_script()
|
||||||
for property in script.get_property_list():
|
for property in script.get_property_list():
|
||||||
if str(property.name).begins_with("test_"):
|
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():
|
for property in get_property_list():
|
||||||
if str(property.name).begins_with("test_"):
|
if str(property.name).begins_with("test_"):
|
||||||
print(Utils.get_property_signature(property))
|
print(Utils.get_property_signature(property))
|
||||||
|
|
|
@ -6,13 +6,13 @@ static var test_static_var_hard_int: int
|
||||||
var test_var_untyped: Variant
|
var test_var_untyped: Variant
|
||||||
var test_var_weak_null: Variant
|
var test_var_weak_null: Variant
|
||||||
var test_var_weak_int: 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
|
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_variant: Variant
|
||||||
var test_var_hard_int: int
|
var test_var_hard_int: int
|
||||||
var test_var_hard_variant_type: Variant.Type
|
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_node_process_mode: Node.ProcessMode
|
||||||
var test_var_hard_my_enum: TestMemberInfo.MyEnum
|
var test_var_hard_my_enum: TestMemberInfo.MyEnum
|
||||||
var test_var_hard_array: Array
|
var test_var_hard_array: Array
|
||||||
|
|
|
@ -30,7 +30,7 @@ func test():
|
||||||
var b := B.new()
|
var b := B.new()
|
||||||
for property in (B as GDScript).get_property_list():
|
for property in (B as GDScript).get_property_list():
|
||||||
if str(property.name).begins_with("test_"):
|
if str(property.name).begins_with("test_"):
|
||||||
print(Utils.get_property_signature(property, true))
|
print(Utils.get_property_signature(property, null, true))
|
||||||
print("---")
|
print("---")
|
||||||
for property in b.get_property_list():
|
for property in b.get_property_list():
|
||||||
if str(property.name).begins_with("test_"):
|
if str(property.name).begins_with("test_"):
|
||||||
|
|
|
@ -20,24 +20,32 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String:
|
||||||
return type_string(property.type)
|
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 = ""
|
var result: String = ""
|
||||||
if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
|
if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
|
||||||
printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.")
|
printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.")
|
||||||
if property.usage & PROPERTY_USAGE_DEFAULT:
|
|
||||||
result += "@export "
|
|
||||||
if is_static:
|
if is_static:
|
||||||
result += "static "
|
result += "static "
|
||||||
result += "var " + property.name + ": " + get_type(property)
|
result += "var " + property.name + ": " + get_type(property)
|
||||||
|
if is_instance_valid(base):
|
||||||
|
result += " = " + var_to_str(base.get(property.name))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
static func get_property_additional_info(property: Dictionary) -> String:
|
static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void:
|
||||||
return 'hint=%s hint_string="%s" usage=%s' % [
|
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_"),
|
get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
|
||||||
str(property.hint_string).c_escape(),
|
str(property.hint_string).c_escape(),
|
||||||
get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
|
get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
|
||||||
]
|
])
|
||||||
|
|
||||||
|
|
||||||
static func get_method_signature(method: Dictionary, is_signal: bool = false) -> String:
|
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"
|
return "PROPERTY_USAGE_NONE"
|
||||||
|
|
||||||
const FLAGS: Array[Array] = [
|
const FLAGS: Array[Array] = [
|
||||||
[PROPERTY_USAGE_DEFAULT, "PROPERTY_USAGE_DEFAULT"],
|
|
||||||
[PROPERTY_USAGE_STORAGE, "PROPERTY_USAGE_STORAGE"],
|
[PROPERTY_USAGE_STORAGE, "PROPERTY_USAGE_STORAGE"],
|
||||||
[PROPERTY_USAGE_EDITOR, "PROPERTY_USAGE_EDITOR"],
|
[PROPERTY_USAGE_EDITOR, "PROPERTY_USAGE_EDITOR"],
|
||||||
[PROPERTY_USAGE_INTERNAL, "PROPERTY_USAGE_INTERNAL"],
|
[PROPERTY_USAGE_INTERNAL, "PROPERTY_USAGE_INTERNAL"],
|
||||||
|
@ -187,6 +194,10 @@ static func get_property_usage_string(usage: int) -> String:
|
||||||
|
|
||||||
var result: String = ""
|
var result: String = ""
|
||||||
|
|
||||||
|
if (usage & PROPERTY_USAGE_DEFAULT) == PROPERTY_USAGE_DEFAULT:
|
||||||
|
result += "PROPERTY_USAGE_DEFAULT|"
|
||||||
|
usage &= ~PROPERTY_USAGE_DEFAULT
|
||||||
|
|
||||||
for flag in FLAGS:
|
for flag in FLAGS:
|
||||||
if usage & flag[0]:
|
if usage & flag[0]:
|
||||||
result += flag[1] + "|"
|
result += flag[1] + "|"
|
||||||
|
|
Loading…
Reference in a new issue