gdharness 1.0.1 → 1.0.3

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.
@@ -92,6 +92,10 @@ func query_class_info(params: Dictionary) -> Dictionary:
92
92
  if not ClassDB.class_exists(class_name_str):
93
93
  return _log.failure("Class not found: " + class_name_str)
94
94
 
95
+ var member: String = str(params.get("member", ""))
96
+ if not member.is_empty():
97
+ return _member_of(class_name_str, member)
98
+
95
99
  var methods: Array[Dictionary] = _methods_of(class_name_str, include_inherited)
96
100
  var properties: Array[Dictionary] = _properties_of(class_name_str, include_inherited)
97
101
  var signals: Array[Dictionary] = _signals_of(class_name_str, include_inherited)
@@ -130,6 +134,77 @@ func query_class_info(params: Dictionary) -> Dictionary:
130
134
  }
131
135
 
132
136
 
137
+ # One member of a class by name, wherever in its ancestry it is declared.
138
+ #
139
+ # The question a member is asked by name for is "does this engine have it, and what does it take":
140
+ # the whole class in answer to that ran to seventy thousand characters for Control, and the member
141
+ # is as often an ancestor's as the class's own, so the ancestry is walked without being asked. Each
142
+ # match says which class declares it. Nothing found names the members whose names contain the one
143
+ # asked for, since the usual miss is a spelling.
144
+ func _member_of(class_name_str: String, member: String) -> Dictionary:
145
+ var found: Array[Dictionary] = []
146
+ var current: String = class_name_str
147
+ while not current.is_empty():
148
+ for m: Dictionary in _methods_of(current, false):
149
+ if m["name"] == member:
150
+ found.append({"kind": "method", "declared_in": current, "member": m})
151
+ for p: Dictionary in _properties_of(current, false):
152
+ if p["name"] == member:
153
+ found.append({"kind": "property", "declared_in": current, "member": p})
154
+ for s: Dictionary in _signals_of(current, false):
155
+ if s["name"] == member:
156
+ found.append({"kind": "signal", "declared_in": current, "member": s})
157
+ for e: String in ClassDB.class_get_enum_list(current, true):
158
+ if e == member:
159
+ var values: Dictionary = {}
160
+ for c: String in ClassDB.class_get_enum_constants(current, e, true):
161
+ values[c] = ClassDB.class_get_integer_constant(current, c)
162
+ found.append(
163
+ {"kind": "enum", "declared_in": current, "member": {"name": e, "values": values}}
164
+ )
165
+ for c: String in ClassDB.class_get_integer_constant_list(current, true):
166
+ if c == member:
167
+ var value: int = ClassDB.class_get_integer_constant(current, c)
168
+ found.append(
169
+ {"kind": "constant", "declared_in": current, "member": {"name": c, "value": value}}
170
+ )
171
+ current = ClassDB.get_parent_class(current)
172
+
173
+ if found.is_empty():
174
+ var alike: Array[String] = _members_alike(class_name_str, member)
175
+ var hint: String = (
176
+ "" if alike.is_empty() else " Members with names containing it: " + ", ".join(alike) + "."
177
+ )
178
+ return _log.failure(
179
+ "%s and its ancestors declare no member named %s.%s" % [class_name_str, member, hint]
180
+ )
181
+
182
+ return {"class_name": class_name_str, "member": member, "found": found}
183
+
184
+
185
+ # The names, across a class and its ancestors, that contain the asked-for one, case-insensitively.
186
+ func _members_alike(class_name_str: String, member: String) -> Array[String]:
187
+ var alike: Array[String] = []
188
+ var wanted: String = member.to_lower()
189
+ var current: String = class_name_str
190
+ while not current.is_empty():
191
+ for m: Dictionary in _methods_of(current, false):
192
+ var name: String = m["name"]
193
+ if name.to_lower().contains(wanted) and not alike.has(name):
194
+ alike.append(name)
195
+ for p: Dictionary in _properties_of(current, false):
196
+ var name: String = p["name"]
197
+ if name.to_lower().contains(wanted) and not alike.has(name):
198
+ alike.append(name)
199
+ for s: Dictionary in _signals_of(current, false):
200
+ var name: String = s["name"]
201
+ if name.to_lower().contains(wanted) and not alike.has(name):
202
+ alike.append(name)
203
+ current = ClassDB.get_parent_class(current)
204
+ alike.sort()
205
+ return alike
206
+
207
+
133
208
  # Inspect class inheritance hierarchy
134
209
  func inspect_inheritance(params: Dictionary) -> Dictionary:
135
210
  var class_name_str: String = str(params.get("class_name", ""))