gdharness 1.2.24 → 1.2.25

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.
@@ -321,11 +321,25 @@ static func acceptable(value: Variant, type: int) -> bool:
321
321
  ## The conversion is also what restores a packed array's exact type. Those cross as the plain JSON
322
322
  ## lists they fit into, so what comes back from the wire is an Array, and the parameter is what says
323
323
  ## it was a PackedStringArray.
324
+ ##
325
+ ## A dictionary with no tag is read as the type wanted when it carries that type's fields, as
326
+ ## scene_node and resource_edit read one: runtime_invoke refused {"x": 140, "y": 300} for a Vector2
327
+ ## argument the editor tools took, so one value was right for one tool and wrong for the next. The
328
+ ## value as sent is what is tagged, since the builders read a nested vector from its own fields.
324
329
  func fitted(value: Variant, type: int) -> Variant:
325
330
  var rebuilt: Variant = deserialize_value(value)
326
331
  if type == TYPE_NIL or typeof(rebuilt) == type:
327
332
  return rebuilt
328
333
 
334
+ if value is Dictionary and type != TYPE_DICTIONARY:
335
+ var fields: Dictionary = value
336
+ if not fields.has("_type"):
337
+ var tagged: Dictionary = fields.duplicate()
338
+ tagged["_type"] = type_string(type)
339
+ var built: Variant = deserialize_value(tagged)
340
+ if typeof(built) == type:
341
+ return built
342
+
329
343
  if rebuilt is Array and LIST_TYPES.has(type):
330
344
  return type_convert(rebuilt, type)
331
345
 
@@ -348,6 +362,21 @@ func fitted(value: Variant, type: int) -> Variant:
348
362
  return type_convert(rebuilt, type)
349
363
 
350
364
 
365
+ ## How a value of [param type] is written to be read as one, for a refusal to name, or empty for a
366
+ ## type that is not built from fields. A refusal naming only the two types left a caller to find
367
+ ## the shape in the description of another op.
368
+ static func written_as(type: int) -> String:
369
+ var tag: String = type_string(type)
370
+ var alternatives: Array = REQUIRED.get(tag, [])
371
+ if alternatives.is_empty() or tag == "float" or tag == "Dictionary":
372
+ return ""
373
+ var keys: Array = alternatives[0]
374
+ var parts: Array[String] = []
375
+ for key: Variant in keys:
376
+ parts.append('"%s": ...' % key)
377
+ return "{%s}" % ", ".join(parts)
378
+
379
+
351
380
  ## Whether [param fields] carries every key of any one of [param alternatives].
352
381
  ##
353
382
  ## More than one spelling because a rectangle has two: the two corners it is answered with, and the
@@ -101,8 +101,14 @@ func set_property(params: Dictionary) -> Dictionary:
101
101
  "type": "error",
102
102
  "message":
103
103
  (
104
- "%s.%s holds %s and the value given is %s, which cannot become one."
105
- % [reached["called"], named, type_string(wanted), type_string(typeof(given))]
104
+ "%s.%s holds %s and the value given is %s, which cannot become one.%s"
105
+ % [
106
+ reached["called"],
107
+ named,
108
+ type_string(wanted),
109
+ type_string(typeof(given)),
110
+ _written_as(wanted)
111
+ ]
106
112
  )
107
113
  }
108
114
  var typed: Dictionary = _values.typed_like(given, old_value, _element_object.bind(node, node_path))
@@ -301,8 +307,15 @@ func call_method(params: Dictionary) -> Dictionary:
301
307
  "type": "error",
302
308
  "message":
303
309
  (
304
- "%s.%s takes %s as argument %d and was given %s, which cannot be converted."
305
- % [reached["called"], named, type_string(wants), index + 1, type_string(typeof(given))]
310
+ "%s.%s takes %s as argument %d and was given %s, which cannot be converted.%s"
311
+ % [
312
+ reached["called"],
313
+ named,
314
+ type_string(wants),
315
+ index + 1,
316
+ type_string(typeof(given)),
317
+ _written_as(wants)
318
+ ]
306
319
  )
307
320
  }
308
321
  # A typed list or map is built as one, since a plain one handed to such a parameter raises
@@ -492,6 +505,13 @@ func _element_object(
492
505
 
493
506
 
494
507
  ## "list" or "map", for a refusal about a typed container.
508
+ ## The sentence a refusal ends with for a type built from fields, naming the shape that is read as
509
+ ## one, or nothing for a type that is not.
510
+ static func _written_as(type: int) -> String:
511
+ var shape: String = Values.written_as(type)
512
+ return "" if shape.is_empty() else " A %s is sent as %s." % [type_string(type), shape]
513
+
514
+
495
515
  static func _sort_of(container: Variant) -> String:
496
516
  return "list" if container is Array else "map"
497
517
 
@@ -65,6 +65,11 @@ static func acceptable(value: Variant, type: int) -> bool:
65
65
  return Serialisation.acceptable(value, type)
66
66
 
67
67
 
68
+ ## How a value of [param type] is written to be read as one, or empty when it is not built from fields.
69
+ static func written_as(type: int) -> String:
70
+ return Serialisation.written_as(type)
71
+
72
+
68
73
  ## The declared type of one parameter of a method, or TYPE_NIL when the method or the parameter
69
74
  ## is not there, which reads as "no opinion".
70
75
  func parameter_type(object: Object, method: String, index: int) -> int:
@@ -321,11 +321,25 @@ static func acceptable(value: Variant, type: int) -> bool:
321
321
  ## The conversion is also what restores a packed array's exact type. Those cross as the plain JSON
322
322
  ## lists they fit into, so what comes back from the wire is an Array, and the parameter is what says
323
323
  ## it was a PackedStringArray.
324
+ ##
325
+ ## A dictionary with no tag is read as the type wanted when it carries that type's fields, as
326
+ ## scene_node and resource_edit read one: runtime_invoke refused {"x": 140, "y": 300} for a Vector2
327
+ ## argument the editor tools took, so one value was right for one tool and wrong for the next. The
328
+ ## value as sent is what is tagged, since the builders read a nested vector from its own fields.
324
329
  func fitted(value: Variant, type: int) -> Variant:
325
330
  var rebuilt: Variant = deserialize_value(value)
326
331
  if type == TYPE_NIL or typeof(rebuilt) == type:
327
332
  return rebuilt
328
333
 
334
+ if value is Dictionary and type != TYPE_DICTIONARY:
335
+ var fields: Dictionary = value
336
+ if not fields.has("_type"):
337
+ var tagged: Dictionary = fields.duplicate()
338
+ tagged["_type"] = type_string(type)
339
+ var built: Variant = deserialize_value(tagged)
340
+ if typeof(built) == type:
341
+ return built
342
+
329
343
  if rebuilt is Array and LIST_TYPES.has(type):
330
344
  return type_convert(rebuilt, type)
331
345
 
@@ -348,6 +362,21 @@ func fitted(value: Variant, type: int) -> Variant:
348
362
  return type_convert(rebuilt, type)
349
363
 
350
364
 
365
+ ## How a value of [param type] is written to be read as one, for a refusal to name, or empty for a
366
+ ## type that is not built from fields. A refusal naming only the two types left a caller to find
367
+ ## the shape in the description of another op.
368
+ static func written_as(type: int) -> String:
369
+ var tag: String = type_string(type)
370
+ var alternatives: Array = REQUIRED.get(tag, [])
371
+ if alternatives.is_empty() or tag == "float" or tag == "Dictionary":
372
+ return ""
373
+ var keys: Array = alternatives[0]
374
+ var parts: Array[String] = []
375
+ for key: Variant in keys:
376
+ parts.append('"%s": ...' % key)
377
+ return "{%s}" % ", ".join(parts)
378
+
379
+
351
380
  ## Whether [param fields] carries every key of any one of [param alternatives].
352
381
  ##
353
382
  ## More than one spelling because a rectangle has two: the two corners it is answered with, and the
@@ -29,6 +29,10 @@ const ProjectDiagnostics = preload("project_diagnostics.gd")
29
29
  const RenameChecks = preload("rename_checks.gd")
30
30
  const ResourceFiles = preload("resource_files.gd")
31
31
 
32
+ ## Printed once the answer is written, after which the engine runs the project's autoloads. Kept in
33
+ ## step with `ANSWERED` in src/headless.ts.
34
+ const ANSWERED: String = "[gdharness] answered"
35
+
32
36
  var _log: Log
33
37
 
34
38
 
@@ -86,6 +90,9 @@ func _init() -> void:
86
90
  _log.error("Could not write the answer to " + answer_path)
87
91
  quit(1)
88
92
  return
93
+ # On stderr, where the engine's errors go, so the server can tell what the project's autoloads
94
+ # report after this from what the operation reported before it.
95
+ printerr(ANSWERED)
89
96
  quit()
90
97
 
91
98
 
@@ -321,11 +321,25 @@ static func acceptable(value: Variant, type: int) -> bool:
321
321
  ## The conversion is also what restores a packed array's exact type. Those cross as the plain JSON
322
322
  ## lists they fit into, so what comes back from the wire is an Array, and the parameter is what says
323
323
  ## it was a PackedStringArray.
324
+ ##
325
+ ## A dictionary with no tag is read as the type wanted when it carries that type's fields, as
326
+ ## scene_node and resource_edit read one: runtime_invoke refused {"x": 140, "y": 300} for a Vector2
327
+ ## argument the editor tools took, so one value was right for one tool and wrong for the next. The
328
+ ## value as sent is what is tagged, since the builders read a nested vector from its own fields.
324
329
  func fitted(value: Variant, type: int) -> Variant:
325
330
  var rebuilt: Variant = deserialize_value(value)
326
331
  if type == TYPE_NIL or typeof(rebuilt) == type:
327
332
  return rebuilt
328
333
 
334
+ if value is Dictionary and type != TYPE_DICTIONARY:
335
+ var fields: Dictionary = value
336
+ if not fields.has("_type"):
337
+ var tagged: Dictionary = fields.duplicate()
338
+ tagged["_type"] = type_string(type)
339
+ var built: Variant = deserialize_value(tagged)
340
+ if typeof(built) == type:
341
+ return built
342
+
329
343
  if rebuilt is Array and LIST_TYPES.has(type):
330
344
  return type_convert(rebuilt, type)
331
345
 
@@ -348,6 +362,21 @@ func fitted(value: Variant, type: int) -> Variant:
348
362
  return type_convert(rebuilt, type)
349
363
 
350
364
 
365
+ ## How a value of [param type] is written to be read as one, for a refusal to name, or empty for a
366
+ ## type that is not built from fields. A refusal naming only the two types left a caller to find
367
+ ## the shape in the description of another op.
368
+ static func written_as(type: int) -> String:
369
+ var tag: String = type_string(type)
370
+ var alternatives: Array = REQUIRED.get(tag, [])
371
+ if alternatives.is_empty() or tag == "float" or tag == "Dictionary":
372
+ return ""
373
+ var keys: Array = alternatives[0]
374
+ var parts: Array[String] = []
375
+ for key: Variant in keys:
376
+ parts.append('"%s": ...' % key)
377
+ return "{%s}" % ", ".join(parts)
378
+
379
+
351
380
  ## Whether [param fields] carries every key of any one of [param alternatives].
352
381
  ##
353
382
  ## More than one spelling because a rectangle has two: the two corners it is answered with, and the