Browse Source

Fix: Typed arrays aren't working with +

mashumafi 2 years ago
parent
commit
2a12213c31

+ 5 - 0
core/variant/variant_op.h

@@ -824,6 +824,11 @@ public:
 	_FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) {
 	_FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) {
 		int asize = array_a.size();
 		int asize = array_a.size();
 		int bsize = array_b.size();
 		int bsize = array_b.size();
+
+		if (array_a.is_typed() && array_a.is_same_typed(array_b)) {
+			sum.set_typed(array_a.get_typed_builtin(), array_a.get_typed_class_name(), array_a.get_typed_script());
+		}
+
 		sum.resize(asize + bsize);
 		sum.resize(asize + bsize);
 		for (int i = 0; i < asize; i++) {
 		for (int i = 0; i < asize; i++) {
 			sum[i] = array_a[i];
 			sum[i] = array_a[i];

+ 22 - 3
modules/gdscript/gdscript_analyzer.cpp

@@ -4306,7 +4306,16 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_va
 	result.builtin_type = p_value.get_type();
 	result.builtin_type = p_value.get_type();
 	result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; // Constant has explicit type.
 	result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; // Constant has explicit type.
 
 
-	if (p_value.get_type() == Variant::OBJECT) {
+	if (p_value.get_type() == Variant::ARRAY) {
+		const Array &array = p_value;
+		if (array.get_typed_script()) {
+			result.set_container_element_type(type_from_metatype(make_script_meta_type(array.get_typed_script())));
+		} else if (array.get_typed_class_name()) {
+			result.set_container_element_type(type_from_metatype(make_native_meta_type(array.get_typed_class_name())));
+		} else if (array.get_typed_builtin() != Variant::NIL) {
+			result.set_container_element_type(type_from_metatype(make_builtin_meta_type((Variant::Type)array.get_typed_builtin())));
+		}
+	} else if (p_value.get_type() == Variant::OBJECT) {
 		// Object is treated as a native type, not a builtin type.
 		// Object is treated as a native type, not a builtin type.
 		result.kind = GDScriptParser::DataType::NATIVE;
 		result.kind = GDScriptParser::DataType::NATIVE;
 
 
@@ -4741,11 +4750,21 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
 		}
 		}
 	}
 	}
 
 
-	Variant::ValidatedOperatorEvaluator op_eval = Variant::get_validated_operator_evaluator(p_operation, a_type, b_type);
+	GDScriptParser::DataType result;
 	bool hard_operation = p_a.is_hard_type() && p_b.is_hard_type();
 	bool hard_operation = p_a.is_hard_type() && p_b.is_hard_type();
+
+	if (p_operation == Variant::OP_ADD && a_type == Variant::ARRAY && b_type == Variant::ARRAY) {
+		if (p_a.get_container_element_type() == p_a.get_container_element_type()) {
+			r_valid = true;
+			result = p_a;
+			result.type_source = hard_operation ? GDScriptParser::DataType::ANNOTATED_INFERRED : GDScriptParser::DataType::INFERRED;
+			return result;
+		}
+	}
+
+	Variant::ValidatedOperatorEvaluator op_eval = Variant::get_validated_operator_evaluator(p_operation, a_type, b_type);
 	bool validated = op_eval != nullptr;
 	bool validated = op_eval != nullptr;
 
 
-	GDScriptParser::DataType result;
 	if (validated) {
 	if (validated) {
 		r_valid = true;
 		r_valid = true;
 		result.type_source = hard_operation ? GDScriptParser::DataType::ANNOTATED_INFERRED : GDScriptParser::DataType::INFERRED;
 		result.type_source = hard_operation ? GDScriptParser::DataType::ANNOTATED_INFERRED : GDScriptParser::DataType::INFERRED;

+ 28 - 0
modules/gdscript/tests/scripts/runtime/features/typed_array_concatenation.gd

@@ -0,0 +1,28 @@
+# https://github.com/godotengine/godot/issues/72948
+
+class Example:
+	extends RefCounted
+
+const const_ints : Array[int] = [1, 2, 3]
+
+func test():
+	var ints: Array[int] = [1, 2, 3]
+	var strings: Array[String] = ["4", "5", "6"]
+
+	var ints_concatenated: Array[int] = ints + ints
+	var strings_concatenated: Array[String] = strings + strings
+	var untyped_concatenated: Array = ints + strings
+	var const_ints_concatenated: Array[int] = const_ints + const_ints
+
+	print(ints_concatenated.get_typed_builtin())
+	print(strings_concatenated.get_typed_builtin())
+	print(untyped_concatenated.get_typed_builtin())
+	print(const_ints_concatenated.get_typed_builtin())
+
+	var objects: Array[Object] = []
+	var objects_concatenated: Array[Object] = objects + objects
+	print(objects_concatenated.get_typed_class_name())
+
+	var examples: Array[Example] = []
+	var examples_concatenated: Array[Example] = examples + examples
+	print(examples_concatenated.get_typed_script() == Example)

+ 7 - 0
modules/gdscript/tests/scripts/runtime/features/typed_array_concatenation.out

@@ -0,0 +1,7 @@
+GDTEST_OK
+2
+4
+0
+2
+Object
+true