diff options
Diffstat (limited to 'modules/gdscript/tests/scripts/analyzer')
52 files changed, 671 insertions, 229 deletions
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_external.out b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_external.out index 64a6bd417d..878e827d04 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_external.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_external.out @@ -1,2 +1,2 @@ GDTEST_ANALYZER_ERROR -Could not resolve member "v". +Could not resolve external class member "v". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.gd b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.gd new file mode 100644 index 0000000000..c180cca03c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.gd @@ -0,0 +1,3 @@ +func test(): + for key: int in { "a": 1 }: + print(key) diff --git a/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.out b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.out new file mode 100644 index 0000000000..8530783673 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot include a value of type "String" as "int". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.gd b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.gd new file mode 100644 index 0000000000..75d1b7fe62 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.gd @@ -0,0 +1,4 @@ +func test(): + var differently: Dictionary[float, float] = { 1.0: 0.0 } + var typed: Dictionary[int, int] = differently + print('not ok') diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.out b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.out new file mode 100644 index 0000000000..e05d4be8c9 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot assign a value of type Dictionary[float, float] to variable "typed" with specified type Dictionary[int, int]. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.gd b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.gd new file mode 100644 index 0000000000..e0af71823a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.gd @@ -0,0 +1,2 @@ +func test(): + const dict: Dictionary[int, int] = { "Hello": "World" } diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.out b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.out new file mode 100644 index 0000000000..8530783673 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot include a value of type "String" as "int". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.gd b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.gd new file mode 100644 index 0000000000..814ba12aef --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.gd @@ -0,0 +1,4 @@ +func test(): + var unconvertible := 1 + var typed: Dictionary[Object, Object] = { unconvertible: unconvertible } + print('not ok') diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.out b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.out new file mode 100644 index 0000000000..9d6c9d9144 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot have a key of type "int" in a dictionary of type "Dictionary[Object, Object]". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.gd b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.gd new file mode 100644 index 0000000000..73d8ce2b96 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.gd @@ -0,0 +1,7 @@ +func expect_typed(typed: Dictionary[int, int]): + print(typed.size()) + +func test(): + var differently: Dictionary[float, float] = { 1.0: 0.0 } + expect_typed(differently) + print('not ok') diff --git a/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.out b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.out new file mode 100644 index 0000000000..302109cf8a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Invalid argument for "expect_typed()" function: argument 1 should be "Dictionary[int, int]" but is "Dictionary[float, float]". diff --git a/modules/gdscript/tests/scripts/analyzer/features/assymetric_assignment_good.gd b/modules/gdscript/tests/scripts/analyzer/features/assymetric_assignment_good.gd index efd8ad6edb..60bcde4b8c 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/assymetric_assignment_good.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/assymetric_assignment_good.gd @@ -3,14 +3,13 @@ const const_color: Color = 'red' func func_color(arg_color: Color = 'blue') -> bool: return arg_color == Color.BLUE -@warning_ignore("assert_always_true") func test(): - assert(const_color == Color.RED) + Utils.check(const_color == Color.RED) - assert(func_color() == true) - assert(func_color('blue') == true) + Utils.check(func_color() == true) + Utils.check(func_color('blue') == true) var var_color: Color = 'green' - assert(var_color == Color.GREEN) + Utils.check(var_color == Color.GREEN) print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd b/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd index bed9dd0e96..5318d11f33 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd @@ -5,20 +5,19 @@ const const_float_cast: float = 76 as float const const_packed_empty: PackedFloat64Array = [] const const_packed_ints: PackedFloat64Array = [52] -@warning_ignore("assert_always_true") func test(): - assert(typeof(const_float_int) == TYPE_FLOAT) - assert(str(const_float_int) == '19') - assert(typeof(const_float_plus) == TYPE_FLOAT) - assert(str(const_float_plus) == '34') - assert(typeof(const_float_cast) == TYPE_FLOAT) - assert(str(const_float_cast) == '76') + Utils.check(typeof(const_float_int) == TYPE_FLOAT) + Utils.check(str(const_float_int) == '19') + Utils.check(typeof(const_float_plus) == TYPE_FLOAT) + Utils.check(str(const_float_plus) == '34') + Utils.check(typeof(const_float_cast) == TYPE_FLOAT) + Utils.check(str(const_float_cast) == '76') - assert(typeof(const_packed_empty) == TYPE_PACKED_FLOAT64_ARRAY) - assert(str(const_packed_empty) == '[]') - assert(typeof(const_packed_ints) == TYPE_PACKED_FLOAT64_ARRAY) - assert(str(const_packed_ints) == '[52]') - assert(typeof(const_packed_ints[0]) == TYPE_FLOAT) - assert(str(const_packed_ints[0]) == '52') + Utils.check(typeof(const_packed_empty) == TYPE_PACKED_FLOAT64_ARRAY) + Utils.check(str(const_packed_empty) == '[]') + Utils.check(typeof(const_packed_ints) == TYPE_PACKED_FLOAT64_ARRAY) + Utils.check(str(const_packed_ints) == '[52]') + Utils.check(typeof(const_packed_ints[0]) == TYPE_FLOAT) + Utils.check(str(const_packed_ints[0]) == '52') print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/enums_in_range_call.gd b/modules/gdscript/tests/scripts/analyzer/features/enums_in_range_call.gd index d2d9d04508..a569488d3c 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/enums_in_range_call.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/enums_in_range_call.gd @@ -5,5 +5,5 @@ func test(): for value in range(E.E0, E.E3): var inferable := value total += inferable - assert(total == 0 + 1 + 2) + Utils.check(total == 0 + 1 + 2) print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd index 39f490c4b3..ec89226328 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd @@ -2,8 +2,6 @@ class_name TestExportEnumAsDictionary enum MyEnum {A, B, C} -const Utils = preload("../../utils.notest.gd") - @export var test_1 = MyEnum @export var test_2 = MyEnum.A @export var test_3 := MyEnum diff --git a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out index 505af5f1f3..0d96f8c021 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out +++ b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out @@ -1,11 +1,11 @@ GDTEST_OK var test_1: Dictionary - hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE + hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" var test_2: TestExportEnumAsDictionary.MyEnum - hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM + hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"TestExportEnumAsDictionary.MyEnum" var test_3: Dictionary - hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE + hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" var test_4: TestExportEnumAsDictionary.MyEnum - hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM + hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"TestExportEnumAsDictionary.MyEnum" var test_5: TestExportEnumAsDictionary.MyEnum - hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM + hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"TestExportEnumAsDictionary.MyEnum" diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser.gd new file mode 100644 index 0000000000..ad265a7365 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser.gd @@ -0,0 +1,17 @@ +extends "external_parser_base1.notest.gd" + +const External1 = preload("external_parser_script1.notest.gd") + +func baz(e1: External1) -> void: + print(e1.e1c.bar) + print(e1.baz) + +func test_external_base_parser_type_resolve(_v: TypeFromBase): + pass + +func test(): + var ext := External1.new() + print(ext.array[0].test2) + print(ext.get_external2().get_external3().test3) + # TODO: This actually produces a runtime error, but we're testing the analyzer here + #baz(ext) diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser.out b/modules/gdscript/tests/scripts/analyzer/features/external_parser.out new file mode 100644 index 0000000000..26c2527fbc --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser.out @@ -0,0 +1,3 @@ +GDTEST_OK +test2 +test3 diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_base1.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_base1.notest.gd new file mode 100644 index 0000000000..d27d8cef3b --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_base1.notest.gd @@ -0,0 +1 @@ +extends "external_parser_base2.notest.gd" diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_base2.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_base2.notest.gd new file mode 100644 index 0000000000..f8de818485 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_base2.notest.gd @@ -0,0 +1,2 @@ +class TypeFromBase: + pass diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1.notest.gd new file mode 100644 index 0000000000..e1221bb138 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1.notest.gd @@ -0,0 +1,12 @@ +extends "external_parser_script1_base.notest.gd" + +const External2 = preload("external_parser_script2.notest.gd") +const External1c = preload("external_parser_script1c.notest.gd") + +@export var e1c: External1c + +var array: Array[External2] = [ External2.new() ] +var baz: int + +func get_external2() -> External2: + return External2.new() diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1_base.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1_base.notest.gd new file mode 100644 index 0000000000..4249efa1f9 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1_base.notest.gd @@ -0,0 +1 @@ +extends Resource diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1c.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1c.notest.gd new file mode 100644 index 0000000000..34a48cba6f --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1c.notest.gd @@ -0,0 +1 @@ +extends "external_parser_script1d.notest.gd" diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1d.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1d.notest.gd new file mode 100644 index 0000000000..43bc6f3e53 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1d.notest.gd @@ -0,0 +1,5 @@ +extends "external_parser_script1f.notest.gd" + +const External1e = preload("external_parser_script1e.notest.gd") + +var bar: Array[External1e] diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1e.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1e.notest.gd new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1e.notest.gd diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1f.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1f.notest.gd new file mode 100644 index 0000000000..4249efa1f9 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script1f.notest.gd @@ -0,0 +1 @@ +extends Resource diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script2.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script2.notest.gd new file mode 100644 index 0000000000..885f813503 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script2.notest.gd @@ -0,0 +1,6 @@ +const External3 = preload("external_parser_script3.notest.gd") + +var test2 := "test2" + +func get_external3() -> External3: + return External3.new() diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_parser_script3.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script3.notest.gd new file mode 100644 index 0000000000..3e62974256 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/external_parser_script3.notest.gd @@ -0,0 +1 @@ +var test3 := "test3" diff --git a/modules/gdscript/tests/scripts/analyzer/features/for_range_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/for_range_usage.gd index 4a7f10f1ee..9ce0782d5c 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/for_range_usage.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/for_range_usage.gd @@ -3,5 +3,5 @@ func test(): var result := '' for i in range(array.size(), 0, -1): result += str(array[i - 1]) - assert(result == '963') + Utils.check(result == '963') print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd index d678f3acfc..e0cbdacb38 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd @@ -2,11 +2,11 @@ func test(): var instance := Parent.new() var result := instance.my_function(1) print(result) - assert(result == 1) + Utils.check(result == 1) instance = Child.new() result = instance.my_function(2) print(result) - assert(result == 0) + Utils.check(result == 0) class Parent: func my_function(par1: int) -> int: diff --git a/modules/gdscript/tests/scripts/analyzer/features/return_conversions.gd b/modules/gdscript/tests/scripts/analyzer/features/return_conversions.gd index 0b1576e66e..cbe8e9da34 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/return_conversions.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/return_conversions.gd @@ -8,27 +8,27 @@ func convert_var_array_to_packed() -> PackedStringArray: var array := ['79']; re func test(): var converted_literal_int := convert_literal_int_to_float() - assert(typeof(converted_literal_int) == TYPE_FLOAT) - assert(converted_literal_int == 76.0) + Utils.check(typeof(converted_literal_int) == TYPE_FLOAT) + Utils.check(converted_literal_int == 76.0) var converted_arg_int := convert_arg_int_to_float(36) - assert(typeof(converted_arg_int) == TYPE_FLOAT) - assert(converted_arg_int == 36.0) + Utils.check(typeof(converted_arg_int) == TYPE_FLOAT) + Utils.check(converted_arg_int == 36.0) var converted_var_int := convert_var_int_to_float() - assert(typeof(converted_var_int) == TYPE_FLOAT) - assert(converted_var_int == 59.0) + Utils.check(typeof(converted_var_int) == TYPE_FLOAT) + Utils.check(converted_var_int == 59.0) var converted_literal_array := convert_literal_array_to_packed() - assert(typeof(converted_literal_array) == TYPE_PACKED_STRING_ARRAY) - assert(str(converted_literal_array) == '["46"]') + Utils.check(typeof(converted_literal_array) == TYPE_PACKED_STRING_ARRAY) + Utils.check(str(converted_literal_array) == '["46"]') var converted_arg_array := convert_arg_array_to_packed(['91']) - assert(typeof(converted_arg_array) == TYPE_PACKED_STRING_ARRAY) - assert(str(converted_arg_array) == '["91"]') + Utils.check(typeof(converted_arg_array) == TYPE_PACKED_STRING_ARRAY) + Utils.check(str(converted_arg_array) == '["91"]') var converted_var_array := convert_var_array_to_packed() - assert(typeof(converted_var_array) == TYPE_PACKED_STRING_ARRAY) - assert(str(converted_var_array) == '["79"]') + Utils.check(typeof(converted_var_array) == TYPE_PACKED_STRING_ARRAY) + Utils.check(str(converted_var_array) == '["79"]') print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/ternary_hard_infer.gd b/modules/gdscript/tests/scripts/analyzer/features/ternary_hard_infer.gd index 44ca5f4dd0..d49acaacd3 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/ternary_hard_infer.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/ternary_hard_infer.gd @@ -2,7 +2,7 @@ func test(): var left_hard_int := 1 var right_hard_int := 2 var result_hard_int := left_hard_int if true else right_hard_int - assert(result_hard_int == 1) + Utils.check(result_hard_int == 1) @warning_ignore("inference_on_variant") var left_hard_variant := 1 as Variant @@ -10,6 +10,6 @@ func test(): var right_hard_variant := 2.0 as Variant @warning_ignore("inference_on_variant") var result_hard_variant := left_hard_variant if true else right_hard_variant - assert(result_hard_variant == 1) + Utils.check(result_hard_variant == 1) print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/type_test_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/type_test_usage.gd index 12dc0b93df..ee30f01dfb 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/type_test_usage.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/type_test_usage.gd @@ -4,124 +4,123 @@ class A extends RefCounted: class B extends A: pass -@warning_ignore("assert_always_true") func test(): var builtin: Variant = 3 - assert((builtin is Variant) == true) - assert((builtin is int) == true) - assert(is_instance_of(builtin, TYPE_INT) == true) - assert((builtin is float) == false) - assert(is_instance_of(builtin, TYPE_FLOAT) == false) + Utils.check((builtin is Variant) == true) + Utils.check((builtin is int) == true) + Utils.check(is_instance_of(builtin, TYPE_INT) == true) + Utils.check((builtin is float) == false) + Utils.check(is_instance_of(builtin, TYPE_FLOAT) == false) const const_builtin: Variant = 3 - assert((const_builtin is Variant) == true) - assert((const_builtin is int) == true) - assert(is_instance_of(const_builtin, TYPE_INT) == true) - assert((const_builtin is float) == false) - assert(is_instance_of(const_builtin, TYPE_FLOAT) == false) + Utils.check((const_builtin is Variant) == true) + Utils.check((const_builtin is int) == true) + Utils.check(is_instance_of(const_builtin, TYPE_INT) == true) + Utils.check((const_builtin is float) == false) + Utils.check(is_instance_of(const_builtin, TYPE_FLOAT) == false) var int_array: Variant = [] as Array[int] - assert((int_array is Variant) == true) - assert((int_array is Array) == true) - assert(is_instance_of(int_array, TYPE_ARRAY) == true) - assert((int_array is Array[int]) == true) - assert((int_array is Array[float]) == false) - assert((int_array is int) == false) - assert(is_instance_of(int_array, TYPE_INT) == false) + Utils.check((int_array is Variant) == true) + Utils.check((int_array is Array) == true) + Utils.check(is_instance_of(int_array, TYPE_ARRAY) == true) + Utils.check((int_array is Array[int]) == true) + Utils.check((int_array is Array[float]) == false) + Utils.check((int_array is int) == false) + Utils.check(is_instance_of(int_array, TYPE_INT) == false) var const_int_array: Variant = [] as Array[int] - assert((const_int_array is Variant) == true) - assert((const_int_array is Array) == true) - assert(is_instance_of(const_int_array, TYPE_ARRAY) == true) - assert((const_int_array is Array[int]) == true) - assert((const_int_array is Array[float]) == false) - assert((const_int_array is int) == false) - assert(is_instance_of(const_int_array, TYPE_INT) == false) + Utils.check((const_int_array is Variant) == true) + Utils.check((const_int_array is Array) == true) + Utils.check(is_instance_of(const_int_array, TYPE_ARRAY) == true) + Utils.check((const_int_array is Array[int]) == true) + Utils.check((const_int_array is Array[float]) == false) + Utils.check((const_int_array is int) == false) + Utils.check(is_instance_of(const_int_array, TYPE_INT) == false) var b_array: Variant = [] as Array[B] - assert((b_array is Variant) == true) - assert((b_array is Array) == true) - assert(is_instance_of(b_array, TYPE_ARRAY) == true) - assert((b_array is Array[B]) == true) - assert((b_array is Array[A]) == false) - assert((b_array is Array[int]) == false) - assert((b_array is int) == false) - assert(is_instance_of(b_array, TYPE_INT) == false) + Utils.check((b_array is Variant) == true) + Utils.check((b_array is Array) == true) + Utils.check(is_instance_of(b_array, TYPE_ARRAY) == true) + Utils.check((b_array is Array[B]) == true) + Utils.check((b_array is Array[A]) == false) + Utils.check((b_array is Array[int]) == false) + Utils.check((b_array is int) == false) + Utils.check(is_instance_of(b_array, TYPE_INT) == false) var const_b_array: Variant = [] as Array[B] - assert((const_b_array is Variant) == true) - assert((const_b_array is Array) == true) - assert(is_instance_of(const_b_array, TYPE_ARRAY) == true) - assert((const_b_array is Array[B]) == true) - assert((const_b_array is Array[A]) == false) - assert((const_b_array is Array[int]) == false) - assert((const_b_array is int) == false) - assert(is_instance_of(const_b_array, TYPE_INT) == false) + Utils.check((const_b_array is Variant) == true) + Utils.check((const_b_array is Array) == true) + Utils.check(is_instance_of(const_b_array, TYPE_ARRAY) == true) + Utils.check((const_b_array is Array[B]) == true) + Utils.check((const_b_array is Array[A]) == false) + Utils.check((const_b_array is Array[int]) == false) + Utils.check((const_b_array is int) == false) + Utils.check(is_instance_of(const_b_array, TYPE_INT) == false) var native: Variant = RefCounted.new() - assert((native is Variant) == true) - assert((native is Object) == true) - assert(is_instance_of(native, TYPE_OBJECT) == true) - assert(is_instance_of(native, Object) == true) - assert((native is RefCounted) == true) - assert(is_instance_of(native, RefCounted) == true) - assert((native is Node) == false) - assert(is_instance_of(native, Node) == false) - assert((native is int) == false) - assert(is_instance_of(native, TYPE_INT) == false) + Utils.check((native is Variant) == true) + Utils.check((native is Object) == true) + Utils.check(is_instance_of(native, TYPE_OBJECT) == true) + Utils.check(is_instance_of(native, Object) == true) + Utils.check((native is RefCounted) == true) + Utils.check(is_instance_of(native, RefCounted) == true) + Utils.check((native is Node) == false) + Utils.check(is_instance_of(native, Node) == false) + Utils.check((native is int) == false) + Utils.check(is_instance_of(native, TYPE_INT) == false) var a_script: Variant = A.new() - assert((a_script is Variant) == true) - assert((a_script is Object) == true) - assert(is_instance_of(a_script, TYPE_OBJECT) == true) - assert(is_instance_of(a_script, Object) == true) - assert((a_script is RefCounted) == true) - assert(is_instance_of(a_script, RefCounted) == true) - assert((a_script is A) == true) - assert(is_instance_of(a_script, A) == true) - assert((a_script is B) == false) - assert(is_instance_of(a_script, B) == false) - assert((a_script is Node) == false) - assert(is_instance_of(a_script, Node) == false) - assert((a_script is int) == false) - assert(is_instance_of(a_script, TYPE_INT) == false) + Utils.check((a_script is Variant) == true) + Utils.check((a_script is Object) == true) + Utils.check(is_instance_of(a_script, TYPE_OBJECT) == true) + Utils.check(is_instance_of(a_script, Object) == true) + Utils.check((a_script is RefCounted) == true) + Utils.check(is_instance_of(a_script, RefCounted) == true) + Utils.check((a_script is A) == true) + Utils.check(is_instance_of(a_script, A) == true) + Utils.check((a_script is B) == false) + Utils.check(is_instance_of(a_script, B) == false) + Utils.check((a_script is Node) == false) + Utils.check(is_instance_of(a_script, Node) == false) + Utils.check((a_script is int) == false) + Utils.check(is_instance_of(a_script, TYPE_INT) == false) var b_script: Variant = B.new() - assert((b_script is Variant) == true) - assert((b_script is Object) == true) - assert(is_instance_of(b_script, TYPE_OBJECT) == true) - assert(is_instance_of(b_script, Object) == true) - assert((b_script is RefCounted) == true) - assert(is_instance_of(b_script, RefCounted) == true) - assert((b_script is A) == true) - assert(is_instance_of(b_script, A) == true) - assert((b_script is B) == true) - assert(is_instance_of(b_script, B) == true) - assert((b_script is Node) == false) - assert(is_instance_of(b_script, Node) == false) - assert((b_script is int) == false) - assert(is_instance_of(b_script, TYPE_INT) == false) + Utils.check((b_script is Variant) == true) + Utils.check((b_script is Object) == true) + Utils.check(is_instance_of(b_script, TYPE_OBJECT) == true) + Utils.check(is_instance_of(b_script, Object) == true) + Utils.check((b_script is RefCounted) == true) + Utils.check(is_instance_of(b_script, RefCounted) == true) + Utils.check((b_script is A) == true) + Utils.check(is_instance_of(b_script, A) == true) + Utils.check((b_script is B) == true) + Utils.check(is_instance_of(b_script, B) == true) + Utils.check((b_script is Node) == false) + Utils.check(is_instance_of(b_script, Node) == false) + Utils.check((b_script is int) == false) + Utils.check(is_instance_of(b_script, TYPE_INT) == false) var var_null: Variant = null - assert((var_null is Variant) == true) - assert((var_null is int) == false) - assert(is_instance_of(var_null, TYPE_INT) == false) - assert((var_null is Object) == false) - assert(is_instance_of(var_null, TYPE_OBJECT) == false) - assert((var_null is RefCounted) == false) - assert(is_instance_of(var_null, RefCounted) == false) - assert((var_null is A) == false) - assert(is_instance_of(var_null, A) == false) + Utils.check((var_null is Variant) == true) + Utils.check((var_null is int) == false) + Utils.check(is_instance_of(var_null, TYPE_INT) == false) + Utils.check((var_null is Object) == false) + Utils.check(is_instance_of(var_null, TYPE_OBJECT) == false) + Utils.check((var_null is RefCounted) == false) + Utils.check(is_instance_of(var_null, RefCounted) == false) + Utils.check((var_null is A) == false) + Utils.check(is_instance_of(var_null, A) == false) const const_null: Variant = null - assert((const_null is Variant) == true) - assert((const_null is int) == false) - assert(is_instance_of(const_null, TYPE_INT) == false) - assert((const_null is Object) == false) - assert(is_instance_of(const_null, TYPE_OBJECT) == false) - assert((const_null is RefCounted) == false) - assert(is_instance_of(const_null, RefCounted) == false) - assert((const_null is A) == false) - assert(is_instance_of(const_null, A) == false) + Utils.check((const_null is Variant) == true) + Utils.check((const_null is int) == false) + Utils.check(is_instance_of(const_null, TYPE_INT) == false) + Utils.check((const_null is Object) == false) + Utils.check(is_instance_of(const_null, TYPE_OBJECT) == false) + Utils.check((const_null is RefCounted) == false) + Utils.check(is_instance_of(const_null, RefCounted) == false) + Utils.check((const_null is A) == false) + Utils.check(is_instance_of(const_null, A) == false) print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd index b000c82717..fe0274c27b 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd @@ -10,206 +10,205 @@ class Members: var two: Array[int] = one func check_passing() -> bool: - assert(str(one) == '[104]') - assert(str(two) == '[104]') + Utils.check(str(one) == '[104]') + Utils.check(str(two) == '[104]') two.push_back(582) - assert(str(one) == '[104, 582]') - assert(str(two) == '[104, 582]') + Utils.check(str(one) == '[104, 582]') + Utils.check(str(two) == '[104, 582]') two = [486] - assert(str(one) == '[104, 582]') - assert(str(two) == '[486]') + Utils.check(str(one) == '[104, 582]') + Utils.check(str(two) == '[486]') return true @warning_ignore("unsafe_method_access") -@warning_ignore("assert_always_true") @warning_ignore("return_value_discarded") func test(): var untyped_basic = [459] - assert(str(untyped_basic) == '[459]') - assert(untyped_basic.get_typed_builtin() == TYPE_NIL) + Utils.check(str(untyped_basic) == '[459]') + Utils.check(untyped_basic.get_typed_builtin() == TYPE_NIL) var inferred_basic := [366] - assert(str(inferred_basic) == '[366]') - assert(inferred_basic.get_typed_builtin() == TYPE_NIL) + Utils.check(str(inferred_basic) == '[366]') + Utils.check(inferred_basic.get_typed_builtin() == TYPE_NIL) var typed_basic: Array = [521] - assert(str(typed_basic) == '[521]') - assert(typed_basic.get_typed_builtin() == TYPE_NIL) + Utils.check(str(typed_basic) == '[521]') + Utils.check(typed_basic.get_typed_builtin() == TYPE_NIL) var empty_floats: Array[float] = [] - assert(str(empty_floats) == '[]') - assert(empty_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(empty_floats) == '[]') + Utils.check(empty_floats.get_typed_builtin() == TYPE_FLOAT) untyped_basic = empty_floats - assert(untyped_basic.get_typed_builtin() == TYPE_FLOAT) + Utils.check(untyped_basic.get_typed_builtin() == TYPE_FLOAT) inferred_basic = empty_floats - assert(inferred_basic.get_typed_builtin() == TYPE_FLOAT) + Utils.check(inferred_basic.get_typed_builtin() == TYPE_FLOAT) typed_basic = empty_floats - assert(typed_basic.get_typed_builtin() == TYPE_FLOAT) + Utils.check(typed_basic.get_typed_builtin() == TYPE_FLOAT) empty_floats.push_back(705.0) untyped_basic.push_back(430.0) inferred_basic.push_back(263.0) typed_basic.push_back(518.0) - assert(str(empty_floats) == '[705, 430, 263, 518]') - assert(str(untyped_basic) == '[705, 430, 263, 518]') - assert(str(inferred_basic) == '[705, 430, 263, 518]') - assert(str(typed_basic) == '[705, 430, 263, 518]') + Utils.check(str(empty_floats) == '[705, 430, 263, 518]') + Utils.check(str(untyped_basic) == '[705, 430, 263, 518]') + Utils.check(str(inferred_basic) == '[705, 430, 263, 518]') + Utils.check(str(typed_basic) == '[705, 430, 263, 518]') const constant_float := 950.0 const constant_int := 170 var typed_float := 954.0 var filled_floats: Array[float] = [constant_float, constant_int, typed_float, empty_floats[1] + empty_floats[2]] - assert(str(filled_floats) == '[950, 170, 954, 693]') - assert(filled_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(filled_floats) == '[950, 170, 954, 693]') + Utils.check(filled_floats.get_typed_builtin() == TYPE_FLOAT) var casted_floats := [empty_floats[2] * 2] as Array[float] - assert(str(casted_floats) == '[526]') - assert(casted_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(casted_floats) == '[526]') + Utils.check(casted_floats.get_typed_builtin() == TYPE_FLOAT) var returned_floats = (func () -> Array[float]: return [554]).call() - assert(str(returned_floats) == '[554]') - assert(returned_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(returned_floats) == '[554]') + Utils.check(returned_floats.get_typed_builtin() == TYPE_FLOAT) var passed_floats = floats_identity([663.0 if randf() > 0.5 else 663.0]) - assert(str(passed_floats) == '[663]') - assert(passed_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(passed_floats) == '[663]') + Utils.check(passed_floats.get_typed_builtin() == TYPE_FLOAT) var default_floats = (func (floats: Array[float] = [364.0]): return floats).call() - assert(str(default_floats) == '[364]') - assert(default_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(default_floats) == '[364]') + Utils.check(default_floats.get_typed_builtin() == TYPE_FLOAT) var typed_int := 556 var converted_floats: Array[float] = [typed_int] converted_floats.push_back(498) - assert(str(converted_floats) == '[556, 498]') - assert(converted_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(converted_floats) == '[556, 498]') + Utils.check(converted_floats.get_typed_builtin() == TYPE_FLOAT) const constant_basic = [228] - assert(str(constant_basic) == '[228]') - assert(constant_basic.get_typed_builtin() == TYPE_NIL) + Utils.check(str(constant_basic) == '[228]') + Utils.check(constant_basic.get_typed_builtin() == TYPE_NIL) const constant_floats: Array[float] = [constant_float - constant_basic[0] - constant_int] - assert(str(constant_floats) == '[552]') - assert(constant_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(constant_floats) == '[552]') + Utils.check(constant_floats.get_typed_builtin() == TYPE_FLOAT) var source_floats: Array[float] = [999.74] untyped_basic = source_floats var destination_floats: Array[float] = untyped_basic destination_floats[0] -= 0.74 - assert(str(source_floats) == '[999]') - assert(str(untyped_basic) == '[999]') - assert(str(destination_floats) == '[999]') - assert(destination_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(source_floats) == '[999]') + Utils.check(str(untyped_basic) == '[999]') + Utils.check(str(destination_floats) == '[999]') + Utils.check(destination_floats.get_typed_builtin() == TYPE_FLOAT) var duplicated_floats := empty_floats.duplicate().slice(2, 3) duplicated_floats[0] *= 3 - assert(str(duplicated_floats) == '[789]') - assert(duplicated_floats.get_typed_builtin() == TYPE_FLOAT) + Utils.check(str(duplicated_floats) == '[789]') + Utils.check(duplicated_floats.get_typed_builtin() == TYPE_FLOAT) var b_objects: Array[B] = [B.new(), B.new() as A, null] - assert(b_objects.size() == 3) - assert(b_objects.get_typed_builtin() == TYPE_OBJECT) - assert(b_objects.get_typed_script() == B) + Utils.check(b_objects.size() == 3) + Utils.check(b_objects.get_typed_builtin() == TYPE_OBJECT) + Utils.check(b_objects.get_typed_script() == B) var a_objects: Array[A] = [A.new(), B.new(), null, b_objects[0]] - assert(a_objects.size() == 4) - assert(a_objects.get_typed_builtin() == TYPE_OBJECT) - assert(a_objects.get_typed_script() == A) + Utils.check(a_objects.size() == 4) + Utils.check(a_objects.get_typed_builtin() == TYPE_OBJECT) + Utils.check(a_objects.get_typed_script() == A) var a_passed = (func check_a_passing(p_objects: Array[A]): return p_objects.size()).call(a_objects) - assert(a_passed == 4) + Utils.check(a_passed == 4) var b_passed = (func check_b_passing(basic: Array): return basic[0] != null).call(b_objects) - assert(b_passed == true) + Utils.check(b_passed == true) var empty_strings: Array[String] = [] var empty_bools: Array[bool] = [] var empty_basic_one := [] var empty_basic_two := [] - assert(empty_strings == empty_bools) - assert(empty_basic_one == empty_basic_two) - assert(empty_strings.hash() == empty_bools.hash()) - assert(empty_basic_one.hash() == empty_basic_two.hash()) + Utils.check(empty_strings == empty_bools) + Utils.check(empty_basic_one == empty_basic_two) + Utils.check(empty_strings.hash() == empty_bools.hash()) + Utils.check(empty_basic_one.hash() == empty_basic_two.hash()) var assign_source: Array[int] = [527] var assign_target: Array[int] = [] assign_target.assign(assign_source) - assert(str(assign_source) == '[527]') - assert(str(assign_target) == '[527]') + Utils.check(str(assign_source) == '[527]') + Utils.check(str(assign_target) == '[527]') assign_source.push_back(657) - assert(str(assign_source) == '[527, 657]') - assert(str(assign_target) == '[527]') + Utils.check(str(assign_source) == '[527, 657]') + Utils.check(str(assign_target) == '[527]') var defaults_passed = (func check_defaults_passing(one: Array[int] = [], two := one): one.push_back(887) two.push_back(198) - assert(str(one) == '[887, 198]') - assert(str(two) == '[887, 198]') + Utils.check(str(one) == '[887, 198]') + Utils.check(str(two) == '[887, 198]') two = [130] - assert(str(one) == '[887, 198]') - assert(str(two) == '[130]') + Utils.check(str(one) == '[887, 198]') + Utils.check(str(two) == '[130]') return true ).call() - assert(defaults_passed == true) + Utils.check(defaults_passed == true) var members := Members.new() var members_passed := members.check_passing() - assert(members_passed == true) + Utils.check(members_passed == true) var resized_basic: Array = [] resized_basic.resize(1) - assert(typeof(resized_basic[0]) == TYPE_NIL) - assert(resized_basic[0] == null) + Utils.check(typeof(resized_basic[0]) == TYPE_NIL) + Utils.check(resized_basic[0] == null) var resized_ints: Array[int] = [] resized_ints.resize(1) - assert(typeof(resized_ints[0]) == TYPE_INT) - assert(resized_ints[0] == 0) + Utils.check(typeof(resized_ints[0]) == TYPE_INT) + Utils.check(resized_ints[0] == 0) var resized_arrays: Array[Array] = [] resized_arrays.resize(1) - assert(typeof(resized_arrays[0]) == TYPE_ARRAY) + Utils.check(typeof(resized_arrays[0]) == TYPE_ARRAY) resized_arrays[0].resize(1) resized_arrays[0][0] = 523 - assert(str(resized_arrays) == '[[523]]') + Utils.check(str(resized_arrays) == '[[523]]') var resized_objects: Array[Object] = [] resized_objects.resize(1) - assert(typeof(resized_objects[0]) == TYPE_NIL) - assert(resized_objects[0] == null) + Utils.check(typeof(resized_objects[0]) == TYPE_NIL) + Utils.check(resized_objects[0] == null) var typed_enums: Array[E] = [] typed_enums.resize(1) - assert(str(typed_enums) == '[0]') + Utils.check(str(typed_enums) == '[0]') typed_enums[0] = E.E0 - assert(str(typed_enums) == '[391]') - assert(typed_enums.get_typed_builtin() == TYPE_INT) + Utils.check(str(typed_enums) == '[391]') + Utils.check(typed_enums.get_typed_builtin() == TYPE_INT) const const_enums: Array[E] = [] - assert(const_enums.get_typed_builtin() == TYPE_INT) - assert(const_enums.get_typed_class_name() == &'') + Utils.check(const_enums.get_typed_builtin() == TYPE_INT) + Utils.check(const_enums.get_typed_class_name() == &'') var a := A.new() var typed_natives: Array[RefCounted] = [a] var typed_scripts = Array(typed_natives, TYPE_OBJECT, "RefCounted", A) - assert(typed_scripts[0] == a) + Utils.check(typed_scripts[0] == a) print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.gd new file mode 100644 index 0000000000..65f5e7da07 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.gd @@ -0,0 +1,20 @@ +func print_untyped(dictionary = { 0: 1 }) -> void: + print(dictionary) + print(dictionary.get_typed_key_builtin()) + print(dictionary.get_typed_value_builtin()) + +func print_inferred(dictionary := { 2: 3 }) -> void: + print(dictionary) + print(dictionary.get_typed_key_builtin()) + print(dictionary.get_typed_value_builtin()) + +func print_typed(dictionary: Dictionary[int, int] = { 4: 5 }) -> void: + print(dictionary) + print(dictionary.get_typed_key_builtin()) + print(dictionary.get_typed_value_builtin()) + +func test(): + print_untyped() + print_inferred() + print_typed() + print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.out b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.out new file mode 100644 index 0000000000..c31561bee3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.out @@ -0,0 +1,11 @@ +GDTEST_OK +{ 0: 1 } +0 +0 +{ 2: 3 } +0 +0 +{ 4: 5 } +2 +2 +ok diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.gd new file mode 100644 index 0000000000..0aa3de2c4a --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.gd @@ -0,0 +1,4 @@ +func test(): + var dict := { 0: 0 } + dict[0] = 1 + print(dict[0]) diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.out b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.out new file mode 100644 index 0000000000..a7f1357bb2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.out @@ -0,0 +1,2 @@ +GDTEST_OK +1 diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd new file mode 100644 index 0000000000..9d3fffd1de --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd @@ -0,0 +1,214 @@ +class A: pass +class B extends A: pass + +enum E { E0 = 391, E1 = 193 } + +func floats_identity(floats: Dictionary[float, float]): return floats + +class Members: + var one: Dictionary[int, int] = { 104: 401 } + var two: Dictionary[int, int] = one + + func check_passing() -> bool: + Utils.check(str(one) == '{ 104: 401 }') + Utils.check(str(two) == '{ 104: 401 }') + two[582] = 285 + Utils.check(str(one) == '{ 104: 401, 582: 285 }') + Utils.check(str(two) == '{ 104: 401, 582: 285 }') + two = { 486: 684 } + Utils.check(str(one) == '{ 104: 401, 582: 285 }') + Utils.check(str(two) == '{ 486: 684 }') + return true + + +@warning_ignore("unsafe_method_access") +@warning_ignore("assert_always_true") +@warning_ignore("return_value_discarded") +func test(): + var untyped_basic = { 459: 954 } + Utils.check(str(untyped_basic) == '{ 459: 954 }') + Utils.check(untyped_basic.get_typed_key_builtin() == TYPE_NIL) + Utils.check(untyped_basic.get_typed_value_builtin() == TYPE_NIL) + + var inferred_basic := { 366: 663 } + Utils.check(str(inferred_basic) == '{ 366: 663 }') + Utils.check(inferred_basic.get_typed_key_builtin() == TYPE_NIL) + Utils.check(inferred_basic.get_typed_value_builtin() == TYPE_NIL) + + var typed_basic: Dictionary = { 521: 125 } + Utils.check(str(typed_basic) == '{ 521: 125 }') + Utils.check(typed_basic.get_typed_key_builtin() == TYPE_NIL) + Utils.check(typed_basic.get_typed_value_builtin() == TYPE_NIL) + + + var empty_floats: Dictionary[float, float] = {} + Utils.check(str(empty_floats) == '{ }') + Utils.check(empty_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(empty_floats.get_typed_value_builtin() == TYPE_FLOAT) + + untyped_basic = empty_floats + Utils.check(untyped_basic.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(untyped_basic.get_typed_value_builtin() == TYPE_FLOAT) + + inferred_basic = empty_floats + Utils.check(inferred_basic.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(inferred_basic.get_typed_value_builtin() == TYPE_FLOAT) + + typed_basic = empty_floats + Utils.check(typed_basic.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(typed_basic.get_typed_value_builtin() == TYPE_FLOAT) + + empty_floats[705.0] = 507.0 + untyped_basic[430.0] = 34.0 + inferred_basic[263.0] = 362.0 + typed_basic[518.0] = 815.0 + Utils.check(str(empty_floats) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }') + Utils.check(str(untyped_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }') + Utils.check(str(inferred_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }') + Utils.check(str(typed_basic) == '{ 705: 507, 430: 34, 263: 362, 518: 815 }') + + + const constant_float := 950.0 + const constant_int := 170 + var typed_float := 954.0 + var filled_floats: Dictionary[float, float] = { constant_float: constant_int, typed_float: empty_floats[430.0] + empty_floats[263.0] } + Utils.check(str(filled_floats) == '{ 950: 170, 954: 396 }') + Utils.check(filled_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(filled_floats.get_typed_value_builtin() == TYPE_FLOAT) + + var casted_floats := { empty_floats[263.0] * 2: empty_floats[263.0] / 2 } as Dictionary[float, float] + Utils.check(str(casted_floats) == '{ 724: 181 }') + Utils.check(casted_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(casted_floats.get_typed_value_builtin() == TYPE_FLOAT) + + var returned_floats = (func () -> Dictionary[float, float]: return { 554: 455 }).call() + Utils.check(str(returned_floats) == '{ 554: 455 }') + Utils.check(returned_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(returned_floats.get_typed_value_builtin() == TYPE_FLOAT) + + var passed_floats = floats_identity({ 663.0 if randf() > 0.5 else 663.0: 366.0 if randf() <= 0.5 else 366.0 }) + Utils.check(str(passed_floats) == '{ 663: 366 }') + Utils.check(passed_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(passed_floats.get_typed_value_builtin() == TYPE_FLOAT) + + var default_floats = (func (floats: Dictionary[float, float] = { 364.0: 463.0 }): return floats).call() + Utils.check(str(default_floats) == '{ 364: 463 }') + Utils.check(default_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(default_floats.get_typed_value_builtin() == TYPE_FLOAT) + + var typed_int := 556 + var converted_floats: Dictionary[float, float] = { typed_int: typed_int } + converted_floats[498.0] = 894 + Utils.check(str(converted_floats) == '{ 556: 556, 498: 894 }') + Utils.check(converted_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(converted_floats.get_typed_value_builtin() == TYPE_FLOAT) + + + const constant_basic = { 228: 822 } + Utils.check(str(constant_basic) == '{ 228: 822 }') + Utils.check(constant_basic.get_typed_key_builtin() == TYPE_NIL) + Utils.check(constant_basic.get_typed_value_builtin() == TYPE_NIL) + + const constant_floats: Dictionary[float, float] = { constant_float - constant_basic[228] - constant_int: constant_float + constant_basic[228] + constant_int } + Utils.check(str(constant_floats) == '{ -42: 1942 }') + Utils.check(constant_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(constant_floats.get_typed_value_builtin() == TYPE_FLOAT) + + + var source_floats: Dictionary[float, float] = { 999.74: 47.999 } + untyped_basic = source_floats + var destination_floats: Dictionary[float, float] = untyped_basic + destination_floats[999.74] -= 0.999 + Utils.check(str(source_floats) == '{ 999.74: 47 }') + Utils.check(str(untyped_basic) == '{ 999.74: 47 }') + Utils.check(str(destination_floats) == '{ 999.74: 47 }') + Utils.check(destination_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(destination_floats.get_typed_value_builtin() == TYPE_FLOAT) + + + var duplicated_floats := empty_floats.duplicate() + duplicated_floats.erase(705.0) + duplicated_floats.erase(430.0) + duplicated_floats.erase(518.0) + duplicated_floats[263.0] *= 3 + Utils.check(str(duplicated_floats) == '{ 263: 1086 }') + Utils.check(duplicated_floats.get_typed_key_builtin() == TYPE_FLOAT) + Utils.check(duplicated_floats.get_typed_value_builtin() == TYPE_FLOAT) + + + var b_objects: Dictionary[int, B] = { 0: B.new(), 1: B.new() as A, 2: null } + Utils.check(b_objects.size() == 3) + Utils.check(b_objects.get_typed_value_builtin() == TYPE_OBJECT) + Utils.check(b_objects.get_typed_value_script() == B) + + var a_objects: Dictionary[int, A] = { 0: A.new(), 1: B.new(), 2: null, 3: b_objects[0] } + Utils.check(a_objects.size() == 4) + Utils.check(a_objects.get_typed_value_builtin() == TYPE_OBJECT) + Utils.check(a_objects.get_typed_value_script() == A) + + var a_passed = (func check_a_passing(p_objects: Dictionary[int, A]): return p_objects.size()).call(a_objects) + Utils.check(a_passed == 4) + + var b_passed = (func check_b_passing(basic: Dictionary): return basic[0] != null).call(b_objects) + Utils.check(b_passed == true) + + + var empty_strings: Dictionary[String, String] = {} + var empty_bools: Dictionary[bool, bool] = {} + var empty_basic_one := {} + var empty_basic_two := {} + Utils.check(empty_strings == empty_bools) + Utils.check(empty_basic_one == empty_basic_two) + Utils.check(empty_strings.hash() == empty_bools.hash()) + Utils.check(empty_basic_one.hash() == empty_basic_two.hash()) + + + var assign_source: Dictionary[int, int] = { 527: 725 } + var assign_target: Dictionary[int, int] = {} + assign_target.assign(assign_source) + Utils.check(str(assign_source) == '{ 527: 725 }') + Utils.check(str(assign_target) == '{ 527: 725 }') + assign_source[657] = 756 + Utils.check(str(assign_source) == '{ 527: 725, 657: 756 }') + Utils.check(str(assign_target) == '{ 527: 725 }') + + + var defaults_passed = (func check_defaults_passing(one: Dictionary[int, int] = {}, two := one): + one[887] = 788 + two[198] = 891 + Utils.check(str(one) == '{ 887: 788, 198: 891 }') + Utils.check(str(two) == '{ 887: 788, 198: 891 }') + two = {130: 31} + Utils.check(str(one) == '{ 887: 788, 198: 891 }') + Utils.check(str(two) == '{ 130: 31 }') + return true + ).call() + Utils.check(defaults_passed == true) + + + var members := Members.new() + var members_passed := members.check_passing() + Utils.check(members_passed == true) + + + var typed_enums: Dictionary[E, E] = {} + typed_enums[E.E0] = E.E1 + Utils.check(str(typed_enums) == '{ 391: 193 }') + Utils.check(typed_enums.get_typed_key_builtin() == TYPE_INT) + Utils.check(typed_enums.get_typed_value_builtin() == TYPE_INT) + + const const_enums: Dictionary[E, E] = {} + Utils.check(const_enums.get_typed_key_builtin() == TYPE_INT) + Utils.check(const_enums.get_typed_key_class_name() == &'') + Utils.check(const_enums.get_typed_value_builtin() == TYPE_INT) + Utils.check(const_enums.get_typed_value_class_name() == &'') + + + var a := A.new() + var b := B.new() + var typed_natives: Dictionary[RefCounted, RefCounted] = { a: b } + var typed_scripts = Dictionary(typed_natives, TYPE_OBJECT, "RefCounted", A, TYPE_OBJECT, "RefCounted", B) + Utils.check(typed_scripts[a] == b) + + + print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.out b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.out new file mode 100644 index 0000000000..1b47ed10dc --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.out @@ -0,0 +1,2 @@ +GDTEST_OK +ok diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.gd new file mode 100644 index 0000000000..f4a23ade14 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.gd @@ -0,0 +1,9 @@ +class Inner: + var prop = "Inner" + +var dict: Dictionary[int, Inner] = { 0: Inner.new() } + + +func test(): + var element: Inner = dict[0] + print(element.prop) diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.out b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.out new file mode 100644 index 0000000000..8f250d2632 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.out @@ -0,0 +1,2 @@ +GDTEST_OK +Inner diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd new file mode 100644 index 0000000000..9e1041db54 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd @@ -0,0 +1,23 @@ +var member := 1 + +func test(): + var number := 1 + var string := "1" + var vector := Vector2i(1, 0) + var array_assign := [1] + var array_index := [1] + var dictionary := { x = 0 } + + var lambda := func (): + member = 2 # Member variable, not captured. + number = 2 # Local variable, captured. + string += "2" # Test compound assignment operator. + vector.x = 2 # Test subscript assignment. + array_assign = [2] # Pass-by-reference type, reassignment. + array_index[0] = 2 # Pass-by-reference type, index access. + dictionary.x = 2 # Pass-by-reference type, attribute access. + + prints("lambda", member, number, string, vector, array_assign, array_index, dictionary) + + lambda.call() + prints("outer", member, number, string, vector, array_assign, array_index, dictionary) diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out new file mode 100644 index 0000000000..e6a1cab77d --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out @@ -0,0 +1,19 @@ +GDTEST_OK +>> WARNING +>> Line: 13 +>> CONFUSABLE_CAPTURE_REASSIGNMENT +>> Reassigning lambda capture does not modify the outer local variable "number". +>> WARNING +>> Line: 14 +>> CONFUSABLE_CAPTURE_REASSIGNMENT +>> Reassigning lambda capture does not modify the outer local variable "string". +>> WARNING +>> Line: 15 +>> CONFUSABLE_CAPTURE_REASSIGNMENT +>> Reassigning lambda capture does not modify the outer local variable "vector". +>> WARNING +>> Line: 16 +>> CONFUSABLE_CAPTURE_REASSIGNMENT +>> Reassigning lambda capture does not modify the outer local variable "array_assign". +lambda 2 2 12 (2, 0) [2] [2] { &"x": 2 } +outer 2 1 1 (1, 0) [1] [2] { &"x": 2 } diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd index 13e3edf93f..f3a8661acf 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd +++ b/modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd @@ -7,3 +7,17 @@ var has_no_zero: HasNoZero # Warning, because there is no `0` in the enum. func test(): print(has_zero) print(has_no_zero) + + +# GH-94634. A parameter is either mandatory or has a default value. +func test_no_exec(param: HasNoZero) -> void: + print(param) + + # Loop iterator always has a value. + for i: HasNoZero in HasNoZero.values(): + print(i) + + match param: + # Pattern bind always has a value. + var x: + print(x) diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.gd b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.gd new file mode 100644 index 0000000000..95d497c3f3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.gd @@ -0,0 +1,7 @@ +extends "./non_tool_extends_tool.notest.gd" + +class InnerClass extends "./non_tool_extends_tool.notest.gd": + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.notest.gd b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.notest.gd new file mode 100644 index 0000000000..07427846d1 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.notest.gd @@ -0,0 +1 @@ +@tool diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.out b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.out new file mode 100644 index 0000000000..f65caf5222 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.out @@ -0,0 +1,9 @@ +GDTEST_OK +>> WARNING +>> Line: 1 +>> MISSING_TOOL +>> The base class script has the "@tool" annotation, but this script does not have it. +>> WARNING +>> Line: 3 +>> MISSING_TOOL +>> The base class script has the "@tool" annotation, but this script does not have it. diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.gd b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.gd new file mode 100644 index 0000000000..a452307d99 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.gd @@ -0,0 +1,9 @@ +@warning_ignore("missing_tool") +extends "./non_tool_extends_tool.notest.gd" + +@warning_ignore("missing_tool") +class InnerClass extends "./non_tool_extends_tool.notest.gd": + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.out b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.out new file mode 100644 index 0000000000..d73c5eb7cd --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.out @@ -0,0 +1 @@ +GDTEST_OK diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd b/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd index d937dfdcfe..37f118dc5d 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd +++ b/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd @@ -1,12 +1,29 @@ -signal s1() -signal s2() -signal s3() +# Doesn't produce the warning: +signal used_as_first_class_signal() +signal used_with_signal_constructor() +signal used_with_signal_emit() +signal used_with_object_emit_signal() +signal used_with_object_connect() +signal used_with_object_disconnect() +signal used_with_self_prefix() + +# Produce the warning: +signal used_with_dynamic_name() +signal just_unused() @warning_ignore("unused_signal") -signal s4() +signal unused_but_ignored() func no_exec(): - s1.emit() - print(s2) + print(used_as_first_class_signal) + print(Signal(self, "used_with_signal_constructor")) + used_with_signal_emit.emit() + print(emit_signal("used_with_object_emit_signal")) + print(connect("used_with_object_connect", Callable())) + disconnect("used_with_object_disconnect", Callable()) + print(self.emit_signal("used_with_self_prefix")) + + var dynamic_name := "used_with_dynamic_name" + print(emit_signal(dynamic_name)) func test(): pass diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.out b/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.out index ff57017830..39ddf91c76 100644 --- a/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.out +++ b/modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.out @@ -1,5 +1,9 @@ GDTEST_OK >> WARNING ->> Line: 3 +>> Line: 11 >> UNUSED_SIGNAL ->> The signal "s3" is declared but never explicitly used in the class. +>> The signal "used_with_dynamic_name" is declared but never explicitly used in the class. +>> WARNING +>> Line: 12 +>> UNUSED_SIGNAL +>> The signal "just_unused" is declared but never explicitly used in the class. |