Skip to content

Commit fe0bfe3

Browse files
ian-coccimiglioctrueden
authored andcommitted
Make progress on introspection methods
1 parent 7b8a6c4 commit fe0bfe3

File tree

1 file changed

+88
-17
lines changed

1 file changed

+88
-17
lines changed

src/scyjava/_types.py

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def find_java_methods(data) -> list[dict[str, Any]]:
330330
returning a table of its available methods.
331331
332332
:param data: The object or class to inspect.
333-
:return: List of table rows with columns "name", "arguments", and "returns".
333+
:return: List of table rows with columns "name", "static", "arguments", and "returns".
334334
"""
335335

336336
if not isjava(data):
@@ -357,14 +357,17 @@ def find_java_methods(data) -> list[dict[str, Any]]:
357357
# })
358358

359359
table = []
360+
Modifier = jimport("java.lang.reflect.Modifier")
360361

361362
for m in methods:
362363
name = m.getName()
363364
args = [c.getName() for c in m.getParameterTypes()]
365+
mods = Modifier.isStatic(m.getModifiers())
364366
returns = m.getReturnType().getName()
365367
table.append(
366368
{
367369
"name": name,
370+
"static": mods,
368371
"arguments": args,
369372
"returns": returns,
370373
}
@@ -374,7 +377,31 @@ def find_java_methods(data) -> list[dict[str, Any]]:
374377
return sorted_table
375378

376379

377-
def map_syntax(base_type):
380+
# TODO
381+
def find_java_fields(data) -> list[dict[str, Any]]:
382+
"""
383+
Use Java reflection to introspect the given Java object,
384+
returning a table of its available fields.
385+
386+
:param data: The object or class to inspect.
387+
:return: List of table rows with columns "name", "arguments", and "returns".
388+
"""
389+
if not isjava(data):
390+
raise ValueError("Not a Java object")
391+
392+
cls = data if jinstance(data, "java.lang.Class") else jclass(data)
393+
394+
fields = cls.getFields()
395+
table = []
396+
397+
for f in fields:
398+
name = f.getName()
399+
table.append(name)
400+
401+
return table
402+
403+
404+
def _map_syntax(base_type):
378405
"""
379406
Maps a java BaseType annotation (see link below) in an Java array
380407
to a specific type with an Python interpretable syntax.
@@ -385,7 +412,7 @@ def map_syntax(base_type):
385412
"[C": "char[]",
386413
"[D": "double[]",
387414
"[F": "float[]",
388-
"[C": "int[]",
415+
"[I": "int[]",
389416
"[J": "long[]",
390417
"[L": "[]", # array
391418
"[S": "short[]",
@@ -394,33 +421,77 @@ def map_syntax(base_type):
394421

395422
if base_type in basetype_mapping:
396423
return basetype_mapping[base_type]
424+
# Handle the case of a returned array of an object
397425
elif base_type.__str__().startswith("[L"):
398426
return base_type.__str__()[2:-1] + "[]"
399427
else:
400428
return base_type
401429

402430

431+
def _make_pretty_string(entry, offset):
432+
"""
433+
Prints the entry with a specific formatting and aligned style
434+
:param entry: Dictionary of class names, modifiers, arguments, and return values.
435+
:param offset: Offset between the return value and the method.
436+
"""
437+
438+
# A star implies that the method is a static method
439+
return_val = f'{entry["returns"].__str__():<{offset}}'
440+
# Handle whether to print static/instance modifiers
441+
obj_name = f'{entry["name"]}'
442+
modifier = f'{"*":>4}' if entry["static"] else f'{"":>4}'
443+
444+
# Handle methods with no arguments
445+
if not entry["arguments"]:
446+
return f"{return_val} {modifier} = {obj_name}()\n"
447+
else:
448+
arg_string = ", ".join([r.__str__() for r in entry["arguments"]])
449+
return f"{return_val} {modifier} = {obj_name}({arg_string})\n"
450+
451+
452+
# TODO
453+
def fields(data) -> str:
454+
"""
455+
Writes data to a printed field names with the field value.
456+
:param data: The object or class to inspect.
457+
"""
458+
table = find_java_fields(data)
459+
460+
all_fields = ""
461+
################
462+
# FILL THIS IN #
463+
################
464+
465+
print(all_fields)
466+
467+
468+
# TODO
469+
def attrs(data):
470+
"""
471+
Writes data to a printed field names with the field value. Alias for `fields(data)`.
472+
:param data: The object or class to inspect.
473+
"""
474+
fields(data)
475+
476+
403477
def methods(data) -> str:
478+
"""
479+
Writes data to a printed string of class methods with inputs, static modifier, arguments, and return values.
480+
481+
:param data: The object or class to inspect.
482+
"""
404483
table = find_java_methods(data)
405484

406485
offset = max(list(map(lambda l: len(l["returns"]), table)))
407486
all_methods = ""
408-
409487
for entry in table:
410-
entry["returns"] = map_syntax(entry["returns"])
411-
entry["arguments"] = [map_syntax(e) for e in entry["arguments"]]
488+
entry["returns"] = _map_syntax(entry["returns"])
489+
entry["arguments"] = [_map_syntax(e) for e in entry["arguments"]]
490+
entry_string = _make_pretty_string(entry, offset)
491+
all_methods += entry_string
412492

413-
if not entry["arguments"]:
414-
all_methods = (
415-
all_methods
416-
+ f'{entry["returns"].__str__():<{offset}} = {entry["name"]}()\n'
417-
)
418-
else:
419-
arg_string = ", ".join([r.__str__() for r in entry["arguments"]])
420-
all_methods = (
421-
all_methods
422-
+ f'{entry["returns"].__str__():<{offset}} = {entry["name"]}({arg_string})\n'
423-
)
493+
# 4 added to align the asterisk with output.
494+
print(f'{"":<{offset+4}}* indicates a static method')
424495
print(all_methods)
425496

426497

0 commit comments

Comments
 (0)