GDScript: Improve PROPERTY_HINT_{ARRAY,DICTIONARY}_TYPE handling
This commit is contained in:
@@ -5779,6 +5779,37 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_metatype(const GDScriptPars
|
||||
return result;
|
||||
}
|
||||
|
||||
GDScriptParser::DataType GDScriptAnalyzer::type_from_property_hint_string(const String &p_type_name) const {
|
||||
GDScriptParser::DataType result;
|
||||
result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||
result.is_constant = false;
|
||||
|
||||
const Variant::Type builtin_type = GDScriptParser::get_builtin_type(p_type_name);
|
||||
if (builtin_type < Variant::VARIANT_MAX) {
|
||||
// Built-in type.
|
||||
result.kind = GDScriptParser::DataType::BUILTIN;
|
||||
result.builtin_type = builtin_type;
|
||||
} else if (class_exists(p_type_name)) {
|
||||
result.kind = GDScriptParser::DataType::NATIVE;
|
||||
result.builtin_type = Variant::OBJECT;
|
||||
result.native_type = p_type_name;
|
||||
} else if (ScriptServer::is_global_class(p_type_name)) {
|
||||
// Just load this as it shouldn't be a GDScript.
|
||||
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(p_type_name));
|
||||
result.kind = GDScriptParser::DataType::SCRIPT;
|
||||
result.builtin_type = Variant::OBJECT;
|
||||
result.native_type = script->get_instance_base_type();
|
||||
result.script_type = script;
|
||||
} else if (p_type_name == SNAME("Variant")) {
|
||||
result.kind = GDScriptParser::DataType::VARIANT;
|
||||
} else {
|
||||
result.kind = GDScriptParser::DataType::VARIANT;
|
||||
ERR_FAIL_V_MSG(result, "Could not find type from property hint string.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo &p_property, bool p_is_arg, bool p_is_readonly) const {
|
||||
GDScriptParser::DataType result;
|
||||
result.is_read_only = p_is_readonly;
|
||||
@@ -5807,86 +5838,10 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
|
||||
result.kind = GDScriptParser::DataType::BUILTIN;
|
||||
result.builtin_type = p_property.type;
|
||||
if (p_property.type == Variant::ARRAY && p_property.hint == PROPERTY_HINT_ARRAY_TYPE) {
|
||||
// Check element type.
|
||||
StringName elem_type_name = p_property.hint_string;
|
||||
GDScriptParser::DataType elem_type;
|
||||
elem_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||
|
||||
Variant::Type elem_builtin_type = GDScriptParser::get_builtin_type(elem_type_name);
|
||||
if (elem_builtin_type < Variant::VARIANT_MAX) {
|
||||
// Builtin type.
|
||||
elem_type.kind = GDScriptParser::DataType::BUILTIN;
|
||||
elem_type.builtin_type = elem_builtin_type;
|
||||
} else if (class_exists(elem_type_name)) {
|
||||
elem_type.kind = GDScriptParser::DataType::NATIVE;
|
||||
elem_type.builtin_type = Variant::OBJECT;
|
||||
elem_type.native_type = elem_type_name;
|
||||
} else if (ScriptServer::is_global_class(elem_type_name)) {
|
||||
// Just load this as it shouldn't be a GDScript.
|
||||
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(elem_type_name));
|
||||
elem_type.kind = GDScriptParser::DataType::SCRIPT;
|
||||
elem_type.builtin_type = Variant::OBJECT;
|
||||
elem_type.native_type = script->get_instance_base_type();
|
||||
elem_type.script_type = script;
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(result, "Could not find element type from property hint of a typed array.");
|
||||
}
|
||||
elem_type.is_constant = false;
|
||||
result.set_container_element_type(0, elem_type);
|
||||
result.set_container_element_type(0, type_from_property_hint_string(p_property.hint_string));
|
||||
} else if (p_property.type == Variant::DICTIONARY && p_property.hint == PROPERTY_HINT_DICTIONARY_TYPE) {
|
||||
// Check element type.
|
||||
StringName key_elem_type_name = p_property.hint_string.get_slicec(';', 0);
|
||||
GDScriptParser::DataType key_elem_type;
|
||||
key_elem_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||
|
||||
Variant::Type key_elem_builtin_type = GDScriptParser::get_builtin_type(key_elem_type_name);
|
||||
if (key_elem_builtin_type < Variant::VARIANT_MAX) {
|
||||
// Builtin type.
|
||||
key_elem_type.kind = GDScriptParser::DataType::BUILTIN;
|
||||
key_elem_type.builtin_type = key_elem_builtin_type;
|
||||
} else if (class_exists(key_elem_type_name)) {
|
||||
key_elem_type.kind = GDScriptParser::DataType::NATIVE;
|
||||
key_elem_type.builtin_type = Variant::OBJECT;
|
||||
key_elem_type.native_type = key_elem_type_name;
|
||||
} else if (ScriptServer::is_global_class(key_elem_type_name)) {
|
||||
// Just load this as it shouldn't be a GDScript.
|
||||
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(key_elem_type_name));
|
||||
key_elem_type.kind = GDScriptParser::DataType::SCRIPT;
|
||||
key_elem_type.builtin_type = Variant::OBJECT;
|
||||
key_elem_type.native_type = script->get_instance_base_type();
|
||||
key_elem_type.script_type = script;
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(result, "Could not find element type from property hint of a typed dictionary.");
|
||||
}
|
||||
key_elem_type.is_constant = false;
|
||||
|
||||
StringName value_elem_type_name = p_property.hint_string.get_slicec(';', 1);
|
||||
GDScriptParser::DataType value_elem_type;
|
||||
value_elem_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||
|
||||
Variant::Type value_elem_builtin_type = GDScriptParser::get_builtin_type(value_elem_type_name);
|
||||
if (value_elem_builtin_type < Variant::VARIANT_MAX) {
|
||||
// Builtin type.
|
||||
value_elem_type.kind = GDScriptParser::DataType::BUILTIN;
|
||||
value_elem_type.builtin_type = value_elem_builtin_type;
|
||||
} else if (class_exists(value_elem_type_name)) {
|
||||
value_elem_type.kind = GDScriptParser::DataType::NATIVE;
|
||||
value_elem_type.builtin_type = Variant::OBJECT;
|
||||
value_elem_type.native_type = value_elem_type_name;
|
||||
} else if (ScriptServer::is_global_class(value_elem_type_name)) {
|
||||
// Just load this as it shouldn't be a GDScript.
|
||||
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(value_elem_type_name));
|
||||
value_elem_type.kind = GDScriptParser::DataType::SCRIPT;
|
||||
value_elem_type.builtin_type = Variant::OBJECT;
|
||||
value_elem_type.native_type = script->get_instance_base_type();
|
||||
value_elem_type.script_type = script;
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(result, "Could not find element type from property hint of a typed dictionary.");
|
||||
}
|
||||
value_elem_type.is_constant = false;
|
||||
|
||||
result.set_container_element_type(0, key_elem_type);
|
||||
result.set_container_element_type(1, value_elem_type);
|
||||
result.set_container_element_type(0, type_from_property_hint_string(p_property.hint_string.get_slicec(';', 0)));
|
||||
result.set_container_element_type(1, type_from_property_hint_string(p_property.hint_string.get_slicec(';', 1)));
|
||||
} else if (p_property.type == Variant::INT) {
|
||||
// Check if it's enum.
|
||||
if ((p_property.usage & PROPERTY_USAGE_CLASS_IS_ENUM) && p_property.class_name != StringName()) {
|
||||
|
||||
Reference in New Issue
Block a user