GDScript: Misc fixes and improvements for signature generation

* Use type hints for `@GlobalScope` enums.
* Use plain `int` for `BitMask<T>`.
* Fix type hints for typed arrays.
* Use `Variant` and `void` type hints.
* Discard unnecessary class prefix.
This commit is contained in:
Danil Alexeev 2023-04-05 17:46:22 +03:00
parent 132000f58d
commit 9df96e97ea
No known key found for this signature in database
GPG key ID: 124453E157DA8DC7
2 changed files with 31 additions and 37 deletions

View file

@ -4546,7 +4546,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
result.set_container_element_type(elem_type);
} else if (p_property.type == Variant::INT) {
// Check if it's enum.
if ((p_property.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) && p_property.class_name != StringName()) {
if ((p_property.usage & PROPERTY_USAGE_CLASS_IS_ENUM) && p_property.class_name != StringName()) {
if (CoreConstants::is_global_enum(p_property.class_name)) {
result = make_global_enum_type(p_property.class_name, StringName(), false);
result.is_constant = false;
@ -4558,6 +4558,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
}
}
}
// PROPERTY_USAGE_CLASS_IS_BITFIELD: BitField[T] isn't supported (yet?), use plain int.
}
}
return result;

View file

@ -578,29 +578,34 @@ static int _get_enum_constant_location(StringName p_class, StringName p_enum_con
// END LOCATION METHODS
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_is_arg = true) {
if (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
String enum_name = p_info.class_name;
if (!enum_name.contains(".")) {
return enum_name;
}
return enum_name.get_slice(".", 1);
static String _trim_parent_class(const String &p_class, const String &p_base_class) {
if (p_base_class.is_empty()) {
return p_class;
}
String n = p_info.name;
int idx = n.find(":");
if (idx != -1) {
return n.substr(idx + 1, n.length());
}
if (p_info.type == Variant::OBJECT) {
if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
return p_info.hint_string;
} else {
return p_info.class_name.operator String();
Vector<String> names = p_class.split(".", false, 1);
if (names.size() == 2) {
String first = names[0];
String rest = names[1];
if (ClassDB::class_exists(p_base_class) && ClassDB::class_exists(first) && ClassDB::is_parent_class(p_base_class, first)) {
return rest;
}
}
if (p_info.type == Variant::NIL) {
return p_class;
}
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_is_arg, const String &p_base_class = "") {
String class_name = p_info.class_name;
bool is_enum = p_info.type == Variant::INT && p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM;
// PROPERTY_USAGE_CLASS_IS_BITFIELD: BitField[T] isn't supported (yet?), use plain int.
if ((p_info.type == Variant::OBJECT || is_enum) && !class_name.is_empty()) {
if (is_enum && CoreConstants::is_global_enum(p_info.class_name)) {
return class_name;
}
return _trim_parent_class(class_name, p_base_class);
} else if (p_info.type == Variant::ARRAY && p_info.hint == PROPERTY_HINT_ARRAY_TYPE && !p_info.hint_string.is_empty()) {
return "Array[" + _trim_parent_class(p_info.hint_string, p_base_class) + "]";
} else if (p_info.type == Variant::NIL) {
if (p_is_arg || (p_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
return "Variant";
} else {
@ -3001,26 +3006,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
arg = arg.substr(0, arg.find(":"));
}
method_hint += arg;
if (use_type_hint && mi.arguments[i].type != Variant::NIL) {
method_hint += ": ";
if (mi.arguments[i].type == Variant::OBJECT && mi.arguments[i].class_name != StringName()) {
method_hint += mi.arguments[i].class_name.operator String();
} else {
method_hint += Variant::get_type_name(mi.arguments[i].type);
}
if (use_type_hint) {
method_hint += ": " + _get_visual_datatype(mi.arguments[i], true, class_name);
}
}
}
method_hint += ")";
if (use_type_hint && (mi.return_val.type != Variant::NIL || !(mi.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT))) {
method_hint += " -> ";
if (mi.return_val.type == Variant::NIL) {
method_hint += "void";
} else if (mi.return_val.type == Variant::OBJECT && mi.return_val.class_name != StringName()) {
method_hint += mi.return_val.class_name.operator String();
} else {
method_hint += Variant::get_type_name(mi.return_val.type);
}
if (use_type_hint) {
method_hint += " -> " + _get_visual_datatype(mi.return_val, false, class_name);
}
method_hint += ":";