2
0
Эх сурвалжийг харах

GDScript: Allow boolean operators between any types

To make consistent with previous behavior. Mostly to be used in
conditions for `if` and `while`.
George Marques 2 жил өмнө
parent
commit
d76b3f2a4c

+ 11 - 0
modules/gdscript/gdscript_analyzer.cpp

@@ -4846,6 +4846,17 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
 }
 
 GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source) {
+	if (p_operation == Variant::OP_AND || p_operation == Variant::OP_OR) {
+		// Those work for any type of argument and always return a boolean.
+		// They don't use the Variant operator since they have short-circuit semantics.
+		r_valid = true;
+		GDScriptParser::DataType result;
+		result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
+		result.kind = GDScriptParser::DataType::BUILTIN;
+		result.builtin_type = Variant::BOOL;
+		return result;
+	}
+
 	Variant::Type a_type = p_a.builtin_type;
 	Variant::Type b_type = p_b.builtin_type;
 

+ 347 - 0
modules/gdscript/tests/scripts/analyzer/features/boolean_operators_for_all_types.gd

@@ -0,0 +1,347 @@
+extends Resource
+
+signal foo
+
+func test():
+	var x
+	# TYPE_NIL
+	x = null
+	prints("TYPE_NIL")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_BOOL
+	x = true
+	prints("TYPE_BOOL")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_INT
+	x = 1
+	prints("TYPE_INT")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_FLOAT
+	x = 1.1
+	prints("TYPE_FLOAT")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_STRING
+	x = "foo"
+	prints("TYPE_STRING")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR2
+	x = Vector2(1, 1)
+	prints("TYPE_VECTOR2")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR2I
+	x = Vector2i(1, 1)
+	prints("TYPE_VECTOR2I")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_RECT2
+	x = Rect2(1, 1, 1, 1)
+	prints("TYPE_RECT2")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_RECT2I
+	x = Rect2i(1, 1, 1, 1)
+	prints("TYPE_RECT2I")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR3
+	x = Vector3(1, 1, 1)
+	prints("TYPE_VECTOR3")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR3I
+	x = Vector3i(1, 1, 1)
+	prints("TYPE_VECTOR3I")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_TRANSFORM2D
+	x = Transform2D.IDENTITY
+	prints("TYPE_TRANSFORM2D")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR4
+	x = Vector4(1, 1, 1, 1)
+	prints("TYPE_VECTOR4")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_VECTOR4I
+	x = Vector4i(1, 1, 1, 1)
+	prints("TYPE_VECTOR4I")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PLANE
+	x = Plane.PLANE_XY
+	prints("TYPE_PLANE")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_QUATERNION
+	x = Quaternion.IDENTITY
+	prints("TYPE_QUATERNION")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_AABB
+	x = AABB(Vector3.ONE, Vector3.ONE)
+	prints("TYPE_AABB")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_BASIS
+	x = Basis.IDENTITY
+	prints("TYPE_BASIS")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_TRANSFORM3D
+	x = Transform3D.IDENTITY
+	prints("TYPE_TRANSFORM3D")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PROJECTION
+	x = Projection.IDENTITY
+	prints("TYPE_PROJECTION")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_COLOR
+	x = Color.WHITE
+	prints("TYPE_COLOR")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_STRING_NAME
+	x = &"name"
+	prints("TYPE_STRING_NAME")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_NODE_PATH
+	x = ^"path"
+	prints("TYPE_NODE_PATH")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_RID
+	x = get_rid()
+	prints("TYPE_RID")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_OBJECT
+	x = self
+	prints("TYPE_OBJECT")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_CALLABLE
+	x = test
+	prints("TYPE_CALLABLE")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_SIGNAL
+	x = foo
+	prints("TYPE_SIGNAL")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_DICTIONARY
+	x = { a = 1}
+	prints("TYPE_DICTIONARY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_ARRAY
+	x = [1]
+	prints("TYPE_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_BYTE_ARRAY
+	x = PackedByteArray([1])
+	prints("TYPE_PACKED_BYTE_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_INT32_ARRAY
+	x = PackedInt32Array([1])
+	prints("TYPE_PACKED_INT32_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_INT64_ARRAY
+	x = PackedInt64Array([1])
+	prints("TYPE_PACKED_INT64_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_FLOAT32_ARRAY
+	x = PackedFloat32Array([1])
+	prints("TYPE_PACKED_FLOAT32_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_FLOAT64_ARRAY
+	x = PackedFloat64Array([1])
+	prints("TYPE_PACKED_FLOAT64_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_STRING_ARRAY
+	x = PackedStringArray(["1"])
+	prints("TYPE_PACKED_STRING_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_VECTOR2_ARRAY
+	x = PackedVector2Array([Vector2.ONE])
+	prints("TYPE_PACKED_VECTOR2_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_VECTOR3_ARRAY
+	x = PackedVector3Array([Vector3.ONE])
+	prints("TYPE_PACKED_VECTOR3_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)
+
+	# TYPE_PACKED_COLOR_ARRAY
+	x = PackedColorArray([Color.WHITE])
+	prints("TYPE_PACKED_COLOR_ARRAY")
+	prints(not x)
+	prints(x and false)
+	prints(x and true)
+	prints(x or false)
+	prints(x or true)

+ 229 - 0
modules/gdscript/tests/scripts/analyzer/features/boolean_operators_for_all_types.out

@@ -0,0 +1,229 @@
+GDTEST_OK
+TYPE_NIL
+true
+false
+false
+false
+true
+TYPE_BOOL
+false
+false
+true
+true
+true
+TYPE_INT
+false
+false
+true
+true
+true
+TYPE_FLOAT
+false
+false
+true
+true
+true
+TYPE_STRING
+false
+false
+true
+true
+true
+TYPE_VECTOR2
+false
+false
+true
+true
+true
+TYPE_VECTOR2I
+false
+false
+true
+true
+true
+TYPE_RECT2
+false
+false
+true
+true
+true
+TYPE_RECT2I
+false
+false
+true
+true
+true
+TYPE_VECTOR3
+false
+false
+true
+true
+true
+TYPE_VECTOR3I
+false
+false
+true
+true
+true
+TYPE_TRANSFORM2D
+true
+false
+false
+false
+true
+TYPE_VECTOR4
+false
+false
+true
+true
+true
+TYPE_VECTOR4I
+false
+false
+true
+true
+true
+TYPE_PLANE
+false
+false
+true
+true
+true
+TYPE_QUATERNION
+true
+false
+false
+false
+true
+TYPE_AABB
+false
+false
+true
+true
+true
+TYPE_BASIS
+true
+false
+false
+false
+true
+TYPE_TRANSFORM3D
+true
+false
+false
+false
+true
+TYPE_PROJECTION
+true
+false
+false
+false
+true
+TYPE_COLOR
+false
+false
+true
+true
+true
+TYPE_STRING_NAME
+false
+false
+true
+true
+true
+TYPE_NODE_PATH
+false
+false
+true
+true
+true
+TYPE_RID
+true
+false
+false
+false
+true
+TYPE_OBJECT
+false
+false
+true
+true
+true
+TYPE_CALLABLE
+false
+false
+true
+true
+true
+TYPE_SIGNAL
+false
+false
+true
+true
+true
+TYPE_DICTIONARY
+false
+false
+true
+true
+true
+TYPE_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_BYTE_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_INT32_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_INT64_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_FLOAT32_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_FLOAT64_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_STRING_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_VECTOR2_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_VECTOR3_ARRAY
+false
+false
+true
+true
+true
+TYPE_PACKED_COLOR_ARRAY
+false
+false
+true
+true
+true