Browse Source

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.
Danil Alexeev 2 years ago
parent
commit
9df96e97ea
2 changed files with 29 additions and 35 deletions
  1. 2 1
      modules/gdscript/gdscript_analyzer.cpp
  2. 27 34
      modules/gdscript/gdscript_editor.cpp

+ 2 - 1
modules/gdscript/gdscript_analyzer.cpp

@@ -4546,7 +4546,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
 			result.set_container_element_type(elem_type);
 			result.set_container_element_type(elem_type);
 		} else if (p_property.type == Variant::INT) {
 		} else if (p_property.type == Variant::INT) {
 			// Check if it's enum.
 			// 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)) {
 				if (CoreConstants::is_global_enum(p_property.class_name)) {
 					result = make_global_enum_type(p_property.class_name, StringName(), false);
 					result = make_global_enum_type(p_property.class_name, StringName(), false);
 					result.is_constant = 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;
 	return result;

+ 27 - 34
modules/gdscript/gdscript_editor.cpp

@@ -578,29 +578,34 @@ static int _get_enum_constant_location(StringName p_class, StringName p_enum_con
 
 
 // END LOCATION METHODS
 // 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;
+static String _trim_parent_class(const String &p_class, const String &p_base_class) {
+	if (p_base_class.is_empty()) {
+		return p_class;
+	}
+	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;
 		}
 		}
-		return enum_name.get_slice(".", 1);
 	}
 	}
+	return p_class;
+}
 
 
-	String n = p_info.name;
-	int idx = n.find(":");
-	if (idx != -1) {
-		return n.substr(idx + 1, n.length());
-	}
+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) {
-		if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
-			return p_info.hint_string;
-		} else {
-			return p_info.class_name.operator String();
+	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;
 		}
 		}
-	}
-	if (p_info.type == Variant::NIL) {
+		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)) {
 		if (p_is_arg || (p_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
 			return "Variant";
 			return "Variant";
 		} else {
 		} else {
@@ -3001,26 +3006,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 							arg = arg.substr(0, arg.find(":"));
 							arg = arg.substr(0, arg.find(":"));
 						}
 						}
 						method_hint += arg;
 						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 += ")";
 				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 += ":";
 				method_hint += ":";