summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/tests
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/tests')
-rw-r--r--modules/gdscript/tests/README.md2
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp2
-rw-r--r--modules/gdscript/tests/scripts/.editorconfig12
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/cyclic_ref_external.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.gd3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/for_loop_wrong_specified_type_with_literal_dictionary.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assign_differently_typed.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_assignment.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_init_with_unconvertible_in_literal.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.gd7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/typed_dictionary_pass_differently_to_typed.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/assymetric_assignment_good.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd25
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enums_in_range_call.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser.gd17
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser.out3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_base1.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_base2.notest.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1.notest.gd12
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1_base.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1c.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1d.notest.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1e.notest.gd0
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script1f.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script2.notest.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_parser_script3.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/for_range_usage.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/return_conversions.gd24
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/ternary_hard_infer.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/type_test_usage.gd193
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd159
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.gd20
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_as_default_parameter.out11
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_inferred_access_isnt_constant.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.gd214
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_usage.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_dictionary_with_custom_class.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.gd23
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/confusable_capture_reassignment.out19
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/enum_without_default_value.gd14
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.gd7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool.out9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/non_tool_extends_tool_ignored.out1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.gd29
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/unused_signal.out8
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.cfg11
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.gd3
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.cfg5
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.cfg11
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.gd3
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.cfg19
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.gd7
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.cfg19
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.gd7
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.gd7
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.gd7
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_call.cfg25
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_call.gd18
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.cfg25
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.gd18
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.cfg25
-rw-r--r--modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.gd22
-rw-r--r--modules/gdscript/tests/scripts/completion/common/no_completion_in_string.cfg26
-rw-r--r--modules/gdscript/tests/scripts/completion/common/no_completion_in_string.gd19
-rw-r--r--modules/gdscript/tests/scripts/completion/common/self.cfg21
-rw-r--r--modules/gdscript/tests/scripts/completion/common/self.gd17
-rw-r--r--modules/gdscript/tests/scripts/completion/filter/organized_export.cfg6
-rw-r--r--modules/gdscript/tests/scripts/completion/filter/organized_export.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/filter/usage_internal.cfg4
-rw-r--r--modules/gdscript/tests/scripts/completion/filter/usage_internal.gd3
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.gd5
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.cfg (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.cfg)0
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.gd (renamed from modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd)0
-rw-r--r--modules/gdscript/tests/scripts/completion/index/array_type.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/index/array_type.gd10
-rw-r--r--modules/gdscript/tests/scripts/completion/index/array_value.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/index/array_value.gd10
-rw-r--r--modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.cfg11
-rw-r--r--modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.gd13
-rw-r--r--modules/gdscript/tests/scripts/completion/index/dictionary_type.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/index/dictionary_type.gd10
-rw-r--r--modules/gdscript/tests/scripts/completion/index/dictionary_value.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/index/dictionary_value.gd10
-rw-r--r--modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.cfg11
-rw-r--r--modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.gd13
-rw-r--r--modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.cfg9
-rw-r--r--modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.gd13
-rw-r--r--modules/gdscript/tests/scripts/completion/index/untyped_local.cfg5
-rw-r--r--modules/gdscript/tests/scripts/completion/index/untyped_local.gd10
-rw-r--r--modules/gdscript/tests/scripts/completion/index/untyped_property.cfg5
-rw-r--r--modules/gdscript/tests/scripts/completion/index/untyped_property.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/infered.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/infered.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/no_type.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/no_type.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint_broad.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint_broad.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.gd8
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/infered.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/infered.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/no_type.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/no_type.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint_broad.cfg13
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint_broad.gd9
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.cfg12
-rw-r--r--modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.gd9
-rw-r--r--modules/gdscript/tests/scripts/parser/.editorconfig2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/annotations.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/annotations.out24
-rw-r--r--modules/gdscript/tests/scripts/parser/features/class.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_arrays.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_arrays.out138
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_enum.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_enum.out40
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable.gd43
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable.out66
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable_global.notest.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_variable_unnamed.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd1
-rw-r--r--modules/gdscript/tests/scripts/parser/features/truthiness.gd40
-rw-r--r--modules/gdscript/tests/scripts/parser/features/truthiness.out65
-rw-r--r--modules/gdscript/tests/scripts/parser/features/typed_dictionaries.gd5
-rw-r--r--modules/gdscript/tests/scripts/parser/features/typed_dictionaries.out3
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.gd1
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/standalone_expression.gd13
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/standalone_expression.out8
-rw-r--r--modules/gdscript/tests/scripts/project.godot7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd9
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/array_string_stringname_equivalent.gd2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/constants_are_read_only.gd9
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/conversions_from_native_members.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd14
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd9
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.gd18
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.out3
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd26
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_captures.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_get_method.gd21
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_get_method.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/match_with_pattern_guards.gd2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/member_info.gd26
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/member_info.out24
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/metatypes.gd13
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/metatypes.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.gd20
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/self_destruction.gd50
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/self_destruction.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd11
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.gd62
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out26
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.gd13
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.gd15
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/standalone_calls_do_not_write_to_nil.gd14
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_array_init_with_untyped_in_literal.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.gd6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.out3
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.gd7
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.out2
-rw-r--r--modules/gdscript/tests/scripts/utils.notest.gd40
-rw-r--r--modules/gdscript/tests/test_completion.h2
225 files changed, 2273 insertions, 522 deletions
diff --git a/modules/gdscript/tests/README.md b/modules/gdscript/tests/README.md
index 714e38397f..4dc706f8d1 100644
--- a/modules/gdscript/tests/README.md
+++ b/modules/gdscript/tests/README.md
@@ -25,6 +25,8 @@ The config file contains two section:
- `cs: boolean = false`: If `true`, the test will be skipped when running a non C# build.
- `use_single_quotes: boolean = false`: Configures the corresponding editor setting for the test.
+- `add_node_path_literals: boolean = false`: Configures the corresponding editor setting for the test.
+- `add_string_name_literals: boolean = false`: Configures the corresponding editor setting for the test.
- `scene: String`: Allows to specify a scene which is opened while autocompletion is performed. If this is not set the test runner will search for a `.tscn` file with the same basename as the GDScript file. If that isn't found either, autocompletion will behave as if no scene was opened.
- `node_path: String`: The node path of the node which holds the current script inside of the scene. Defaults to the scene root node.
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index fbfa4a0a79..025fcbd32a 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -622,7 +622,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
enable_stdout();
result.status = GDTEST_COMPILER_ERROR;
result.output = get_text_for_status(result.status) + "\n";
- result.output = compiler.get_error();
+ result.output += compiler.get_error() + "\n";
if (!p_is_generating) {
result.passed = check_output(result.output);
}
diff --git a/modules/gdscript/tests/scripts/.editorconfig b/modules/gdscript/tests/scripts/.editorconfig
new file mode 100644
index 0000000000..da1efefe3c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/.editorconfig
@@ -0,0 +1,12 @@
+# This file is required to workaround `.editorconfig` autogeneration (see #96845).
+
+# Some tests handle invalid syntax deliberately; exclude relevant attributes.
+
+[parser/features/mixed_indentation_on_blank_lines.gd]
+trim_trailing_whitespace = false
+
+[parser/warnings/empty_file_newline.notest.gd]
+insert_final_newline = false
+
+[parser/warnings/empty_file_newline_comment.notest.gd]
+insert_final_newline = false
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.
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.cfg b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.cfg
new file mode 100644
index 0000000000..a8f26d83f9
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.cfg
@@ -0,0 +1,11 @@
+[input]
+add_node_path_literals=true
+[output]
+include=[
+ {"insert_text": "^\"property_of_a\""},
+ {"insert_text": "^\"name\""},
+]
+exclude=[
+ {"insert_text": "\"property_of_a\""},
+ {"insert_text": "\"name\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.gd b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.gd
new file mode 100644
index 0000000000..bfdb5c7995
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_node_path_tween.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A = preload("res://completion/class_a.notest.gd")
+
+func _ready() -> void:
+ var a := A.new()
+ var tween := get_tree().create_tween()
+ tween.tween_property(a, ➡)
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.cfg b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.cfg
new file mode 100644
index 0000000000..309fa8ed38
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.cfg
@@ -0,0 +1,9 @@
+[input]
+add_string_name_literals=true
+[output]
+include=[
+ {"insert_text": "&\"test_input_action\""},
+]
+exclude=[
+ {"insert_text": "\"test_input_action\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.gd b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.gd
new file mode 100644
index 0000000000..9b325e632d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/add_string_name_input_event.gd
@@ -0,0 +1,3 @@
+func _input(event: InputEvent) -> void:
+ event.is_action_pressed(➡)
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.cfg b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.cfg
new file mode 100644
index 0000000000..be9bd510e1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.cfg
@@ -0,0 +1,5 @@
+[output]
+include=[
+ {"insert_text": "\"property_of_a\""},
+ {"insert_text": "\"name\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.gd b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.gd
new file mode 100644
index 0000000000..a8e04a62a7
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/argument_options_inside_string_literal.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A = preload ("res://completion/class_a.notest.gd")
+
+func _ready() -> void:
+ var a := A.new()
+ var tween := get_tree().create_tween()
+ tween.tween_property(a, "➡")
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.cfg b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.cfg
new file mode 100644
index 0000000000..45d0ad0f3b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.cfg
@@ -0,0 +1,11 @@
+[input]
+add_node_path_literals=false
+[output]
+include=[
+ {"insert_text": "\"property_of_a\""},
+ {"insert_text": "\"name\""},
+]
+exclude=[
+ {"insert_text": "^\"property_of_a\""},
+ {"insert_text": "^\"name\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.gd b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.gd
new file mode 100644
index 0000000000..bfdb5c7995
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_node_path_tween.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A = preload("res://completion/class_a.notest.gd")
+
+func _ready() -> void:
+ var a := A.new()
+ var tween := get_tree().create_tween()
+ tween.tween_property(a, ➡)
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.cfg b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.cfg
new file mode 100644
index 0000000000..7a388d54e1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.cfg
@@ -0,0 +1,9 @@
+[input]
+add_string_name_literals=false
+[output]
+include=[
+ {"insert_text": "\"test_input_action\""},
+]
+exclude=[
+ {"insert_text": "&\"test_input_action\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.gd b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.gd
new file mode 100644
index 0000000000..9b325e632d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/string_literals/dont_add_string_name_input_event.gd
@@ -0,0 +1,3 @@
+func _input(event: InputEvent) -> void:
+ event.is_action_pressed(➡)
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.cfg b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.cfg
new file mode 100644
index 0000000000..e4759ac76b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.cfg
@@ -0,0 +1,19 @@
+[output]
+include=[
+ {"display": "new"},
+ {"display": "SIZE_EXPAND"},
+ {"display": "SIZE_EXPAND_FILL"},
+ {"display": "SIZE_FILL"},
+ {"display": "SIZE_SHRINK_BEGIN"},
+ {"display": "SIZE_SHRINK_CENTER"},
+ {"display": "SIZE_SHRINK_END"},
+]
+exclude=[
+ {"display": "Control.SIZE_EXPAND"},
+ {"display": "Control.SIZE_EXPAND_FILL"},
+ {"display": "Control.SIZE_FILL"},
+ {"display": "Control.SIZE_SHRINK_BEGIN"},
+ {"display": "Control.SIZE_SHRINK_CENTER"},
+ {"display": "Control.SIZE_SHRINK_END"},
+ {"display": "contro_var"}
+]
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.gd b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.gd
new file mode 100644
index 0000000000..4aeafb2e0a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute.gd
@@ -0,0 +1,7 @@
+extends Control
+
+var contro_var
+
+func _ready():
+ size_flags_horizontal = Control.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.cfg b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.cfg
new file mode 100644
index 0000000000..e4759ac76b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.cfg
@@ -0,0 +1,19 @@
+[output]
+include=[
+ {"display": "new"},
+ {"display": "SIZE_EXPAND"},
+ {"display": "SIZE_EXPAND_FILL"},
+ {"display": "SIZE_FILL"},
+ {"display": "SIZE_SHRINK_BEGIN"},
+ {"display": "SIZE_SHRINK_CENTER"},
+ {"display": "SIZE_SHRINK_END"},
+]
+exclude=[
+ {"display": "Control.SIZE_EXPAND"},
+ {"display": "Control.SIZE_EXPAND_FILL"},
+ {"display": "Control.SIZE_FILL"},
+ {"display": "Control.SIZE_SHRINK_BEGIN"},
+ {"display": "Control.SIZE_SHRINK_CENTER"},
+ {"display": "Control.SIZE_SHRINK_END"},
+ {"display": "contro_var"}
+]
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.gd b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.gd
new file mode 100644
index 0000000000..47e9bd5a67
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_attribute_identifier.gd
@@ -0,0 +1,7 @@
+extends Control
+
+var contro_var
+
+func _ready():
+ size_flags_horizontal = Control.SIZE➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.cfg b/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.cfg
new file mode 100644
index 0000000000..5cc4ec5fd3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ {"display": "Control.SIZE_EXPAND"},
+ {"display": "Control.SIZE_EXPAND_FILL"},
+ {"display": "Control.SIZE_FILL"},
+ {"display": "Control.SIZE_SHRINK_BEGIN"},
+ {"display": "Control.SIZE_SHRINK_CENTER"},
+ {"display": "Control.SIZE_SHRINK_END"},
+]
+exclude=[
+ {"display": "contro_var"}
+]
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.gd b/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.gd
new file mode 100644
index 0000000000..5c96720bd3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_identifier.gd
@@ -0,0 +1,7 @@
+extends Control
+
+var contro_var
+
+func _ready():
+ size_flags_horizontal = Con➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.cfg b/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.cfg
new file mode 100644
index 0000000000..5cc4ec5fd3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ {"display": "Control.SIZE_EXPAND"},
+ {"display": "Control.SIZE_EXPAND_FILL"},
+ {"display": "Control.SIZE_FILL"},
+ {"display": "Control.SIZE_SHRINK_BEGIN"},
+ {"display": "Control.SIZE_SHRINK_CENTER"},
+ {"display": "Control.SIZE_SHRINK_END"},
+]
+exclude=[
+ {"display": "contro_var"}
+]
diff --git a/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.gd b/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.gd
new file mode 100644
index 0000000000..d8bf13e51d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/assignment_options/enum_no_identifier.gd
@@ -0,0 +1,7 @@
+extends Control
+
+var contro_var
+
+func _ready():
+ size_flags_horizontal = ➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.cfg b/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.cfg
new file mode 100644
index 0000000000..5f08f9c265
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.cfg
@@ -0,0 +1,25 @@
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+
+ ; GDScript: identifiers.gd
+ {"display": "test_signal_1"},
+ {"display": "test_signal_2"},
+ {"display": "test_var_1"},
+ {"display": "test_var_2"},
+ {"display": "test_func_1"},
+ {"display": "test_func_2"},
+ {"display": "test_parameter_1"},
+ {"display": "test_parameter_2"},
+ {"display": "local_test_var_1"},
+ {"display": "local_test_var_2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.gd b/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.gd
new file mode 100644
index 0000000000..91488c25aa
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_call.gd
@@ -0,0 +1,18 @@
+extends "res://completion/class_a.notest.gd"
+
+signal test_signal_1(a)
+signal test_signal_2(a: int)
+
+var test_var_1
+var test_var_2: int
+
+func test_func_1(t):
+ pass
+
+func test_func_2(t: int) -> void:
+ pass
+
+func _init(test_parameter_1, test_parameter_2: String):
+ var local_test_var_1
+ var local_test_var_2: int
+ print(t➡)
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.cfg b/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.cfg
new file mode 100644
index 0000000000..5f08f9c265
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.cfg
@@ -0,0 +1,25 @@
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+
+ ; GDScript: identifiers.gd
+ {"display": "test_signal_1"},
+ {"display": "test_signal_2"},
+ {"display": "test_var_1"},
+ {"display": "test_var_2"},
+ {"display": "test_func_1"},
+ {"display": "test_func_2"},
+ {"display": "test_parameter_1"},
+ {"display": "test_parameter_2"},
+ {"display": "local_test_var_1"},
+ {"display": "local_test_var_2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.gd b/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.gd
new file mode 100644
index 0000000000..a2f5b7bc23
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_function_body.gd
@@ -0,0 +1,18 @@
+extends "res://completion/class_a.notest.gd"
+
+signal test_signal_1(a)
+signal test_signal_2(a: int)
+
+var test_var_1
+var test_var_2: int
+
+func test_func_1(t):
+ pass
+
+func test_func_2(t: int) -> void:
+ pass
+
+func _init(test_parameter_1, test_parameter_2: String):
+ var local_test_var_1
+ var local_test_var_2: int
+ t➡
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.cfg b/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.cfg
new file mode 100644
index 0000000000..5f08f9c265
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.cfg
@@ -0,0 +1,25 @@
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+
+ ; GDScript: identifiers.gd
+ {"display": "test_signal_1"},
+ {"display": "test_signal_2"},
+ {"display": "test_var_1"},
+ {"display": "test_var_2"},
+ {"display": "test_func_1"},
+ {"display": "test_func_2"},
+ {"display": "test_parameter_1"},
+ {"display": "test_parameter_2"},
+ {"display": "local_test_var_1"},
+ {"display": "local_test_var_2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.gd b/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.gd
new file mode 100644
index 0000000000..fed0b869c4
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/identifiers_in_unclosed_call.gd
@@ -0,0 +1,22 @@
+# godotengine/godot#92226
+extends "res://completion/class_a.notest.gd"
+
+signal test_signal_1(a)
+signal test_signal_2(a: int)
+
+var test_var_1
+var test_var_2: int
+
+func test_func_1(t):
+ pass
+
+func test_func_2(t: int) -> void:
+ pass
+
+func _init(test_parameter_1, test_parameter_2: String):
+ var local_test_var_1
+ var local_test_var_2: int
+ print(t➡
+
+ if true:
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.cfg b/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.cfg
new file mode 100644
index 0000000000..462846c9b2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.cfg
@@ -0,0 +1,26 @@
+scene="res://completion/get_node/get_node.tscn"
+[output]
+exclude=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+ {"display": "add_child"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+
+ ; GDScript: no_completion_in_string.gd
+ {"display": "test_signal_1"},
+ {"display": "test_signal_2"},
+ {"display": "test_var_1"},
+ {"display": "test_var_2"},
+ {"display": "test_func_1"},
+ {"display": "test_func_2"},
+ {"display": "test_parameter_1"},
+ {"display": "test_parameter_2"},
+ {"display": "local_test_var_1"},
+ {"display": "local_test_var_2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.gd b/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.gd
new file mode 100644
index 0000000000..da52af9fe3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/no_completion_in_string.gd
@@ -0,0 +1,19 @@
+# godotengine/godot#62945
+extends "res://completion/class_a.notest.gd"
+
+signal test_signal_1(a)
+signal test_signal_2(a: int)
+
+var test_var_1
+var test_var_2: int
+
+func test_func_1(t):
+ pass
+
+func test_func_2(t: int) -> void:
+ pass
+
+func _init(test_parameter_1, test_parameter_2: String):
+ var local_test_var_1
+ var local_test_var_2: int
+ var a = "➡"
diff --git a/modules/gdscript/tests/scripts/completion/common/self.cfg b/modules/gdscript/tests/scripts/completion/common/self.cfg
new file mode 100644
index 0000000000..871a404e3a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/self.cfg
@@ -0,0 +1,21 @@
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+
+ ; GDScript: self.gd
+ {"display": "test_signal_1"},
+ {"display": "test_signal_2"},
+ {"display": "test_var_1"},
+ {"display": "test_var_2"},
+ {"display": "test_func_1"},
+ {"display": "test_func_2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/common/self.gd b/modules/gdscript/tests/scripts/completion/common/self.gd
new file mode 100644
index 0000000000..ed181af0c5
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/common/self.gd
@@ -0,0 +1,17 @@
+extends "res://completion/class_a.notest.gd"
+
+signal test_signal_1(a)
+signal test_signal_2(a: int)
+
+var test_var_1
+var test_var_2: int
+
+func test_func_1(t):
+ pass
+
+func test_func_2(t: int) -> void:
+ pass
+
+func _init():
+ self.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/filter/organized_export.cfg b/modules/gdscript/tests/scripts/completion/filter/organized_export.cfg
new file mode 100644
index 0000000000..961a9ea58d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/filter/organized_export.cfg
@@ -0,0 +1,6 @@
+[output]
+exclude=[
+ {"display": "Test Category"},
+ {"display": "Test Group"},
+ {"display": "Test Subgroup"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/filter/organized_export.gd b/modules/gdscript/tests/scripts/completion/filter/organized_export.gd
new file mode 100644
index 0000000000..9fa9618cee
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/filter/organized_export.gd
@@ -0,0 +1,9 @@
+extends CPUParticles2D
+
+@export_category("Test Category")
+@export_group("Test Group")
+@export_subgroup("Test Subgroup")
+
+func _init():
+ t➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/filter/usage_internal.cfg b/modules/gdscript/tests/scripts/completion/filter/usage_internal.cfg
new file mode 100644
index 0000000000..8c5bff5eac
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/filter/usage_internal.cfg
@@ -0,0 +1,4 @@
+[output]
+exclude=[
+ {"display": "messages"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/filter/usage_internal.gd b/modules/gdscript/tests/scripts/completion/filter/usage_internal.gd
new file mode 100644
index 0000000000..484c1c0d10
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/filter/usage_internal.gd
@@ -0,0 +1,3 @@
+func test():
+ var trans = Translation.new()
+ trans.➡
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.cfg b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.cfg
new file mode 100644
index 0000000000..36c150f6e3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.cfg
@@ -0,0 +1,9 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+ {"display": "%UniqueA"},
+]
+exclude=[
+ {"display": "\"%UniqueA\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.gd b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.gd
new file mode 100644
index 0000000000..def050e938
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_unique.gd
@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+ $➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.cfg b/modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.cfg
index ae7d34d87d..ae7d34d87d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd b/modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.gd
index 7710c2d13b..7710c2d13b 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered/local_infered.gd
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.cfg b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.cfg
index 9c580b711d..9c580b711d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.gd
index 6b29bf5526..6b29bf5526 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/class_local_infered_scene.gd
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.cfg b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.cfg
index 446198dd35..446198dd35 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.gd
index 7710c2d13b..7710c2d13b 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_infered_scene/native_local_infered_scene.gd
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.cfg b/modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.cfg
index ae7d34d87d..ae7d34d87d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd b/modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.gd
index 97b288334e..97b288334e 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered/member_infered.gd
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.cfg b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.cfg
index 9c580b711d..9c580b711d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.gd
index 402fd1d275..402fd1d275 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/class_member_infered_scene.gd
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.cfg b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.cfg
index 446198dd35..446198dd35 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.cfg
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.cfg
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.gd
index 97b288334e..97b288334e 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_infered_scene/native_member_infered_scene.gd
diff --git a/modules/gdscript/tests/scripts/completion/index/array_type.cfg b/modules/gdscript/tests/scripts/completion/index/array_type.cfg
new file mode 100644
index 0000000000..5cd5565d00
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/array_type.cfg
@@ -0,0 +1,9 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
+exclude=[
+ {"display": "append"},
+ {"display": "\"append\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/array_type.gd b/modules/gdscript/tests/scripts/completion/index/array_type.gd
new file mode 100644
index 0000000000..e0a15da556
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/array_type.gd
@@ -0,0 +1,10 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var array: Array
+
+ array[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/index/array_value.cfg b/modules/gdscript/tests/scripts/completion/index/array_value.cfg
new file mode 100644
index 0000000000..5cd5565d00
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/array_value.cfg
@@ -0,0 +1,9 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
+exclude=[
+ {"display": "append"},
+ {"display": "\"append\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/array_value.gd b/modules/gdscript/tests/scripts/completion/index/array_value.gd
new file mode 100644
index 0000000000..17451725bc
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/array_value.gd
@@ -0,0 +1,10 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var array = []
+
+ array[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.cfg b/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.cfg
new file mode 100644
index 0000000000..ecea284b5d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.cfg
@@ -0,0 +1,11 @@
+[output]
+include=[
+ {"display": "\"key1\""},
+ {"display": "\"key2\""},
+]
+exclude=[
+ {"display": "keys"},
+ {"display": "\"keys\""},
+ {"display": "key1"},
+ {"display": "key2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.gd b/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.gd
new file mode 100644
index 0000000000..06498c57a6
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/const_dictionary_keys.gd
@@ -0,0 +1,13 @@
+extends Node
+
+var outer
+
+const dict = {
+ "key1": "value",
+ "key2": null,
+}
+
+func _ready() -> void:
+ var inner
+
+ dict["➡"]
diff --git a/modules/gdscript/tests/scripts/completion/index/dictionary_type.cfg b/modules/gdscript/tests/scripts/completion/index/dictionary_type.cfg
new file mode 100644
index 0000000000..cddf7b8cc8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/dictionary_type.cfg
@@ -0,0 +1,9 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
+exclude=[
+ {"display": "keys"},
+ {"display": "\"keys\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/dictionary_type.gd b/modules/gdscript/tests/scripts/completion/index/dictionary_type.gd
new file mode 100644
index 0000000000..b02c62eea5
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/dictionary_type.gd
@@ -0,0 +1,10 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var dict: Dictionary
+
+ dict[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/index/dictionary_value.cfg b/modules/gdscript/tests/scripts/completion/index/dictionary_value.cfg
new file mode 100644
index 0000000000..cddf7b8cc8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/dictionary_value.cfg
@@ -0,0 +1,9 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
+exclude=[
+ {"display": "keys"},
+ {"display": "\"keys\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/dictionary_value.gd b/modules/gdscript/tests/scripts/completion/index/dictionary_value.gd
new file mode 100644
index 0000000000..60bf391716
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/dictionary_value.gd
@@ -0,0 +1,10 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var dict = {}
+
+ dict[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.cfg b/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.cfg
new file mode 100644
index 0000000000..ecea284b5d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.cfg
@@ -0,0 +1,11 @@
+[output]
+include=[
+ {"display": "\"key1\""},
+ {"display": "\"key2\""},
+]
+exclude=[
+ {"display": "keys"},
+ {"display": "\"keys\""},
+ {"display": "key1"},
+ {"display": "key2"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.gd b/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.gd
new file mode 100644
index 0000000000..2220cdcc59
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/local_dictionary_keys.gd
@@ -0,0 +1,13 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var dict: Dictionary = {
+ "key1": "value",
+ "key2": null,
+ }
+
+ dict["➡"]
diff --git a/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.cfg b/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.cfg
new file mode 100644
index 0000000000..8da525bff8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.cfg
@@ -0,0 +1,9 @@
+[output]
+exclude=[
+ {"display": "keys"},
+ {"display": "\"keys\""},
+ {"display": "key1"},
+ {"display": "key2"},
+ {"display": "\"key1\""},
+ {"display": "\"key2\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.gd b/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.gd
new file mode 100644
index 0000000000..ba8d7f76fd
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/property_dictionary_keys.gd
@@ -0,0 +1,13 @@
+extends Node
+
+var outer
+
+var dict = {
+ "key1": "value",
+ "key2": null,
+}
+
+func _ready() -> void:
+ var inner
+
+ dict["➡"]
diff --git a/modules/gdscript/tests/scripts/completion/index/untyped_local.cfg b/modules/gdscript/tests/scripts/completion/index/untyped_local.cfg
new file mode 100644
index 0000000000..1173043f94
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/untyped_local.cfg
@@ -0,0 +1,5 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/untyped_local.gd b/modules/gdscript/tests/scripts/completion/index/untyped_local.gd
new file mode 100644
index 0000000000..1a1157af02
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/untyped_local.gd
@@ -0,0 +1,10 @@
+extends Node
+
+var outer
+
+func _ready() -> void:
+ var inner
+
+ var array
+
+ array[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/index/untyped_property.cfg b/modules/gdscript/tests/scripts/completion/index/untyped_property.cfg
new file mode 100644
index 0000000000..1173043f94
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/untyped_property.cfg
@@ -0,0 +1,5 @@
+[output]
+include=[
+ {"display": "outer"},
+ {"display": "inner"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/index/untyped_property.gd b/modules/gdscript/tests/scripts/completion/index/untyped_property.gd
new file mode 100644
index 0000000000..9fa23da504
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/index/untyped_property.gd
@@ -0,0 +1,9 @@
+extends Node
+
+var outer
+var array
+
+func _ready() -> void:
+ var inner
+
+ array[i➡]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/infered.cfg b/modules/gdscript/tests/scripts/completion/types/local/infered.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/infered.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/infered.gd b/modules/gdscript/tests/scripts/completion/types/local/infered.gd
new file mode 100644
index 0000000000..f003c366a4
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/infered.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+ var test := A.new()
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/local/no_type.cfg b/modules/gdscript/tests/scripts/completion/types/local/no_type.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/no_type.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/no_type.gd b/modules/gdscript/tests/scripts/completion/types/local/no_type.gd
new file mode 100644
index 0000000000..f6b5ae3aef
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/no_type.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+ var test = A.new()
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint.cfg b/modules/gdscript/tests/scripts/completion/types/local/typehint.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint.gd b/modules/gdscript/tests/scripts/completion/types/local/typehint.gd
new file mode 100644
index 0000000000..24bcfc04fc
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+ var test: A
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.cfg b/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.gd b/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.gd
new file mode 100644
index 0000000000..88b4812c30
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint_broad.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+ var test: Node = A.new()
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.cfg b/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.gd b/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.gd
new file mode 100644
index 0000000000..8e226546f3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/local/typehint_incompatible.gd
@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+ var test: A = Node.new()
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/member/infered.cfg b/modules/gdscript/tests/scripts/completion/types/member/infered.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/infered.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/member/infered.gd b/modules/gdscript/tests/scripts/completion/types/member/infered.gd
new file mode 100644
index 0000000000..069abd7891
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/infered.gd
@@ -0,0 +1,9 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test := A.new()
+
+func a():
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/member/no_type.cfg b/modules/gdscript/tests/scripts/completion/types/member/no_type.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/no_type.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/member/no_type.gd b/modules/gdscript/tests/scripts/completion/types/member/no_type.gd
new file mode 100644
index 0000000000..9bb9549e97
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/no_type.gd
@@ -0,0 +1,9 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test = A.new()
+
+func a():
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint.cfg b/modules/gdscript/tests/scripts/completion/types/member/typehint.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint.gd b/modules/gdscript/tests/scripts/completion/types/member/typehint.gd
new file mode 100644
index 0000000000..7763a2e898
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint.gd
@@ -0,0 +1,9 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test: A
+
+func a():
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.cfg b/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.cfg
new file mode 100644
index 0000000000..81401316ec
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.cfg
@@ -0,0 +1,13 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+]
+exclude=[
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.gd b/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.gd
new file mode 100644
index 0000000000..a8506705a1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint_broad.gd
@@ -0,0 +1,9 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test: Node = A.new()
+
+func a():
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.cfg b/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.cfg
new file mode 100644
index 0000000000..8b68d51a89
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.cfg
@@ -0,0 +1,12 @@
+[output]
+include=[
+ ; Node
+ {"display": "add_child"},
+ {"display": "owner"},
+ {"display": "child_entered_tree"},
+
+ ; GDScript: class_a.notest.gd
+ {"display": "property_of_a"},
+ {"display": "func_of_a"},
+ {"display": "signal_of_a"},
+]
diff --git a/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.gd b/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.gd
new file mode 100644
index 0000000000..8b5a80cfb3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/types/member/typehint_incompatible.gd
@@ -0,0 +1,9 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test: A = Node.new()
+
+func a():
+ test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/parser/.editorconfig b/modules/gdscript/tests/scripts/parser/.editorconfig
deleted file mode 100644
index fa43b3ad78..0000000000
--- a/modules/gdscript/tests/scripts/parser/.editorconfig
+++ /dev/null
@@ -1,2 +0,0 @@
-[*.{gd,out}]
-trim_trailing_whitespace = false
diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.gd b/modules/gdscript/tests/scripts/parser/features/annotations.gd
index 7a7d6d953e..1e5d3fdcad 100644
--- a/modules/gdscript/tests/scripts/parser/features/annotations.gd
+++ b/modules/gdscript/tests/scripts/parser/features/annotations.gd
@@ -1,7 +1,5 @@
extends Node
-const Utils = preload("../../utils.notest.gd")
-
@export_enum("A", "B", "C") var test_1
@export_enum("A", "B", "C",) var test_2
diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.out b/modules/gdscript/tests/scripts/parser/features/annotations.out
index 2ba9dd7496..6516672820 100644
--- a/modules/gdscript/tests/scripts/parser/features/annotations.out
+++ b/modules/gdscript/tests/scripts/parser/features/annotations.out
@@ -1,25 +1,25 @@
GDTEST_OK
var test_1: int = null
- hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_2: int = null
- hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_3: int = null
- hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_4: int = null
- hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_5: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_6: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_7: int = 42
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_8: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_9: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_10: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_11: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_12: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/parser/features/class.gd b/modules/gdscript/tests/scripts/parser/features/class.gd
index af24b32322..482d04a63b 100644
--- a/modules/gdscript/tests/scripts/parser/features/class.gd
+++ b/modules/gdscript/tests/scripts/parser/features/class.gd
@@ -18,8 +18,8 @@ func test():
test_instance.number = 42
var test_sub = TestSub.new()
- assert(test_sub.number == 25) # From Test.
- assert(test_sub.other_string == "bye") # From TestSub.
+ Utils.check(test_sub.number == 25) # From Test.
+ Utils.check(test_sub.other_string == "bye") # From TestSub.
var _test_constructor = TestConstructor.new()
_test_constructor = TestConstructor.new(500)
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
index 553d40d953..a8ef52583d 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{ "a": 1, "b": 2, "with spaces": 3, "2": 4 }
+{ &"a": 1, &"b": 2, &"with spaces": 3, &"2": 4 }
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
index cf79845f53..4e404e1d26 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{ "hello": { "world": { "is": "beautiful" } } }
+{ "hello": { &"world": { "is": "beautiful" } } }
diff --git a/modules/gdscript/tests/scripts/parser/features/export_arrays.gd b/modules/gdscript/tests/scripts/parser/features/export_arrays.gd
index 0d97135a7b..cfda255905 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_arrays.gd
+++ b/modules/gdscript/tests/scripts/parser/features/export_arrays.gd
@@ -1,5 +1,3 @@
-const Utils = preload("../../utils.notest.gd")
-
@export_dir var test_dir: Array[String]
@export_dir var test_dir_packed: PackedStringArray
@export_file var test_file: Array[String]
diff --git a/modules/gdscript/tests/scripts/parser/features/export_arrays.out b/modules/gdscript/tests/scripts/parser/features/export_arrays.out
index acbf389645..f1522d096f 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_arrays.out
+++ b/modules/gdscript/tests/scripts/parser/features/export_arrays.out
@@ -1,139 +1,139 @@
GDTEST_OK
var test_dir: Array
- hint=TYPE_STRING hint_string="String/DIR:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<DIR>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_dir_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/DIR:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<DIR>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_file: Array
- hint=TYPE_STRING hint_string="String/FILE:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<FILE>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_file_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/FILE:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<FILE>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_global_dir: Array
- hint=TYPE_STRING hint_string="String/GLOBAL_DIR:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<GLOBAL_DIR>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_global_dir_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/GLOBAL_DIR:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<GLOBAL_DIR>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_global_file: Array
- hint=TYPE_STRING hint_string="String/GLOBAL_FILE:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<GLOBAL_FILE>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_global_file_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/GLOBAL_FILE:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<GLOBAL_FILE>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag: Array
- hint=TYPE_STRING hint_string="int/FLAGS:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<FLAGS>:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/FLAGS:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<FLAGS>:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/FLAGS:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<FLAGS>:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/FLAGS:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<FLAGS>:A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_nav: Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_nav_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_2D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_nav_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_nav_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_phys: Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_phys_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_2D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_phys_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_phys_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_render: Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_render_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_2D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_render_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_2d_render_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_2D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_2D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_nav: Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_nav_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_3D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_nav_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_nav_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_NAVIGATION:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_NAVIGATION>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_phys: Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_phys_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_3D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_phys_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_phys_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_PHYSICS:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_PHYSICS>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_render: Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_render_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/LAYERS_3D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_render_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_bit_flag_3d_render_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/LAYERS_3D_RENDER:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<LAYERS_3D_RENDER>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_multiline: Array
- hint=TYPE_STRING hint_string="String/MULTILINE_TEXT:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<MULTILINE_TEXT>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_multiline_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/MULTILINE_TEXT:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<MULTILINE_TEXT>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_placeholder: Array
- hint=TYPE_STRING hint_string="String/PLACEHOLDER_TEXT:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<PLACEHOLDER_TEXT>:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_placeholder_packed: PackedStringArray
- hint=TYPE_STRING hint_string="String/PLACEHOLDER_TEXT:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<PLACEHOLDER_TEXT>:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_int: Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_int_packed_byte: PackedByteArray
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_int_packed32: PackedInt32Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_int_packed64: PackedInt64Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_int_float_step: Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10,0.01" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10,0.01" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_float: Array
- hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_float_packed32: PackedFloat32Array
- hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_float_packed64: PackedFloat64Array
- hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_exp_easing: Array
- hint=TYPE_STRING hint_string="float/EXP_EASING:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<EXP_EASING>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_exp_easing_packed32: PackedFloat32Array
- hint=TYPE_STRING hint_string="float/EXP_EASING:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<EXP_EASING>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_exp_easing_packed64: PackedFloat64Array
- hint=TYPE_STRING hint_string="float/EXP_EASING:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<EXP_EASING>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_node_path: Array
- hint=TYPE_STRING hint_string="NodePath/NODE_PATH_VALID_TYPES:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<NodePath>/<NODE_PATH_VALID_TYPES>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color: Array
- hint=TYPE_STRING hint_string="Color/COLOR_NO_ALPHA:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color_packed: PackedColorArray
- hint=TYPE_STRING hint_string="Color/COLOR_NO_ALPHA:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_byte_array: PackedByteArray
- hint=TYPE_STRING hint_string="int:int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int32_array: PackedInt32Array
- hint=TYPE_STRING hint_string="int:int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int64_array: PackedInt64Array
- hint=TYPE_STRING hint_string="int:int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_float32_array: PackedFloat32Array
- hint=TYPE_STRING hint_string="float:float" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_float64_array: PackedFloat64Array
- hint=TYPE_STRING hint_string="float:float" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_color_array: PackedColorArray
- hint=TYPE_STRING hint_string="Color:Color" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Color>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector2_array: PackedVector2Array
- hint=TYPE_STRING hint_string="Vector2:Vector2" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Vector2>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector3_array: PackedVector3Array
- hint=TYPE_STRING hint_string="Vector3:Vector3" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Vector3>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_vector4_array: PackedVector4Array
- hint=TYPE_STRING hint_string="Vector4:Vector4" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Vector4>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_byte_array: PackedByteArray
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_int32_array: PackedInt32Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_int64_array: PackedInt64Array
- hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_float32_array: PackedFloat32Array
- hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_weak_packed_float64_array: PackedFloat64Array
- hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<float>/<RANGE>:1,10" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_noalpha_weak_packed_color_array: PackedColorArray
- hint=TYPE_STRING hint_string="Color/COLOR_NO_ALPHA:" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<Color>/<COLOR_NO_ALPHA>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.gd b/modules/gdscript/tests/scripts/parser/features/export_enum.gd
index 7f0737f4db..d50f0b2528 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_enum.gd
+++ b/modules/gdscript/tests/scripts/parser/features/export_enum.gd
@@ -1,5 +1,3 @@
-const Utils = preload("../../utils.notest.gd")
-
@export_enum("Red", "Green", "Blue") var test_untyped
@export_enum("Red:10", "Green:20", "Blue:30") var test_with_values
diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.out b/modules/gdscript/tests/scripts/parser/features/export_enum.out
index c87f9b17f0..31d3fa8902 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_enum.out
+++ b/modules/gdscript/tests/scripts/parser/features/export_enum.out
@@ -1,41 +1,41 @@
GDTEST_OK
var test_untyped: int = null
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_with_values: int = null
- hint=ENUM hint_string="Red:10,Green:20,Blue:30" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red:10,Green:20,Blue:30" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_variant: int = null
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_int: int = 0
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_string: String = ""
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_array_int: Array = Array[int]([])
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_array_string: Array = Array[String]([])
- hint=TYPE_STRING hint_string="String/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_byte_array: PackedByteArray = PackedByteArray()
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int32_array: PackedInt32Array = PackedInt32Array()
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_int64_array: PackedInt64Array = PackedInt64Array()
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_weak_packed_string_array: PackedStringArray = PackedStringArray()
- hint=TYPE_STRING hint_string="String/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_variant: int = null
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_int: int = 0
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_string: String = ""
- hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_array_int: Array = Array[int]([])
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_array_string: Array = Array[String]([])
- hint=TYPE_STRING hint_string="String/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_variant_array_int: Array = Array[int]([])
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_variant_packed_int32_array: PackedInt32Array = PackedInt32Array()
- hint=TYPE_STRING hint_string="int/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_variant_array_string: Array = Array[String]([])
- hint=TYPE_STRING hint_string="String/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_variant_packed_string_array: PackedStringArray = PackedStringArray()
- hint=TYPE_STRING hint_string="String/ENUM:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=TYPE_STRING hint_string="<String>/<ENUM>:Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd
index 2a218774de..1e134d0e0e 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd
@@ -1,20 +1,51 @@
+class_name ExportVariableTest
extends Node
-const Utils = preload("../../utils.notest.gd")
+const PreloadedGlobalClass = preload("./export_variable_global.notest.gd")
+const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd")
+# Built-in types.
@export var test_weak_int = 1
@export var test_hard_int: int = 2
-@export_storage var test_storage_untyped
-@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`.
-@export_storage var test_storage_hard_int: int = 4
@export_range(0, 100) var test_range = 100
@export_range(0, 100, 1) var test_range_step = 101
@export_range(0, 100, 1, "or_greater") var test_range_step_or_greater = 102
@export var test_color: Color
@export_color_no_alpha var test_color_no_alpha: Color
@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var test_node_path := ^"hello"
-@export var test_node: Node
-@export var test_node_array: Array[Node]
+
+# Enums.
+@export var test_side: Side
+@export var test_atm: AutoTranslateMode
+
+# Resources and nodes.
+@export var test_image: Image
+@export var test_timer: Timer
+
+# Global custom classes.
+@export var test_global_class: ExportVariableTest
+@export var test_preloaded_global_class: PreloadedGlobalClass
+@export var test_preloaded_unnamed_class: PreloadedUnnamedClass # GH-93168
+
+# Arrays.
+@export var test_array: Array
+@export var test_array_bool: Array[bool]
+@export var test_array_array: Array[Array]
+@export var test_array_side: Array[Side]
+@export var test_array_atm: Array[AutoTranslateMode]
+@export var test_array_image: Array[Image]
+@export var test_array_timer: Array[Timer]
+
+# `@export_storage`.
+@export_storage var test_storage_untyped
+@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`.
+@export_storage var test_storage_hard_int: int = 4
+
+# `@export_custom`.
+# NOTE: `PROPERTY_USAGE_NIL_IS_VARIANT` flag will be removed.
+@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_untyped
+@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_weak_int = 5
+@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_hard_int: int = 6
func test():
for property in get_property_list():
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out
index b3f9d0ca9c..d10462bb8d 100644
--- a/modules/gdscript/tests/scripts/parser/features/export_variable.out
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out
@@ -1,27 +1,57 @@
GDTEST_OK
var test_weak_int: int = 1
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_hard_int: int = 2
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
-var test_storage_untyped: Variant = null
- hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
-var test_storage_weak_int: Variant = 3
- hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT
-var test_storage_hard_int: int = 4
- hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range: int = 100
- hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_step: int = 101
- hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_range_step_or_greater: int = 102
- hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color: Color = Color(0, 0, 0, 1)
- hint=NONE hint_string="Color" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_color_no_alpha: Color = Color(0, 0, 0, 1)
- hint=COLOR_NO_ALPHA hint_string="" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=COLOR_NO_ALPHA hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
var test_node_path: NodePath = NodePath("hello")
- hint=NODE_PATH_VALID_TYPES hint_string="Sprite2D,Sprite3D,Control,Node" usage=DEFAULT|SCRIPT_VARIABLE
-var test_node: Node = null
- hint=NODE_TYPE hint_string="Node" usage=DEFAULT|SCRIPT_VARIABLE
-var test_node_array: Array = Array[Node]([])
- hint=TYPE_STRING hint_string="Object/NODE_TYPE:Node" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NODE_PATH_VALID_TYPES hint_string="Sprite2D,Sprite3D,Control,Node" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_side: Side = 0
+ hint=ENUM hint_string="Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Side"
+var test_atm: Node.AutoTranslateMode = 0
+ hint=ENUM hint_string="Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM class_name=&"Node.AutoTranslateMode"
+var test_image: Image = null
+ hint=RESOURCE_TYPE hint_string="Image" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Image"
+var test_timer: Timer = null
+ hint=NODE_TYPE hint_string="Timer" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Timer"
+var test_global_class: ExportVariableTest = null
+ hint=NODE_TYPE hint_string="ExportVariableTest" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"ExportVariableTest"
+var test_preloaded_global_class: ExportVariableTestGlobalClass = null
+ hint=NODE_TYPE hint_string="ExportVariableTestGlobalClass" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"ExportVariableTestGlobalClass"
+var test_preloaded_unnamed_class: Node2D = null
+ hint=NODE_TYPE hint_string="Node2D" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Node2D"
+var test_array: Array = []
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_bool: Array = Array[bool]([])
+ hint=TYPE_STRING hint_string="<bool>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_array: Array = Array[Array]([])
+ hint=TYPE_STRING hint_string="<Array>:" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_side: Array = Array[int]([])
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Side Left:0,Side Top:1,Side Right:2,Side Bottom:3" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_atm: Array = Array[int]([])
+ hint=TYPE_STRING hint_string="<int>/<ENUM>:Auto Translate Mode Inherit:0,Auto Translate Mode Always:1,Auto Translate Mode Disabled:2" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_image: Array = Array[Image]([])
+ hint=TYPE_STRING hint_string="<Object>/<RESOURCE_TYPE>:Image" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_array_timer: Array = Array[Timer]([])
+ hint=TYPE_STRING hint_string="<Object>/<NODE_TYPE>:Timer" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_storage_untyped: Variant = null
+ hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT class_name=&""
+var test_storage_weak_int: Variant = 3
+ hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT class_name=&""
+var test_storage_hard_int: int = 4
+ hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE class_name=&""
+var test_export_custom_untyped: null = null
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_export_custom_weak_int: int = 5
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
+var test_export_custom_hard_int: int = 6
+ hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable_global.notest.gd b/modules/gdscript/tests/scripts/parser/features/export_variable_global.notest.gd
new file mode 100644
index 0000000000..caa2ead214
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable_global.notest.gd
@@ -0,0 +1,2 @@
+class_name ExportVariableTestGlobalClass
+extends Node2D
diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable_unnamed.notest.gd b/modules/gdscript/tests/scripts/parser/features/export_variable_unnamed.notest.gd
new file mode 100644
index 0000000000..e251cf8aee
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/export_variable_unnamed.notest.gd
@@ -0,0 +1 @@
+extends Node2D
diff --git a/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd
index 2fa45c1d7d..0ec118b6b7 100644
--- a/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd
+++ b/modules/gdscript/tests/scripts/parser/features/good_continue_in_lambda.gd
@@ -9,5 +9,5 @@ func test():
j_string += str(j)
return j_string
i_string += lambda.call()
- assert(i_string == '0202')
+ Utils.check(i_string == '0202')
print('ok')
diff --git a/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd
index 46b6856d22..c3a42288c7 100644
--- a/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd
+++ b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd
@@ -9,6 +9,7 @@ func four_parameters(_a, callable : Callable, b=func(): print(10)):
func test():
var v
+ @warning_ignore("confusable_capture_reassignment")
v=func():v=1
if true: v=1
print(v)
diff --git a/modules/gdscript/tests/scripts/parser/features/truthiness.gd b/modules/gdscript/tests/scripts/parser/features/truthiness.gd
index 9c67a152f5..736cda7f74 100644
--- a/modules/gdscript/tests/scripts/parser/features/truthiness.gd
+++ b/modules/gdscript/tests/scripts/parser/features/truthiness.gd
@@ -1,30 +1,32 @@
func test():
- # The assertions below should all evaluate to `true` for this test to pass.
- assert(true)
- assert(not false)
- assert(500)
- assert(not 0)
- assert(500.5)
- assert(not 0.0)
- assert("non-empty string")
- assert(["non-empty array"])
- assert({"non-empty": "dictionary"})
- assert(Vector2(1, 0))
- assert(Vector2i(-1, -1))
- assert(Vector3(0, 0, 0.0001))
- assert(Vector3i(0, 0, 10000))
+ # The checks below should all evaluate to `true` for this test to pass.
+ Utils.check(true)
+ Utils.check(not false)
+ Utils.check(500)
+ Utils.check(not 0)
+ Utils.check(500.5)
+ Utils.check(not 0.0)
+ Utils.check("non-empty string")
+ Utils.check(["non-empty array"])
+ Utils.check({"non-empty": "dictionary"})
+ Utils.check(Vector2(1, 0))
+ Utils.check(Vector2i(-1, -1))
+ Utils.check(Vector3(0, 0, 0.0001))
+ Utils.check(Vector3i(0, 0, 10000))
# Zero position is `true` only if the Rect2's size is non-zero.
- assert(Rect2(0, 0, 0, 1))
+ Utils.check(Rect2(0, 0, 0, 1))
# Zero size is `true` only if the position is non-zero.
- assert(Rect2(1, 1, 0, 0))
+ Utils.check(Rect2(1, 1, 0, 0))
# Zero position is `true` only if the Rect2's size is non-zero.
- assert(Rect2i(0, 0, 0, 1))
+ Utils.check(Rect2i(0, 0, 0, 1))
# Zero size is `true` only if the position is non-zero.
- assert(Rect2i(1, 1, 0, 0))
+ Utils.check(Rect2i(1, 1, 0, 0))
# A fully black color is only truthy if its alpha component is not equal to `1`.
- assert(Color(0, 0, 0, 0.5))
+ Utils.check(Color(0, 0, 0, 0.5))
+
+ print("ok")
diff --git a/modules/gdscript/tests/scripts/parser/features/truthiness.out b/modules/gdscript/tests/scripts/parser/features/truthiness.out
index 705524857b..1b47ed10dc 100644
--- a/modules/gdscript/tests/scripts/parser/features/truthiness.out
+++ b/modules/gdscript/tests/scripts/parser/features/truthiness.out
@@ -1,65 +1,2 @@
GDTEST_OK
->> WARNING
->> Line: 3
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 4
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 5
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 6
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 7
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 8
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 9
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 12
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 13
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 14
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 15
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 18
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 21
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 24
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 27
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
->> WARNING
->> Line: 30
->> ASSERT_ALWAYS_TRUE
->> Assert statement is redundant because the expression is always true.
+ok
diff --git a/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.gd b/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.gd
new file mode 100644
index 0000000000..57e6489484
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.gd
@@ -0,0 +1,5 @@
+func test():
+ var my_dictionary: Dictionary[int, String] = { 1: "one", 2: "two", 3: "three" }
+ var inferred_dictionary := { 1: "one", 2: "two", 3: "three" } # This is Dictionary[int, String].
+ print(my_dictionary)
+ print(inferred_dictionary)
diff --git a/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.out b/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.out
new file mode 100644
index 0000000000..6021c338ee
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/typed_dictionaries.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+{ 1: "one", 2: "two", 3: "three" }
+{ 1: "one", 2: "two", 3: "three" }
diff --git a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.gd b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.gd
index 00598e4d50..f8f70b8cc3 100644
--- a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.gd
+++ b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.gd
@@ -4,3 +4,4 @@ func i_return_int() -> int:
func test():
i_return_int()
+ preload("../../utils.notest.gd") # `preload` is a function-like keyword.
diff --git a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
index f2db4e9307..107051df6c 100644
--- a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
+++ b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
@@ -3,3 +3,7 @@ GDTEST_OK
>> Line: 6
>> RETURN_VALUE_DISCARDED
>> The function "i_return_int()" returns a value that will be discarded if not used.
+>> WARNING
+>> Line: 7
+>> RETURN_VALUE_DISCARDED
+>> The function "preload()" returns a value that will be discarded if not used.
diff --git a/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.gd b/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.gd
index dc4223ec2d..74f42b012b 100644
--- a/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.gd
+++ b/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.gd
@@ -6,3 +6,16 @@ func test():
Vector3.ZERO
[true, false]
float(125)
+ # The following statements should not produce `STANDALONE_EXPRESSION`:
+ var _a = 1
+ _a = 2 # Assignment is a local (or global) side effect.
+ @warning_ignore("redundant_await")
+ await 3 # The `await` operand is usually a coroutine or a signal.
+ absi(4) # A call (in general) can have side effects.
+ @warning_ignore("return_value_discarded")
+ preload("../../utils.notest.gd") # A static initializer may have side effects.
+ """
+ Python-like "comment".
+ """
+ @warning_ignore("standalone_ternary")
+ 1 if 2 else 3 # Produces `STANDALONE_TERNARY` instead.
diff --git a/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.out b/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.out
index a2c67a6e51..72c659c952 100644
--- a/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.out
+++ b/modules/gdscript/tests/scripts/parser/warnings/standalone_expression.out
@@ -2,16 +2,16 @@ GDTEST_OK
>> WARNING
>> Line: 3
>> STANDALONE_EXPRESSION
->> Standalone expression (the line has no effect).
+>> Standalone expression (the line may have no effect).
>> WARNING
>> Line: 4
>> STANDALONE_EXPRESSION
->> Standalone expression (the line has no effect).
+>> Standalone expression (the line may have no effect).
>> WARNING
>> Line: 6
>> STANDALONE_EXPRESSION
->> Standalone expression (the line has no effect).
+>> Standalone expression (the line may have no effect).
>> WARNING
>> Line: 7
>> STANDALONE_EXPRESSION
->> Standalone expression (the line has no effect).
+>> Standalone expression (the line may have no effect).
diff --git a/modules/gdscript/tests/scripts/project.godot b/modules/gdscript/tests/scripts/project.godot
index c500ef443d..c9035ecab9 100644
--- a/modules/gdscript/tests/scripts/project.godot
+++ b/modules/gdscript/tests/scripts/project.godot
@@ -8,3 +8,10 @@ config_version=5
[application]
config/name="GDScript Integration Test Suite"
+
+[input]
+
+test_input_action={
+"deadzone": 0.5,
+"events": []
+}
diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd
new file mode 100644
index 0000000000..3724c8c713
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd
@@ -0,0 +1,9 @@
+# https://github.com/godotengine/godot/issues/90086
+
+class MyObj:
+ var obj: WeakRef
+
+func test():
+ var obj_1 = MyObj.new()
+ var obj_2 = MyObj.new()
+ obj_1.obj = obj_2
diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out
new file mode 100644
index 0000000000..dfca5b1eca
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/invalid_property_assignment.gd
+>> 9
+>> Invalid assignment of property or key 'obj' with value of type 'RefCounted (MyObj)' on a base object of type 'RefCounted (MyObj)'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out
index 7b9f1066b0..9b38957101 100644
--- a/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out
@@ -1,4 +1,5 @@
GDTEST_RUNTIME_ERROR
>> ERROR
>> Method/function failed.
+>> Unable to convert array index 0 from "Object" to "Object".
not ok
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.gd
new file mode 100644
index 0000000000..75004742a2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.gd
@@ -0,0 +1,4 @@
+func test():
+ var basic := { 1: 1 }
+ var typed: Dictionary[int, int] = basic
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.out
new file mode 100644
index 0000000000..cadb17f570
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_basic_to_typed.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_assign_basic_to_typed.gd
+>> 3
+>> Trying to assign a dictionary of type "Dictionary" to a variable of type "Dictionary[int, int]".
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.gd
new file mode 100644
index 0000000000..e5ab4a1a85
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.gd
@@ -0,0 +1,4 @@
+func test():
+ var differently: Variant = { 1.0: 0.0 } as Dictionary[float, float]
+ var typed: Dictionary[int, int] = differently
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.out
new file mode 100644
index 0000000000..fe1e5d1285
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_assign_differently_typed.gd
+>> 3
+>> Trying to assign a dictionary of type "Dictionary[float, float]" to a variable of type "Dictionary[int, int]".
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.gd
new file mode 100644
index 0000000000..2f0b3bd0eb
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.gd
@@ -0,0 +1,7 @@
+func get_key() -> Variant:
+ return "key"
+
+func test():
+ var typed: Dictionary[int, int]
+ typed[get_key()] = 0
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.out
new file mode 100644
index 0000000000..5f6dd7f641
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_key.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_assign_differently_typed_key.gd
+>> 6
+>> Invalid assignment of property or key 'key' with value of type 'int' on a base object of type 'Dictionary[int, int]'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.gd
new file mode 100644
index 0000000000..b171159aed
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.gd
@@ -0,0 +1,7 @@
+func get_value() -> Variant:
+ return "value"
+
+func test():
+ var typed: Dictionary[int, int]
+ typed[0] = get_value()
+ print("not ok")
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.out
new file mode 100644
index 0000000000..f766d14261
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_differently_typed_value.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_assign_differently_typed_value.gd
+>> 6
+>> Invalid assignment of property or key '0' with value of type 'String' on a base object of type 'Dictionary[int, int]'.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.gd
new file mode 100644
index 0000000000..6cc0e57255
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.gd
@@ -0,0 +1,7 @@
+class Foo: pass
+class Bar extends Foo: pass
+class Baz extends Foo: pass
+
+func test():
+ var typed: Dictionary[Bar, Bar] = { Baz.new() as Foo: Baz.new() as Foo }
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out
new file mode 100644
index 0000000000..18a4c360e2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out
@@ -0,0 +1,5 @@
+GDTEST_RUNTIME_ERROR
+>> ERROR
+>> Method/function failed.
+>> Unable to convert key from "Object" to "Object".
+not ok
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.gd
new file mode 100644
index 0000000000..8f7d732584
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.gd
@@ -0,0 +1,7 @@
+func expect_typed(typed: Dictionary[int, int]):
+ print(typed.size())
+
+func test():
+ var basic := { 1: 1 }
+ expect_typed(basic)
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.out
new file mode 100644
index 0000000000..fb45461701
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_basic_to_typed.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_pass_basic_to_typed.gd
+>> 6
+>> Invalid type in function 'expect_typed' in base 'RefCounted (typed_dictionary_pass_basic_to_typed.gd)'. The dictionary of argument 1 (Dictionary) does not have the same element type as the expected typed dictionary argument.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.gd b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.gd
new file mode 100644
index 0000000000..978a9fdfee
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/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: Variant = { 1.0: 0.0 } as Dictionary[float, float]
+ expect_typed(differently)
+ print('not ok')
diff --git a/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.out b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.out
new file mode 100644
index 0000000000..4036a1bf01
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_pass_differently_to_typed.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/typed_dictionary_pass_differently_to_typed.gd
+>> 6
+>> Invalid type in function 'expect_typed' in base 'RefCounted (typed_dictionary_pass_differently_to_typed.gd)'. The dictionary of argument 1 (Dictionary[float, float]) does not have the same element type as the expected typed dictionary argument.
diff --git a/modules/gdscript/tests/scripts/runtime/features/array_string_stringname_equivalent.gd b/modules/gdscript/tests/scripts/runtime/features/array_string_stringname_equivalent.gd
index bd38259cec..6eec37d64d 100644
--- a/modules/gdscript/tests/scripts/runtime/features/array_string_stringname_equivalent.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/array_string_stringname_equivalent.gd
@@ -25,7 +25,7 @@ func test():
print("String in Array[StringName]: ", "abc" in stringname_array)
var packed_string_array: PackedStringArray = []
- assert(!packed_string_array.push_back("abc"))
+ Utils.check(!packed_string_array.push_back("abc"))
print("StringName in PackedStringArray: ", &"abc" in packed_string_array)
string_array.push_back("abc")
diff --git a/modules/gdscript/tests/scripts/runtime/features/constants_are_read_only.gd b/modules/gdscript/tests/scripts/runtime/features/constants_are_read_only.gd
index d1746979be..6aa863c05f 100644
--- a/modules/gdscript/tests/scripts/runtime/features/constants_are_read_only.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/constants_are_read_only.gd
@@ -1,10 +1,9 @@
const array: Array = [0]
const dictionary := {1: 2}
-@warning_ignore("assert_always_true")
func test():
- assert(array.is_read_only() == true)
- assert(str(array) == '[0]')
- assert(dictionary.is_read_only() == true)
- assert(str(dictionary) == '{ 1: 2 }')
+ Utils.check(array.is_read_only() == true)
+ Utils.check(str(array) == '[0]')
+ Utils.check(dictionary.is_read_only() == true)
+ Utils.check(str(dictionary) == '{ 1: 2 }')
print('ok')
diff --git a/modules/gdscript/tests/scripts/runtime/features/conversions_from_native_members.gd b/modules/gdscript/tests/scripts/runtime/features/conversions_from_native_members.gd
index a778fb1a94..0f2526667d 100644
--- a/modules/gdscript/tests/scripts/runtime/features/conversions_from_native_members.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/conversions_from_native_members.gd
@@ -2,8 +2,8 @@ class Foo extends Node:
func _init():
name = 'f'
var string: String = name
- assert(typeof(string) == TYPE_STRING)
- assert(string == 'f')
+ Utils.check(typeof(string) == TYPE_STRING)
+ Utils.check(string == 'f')
print('ok')
func test():
diff --git a/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd b/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd
index 0851d939dc..9e67e75140 100644
--- a/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/default_set_beforehand.gd
@@ -6,15 +6,15 @@ extends Node
@onready var later_untyped = [1]
func test():
- assert(typeof(later_inferred) == TYPE_ARRAY)
- assert(later_inferred.size() == 0)
+ Utils.check(typeof(later_inferred) == TYPE_ARRAY)
+ Utils.check(later_inferred.size() == 0)
- assert(typeof(later_static) == TYPE_ARRAY)
- assert(later_static.size() == 0)
+ Utils.check(typeof(later_static) == TYPE_ARRAY)
+ Utils.check(later_static.size() == 0)
- assert(typeof(later_static_with_init) == TYPE_ARRAY)
- assert(later_static_with_init.size() == 0)
+ Utils.check(typeof(later_static_with_init) == TYPE_ARRAY)
+ Utils.check(later_static_with_init.size() == 0)
- assert(typeof(later_untyped) == TYPE_NIL)
+ Utils.check(typeof(later_untyped) == TYPE_NIL)
print("ok")
diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.gd b/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.gd
index 94bac1974f..de5eaabb79 100644
--- a/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.gd
@@ -7,11 +7,11 @@ func test():
stringname_dict[&"abc"] = 24
print("String key is TYPE_STRING: ", typeof(string_dict.keys()[0]) == TYPE_STRING)
- print("StringName key is TYPE_STRING: ", typeof(stringname_dict.keys()[0]) == TYPE_STRING)
+ print("StringName key is TYPE_STRING_NAME: ", typeof(stringname_dict.keys()[0]) == TYPE_STRING_NAME)
print("StringName gets String: ", string_dict.get(&"abc"))
print("String gets StringName: ", stringname_dict.get("abc"))
stringname_dict[&"abc"] = 42
- # They compare equal because StringName keys are converted to String.
+ # They compare equal because StringName keys are considered equivalent to String keys.
print("String Dictionary == StringName Dictionary: ", string_dict == stringname_dict)
diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.out b/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.out
index ab5b89d55c..a1461912bf 100644
--- a/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.out
+++ b/modules/gdscript/tests/scripts/runtime/features/dictionary_string_stringname_equivalent.out
@@ -1,6 +1,6 @@
GDTEST_OK
String key is TYPE_STRING: true
-StringName key is TYPE_STRING: true
+StringName key is TYPE_STRING_NAME: true
StringName gets String: 42
String gets StringName: 24
String Dictionary == StringName Dictionary: true
diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd
index 0133d7fcfc..90df98e05b 100644
--- a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd
@@ -1,5 +1,3 @@
-const Utils = preload("../../utils.notest.gd")
-
# GH-73843
@export_group("Resource")
diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out
index 9387ec50d7..a1e7233078 100644
--- a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out
+++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out
@@ -1,8 +1,8 @@
GDTEST_OK
Not shadowed: Resource
var test_1: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
@export_category("test_1")
- hint=NONE hint_string="" usage=CATEGORY
+ hint=NONE hint_string="" usage=CATEGORY class_name=&""
var test_2: int = 0
- hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE
+ hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
diff --git a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd
index bc899a3a6f..393500bd9b 100644
--- a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.gd
@@ -28,13 +28,18 @@ func test():
prints(var_to_str(e), var_to_str(elem))
print("Test String-keys dictionary.")
- var d1 := {a = 1, b = 2, c = 3}
+ var d1 := { a = 1, b = 2, c = 3 }
for k: StringName in d1:
var key := k
prints(var_to_str(k), var_to_str(key))
print("Test RefCounted-keys dictionary.")
- var d2 := {RefCounted.new(): 1, Resource.new(): 2, ConfigFile.new(): 3}
+ var d2 := { RefCounted.new(): 1, Resource.new(): 2, ConfigFile.new(): 3 }
for k: RefCounted in d2:
var key := k
prints(k.get_class(), key.get_class())
+
+ print("Test implicitly typed dictionary literal.")
+ for k: StringName in { x = 123, y = 456, z = 789 }:
+ var key := k
+ prints(var_to_str(k), var_to_str(key))
diff --git a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out
index eeebdc4be5..89cc1b76fe 100644
--- a/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out
+++ b/modules/gdscript/tests/scripts/runtime/features/for_loop_iterator_specified_types.out
@@ -27,3 +27,7 @@ Test RefCounted-keys dictionary.
RefCounted RefCounted
Resource Resource
ConfigFile ConfigFile
+Test implicitly typed dictionary literal.
+&"x" &"x"
+&"y" &"y"
+&"z" &"z"
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.gd b/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.gd
new file mode 100644
index 0000000000..67225cad6a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.gd
@@ -0,0 +1,18 @@
+# https://github.com/godotengine/godot/issues/93952
+
+func foo():
+ pass
+
+func test():
+ var a: int
+
+ var lambda_self := func (x: int) -> void:
+ foo()
+ print(a, x)
+
+ print(lambda_self.get_argument_count()) # Should print 1.
+
+ var lambda_non_self := func (x: int) -> void:
+ print(a, x)
+
+ print(lambda_non_self.get_argument_count()) # Should print 1.
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.out b/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.out
new file mode 100644
index 0000000000..04b4638adf
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_bind_argument_count.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+1
+1
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd
new file mode 100644
index 0000000000..bbdf745540
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd
@@ -0,0 +1,26 @@
+# GH-92217
+# TODO: Add more tests.
+
+static var static_var: int:
+ set(value):
+ prints("set static_var", value)
+ get:
+ print("get static_var")
+ return 0
+
+var member_var: int:
+ set(value):
+ prints("set member_var", value)
+ get:
+ print("get member_var")
+ return 0
+
+func test():
+ var lambda := func ():
+ var _tmp := static_var
+ _tmp = member_var
+
+ static_var = 1
+ member_var = 1
+
+ lambda.call()
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out
new file mode 100644
index 0000000000..0bdf74a43f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+get static_var
+get member_var
+set static_var 1
+set member_var 1
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.gd b/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.gd
new file mode 100644
index 0000000000..160e43a797
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.gd
@@ -0,0 +1,21 @@
+# https://github.com/godotengine/godot/issues/94074
+
+func foo():
+ pass
+
+func test():
+ var lambda_self := func test() -> void:
+ foo()
+ var anon_lambda_self := func() -> void:
+ foo()
+
+ print(lambda_self.get_method()) # Should print "test".
+ print(anon_lambda_self.get_method()) # Should print "<anonymous lambda>".
+
+ var lambda_non_self := func test() -> void:
+ pass
+ var anon_lambda_non_self := func() -> void:
+ pass
+
+ print(lambda_non_self.get_method()) # Should print "test".
+ print(anon_lambda_non_self.get_method()) # Should print "<anonymous lambda>".
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.out b/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.out
new file mode 100644
index 0000000000..17ee47fca2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_get_method.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+test
+<anonymous lambda>
+test
+<anonymous lambda>
diff --git a/modules/gdscript/tests/scripts/runtime/features/match_with_pattern_guards.gd b/modules/gdscript/tests/scripts/runtime/features/match_with_pattern_guards.gd
index 4cb51f8512..48a9349bf8 100644
--- a/modules/gdscript/tests/scripts/runtime/features/match_with_pattern_guards.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/match_with_pattern_guards.gd
@@ -62,7 +62,7 @@ func test():
0 when side_effect():
print("will run the side effect call, but not this")
_:
- assert(global == 1)
+ Utils.check(global == 1)
print("side effect only ran once")
func side_effect():
diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info.gd b/modules/gdscript/tests/scripts/runtime/features/member_info.gd
index 42b29eee43..4ce53aa395 100644
--- a/modules/gdscript/tests/scripts/runtime/features/member_info.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/member_info.gd
@@ -5,8 +5,6 @@ class MyClass:
enum MyEnum {}
-const Utils = preload("../../utils.notest.gd")
-
static var test_static_var_untyped
static var test_static_var_weak_null = null
static var test_static_var_weak_int = 1
@@ -33,6 +31,16 @@ var test_var_hard_array_my_enum: Array[MyEnum]
var test_var_hard_array_resource: Array[Resource]
var test_var_hard_array_this: Array[TestMemberInfo]
var test_var_hard_array_my_class: Array[MyClass]
+var test_var_hard_dictionary: Dictionary
+var test_var_hard_dictionary_int_variant: Dictionary[int, Variant]
+var test_var_hard_dictionary_variant_int: Dictionary[Variant, int]
+var test_var_hard_dictionary_int_int: Dictionary[int, int]
+var test_var_hard_dictionary_variant_type: Dictionary[Variant.Type, Variant.Type]
+var test_var_hard_dictionary_node_process_mode: Dictionary[Node.ProcessMode, Node.ProcessMode]
+var test_var_hard_dictionary_my_enum: Dictionary[MyEnum, MyEnum]
+var test_var_hard_dictionary_resource: Dictionary[Resource, Resource]
+var test_var_hard_dictionary_this: Dictionary[TestMemberInfo, TestMemberInfo]
+var test_var_hard_dictionary_my_class: Dictionary[MyClass, MyClass]
var test_var_hard_resource: Resource
var test_var_hard_this: TestMemberInfo
var test_var_hard_my_class: MyClass
@@ -45,17 +53,17 @@ func test_func_weak_null(): return null
func test_func_weak_int(): return 1
func test_func_hard_variant() -> Variant: return null
func test_func_hard_int() -> int: return 1
-func test_func_args_1(_a: int, _b: Array[int], _c: int = 1, _d = 2): pass
+func test_func_args_1(_a: int, _b: Array[int], _c: Dictionary[int, int], _d: int = 1, _e = 2): pass
func test_func_args_2(_a = 1, _b = _a, _c = [2], _d = 3): pass
signal test_signal_1()
signal test_signal_2(a: Variant, b)
-signal test_signal_3(a: int, b: Array[int])
-signal test_signal_4(a: Variant.Type, b: Array[Variant.Type])
-signal test_signal_5(a: MyEnum, b: Array[MyEnum])
-signal test_signal_6(a: Resource, b: Array[Resource])
-signal test_signal_7(a: TestMemberInfo, b: Array[TestMemberInfo])
-signal test_signal_8(a: MyClass, b: Array[MyClass])
+signal test_signal_3(a: int, b: Array[int], c: Dictionary[int, int])
+signal test_signal_4(a: Variant.Type, b: Array[Variant.Type], c: Dictionary[Variant.Type, Variant.Type])
+signal test_signal_5(a: MyEnum, b: Array[MyEnum], c: Dictionary[MyEnum, MyEnum])
+signal test_signal_6(a: Resource, b: Array[Resource], c: Dictionary[Resource, Resource])
+signal test_signal_7(a: TestMemberInfo, b: Array[TestMemberInfo], c: Dictionary[TestMemberInfo, TestMemberInfo])
+signal test_signal_8(a: MyClass, b: Array[MyClass], c: Dictionary[MyClass, MyClass])
func no_exec():
test_signal_1.emit()
diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info.out b/modules/gdscript/tests/scripts/runtime/features/member_info.out
index 7c826ac05a..2baf451aa5 100644
--- a/modules/gdscript/tests/scripts/runtime/features/member_info.out
+++ b/modules/gdscript/tests/scripts/runtime/features/member_info.out
@@ -23,6 +23,16 @@ var test_var_hard_array_my_enum: Array[TestMemberInfo.MyEnum]
var test_var_hard_array_resource: Array[Resource]
var test_var_hard_array_this: Array[TestMemberInfo]
var test_var_hard_array_my_class: Array[RefCounted]
+var test_var_hard_dictionary: Dictionary
+var test_var_hard_dictionary_int_variant: Dictionary[int, Variant]
+var test_var_hard_dictionary_variant_int: Dictionary[Variant, int]
+var test_var_hard_dictionary_int_int: Dictionary[int, int]
+var test_var_hard_dictionary_variant_type: Dictionary[Variant.Type, Variant.Type]
+var test_var_hard_dictionary_node_process_mode: Dictionary[Node.ProcessMode, Node.ProcessMode]
+var test_var_hard_dictionary_my_enum: Dictionary[TestMemberInfo.MyEnum, TestMemberInfo.MyEnum]
+var test_var_hard_dictionary_resource: Dictionary[Resource, Resource]
+var test_var_hard_dictionary_this: Dictionary[TestMemberInfo, TestMemberInfo]
+var test_var_hard_dictionary_my_class: Dictionary[RefCounted, RefCounted]
var test_var_hard_resource: Resource
var test_var_hard_this: TestMemberInfo
var test_var_hard_my_class: RefCounted
@@ -33,13 +43,13 @@ func test_func_weak_null() -> Variant
func test_func_weak_int() -> Variant
func test_func_hard_variant() -> Variant
func test_func_hard_int() -> int
-func test_func_args_1(_a: int, _b: Array[int], _c: int = 1, _d: Variant = 2) -> void
+func test_func_args_1(_a: int, _b: Array[int], _c: Dictionary[int, int], _d: int = 1, _e: Variant = 2) -> void
func test_func_args_2(_a: Variant = 1, _b: Variant = null, _c: Variant = null, _d: Variant = 3) -> void
signal test_signal_1()
signal test_signal_2(a: Variant, b: Variant)
-signal test_signal_3(a: int, b: Array[int])
-signal test_signal_4(a: Variant.Type, b: Array[Variant.Type])
-signal test_signal_5(a: TestMemberInfo.MyEnum, b: Array[TestMemberInfo.MyEnum])
-signal test_signal_6(a: Resource, b: Array[Resource])
-signal test_signal_7(a: TestMemberInfo, b: Array[TestMemberInfo])
-signal test_signal_8(a: RefCounted, b: Array[RefCounted])
+signal test_signal_3(a: int, b: Array[int], c: Dictionary[int, int])
+signal test_signal_4(a: Variant.Type, b: Array[Variant.Type], c: Dictionary[Variant.Type, Variant.Type])
+signal test_signal_5(a: TestMemberInfo.MyEnum, b: Array[TestMemberInfo.MyEnum], c: Dictionary[TestMemberInfo.MyEnum, TestMemberInfo.MyEnum])
+signal test_signal_6(a: Resource, b: Array[Resource], c: Dictionary[Resource, Resource])
+signal test_signal_7(a: TestMemberInfo, b: Array[TestMemberInfo], c: Dictionary[TestMemberInfo, TestMemberInfo])
+signal test_signal_8(a: RefCounted, b: Array[RefCounted], c: Dictionary[RefCounted, RefCounted])
diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd b/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd
index ee5c1e1267..4ddbeaec0b 100644
--- a/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd
@@ -1,7 +1,5 @@
# GH-82169
-const Utils = preload("../../utils.notest.gd")
-
class A:
static var test_static_var_a1
static var test_static_var_a2
diff --git a/modules/gdscript/tests/scripts/runtime/features/metatypes.gd b/modules/gdscript/tests/scripts/runtime/features/metatypes.gd
index 6c5df32ffe..d6847768e6 100644
--- a/modules/gdscript/tests/scripts/runtime/features/metatypes.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/metatypes.gd
@@ -3,7 +3,6 @@ class MyClass:
enum MyEnum {A, B, C}
-const Utils = preload("../../utils.notest.gd")
const Other = preload("./metatypes.notest.gd")
var test_native := JSON
@@ -25,12 +24,24 @@ func test():
if str(property.name).begins_with("test_"):
print(Utils.get_property_signature(property))
+ print("---")
check_gdscript_native_class(test_native)
check_gdscript(test_script)
check_gdscript(test_class)
check_enum(test_enum)
+ print("---")
print(test_native.stringify([]))
print(test_script.TEST)
print(test_class.TEST)
print(test_enum.keys())
+
+ print("---")
+ # Some users add unnecessary type hints to `const`-`preload`, which removes metatypes.
+ # For **constant** `GDScript` we still check the class members, despite the wider type.
+ const ScriptNoMeta: GDScript = Other
+ const ClassNoMeta: GDScript = MyClass
+ var a := ScriptNoMeta.TEST
+ var b := ClassNoMeta.TEST
+ print(a)
+ print(b)
diff --git a/modules/gdscript/tests/scripts/runtime/features/metatypes.out b/modules/gdscript/tests/scripts/runtime/features/metatypes.out
index 352d1caa59..c42287438c 100644
--- a/modules/gdscript/tests/scripts/runtime/features/metatypes.out
+++ b/modules/gdscript/tests/scripts/runtime/features/metatypes.out
@@ -3,11 +3,16 @@ var test_native: GDScriptNativeClass
var test_script: GDScript
var test_class: GDScript
var test_enum: Dictionary
+---
GDScriptNativeClass
GDScript
GDScript
{ "A": 0, "B": 1, "C": 2 }
+---
[]
100
10
["A", "B", "C"]
+---
+100
+10
diff --git a/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.gd b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.gd
index c774ebf83c..df639a7b4d 100644
--- a/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.gd
@@ -1,6 +1,5 @@
# GH-77666
-
-func test():
+func test_exit_if():
var ref := RefCounted.new()
print(ref.get_reference_count())
@@ -8,3 +7,20 @@ func test():
var _temp := ref
print(ref.get_reference_count())
+
+# GH-94654
+func test_exit_while():
+ var slots_data := []
+
+ while true:
+ @warning_ignore("confusable_local_declaration")
+ var slot = 42
+ slots_data.append(slot)
+ break
+
+ var slot: int = slots_data[0]
+ print(slot)
+
+func test():
+ test_exit_if()
+ test_exit_while()
diff --git a/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.out b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.out
index 04b4638adf..164eb24963 100644
--- a/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.out
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on_exit_block.out
@@ -1,3 +1,4 @@
GDTEST_OK
1
1
+42
diff --git a/modules/gdscript/tests/scripts/runtime/features/self_destruction.gd b/modules/gdscript/tests/scripts/runtime/features/self_destruction.gd
new file mode 100644
index 0000000000..442335faeb
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/self_destruction.gd
@@ -0,0 +1,50 @@
+# https://github.com/godotengine/godot/issues/75658
+
+class MyObj:
+ var callable: Callable
+
+ func run():
+ callable.call()
+
+ var prop:
+ set(value):
+ callable.call()
+ get:
+ callable.call()
+ return 0
+
+ func _on_some_signal():
+ callable.call()
+
+ func _init(p_callable: Callable):
+ self.callable = p_callable
+
+signal some_signal
+
+var obj: MyObj
+
+func test():
+ # Call.
+ obj = MyObj.new(nullify_obj)
+ obj.run()
+ print(obj)
+
+ # Get.
+ obj = MyObj.new(nullify_obj)
+ var _aux = obj.prop
+ print(obj)
+
+ # Set.
+ obj = MyObj.new(nullify_obj)
+ obj.prop = 1
+ print(obj)
+
+ # Signal handling.
+ obj = MyObj.new(nullify_obj)
+ @warning_ignore("return_value_discarded")
+ some_signal.connect(obj._on_some_signal)
+ some_signal.emit()
+ print(obj)
+
+func nullify_obj():
+ obj = null
diff --git a/modules/gdscript/tests/scripts/runtime/features/self_destruction.out b/modules/gdscript/tests/scripts/runtime/features/self_destruction.out
new file mode 100644
index 0000000000..ee4024a524
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/self_destruction.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+<null>
+<null>
+<null>
+<null>
diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd
new file mode 100644
index 0000000000..dee36d3ae0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd
@@ -0,0 +1,11 @@
+# https://github.com/godotengine/godot/issues/90086
+
+class MyObj:
+ var obj : WeakRef
+
+func test():
+ var obj_1 = MyObj.new()
+ var obj_2 = MyObj.new()
+ Utils.check(obj_2.get_reference_count() == 1)
+ obj_1.set(&"obj", obj_2)
+ Utils.check(obj_2.get_reference_count() == 1)
diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out
new file mode 100644
index 0000000000..d73c5eb7cd
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out
@@ -0,0 +1 @@
+GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.gd b/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.gd
new file mode 100644
index 0000000000..f70b521e1a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.gd
@@ -0,0 +1,62 @@
+# GH-94667
+
+class Inner:
+ var subprop: Vector2:
+ set(value):
+ prints("subprop setter", value)
+ subprop = value
+ get:
+ print("subprop getter")
+ return subprop
+
+ func _to_string() -> String:
+ return "<Inner>"
+
+var prop1:
+ set(value):
+ prints("prop1 setter", value)
+ prop1 = value
+
+var prop2: Inner:
+ set(value):
+ prints("prop2 setter", value)
+ prop2 = value
+
+var prop3:
+ set(value):
+ prints("prop3 setter", value)
+ prop3 = value
+ get:
+ print("prop3 getter")
+ return prop3
+
+var prop4: Inner:
+ set(value):
+ prints("prop4 setter", value)
+ prop4 = value
+ get:
+ print("prop4 getter")
+ return prop4
+
+func test():
+ print("===")
+ prop1 = Vector2()
+ prop1.x = 1.0
+ print("---")
+ prop1 = Inner.new()
+ prop1.subprop.x = 1.0
+
+ print("===")
+ prop2 = Inner.new()
+ prop2.subprop.x = 1.0
+
+ print("===")
+ prop3 = Vector2()
+ prop3.x = 1.0
+ print("---")
+ prop3 = Inner.new()
+ prop3.subprop.x = 1.0
+
+ print("===")
+ prop4 = Inner.new()
+ prop4.subprop.x = 1.0
diff --git a/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out b/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out
new file mode 100644
index 0000000000..c51759f481
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/setter_chain_shared_types.out
@@ -0,0 +1,26 @@
+GDTEST_OK
+===
+prop1 setter (0, 0)
+prop1 setter (1, 0)
+---
+prop1 setter <Inner>
+subprop getter
+subprop setter (1, 0)
+===
+prop2 setter <Inner>
+subprop getter
+subprop setter (1, 0)
+===
+prop3 setter (0, 0)
+prop3 getter
+prop3 setter (1, 0)
+---
+prop3 setter <Inner>
+prop3 getter
+subprop getter
+subprop setter (1, 0)
+===
+prop4 setter <Inner>
+prop4 getter
+subprop getter
+subprop setter (1, 0)
diff --git a/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.gd b/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.gd
new file mode 100644
index 0000000000..9e27a500bf
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.gd
@@ -0,0 +1,13 @@
+# https://github.com/godotengine/godot/issues/85952
+
+var vec: Vector2 = Vector2.ZERO:
+ set(new_vec):
+ prints("setting vec from", vec, "to", new_vec)
+ if new_vec == Vector2(1, 1):
+ vec = new_vec
+
+func test():
+ vec.x = 2
+ vec.y = 2
+
+ prints("vec is", vec)
diff --git a/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out b/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out
new file mode 100644
index 0000000000..31b3b3a3a8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/simple_setter_chain_call_setter.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+setting vec from (0, 0) to (2, 0)
+setting vec from (0, 0) to (0, 2)
+vec is (0, 0)
diff --git a/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.gd b/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.gd
new file mode 100644
index 0000000000..11a670a7fb
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.gd
@@ -0,0 +1,15 @@
+extends Node
+
+func test() -> void:
+ var node1 := Node.new()
+ node1.name = "_"
+ var node2 := Node.new()
+ node2.name = "Child"
+ var node3 := Node.new()
+ node3.name = "Child"
+
+ add_child(node1)
+ node1.add_child(node2)
+ add_child(node3)
+
+ Utils.check(get_node("_/Child") == $_/Child)
diff --git a/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.out b/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.out
new file mode 100644
index 0000000000..d73c5eb7cd
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/single_underscore_node_name.out
@@ -0,0 +1 @@
+GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/runtime/features/standalone_calls_do_not_write_to_nil.gd b/modules/gdscript/tests/scripts/runtime/features/standalone_calls_do_not_write_to_nil.gd
index 691b611574..d72662736e 100644
--- a/modules/gdscript/tests/scripts/runtime/features/standalone_calls_do_not_write_to_nil.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/standalone_calls_do_not_write_to_nil.gd
@@ -14,33 +14,33 @@ func test():
func test_construct(v, f):
@warning_ignore("unsafe_call_argument")
Vector2(v, v) # Built-in type construct.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_utility(v, f):
abs(v) # Utility function.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_builtin_call(v, f):
@warning_ignore("unsafe_method_access")
v.angle() # Built-in method call.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_builtin_call_validated(v: Vector2, f):
@warning_ignore("return_value_discarded")
v.abs() # Built-in method call validated.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_object_call(v, f):
@warning_ignore("unsafe_method_access")
v.get_reference_count() # Native type method call.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_object_call_method_bind(v: Resource, f):
@warning_ignore("return_value_discarded")
v.duplicate() # Native type method call with MethodBind.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
func test_object_call_method_bind_validated(v: RefCounted, f):
@warning_ignore("return_value_discarded")
v.get_reference_count() # Native type method call with validated MethodBind.
- assert(not f) # Test unary operator reading from `nil`.
+ Utils.check(not f) # Test unary operator reading from `nil`.
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.gd b/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.gd
new file mode 100644
index 0000000000..13f2c3b956
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.gd
@@ -0,0 +1,7 @@
+# GH-93990
+
+func test_param(array: Array[String]) -> void:
+ print(array.get_typed_builtin() == TYPE_STRING)
+
+func test() -> void:
+ test_param(PackedStringArray())
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.out b/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.out
new file mode 100644
index 0000000000..55482c2b52
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_array_implicit_cast_param.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+true
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_array_init_with_untyped_in_literal.gd b/modules/gdscript/tests/scripts/runtime/features/typed_array_init_with_untyped_in_literal.gd
index ec444b4ffa..859bfd7987 100644
--- a/modules/gdscript/tests/scripts/runtime/features/typed_array_init_with_untyped_in_literal.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_array_init_with_untyped_in_literal.gd
@@ -1,6 +1,6 @@
func test():
var untyped: Variant = 32
var typed: Array[int] = [untyped]
- assert(typed.get_typed_builtin() == TYPE_INT)
- assert(str(typed) == '[32]')
+ Utils.check(typed.get_typed_builtin() == TYPE_INT)
+ Utils.check(str(typed) == '[32]')
print('ok')
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.gd b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.gd
new file mode 100644
index 0000000000..0371ee5630
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.gd
@@ -0,0 +1,6 @@
+func test_param(dictionary: Dictionary[int, String]) -> void:
+ print(dictionary.get_typed_key_builtin() == TYPE_INT)
+ print(dictionary.get_typed_value_builtin() == TYPE_STRING)
+
+func test() -> void:
+ test_param({ 123: "some_string" })
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.out b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.out
new file mode 100644
index 0000000000..9d111a8322
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_implicit_cast_param.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+true
+true
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.gd b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.gd
new file mode 100644
index 0000000000..ee51440d80
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.gd
@@ -0,0 +1,7 @@
+func test():
+ var untyped: Variant = 32
+ var typed: Dictionary[int, int] = { untyped: untyped }
+ Utils.check(typed.get_typed_key_builtin() == TYPE_INT)
+ Utils.check(typed.get_typed_value_builtin() == TYPE_INT)
+ Utils.check(str(typed) == '{ 32: 32 }')
+ print('ok')
diff --git a/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.out b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.out
new file mode 100644
index 0000000000..1b47ed10dc
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/typed_dictionary_init_with_untyped_in_literal.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+ok
diff --git a/modules/gdscript/tests/scripts/utils.notest.gd b/modules/gdscript/tests/scripts/utils.notest.gd
index 1cf46c179e..1e2788f765 100644
--- a/modules/gdscript/tests/scripts/utils.notest.gd
+++ b/modules/gdscript/tests/scripts/utils.notest.gd
@@ -1,3 +1,13 @@
+class_name Utils
+
+
+# `assert()` is not evaluated in non-debug builds. Do not use `assert()`
+# for anything other than testing the `assert()` itself.
+static func check(condition: Variant) -> void:
+ if not condition:
+ printerr("Check failed.")
+
+
static func get_type(property: Dictionary, is_return: bool = false) -> String:
match property.type:
TYPE_NIL:
@@ -14,6 +24,11 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String:
if str(property.hint_string).is_empty():
return "Array[<unknown type>]"
return "Array[%s]" % property.hint_string
+ TYPE_DICTIONARY:
+ if property.hint == PROPERTY_HINT_DICTIONARY_TYPE:
+ if str(property.hint_string).is_empty():
+ return "Dictionary[<unknown type>, <unknown type>]"
+ return "Dictionary[%s]" % str(property.hint_string).replace(";", ", ")
TYPE_OBJECT:
if not str(property.class_name).is_empty():
return property.class_name
@@ -46,7 +61,7 @@ static func get_human_readable_hint_string(property: Dictionary) -> String:
while true:
if not hint_string.contains(":"):
- push_error("Invalid PROPERTY_HINT_TYPE_STRING format.")
+ printerr("Invalid PROPERTY_HINT_TYPE_STRING format.")
var elem_type_hint: String = hint_string.get_slice(":", 0)
hint_string = hint_string.substr(elem_type_hint.length() + 1)
@@ -55,18 +70,18 @@ static func get_human_readable_hint_string(property: Dictionary) -> String:
if elem_type_hint.is_valid_int():
elem_type = elem_type_hint.to_int()
- type_hint_prefixes += type_string(elem_type) + ":"
+ type_hint_prefixes += "<%s>:" % type_string(elem_type)
else:
if elem_type_hint.count("/") != 1:
- push_error("Invalid PROPERTY_HINT_TYPE_STRING format.")
+ printerr("Invalid PROPERTY_HINT_TYPE_STRING format.")
elem_type = elem_type_hint.get_slice("/", 0).to_int()
elem_hint = elem_type_hint.get_slice("/", 1).to_int()
- type_hint_prefixes += "%s/%s:" % [
- type_string(elem_type),
- get_property_hint_name(elem_hint).trim_prefix("PROPERTY_HINT_"),
+ type_hint_prefixes += "<%s>/<%s>:" % [
+ type_string(elem_type),
+ get_property_hint_name(elem_hint).trim_prefix("PROPERTY_HINT_"),
]
- if elem_type < TYPE_ARRAY:
+ if elem_type < TYPE_ARRAY or hint_string.is_empty():
break
return type_hint_prefixes + hint_string
@@ -76,10 +91,11 @@ static func get_human_readable_hint_string(property: Dictionary) -> String:
static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void:
print(get_property_signature(property, base, is_static))
- print(' hint=%s hint_string="%s" usage=%s' % [
+ print(' hint=%s hint_string="%s" usage=%s class_name=&"%s"' % [
get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"),
- get_human_readable_hint_string(property),
+ get_human_readable_hint_string(property).c_escape(),
get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""),
+ property.class_name.c_escape(),
])
@@ -177,6 +193,8 @@ static func get_property_hint_name(hint: PropertyHint) -> String:
return "PROPERTY_HINT_INT_IS_POINTER"
PROPERTY_HINT_ARRAY_TYPE:
return "PROPERTY_HINT_ARRAY_TYPE"
+ PROPERTY_HINT_DICTIONARY_TYPE:
+ return "PROPERTY_HINT_DICTIONARY_TYPE"
PROPERTY_HINT_LOCALE_ID:
return "PROPERTY_HINT_LOCALE_ID"
PROPERTY_HINT_LOCALIZABLE_STRING:
@@ -187,7 +205,7 @@ static func get_property_hint_name(hint: PropertyHint) -> String:
return "PROPERTY_HINT_HIDE_QUATERNION_EDIT"
PROPERTY_HINT_PASSWORD:
return "PROPERTY_HINT_PASSWORD"
- push_error("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.")
+ printerr("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.")
return "<invalid hint>"
@@ -239,7 +257,7 @@ static func get_property_usage_string(usage: int) -> String:
usage &= ~flag[0]
if usage != PROPERTY_USAGE_NONE:
- push_error("Argument `usage` is invalid. Use `PROPERTY_USAGE_*` constants.")
+ printerr("Argument `usage` is invalid. Use `PROPERTY_USAGE_*` constants.")
return "<invalid usage flags>"
return result.left(-1)
diff --git a/modules/gdscript/tests/test_completion.h b/modules/gdscript/tests/test_completion.h
index 327446acee..387358934d 100644
--- a/modules/gdscript/tests/test_completion.h
+++ b/modules/gdscript/tests/test_completion.h
@@ -130,6 +130,8 @@ static void test_directory(const String &p_dir) {
#endif
EditorSettings::get_singleton()->set_setting("text_editor/completion/use_single_quotes", conf.get_value("input", "use_single_quotes", false));
+ EditorSettings::get_singleton()->set_setting("text_editor/completion/add_node_path_literals", conf.get_value("input", "add_node_path_literals", false));
+ EditorSettings::get_singleton()->set_setting("text_editor/completion/add_string_name_literals", conf.get_value("input", "add_string_name_literals", false));
List<Dictionary> include;
to_dict_list(conf.get_value("output", "include", Array()), include);