Browse Source

Merge pull request #70644 from vonagam/fix-variant-type-arg

GDScript: Fix getting type from PropertyInfo for Variant arguments
Rémi Verschelde 2 years ago
parent
commit
e80cf3259e

+ 7 - 10
modules/gdscript/gdscript_analyzer.cpp

@@ -68,9 +68,6 @@ static MethodInfo info_from_utility_func(const StringName &p_function) {
 			pi.name = "arg" + itos(i + 1);
 #endif
 			pi.type = Variant::get_utility_function_argument_type(p_function, i);
-			if (pi.type == Variant::NIL) {
-				pi.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
-			}
 			info.arguments.push_back(pi);
 		}
 	}
@@ -2456,7 +2453,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
 					bool types_match = true;
 
 					for (int i = 0; i < p_call->arguments.size(); i++) {
-						GDScriptParser::DataType par_type = type_from_property(info.arguments[i]);
+						GDScriptParser::DataType par_type = type_from_property(info.arguments[i], true);
 
 						if (!is_type_compatible(par_type, p_call->arguments[i]->get_datatype(), true)) {
 							types_match = false;
@@ -2513,7 +2510,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
 					case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
 						PropertyInfo wrong_arg = function_info.arguments[err.argument];
 						push_error(vformat(R"*(Invalid argument for "%s()" function: argument %d should be "%s" but is "%s".)*", function_name, err.argument + 1,
-										   type_from_property(wrong_arg).to_string(), p_call->arguments[err.argument]->get_datatype().to_string()),
+										   type_from_property(wrong_arg, true).to_string(), p_call->arguments[err.argument]->get_datatype().to_string()),
 								p_call->arguments[err.argument]);
 					} break;
 					case Callable::CallError::CALL_ERROR_INVALID_METHOD:
@@ -2560,7 +2557,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
 					case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
 						String expected_type_name;
 						if (err.argument < function_info.arguments.size()) {
-							expected_type_name = type_from_property(function_info.arguments[err.argument]).to_string();
+							expected_type_name = type_from_property(function_info.arguments[err.argument], true).to_string();
 						} else {
 							expected_type_name = Variant::get_type_name((Variant::Type)err.expected);
 						}
@@ -3921,10 +3918,10 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_metatype(const GDScriptPars
 	return result;
 }
 
-GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo &p_property) const {
+GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo &p_property, bool p_is_arg) const {
 	GDScriptParser::DataType result;
 	result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
-	if (p_property.type == Variant::NIL && (p_property.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
+	if (p_property.type == Variant::NIL && (p_is_arg || (p_property.usage & PROPERTY_USAGE_NIL_IS_VARIANT))) {
 		// Variant
 		result.kind = GDScriptParser::DataType::VARIANT;
 		return result;
@@ -4111,7 +4108,7 @@ bool GDScriptAnalyzer::function_signature_from_info(const MethodInfo &p_info, GD
 	r_static = (p_info.flags & METHOD_FLAG_STATIC) != 0;
 
 	for (const PropertyInfo &E : p_info.arguments) {
-		r_par_types.push_back(type_from_property(E));
+		r_par_types.push_back(type_from_property(E, true));
 	}
 	return true;
 }
@@ -4120,7 +4117,7 @@ bool GDScriptAnalyzer::validate_call_arg(const MethodInfo &p_method, const GDScr
 	List<GDScriptParser::DataType> arg_types;
 
 	for (const PropertyInfo &E : p_method.arguments) {
-		arg_types.push_back(type_from_property(E));
+		arg_types.push_back(type_from_property(E, true));
 	}
 
 	return validate_call_arg(arg_types, p_method.default_arguments.size(), (p_method.flags & METHOD_FLAG_VARARG) != 0, p_call);

+ 1 - 1
modules/gdscript/gdscript_analyzer.h

@@ -108,7 +108,7 @@ class GDScriptAnalyzer {
 	// Helpers.
 	GDScriptParser::DataType type_from_variant(const Variant &p_value, const GDScriptParser::Node *p_source);
 	static GDScriptParser::DataType type_from_metatype(const GDScriptParser::DataType &p_meta_type);
-	GDScriptParser::DataType type_from_property(const PropertyInfo &p_property) const;
+	GDScriptParser::DataType type_from_property(const PropertyInfo &p_property, bool p_is_arg = false) const;
 	GDScriptParser::DataType make_global_class_meta_type(const StringName &p_class_name, const GDScriptParser::Node *p_source);
 	bool get_function_signature(GDScriptParser::Node *p_source, bool p_is_constructor, GDScriptParser::DataType base_type, const StringName &p_function, GDScriptParser::DataType &r_return_type, List<GDScriptParser::DataType> &r_par_types, int &r_default_arg_count, bool &r_static, bool &r_vararg);
 	bool function_signature_from_info(const MethodInfo &p_info, GDScriptParser::DataType &r_return_type, List<GDScriptParser::DataType> &r_par_types, int &r_default_arg_count, bool &r_static, bool &r_vararg);

+ 0 - 7
modules/gdscript/tests/scripts/analyzer/errors/enum_shadows_outer_enum.gd

@@ -1,7 +0,0 @@
-enum { V }
-
-class InnerClass:
-	enum { V }
-
-func test():
-	pass

+ 0 - 2
modules/gdscript/tests/scripts/analyzer/errors/enum_shadows_outer_enum.out

@@ -1,2 +0,0 @@
-GDTEST_PARSER_ERROR
-Name "V" is already used as a class enum value.

+ 6 - 0
modules/gdscript/tests/scripts/analyzer/features/variant_arg_in_virtual_method.gd

@@ -0,0 +1,6 @@
+class Check extends Node:
+	func _set(_property: StringName, _value: Variant) -> bool:
+		return true
+
+func test() -> void:
+	print('OK')

+ 2 - 0
modules/gdscript/tests/scripts/analyzer/features/variant_arg_in_virtual_method.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+OK