Browse Source

Add test for `get_node` autocompletion

HolonProduction 1 year ago
parent
commit
fc7d7d3dae
73 changed files with 693 additions and 6 deletions
  1. 15 1
      modules/gdscript/gdscript_editor.cpp
  2. 8 0
      modules/gdscript/tests/scripts/completion/class_a.notest.gd
  3. 19 0
      modules/gdscript/tests/scripts/completion/get_node/get_node.tscn
  4. 0 4
      modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.cfg
  5. 7 0
      modules/gdscript/tests/scripts/completion/get_node/literal/dollar.cfg
  6. 5 0
      modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd
  7. 7 0
      modules/gdscript/tests/scripts/completion/get_node/literal/percent.cfg
  8. 5 0
      modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd
  9. 14 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.cfg
  10. 5 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd
  11. 14 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.cfg
  12. 4 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd
  13. 14 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.cfg
  14. 5 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd
  15. 14 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.cfg
  16. 4 0
      modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd
  17. 7 0
      modules/gdscript/tests/scripts/completion/get_node/local/local.cfg
  18. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local/local.gd
  19. 7 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.cfg
  20. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
  21. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.cfg
  22. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
  23. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.cfg
  24. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
  25. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.cfg
  26. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd
  27. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.cfg
  28. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd
  29. 12 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.cfg
  30. 7 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd
  31. 12 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.cfg
  32. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd
  33. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.cfg
  34. 7 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd
  35. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.cfg
  36. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd
  37. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.cfg
  38. 6 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd
  39. 14 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.cfg
  40. 6 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd
  41. 20 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.cfg
  42. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd
  43. 20 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.cfg
  44. 5 0
      modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd
  45. 7 0
      modules/gdscript/tests/scripts/completion/get_node/member/member.cfg
  46. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member/member.gd
  47. 7 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.cfg
  48. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
  49. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.cfg
  50. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
  51. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.cfg
  52. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
  53. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.cfg
  54. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd
  55. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.cfg
  56. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd
  57. 12 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.cfg
  58. 8 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd
  59. 12 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.cfg
  60. 1 1
      modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd
  61. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.cfg
  62. 8 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd
  63. 14 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.cfg
  64. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd
  65. 16 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.cfg
  66. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd
  67. 16 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.cfg
  68. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd
  69. 20 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.cfg
  70. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd
  71. 20 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.cfg
  72. 6 0
      modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd
  73. 10 0
      modules/gdscript/tests/test_completion.h

+ 15 - 1
modules/gdscript/gdscript_editor.cpp

@@ -1125,19 +1125,31 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
 				base_type = GDScriptParser::DataType();
 			} break;
 			case GDScriptParser::DataType::SCRIPT: {
+				print_line("identifier script");
 				Ref<Script> scr = base_type.script_type;
 				if (scr.is_valid()) {
+<<<<<<< HEAD
 					if (p_types_only) {
 						// TODO: Need to implement Script::get_script_enum_list and retrieve the enum list from a script.
 					} else if (!p_only_functions) {
+=======
+					print_line("script valid");
+					if (!p_only_functions) {
+						print_line("not only functions");
+>>>>>>> ae78637b78 (Add test for `get_node` autocompletion)
 						if (!base_type.is_meta_type) {
+							print_line("no meta type");
 							List<PropertyInfo> members;
 							scr->get_script_property_list(&members);
+							print_line("scripts", members.size());
 							for (const PropertyInfo &E : members) {
+								print_line(E.name);
 								if (E.usage & (PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_INTERNAL)) {
+									print_line("filtered 1");
 									continue;
 								}
 								if (E.name.contains("/")) {
+									print_line("filtered 2");
 									continue;
 								}
 								int location = p_recursion_depth + _get_property_location(scr, E.name);
@@ -2173,6 +2185,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
 		if (_guess_expression_type(c, last_assigned_expression, assigned_type)) {
 			if (id_type.is_set() && assigned_type.type.is_set() && !GDScriptAnalyzer::check_type_compatibility(id_type, assigned_type.type)) {
 				// The assigned type is incompatible. The annotated type takes priority.
+				print_line("Just here for testing.");
 				r_type.assigned_expression = last_assigned_expression;
 				r_type.type = id_type;
 			} else {
@@ -3163,6 +3176,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 			is_function = true;
 			[[fallthrough]];
 		case GDScriptParser::COMPLETION_ATTRIBUTE: {
+			print_line("completion attribute");
 			r_forced = true;
 			const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node);
 			if (attr->base) {
@@ -3171,7 +3185,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
 				if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) {
 					break;
 				}
-
+				print_line(base.type.script_path, base.type.kind);
 				_find_identifiers_in_base(base, is_function, false, options, 0);
 			}
 		} break;

+ 8 - 0
modules/gdscript/tests/scripts/completion/class_a.notest.gd

@@ -0,0 +1,8 @@
+extends Node
+
+signal signal_of_a
+
+var property_of_a
+
+func func_of_a():
+	pass

+ 19 - 0
modules/gdscript/tests/scripts/completion/get_node/get_node.tscn

@@ -0,0 +1,19 @@
+[gd_scene load_steps=2 format=3 uid="uid://c8wekfd5ql7bc"]
+
+[ext_resource type="Script" path="res://completion/class_a.notest.gd" id="1_ldc4g"]
+
+[node name="GetNode" type="Node"]
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
+
+[node name="UniqueNames" type="Node" parent="."]
+
+[node name="UniqueAnimationPlayer" type="AnimationPlayer" parent="UniqueNames"]
+unique_name_in_owner = true
+
+[node name="UniqueA" type="Node" parent="UniqueNames"]
+script = ExtResource("1_ldc4g")
+unique_name_in_owner = true
+
+[node name="A" type="Node" parent="."]
+script = ExtResource("1_ldc4g")

+ 0 - 4
modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.cfg

@@ -1,4 +0,0 @@
-[output]
-include=[
-    {"display": "autoplay"},
-]

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/dollar.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd

@@ -0,0 +1,5 @@
+extends Node
+
+
+func a():
+    %AnimationPlayer.➡

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/percent.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd

@@ -0,0 +1,5 @@
+extends Node
+
+
+func a():
+    $UniqueAnimationPlayer.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+
+func a():
+    $A.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 4 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd

@@ -0,0 +1,4 @@
+extends Node
+
+func a():
+    $AnimationPlayer.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+
+func a():
+    %UniqueA.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 4 - 0
modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd

@@ -0,0 +1,4 @@
+extends Node
+
+func a():
+    %UniqueAnimationPlayer.➡

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/local/local.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local/local.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test = $AnimationPlayer
+    test.➡

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test := $AnimationPlayer
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test := $A
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test := $AnimationPlayer
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test = $A
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test = $AnimationPlayer
+    test.➡

+ 12 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_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"},
+]

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd

@@ -0,0 +1,7 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+    var test: A = $A
+    test.➡

+ 12 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.cfg

@@ -0,0 +1,12 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test: AnimationPlayer = $AnimationPlayer
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd

@@ -0,0 +1,7 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+func a():
+    var test: A = $A
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test: AnimationPlayer = $AnimationPlayer
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd

@@ -0,0 +1,6 @@
+# TODO
+extends Node
+
+func a():
+    var test: Node = $A
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd

@@ -0,0 +1,6 @@
+# TODO
+extends Node
+
+func a():
+    var test: Node = $AnimationPlayer
+    test.➡

+ 20 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.cfg

@@ -0,0 +1,20 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; Area2D
+    {"display": "get_overlapping_areas"},
+    {"display": "linear_damp"},
+    {"display": "area_entered"},
+]
+exclude=[
+    ; GDScript: class_a.notest.gd
+    {"display": "property_of_a"},
+    {"display": "func_of_a"},
+    {"display": "signal_of_a"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test: Area2D = $A
+    test.➡

+ 20 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.cfg

@@ -0,0 +1,20 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; Area2D
+    {"display": "get_overlapping_areas"},
+    {"display": "linear_damp"},
+    {"display": "area_entered"},
+]
+exclude=[
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 5 - 0
modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd

@@ -0,0 +1,5 @@
+extends Node
+
+func a():
+    var test: Area2D = $AnimationPlayer
+    test.➡

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/member/member.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member/member.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test = $AnimationPlayer
+
+func a():
+    test.➡

+ 7 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.cfg

@@ -0,0 +1,7 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test := $AnimationPlayer
+
+func a():
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test := $A
+
+func a():
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test := $AnimationPlayer
+
+func a():
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test = $A
+
+func a():
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test = $AnimationPlayer
+
+func a():
+    test.➡

+ 12 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_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"},
+]

+ 8 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd

@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test: A = $A
+
+func a():
+    test.➡

+ 12 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.cfg

@@ -0,0 +1,12 @@
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+    
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 1 - 1
modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.gd → modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd

@@ -2,5 +2,5 @@ extends Node
 
 var test: AnimationPlayer = $AnimationPlayer
 
-func _ready():
+func a():
     test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+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"},
+]

+ 8 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd

@@ -0,0 +1,8 @@
+extends Node
+
+const A := preload("res://completion/class_a.notest.gd")
+
+var test: A = $A
+
+func a():
+    test.➡

+ 14 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.cfg

@@ -0,0 +1,14 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test: AnimationPlayer = $AnimationPlayer
+
+func a():
+    test.➡

+ 16 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.cfg

@@ -0,0 +1,16 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[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"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test: Node = $A
+
+func a():
+    test.➡

+ 16 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.cfg

@@ -0,0 +1,16 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+]
+exclude=[
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test: Node = $AnimationPlayer
+
+func a():
+    test.➡

+ 20 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.cfg

@@ -0,0 +1,20 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; Area2D
+    {"display": "get_overlapping_areas"},
+    {"display": "linear_damp"},
+    {"display": "area_entered"},
+]
+exclude=[
+    ; GDScript: class_a.notest.gd
+    {"display": "property_of_a"},
+    {"display": "func_of_a"},
+    {"display": "signal_of_a"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test: Area2D = $A
+
+func a():
+    test.➡

+ 20 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.cfg

@@ -0,0 +1,20 @@
+[input]
+scene="res://completion/get_node/get_node.tscn"
+[output]
+include=[
+    ; Node
+    {"display": "add_child"},
+    {"display": "owner"},
+    {"display": "child_entered_tree"},
+
+    ; Area2D
+    {"display": "get_overlapping_areas"},
+    {"display": "linear_damp"},
+    {"display": "area_entered"},
+]
+exclude=[
+    ; AnimationPlayer
+    {"display": "autoplay"},
+    {"display": "play"},
+    {"display": "animation_changed"},
+]

+ 6 - 0
modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd

@@ -0,0 +1,6 @@
+extends Node
+
+var test: Area2D = $AnimationPlayer
+
+func a():
+    test.➡

+ 10 - 0
modules/gdscript/tests/test_completion.h

@@ -113,6 +113,8 @@ static void test_directory(const String &p_dir) {
 			// Require pointer sentinel char in scripts.
 			CHECK(code.find_char(0xFFFF) != -1);
 
+			print_line("Testing completion for: ", next);
+
 			ConfigFile conf;
 			if (conf.load(path.path_join(next.get_basename() + ".cfg")) != OK) {
 				FAIL("No config file found.");
@@ -153,6 +155,7 @@ static void test_directory(const String &p_dir) {
 			GDScriptLanguage::get_singleton()->complete_code(code, path.path_join(next), owner, &options, forced, call_hint);
 			String contains_excluded;
 			for (ScriptLanguage::CodeCompletionOption &option : options) {
+				print_line(option.display);
 				for (const Dictionary &E : exclude) {
 					if (match_option(E, option)) {
 						contains_excluded = option.display;
@@ -166,11 +169,18 @@ static void test_directory(const String &p_dir) {
 				for (const Dictionary &E : include) {
 					if (match_option(E, option)) {
 						include.erase(E);
+						print_line("erased");
 						break;
 					}
 				}
 			}
 			CHECK_MESSAGE(contains_excluded.is_empty(), "Autocompletion suggests illegal option '", contains_excluded, "' for '", path.path_join(next), "'.");
+
+			if (!include.is_empty()) {
+				for (const Dictionary &E : include) {
+					print_line(E);
+				}
+			}
 			CHECK(include.is_empty());
 
 			String expected_call_hint = conf.get_value("output", "call_hint", call_hint);