GDScript: Fix subscript resolution for constant non-metatypes
This commit is contained in:
parent
571cd0eb79
commit
c35cb51d74
5 changed files with 193 additions and 17 deletions
|
@ -4099,7 +4099,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
|
|||
GDScriptParser::DataType base_type = p_subscript->base->get_datatype();
|
||||
bool valid = false;
|
||||
// If the base is a metatype, use the analyzer instead.
|
||||
if (p_subscript->base->is_constant && !base_type.is_meta_type) {
|
||||
if (p_subscript->base->is_constant && !base_type.is_meta_type && base_type.kind != GDScriptParser::DataType::CLASS) {
|
||||
// Just try to get it.
|
||||
Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid);
|
||||
if (valid) {
|
||||
|
|
|
@ -4095,25 +4095,29 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
|
|||
}
|
||||
} break;
|
||||
case GDScriptParser::DataType::ENUM: {
|
||||
variable->export_info.type = Variant::INT;
|
||||
variable->export_info.hint = PROPERTY_HINT_ENUM;
|
||||
if (export_type.is_meta_type) {
|
||||
variable->export_info.type = Variant::DICTIONARY;
|
||||
} else {
|
||||
variable->export_info.type = Variant::INT;
|
||||
variable->export_info.hint = PROPERTY_HINT_ENUM;
|
||||
|
||||
String enum_hint_string;
|
||||
bool first = true;
|
||||
for (const KeyValue<StringName, int64_t> &E : export_type.enum_values) {
|
||||
if (!first) {
|
||||
enum_hint_string += ",";
|
||||
} else {
|
||||
first = false;
|
||||
String enum_hint_string;
|
||||
bool first = true;
|
||||
for (const KeyValue<StringName, int64_t> &E : export_type.enum_values) {
|
||||
if (!first) {
|
||||
enum_hint_string += ",";
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
enum_hint_string += E.key.operator String().capitalize().xml_escape();
|
||||
enum_hint_string += ":";
|
||||
enum_hint_string += String::num_int64(E.value).xml_escape();
|
||||
}
|
||||
enum_hint_string += E.key.operator String().capitalize().xml_escape();
|
||||
enum_hint_string += ":";
|
||||
enum_hint_string += String::num_int64(E.value).xml_escape();
|
||||
}
|
||||
|
||||
variable->export_info.hint_string = enum_hint_string;
|
||||
variable->export_info.usage |= PROPERTY_USAGE_CLASS_IS_ENUM;
|
||||
variable->export_info.class_name = String(export_type.native_type).replace("::", ".");
|
||||
variable->export_info.hint_string = enum_hint_string;
|
||||
variable->export_info.usage |= PROPERTY_USAGE_CLASS_IS_ENUM;
|
||||
variable->export_info.class_name = String(export_type.native_type).replace("::", ".");
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", variable);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
class_name TestExportEnumAsDictionary
|
||||
|
||||
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
|
||||
|
||||
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))
|
|
@ -0,0 +1,11 @@
|
|||
GDTEST_OK
|
||||
@export var x1: Dictionary
|
||||
hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
|
||||
@export var x2: TestExportEnumAsDictionary.MyEnum
|
||||
hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
|
||||
@export var x3: Dictionary
|
||||
hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
|
||||
@export var x4: TestExportEnumAsDictionary.MyEnum
|
||||
hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
|
||||
@export var x5: TestExportEnumAsDictionary.MyEnum
|
||||
hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM
|
|
@ -19,6 +19,7 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String:
|
|||
return property.class_name
|
||||
return variant_get_type_name(property.type)
|
||||
|
||||
|
||||
static func get_property_signature(property: Dictionary, is_static: bool = false) -> String:
|
||||
var result: String = ""
|
||||
if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
|
||||
|
@ -30,6 +31,15 @@ static func get_property_signature(property: Dictionary, is_static: bool = false
|
|||
result += "var " + property.name + ": " + get_type(property)
|
||||
return result
|
||||
|
||||
|
||||
static func get_property_additional_info(property: Dictionary) -> String:
|
||||
return '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:
|
||||
var result: String = ""
|
||||
if method.flags & METHOD_FLAG_STATIC:
|
||||
|
@ -55,6 +65,7 @@ static func get_method_signature(method: Dictionary, is_signal: bool = false) ->
|
|||
result += " -> " + get_type(method.return, true)
|
||||
return result
|
||||
|
||||
|
||||
static func variant_get_type_name(type: Variant.Type) -> String:
|
||||
match type:
|
||||
TYPE_NIL:
|
||||
|
@ -135,3 +146,136 @@ static func variant_get_type_name(type: Variant.Type) -> String:
|
|||
return "PackedColorArray"
|
||||
push_error("Argument `type` is invalid. Use `TYPE_*` constants.")
|
||||
return "<invalid type>"
|
||||
|
||||
|
||||
static func get_property_hint_name(hint: PropertyHint) -> String:
|
||||
match hint:
|
||||
PROPERTY_HINT_NONE:
|
||||
return "PROPERTY_HINT_NONE"
|
||||
PROPERTY_HINT_RANGE:
|
||||
return "PROPERTY_HINT_RANGE"
|
||||
PROPERTY_HINT_ENUM:
|
||||
return "PROPERTY_HINT_ENUM"
|
||||
PROPERTY_HINT_ENUM_SUGGESTION:
|
||||
return "PROPERTY_HINT_ENUM_SUGGESTION"
|
||||
PROPERTY_HINT_EXP_EASING:
|
||||
return "PROPERTY_HINT_EXP_EASING"
|
||||
PROPERTY_HINT_LINK:
|
||||
return "PROPERTY_HINT_LINK"
|
||||
PROPERTY_HINT_FLAGS:
|
||||
return "PROPERTY_HINT_FLAGS"
|
||||
PROPERTY_HINT_LAYERS_2D_RENDER:
|
||||
return "PROPERTY_HINT_LAYERS_2D_RENDER"
|
||||
PROPERTY_HINT_LAYERS_2D_PHYSICS:
|
||||
return "PROPERTY_HINT_LAYERS_2D_PHYSICS"
|
||||
PROPERTY_HINT_LAYERS_2D_NAVIGATION:
|
||||
return "PROPERTY_HINT_LAYERS_2D_NAVIGATION"
|
||||
PROPERTY_HINT_LAYERS_3D_RENDER:
|
||||
return "PROPERTY_HINT_LAYERS_3D_RENDER"
|
||||
PROPERTY_HINT_LAYERS_3D_PHYSICS:
|
||||
return "PROPERTY_HINT_LAYERS_3D_PHYSICS"
|
||||
PROPERTY_HINT_LAYERS_3D_NAVIGATION:
|
||||
return "PROPERTY_HINT_LAYERS_3D_NAVIGATION"
|
||||
PROPERTY_HINT_LAYERS_AVOIDANCE:
|
||||
return "PROPERTY_HINT_LAYERS_AVOIDANCE"
|
||||
PROPERTY_HINT_FILE:
|
||||
return "PROPERTY_HINT_FILE"
|
||||
PROPERTY_HINT_DIR:
|
||||
return "PROPERTY_HINT_DIR"
|
||||
PROPERTY_HINT_GLOBAL_FILE:
|
||||
return "PROPERTY_HINT_GLOBAL_FILE"
|
||||
PROPERTY_HINT_GLOBAL_DIR:
|
||||
return "PROPERTY_HINT_GLOBAL_DIR"
|
||||
PROPERTY_HINT_RESOURCE_TYPE:
|
||||
return "PROPERTY_HINT_RESOURCE_TYPE"
|
||||
PROPERTY_HINT_MULTILINE_TEXT:
|
||||
return "PROPERTY_HINT_MULTILINE_TEXT"
|
||||
PROPERTY_HINT_EXPRESSION:
|
||||
return "PROPERTY_HINT_EXPRESSION"
|
||||
PROPERTY_HINT_PLACEHOLDER_TEXT:
|
||||
return "PROPERTY_HINT_PLACEHOLDER_TEXT"
|
||||
PROPERTY_HINT_COLOR_NO_ALPHA:
|
||||
return "PROPERTY_HINT_COLOR_NO_ALPHA"
|
||||
PROPERTY_HINT_OBJECT_ID:
|
||||
return "PROPERTY_HINT_OBJECT_ID"
|
||||
PROPERTY_HINT_TYPE_STRING:
|
||||
return "PROPERTY_HINT_TYPE_STRING"
|
||||
PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE:
|
||||
return "PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE"
|
||||
PROPERTY_HINT_OBJECT_TOO_BIG:
|
||||
return "PROPERTY_HINT_OBJECT_TOO_BIG"
|
||||
PROPERTY_HINT_NODE_PATH_VALID_TYPES:
|
||||
return "PROPERTY_HINT_NODE_PATH_VALID_TYPES"
|
||||
PROPERTY_HINT_SAVE_FILE:
|
||||
return "PROPERTY_HINT_SAVE_FILE"
|
||||
PROPERTY_HINT_GLOBAL_SAVE_FILE:
|
||||
return "PROPERTY_HINT_GLOBAL_SAVE_FILE"
|
||||
PROPERTY_HINT_INT_IS_OBJECTID:
|
||||
return "PROPERTY_HINT_INT_IS_OBJECTID"
|
||||
PROPERTY_HINT_INT_IS_POINTER:
|
||||
return "PROPERTY_HINT_INT_IS_POINTER"
|
||||
PROPERTY_HINT_ARRAY_TYPE:
|
||||
return "PROPERTY_HINT_ARRAY_TYPE"
|
||||
PROPERTY_HINT_LOCALE_ID:
|
||||
return "PROPERTY_HINT_LOCALE_ID"
|
||||
PROPERTY_HINT_LOCALIZABLE_STRING:
|
||||
return "PROPERTY_HINT_LOCALIZABLE_STRING"
|
||||
PROPERTY_HINT_NODE_TYPE:
|
||||
return "PROPERTY_HINT_NODE_TYPE"
|
||||
PROPERTY_HINT_HIDE_QUATERNION_EDIT:
|
||||
return "PROPERTY_HINT_HIDE_QUATERNION_EDIT"
|
||||
PROPERTY_HINT_PASSWORD:
|
||||
return "PROPERTY_HINT_PASSWORD"
|
||||
push_error("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.")
|
||||
return "<invalid hint>"
|
||||
|
||||
|
||||
static func get_property_usage_string(usage: int) -> String:
|
||||
if usage == PROPERTY_USAGE_NONE:
|
||||
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"],
|
||||
[PROPERTY_USAGE_CHECKABLE, "PROPERTY_USAGE_CHECKABLE"],
|
||||
[PROPERTY_USAGE_CHECKED, "PROPERTY_USAGE_CHECKED"],
|
||||
[PROPERTY_USAGE_GROUP, "PROPERTY_USAGE_GROUP"],
|
||||
[PROPERTY_USAGE_CATEGORY, "PROPERTY_USAGE_CATEGORY"],
|
||||
[PROPERTY_USAGE_SUBGROUP, "PROPERTY_USAGE_SUBGROUP"],
|
||||
[PROPERTY_USAGE_CLASS_IS_BITFIELD, "PROPERTY_USAGE_CLASS_IS_BITFIELD"],
|
||||
[PROPERTY_USAGE_NO_INSTANCE_STATE, "PROPERTY_USAGE_NO_INSTANCE_STATE"],
|
||||
[PROPERTY_USAGE_RESTART_IF_CHANGED, "PROPERTY_USAGE_RESTART_IF_CHANGED"],
|
||||
[PROPERTY_USAGE_SCRIPT_VARIABLE, "PROPERTY_USAGE_SCRIPT_VARIABLE"],
|
||||
[PROPERTY_USAGE_STORE_IF_NULL, "PROPERTY_USAGE_STORE_IF_NULL"],
|
||||
[PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED, "PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED"],
|
||||
[PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE, "PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE"],
|
||||
[PROPERTY_USAGE_CLASS_IS_ENUM, "PROPERTY_USAGE_CLASS_IS_ENUM"],
|
||||
[PROPERTY_USAGE_NIL_IS_VARIANT, "PROPERTY_USAGE_NIL_IS_VARIANT"],
|
||||
[PROPERTY_USAGE_ARRAY, "PROPERTY_USAGE_ARRAY"],
|
||||
[PROPERTY_USAGE_ALWAYS_DUPLICATE, "PROPERTY_USAGE_ALWAYS_DUPLICATE"],
|
||||
[PROPERTY_USAGE_NEVER_DUPLICATE, "PROPERTY_USAGE_NEVER_DUPLICATE"],
|
||||
[PROPERTY_USAGE_HIGH_END_GFX, "PROPERTY_USAGE_HIGH_END_GFX"],
|
||||
[PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT, "PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT"],
|
||||
[PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT, "PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT"],
|
||||
[PROPERTY_USAGE_KEYING_INCREMENTS, "PROPERTY_USAGE_KEYING_INCREMENTS"],
|
||||
[PROPERTY_USAGE_DEFERRED_SET_RESOURCE, "PROPERTY_USAGE_DEFERRED_SET_RESOURCE"],
|
||||
[PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT, "PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT"],
|
||||
[PROPERTY_USAGE_EDITOR_BASIC_SETTING, "PROPERTY_USAGE_EDITOR_BASIC_SETTING"],
|
||||
[PROPERTY_USAGE_READ_ONLY, "PROPERTY_USAGE_READ_ONLY"],
|
||||
[PROPERTY_USAGE_SECRET, "PROPERTY_USAGE_SECRET"],
|
||||
]
|
||||
|
||||
var result: String = ""
|
||||
|
||||
for flag in FLAGS:
|
||||
if usage & flag[0]:
|
||||
result += flag[1] + "|"
|
||||
usage &= ~flag[0]
|
||||
|
||||
if usage != PROPERTY_USAGE_NONE:
|
||||
push_error("Argument `usage` is invalid. Use `PROPERTY_USAGE_*` constants.")
|
||||
return "<invalid usage flags>"
|
||||
|
||||
return result.left(-1)
|
||||
|
|
Loading…
Reference in a new issue