gdharness 1.3.41 → 1.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/build/cli.js +131 -47
  2. package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
  3. package/build/godot/addons/gdharness_editor/animation_reads.gd +84 -35
  4. package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
  5. package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +114 -39
  7. package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
  8. package/build/godot/addons/gdharness_editor/headless_check.gd +94 -41
  9. package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
  10. package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
  11. package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
  12. package/build/godot/addons/gdharness_editor/reading.gd +37 -12
  13. package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/scene_file.gd +136 -79
  15. package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
  16. package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
  17. package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
  18. package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
  19. package/build/godot/addons/gdharness_editor/tools/animation_states.gd +41 -28
  20. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +84 -50
  21. package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
  22. package/build/godot/addons/gdharness_editor/tools/class_tools.gd +34 -30
  23. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
  24. package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
  25. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
  26. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
  27. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +181 -107
  28. package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
  29. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +75 -43
  30. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
  31. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
  32. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +66 -0
  33. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd.uid +1 -0
  34. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +171 -62
  35. package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
  36. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
  37. package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
  38. package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
  39. package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
  40. package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
  41. package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
  42. package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
  43. package/build/godot/addons/gdharness_runtime/reading.gd +37 -12
  44. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
  45. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +153 -148
  46. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
  47. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
  48. package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
  49. package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
  50. package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
  51. package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
  52. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
  53. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +38 -20
  54. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
  55. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
  56. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
  57. package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
  58. package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
  59. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
  60. package/build/godot/addons/gdharness_runtime/runtime_touch.gd +211 -0
  61. package/build/godot/addons/gdharness_runtime/runtime_touch.gd.uid +1 -0
  62. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
  63. package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
  64. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
  65. package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
  66. package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
  67. package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
  68. package/build/godot/addons/gdharness_tests/bench.gd +4 -5
  69. package/build/godot/addons/gdharness_tests/event.gd +10 -5
  70. package/build/godot/addons/gdharness_tests/share.gd +38 -18
  71. package/build/godot/addons/gdharness_tests/suites.gd +3 -3
  72. package/build/godot/addons/gdharness_tests/wait.gd +3 -2
  73. package/build/godot/loader/loader.gd +9 -9
  74. package/build/godot/operations/animation_reads.gd +84 -35
  75. package/build/godot/operations/audio_buses.gd +48 -19
  76. package/build/godot/operations/class_cache.gd +16 -11
  77. package/build/godot/operations/classdb_queries.gd +89 -44
  78. package/build/godot/operations/declared_values.gd +68 -32
  79. package/build/godot/operations/dependencies.gd +139 -93
  80. package/build/godot/operations/editor_tools.gd +9 -10
  81. package/build/godot/operations/export_presets.gd +100 -54
  82. package/build/godot/operations/file_reads.gd +114 -39
  83. package/build/godot/operations/file_walk.gd +12 -5
  84. package/build/godot/operations/gdscript_analysis.gd +105 -66
  85. package/build/godot/operations/gdscript_authoring.gd +138 -39
  86. package/build/godot/operations/godot_operations.gd +17 -11
  87. package/build/godot/operations/import_pipeline.gd +110 -59
  88. package/build/godot/operations/input_actions.gd +63 -39
  89. package/build/godot/operations/patterns.gd +3 -1
  90. package/build/godot/operations/plugins.gd +36 -16
  91. package/build/godot/operations/project_config.gd +144 -27
  92. package/build/godot/operations/project_diagnostics.gd +24 -11
  93. package/build/godot/operations/project_file.gd +16 -16
  94. package/build/godot/operations/project_validation.gd +71 -44
  95. package/build/godot/operations/property_paths.gd +22 -12
  96. package/build/godot/operations/property_values.gd +143 -78
  97. package/build/godot/operations/reading.gd +37 -12
  98. package/build/godot/operations/rename_checks.gd +2 -2
  99. package/build/godot/operations/resource_files.gd +11 -9
  100. package/build/godot/operations/same_values.gd +4 -4
  101. package/build/godot/operations/scene_connections.gd +27 -13
  102. package/build/godot/operations/script_check.gd +52 -49
  103. package/build/godot/operations/serialisation.gd +75 -51
  104. package/build/godot/operations/setting_reads.gd +7 -6
  105. package/build/godot/operations/value_shapes.gd +5 -6
  106. package/build/godot/tests/listed.gd +321 -268
  107. package/package.json +1 -1
@@ -13,55 +13,6 @@ var _dependencies: GdhDependencies = null
13
13
  var _reading: String = ""
14
14
 
15
15
 
16
- ## What one class body declares, the script's own or an inner class's.
17
- class GdhMembers:
18
- var declared_class_name: Variant = null
19
- var extends_name: String = "RefCounted"
20
- var signals: Array[Dictionary] = []
21
- var variables: Array[Dictionary] = []
22
- var functions: Array[Dictionary] = []
23
- var constants: Array[Dictionary] = []
24
- var enums: Array[Dictionary] = []
25
- var inner_classes: Array[Dictionary] = []
26
- ## The `##` comment the class is documented with, empty when it has none.
27
- var doc: String = ""
28
- ## The index of the last line the body holds.
29
- var last: int = -1
30
- ## An inner class's name and the line its `class` is on.
31
- var inner_name: String = ""
32
- var line: int = 0
33
-
34
- ## The inner class as its entry under inner_classes, in the fields a script's own are in.
35
- func as_inner() -> Dictionary:
36
- return {
37
- "name": inner_name,
38
- "line": line,
39
- "extends": extends_name,
40
- "signals": signals,
41
- "variables": variables,
42
- "functions": functions,
43
- "constants": constants,
44
- "enums": enums,
45
- "inner_classes": inner_classes,
46
- }
47
-
48
- ## Whether a member is declared yet, past which a `##` block no longer documents the class.
49
- func declares_members() -> bool:
50
- return not (
51
- signals.is_empty()
52
- and variables.is_empty()
53
- and functions.is_empty()
54
- and constants.is_empty()
55
- and enums.is_empty()
56
- and inner_classes.is_empty()
57
- )
58
-
59
- ## [param lines] as the class's documentation, when it has none yet.
60
- func take_doc(lines: Array[String]) -> void:
61
- if doc.is_empty() and not lines.is_empty():
62
- doc = "\n".join(PackedStringArray(lines))
63
-
64
-
65
16
  func _init(p_log: GdhLog) -> void:
66
17
  _log = p_log
67
18
 
@@ -116,7 +67,7 @@ func get_gdscript_info(params: Dictionary) -> Dictionary:
116
67
  var declaring: String = str(declared_by[used])
117
68
  if declaring == full_script_path:
118
69
  continue
119
- classes_used.append({"name": used, "path": declaring})
70
+ classes_used.append({ "name": used, "path": declaring })
120
71
  if not declaring in dependencies:
121
72
  dependencies.append(declaring)
122
73
 
@@ -133,7 +84,7 @@ func get_gdscript_info(params: Dictionary) -> Dictionary:
133
84
  var autoloads_used: Array[Dictionary] = []
134
85
  for used: String in GdhDependencies.classes_used_in(content, global_autoloads):
135
86
  if str(global_autoloads[used]) != full_script_path:
136
- autoloads_used.append({"name": used, "path": str(global_autoloads[used])})
87
+ autoloads_used.append({ "name": used, "path": str(global_autoloads[used]) })
137
88
 
138
89
  var answer: Dictionary = {
139
90
  "path": script_path,
@@ -149,7 +100,8 @@ func get_gdscript_info(params: Dictionary) -> Dictionary:
149
100
  "dependencies": dependencies,
150
101
  "classes_used": classes_used,
151
102
  "autoloads_used": autoloads_used,
152
- "line_count": lines.size() - 1 if content.is_empty() or content.ends_with("\n") else lines.size()
103
+ "line_count":
104
+ lines.size() - 1 if content.is_empty() or content.ends_with("\n") else lines.size(),
153
105
  }
154
106
  if not own.doc.is_empty():
155
107
  answer["class_doc"] = own.doc
@@ -249,6 +201,16 @@ func _members(
249
201
  i += 1
250
202
  stripped = (stripped + " " + GdhPatterns.without_comment(lines[i])).strip_edges()
251
203
  header = GdhPatterns.without_annotations(stripped)
204
+ # A value that opens a triple-quoted string ends where the string does, and read from its
205
+ # first line alone it was the opening quotes and the text up to the line break.
206
+ if in_multiline_string and (header.begins_with("const ") or _declares_variable(header)):
207
+ while i + 1 < lines.size():
208
+ i += 1
209
+ stripped += "\n" + lines[i]
210
+ if _triple_quotes(lines[i]) % 2 == 1:
211
+ break
212
+ in_multiline_string = false
213
+ header = GdhPatterns.without_annotations(stripped)
252
214
  var declaration: RegExMatch = GdhPatterns.declared_class(header)
253
215
  var entry: Dictionary = {}
254
216
  if declaration != null:
@@ -273,7 +235,7 @@ func _members(
273
235
  elif header.begins_with("enum "):
274
236
  entry = _parse_enum(header, at + 1)
275
237
  own.enums.append(entry)
276
- elif header.begins_with("var ") or header.begins_with("static var "):
238
+ elif _declares_variable(header):
277
239
  # The whole line here, not the header: which annotations a variable carries is the
278
240
  # answer rather than noise in front of it, and `@export_range(0, 1)` is the hint.
279
241
  entry = _parse_variable(stripped, at + 1)
@@ -325,7 +287,9 @@ func _inner_class(
325
287
  body_margin = indent
326
288
  break
327
289
  var body: GdhMembers = (
328
- GdhMembers.new() if body_margin.is_empty() else _members(lines, at + 1, body_margin, dependencies)
290
+ GdhMembers.new()
291
+ if body_margin.is_empty()
292
+ else _members(lines, at + 1, body_margin, dependencies)
329
293
  )
330
294
  if body_margin.is_empty():
331
295
  body.last = at
@@ -342,7 +306,10 @@ static func _not_a_script(path: String) -> String:
342
306
  var said: String = "%s is not a GDScript file, and script_info reads .gd files only" % path
343
307
  match path.get_extension().to_lower():
344
308
  "tscn", "scn":
345
- return said + ": scene_tree reads a scene's nodes, and with properties the script each carries."
309
+ return (
310
+ said
311
+ + ": scene_tree reads a scene's nodes, and with properties the script each carries."
312
+ )
346
313
  "tres", "res":
347
314
  return said + ": resource_edit read reads a resource."
348
315
  return said + "."
@@ -387,7 +354,7 @@ func _native_ancestor(base: String, from_path: String) -> String:
387
354
  if path in seen:
388
355
  return ""
389
356
  seen.append(path)
390
- var above: Dictionary = get_gdscript_info({"script_path": path})
357
+ var above: Dictionary = get_gdscript_info({ "script_path": path })
391
358
  if above.is_empty():
392
359
  return ""
393
360
  current = str(above.get("extends", ""))
@@ -412,7 +379,7 @@ func _add_inherited(answer: Dictionary, seen: Array[String]) -> void:
412
379
  if base_path.is_empty() or base_path in seen:
413
380
  break
414
381
  seen.append(base_path)
415
- var above: Dictionary = get_gdscript_info({"script_path": base_path})
382
+ var above: Dictionary = get_gdscript_info({ "script_path": base_path })
416
383
  # A read that failed answers with an empty dictionary rather than with a flag, so that is
417
384
  # what is asked. `_script_named` has already checked the file is there, which leaves only
418
385
  # an open that fails, and the chain stops without recording a file nothing was read from.
@@ -469,12 +436,14 @@ func _parse_signal(line: String, line_num: int) -> Dictionary:
469
436
  # comma answered with two.
470
437
  var paren_end: int = _closing_paren(signal_text, paren_start)
471
438
  if paren_end > paren_start:
472
- for p: String in _arguments_in(signal_text.substr(paren_start + 1, paren_end - paren_start - 1)):
439
+ for p: String in _arguments_in(
440
+ signal_text.substr(paren_start + 1, paren_end - paren_start - 1)
441
+ ):
473
442
  params.append(_parse_param(p))
474
443
  else:
475
444
  signal_name = signal_text
476
445
 
477
- return {"name": signal_name, "params": params, "line": line_num}
446
+ return { "name": signal_name, "params": params, "line": line_num }
478
447
 
479
448
 
480
449
  func _parse_constant(line: String, line_num: int) -> Dictionary:
@@ -497,7 +466,7 @@ func _parse_constant(line: String, line_num: int) -> Dictionary:
497
466
  else:
498
467
  name = const_text
499
468
 
500
- var constant: Dictionary = {"name": name, "value": value, "type": type_hint, "line": line_num}
469
+ var constant: Dictionary = { "name": name, "value": value, "type": type_hint, "line": line_num }
501
470
  # A constant has its value's type whether or not it is written with :=.
502
471
  if type_hint.is_empty():
503
472
  _infer(constant, value)
@@ -578,7 +547,7 @@ func _parse_enum(line: String, line_num: int) -> Dictionary:
578
547
  else:
579
548
  enum_name = enum_text
580
549
 
581
- return {"name": enum_name, "values": values, "line": line_num}
550
+ return { "name": enum_name, "values": values, "line": line_num }
582
551
 
583
552
 
584
553
  func _parse_variable(line: String, line_num: int) -> Dictionary:
@@ -599,9 +568,13 @@ func _parse_variable(line: String, line_num: int) -> Dictionary:
599
568
 
600
569
  var var_pos: int = line.find("var ")
601
570
  if var_pos == -1:
602
- return {"name": "", "line": line_num}
571
+ return { "name": "", "line": line_num }
603
572
 
604
573
  var var_text: String = line.substr(var_pos + 4).strip_edges()
574
+ # A colon closing the line opens the variable's setter and getter, and was read as the end of
575
+ # its default: `= Kind.ROUND:`.
576
+ if var_text.ends_with(":"):
577
+ var_text = var_text.left(-1).strip_edges()
605
578
  var name: String = ""
606
579
  var type_hint: String = ""
607
580
  var default_value: String = ""
@@ -638,10 +611,12 @@ func _parse_variable(line: String, line_num: int) -> Dictionary:
638
611
  "is_onready": is_onready,
639
612
  # One per class rather than per instance, which a caller reading a counter needs to know.
640
613
  "is_static": GdhPatterns.without_annotations(line).begins_with("static "),
641
- "line": line_num
614
+ "line": line_num,
642
615
  }
643
616
  # Only := types a variable by its value; one written with = alone holds any type.
644
- var walrus: bool = "=" in var_text and var_text.split("=", true, 1)[0].strip_edges().ends_with(":")
617
+ var walrus: bool = (
618
+ "=" in var_text and var_text.split("=", true, 1)[0].strip_edges().ends_with(":")
619
+ )
645
620
  if walrus and type_hint.is_empty():
646
621
  _infer(variable, default_value)
647
622
  return variable
@@ -687,7 +662,7 @@ func _parse_function(line: String, line_num: int, annotated: String = "") -> Dic
687
662
  # Said rather than left to be inferred: an abstract method has no body, so a caller that
688
663
  # saw only the declaration would otherwise take it for one whose body it failed to read.
689
664
  "is_abstract": "abstract" in GdhPatterns.annotations_on(annotated),
690
- "line": line_num
665
+ "line": line_num,
691
666
  }
692
667
 
693
668
 
@@ -835,7 +810,7 @@ func _parse_param(param_text: String) -> Dictionary:
835
810
  var stated_default: Variant = null
836
811
  if "=" in param_text:
837
812
  stated_default = default_value
838
- return {"name": name, "type": type_hint, "default": stated_default, "is_rest": is_rest}
813
+ return { "name": name, "type": type_hint, "default": stated_default, "is_rest": is_rest }
839
814
 
840
815
 
841
816
  func _collect_dependencies(line: String, into: Array[String]) -> void:
@@ -847,6 +822,10 @@ func _collect_dependencies(line: String, into: Array[String]) -> void:
847
822
 
848
823
 
849
824
  # How many triple quotes of either kind [param line] holds.
825
+ static func _declares_variable(header: String) -> bool:
826
+ return header.begins_with("var ") or header.begins_with("static var ")
827
+
828
+
850
829
  static func _triple_quotes(line: String) -> int:
851
830
  return line.count('"""') + line.count("'''")
852
831
 
@@ -859,3 +838,63 @@ func _extract_dependencies(line: String) -> Array[String]:
859
838
  deps.append(m.get_string(1))
860
839
 
861
840
  return deps
841
+
842
+
843
+ ## What one class body declares, the script's own or an inner class's.
844
+ class GdhMembers:
845
+ var declared_class_name: Variant = null
846
+
847
+ var extends_name: String = "RefCounted"
848
+
849
+ var signals: Array[Dictionary] = []
850
+
851
+ var variables: Array[Dictionary] = []
852
+
853
+ var functions: Array[Dictionary] = []
854
+
855
+ var constants: Array[Dictionary] = []
856
+
857
+ var enums: Array[Dictionary] = []
858
+
859
+ var inner_classes: Array[Dictionary] = []
860
+
861
+ ## The `##` comment the class is documented with, empty when it has none.
862
+ var doc: String = ""
863
+
864
+ ## The index of the last line the body holds.
865
+ var last: int = -1
866
+
867
+ ## An inner class's name and the line its `class` is on.
868
+ var inner_name: String = ""
869
+
870
+ var line: int = 0
871
+
872
+ ## The inner class as its entry under inner_classes, in the fields a script's own are in.
873
+ func as_inner() -> Dictionary:
874
+ return {
875
+ "name": inner_name,
876
+ "line": line,
877
+ "extends": extends_name,
878
+ "signals": signals,
879
+ "variables": variables,
880
+ "functions": functions,
881
+ "constants": constants,
882
+ "enums": enums,
883
+ "inner_classes": inner_classes,
884
+ }
885
+
886
+ ## Whether a member is declared yet, past which a `##` block no longer documents the class.
887
+ func declares_members() -> bool:
888
+ return not (
889
+ signals.is_empty()
890
+ and variables.is_empty()
891
+ and functions.is_empty()
892
+ and constants.is_empty()
893
+ and enums.is_empty()
894
+ and inner_classes.is_empty()
895
+ )
896
+
897
+ ## [param lines] as the class's documentation, when it has none yet.
898
+ func take_doc(lines: Array[String]) -> void:
899
+ if doc.is_empty() and not lines.is_empty():
900
+ doc = "\n".join(PackedStringArray(lines))