|
| 1 | +""" |
| 2 | +High-level convenience functions for inspecting Java objects. |
| 3 | +""" |
| 4 | + |
| 5 | +from typing import Optional |
| 6 | + |
| 7 | +from scyjava._introspect import jreflect, jsource |
| 8 | + |
| 9 | + |
| 10 | +def members(data): |
| 11 | + """ |
| 12 | + Print all the members (constructors, fields, and methods) |
| 13 | + for a Java class, object, or class name. |
| 14 | +
|
| 15 | + :param data: The Java class, object, or fully qualified class name as string. |
| 16 | + """ |
| 17 | + _print_data(data, aspect="all") |
| 18 | + |
| 19 | + |
| 20 | +def constructors(data): |
| 21 | + """ |
| 22 | + Print the constructors for a Java class, object, or class name. |
| 23 | +
|
| 24 | + :param data: The Java class, object, or fully qualified class name as string. |
| 25 | + """ |
| 26 | + _print_data(data, aspect="constructors") |
| 27 | + |
| 28 | + |
| 29 | +def fields(data): |
| 30 | + """ |
| 31 | + Print the fields for a Java class, object, or class name. |
| 32 | +
|
| 33 | + :param data: The Java class, object, or fully qualified class name as string. |
| 34 | + """ |
| 35 | + _print_data(data, aspect="fields") |
| 36 | + |
| 37 | + |
| 38 | +def methods(data): |
| 39 | + """ |
| 40 | + Print the methods for a Java class, object, or class name. |
| 41 | +
|
| 42 | + :param data: The Java class, object, or fully qualified class name as string. |
| 43 | + """ |
| 44 | + _print_data(data, aspect="methods") |
| 45 | + |
| 46 | + |
| 47 | +def src(data): |
| 48 | + """ |
| 49 | + Print the source code URL for a Java class, object, or class name. |
| 50 | +
|
| 51 | + :param data: The Java class, object, or fully qualified class name as string. |
| 52 | + """ |
| 53 | + source_url = jsource(data) |
| 54 | + print(f"Source code URL: {source_url}") |
| 55 | + |
| 56 | + |
| 57 | +def _map_syntax(base_type): |
| 58 | + """ |
| 59 | + Map a Java BaseType annotation (see link below) in an Java array |
| 60 | + to a specific type with an Python interpretable syntax. |
| 61 | + https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3 |
| 62 | + """ |
| 63 | + basetype_mapping = { |
| 64 | + "[B": "byte[]", |
| 65 | + "[C": "char[]", |
| 66 | + "[D": "double[]", |
| 67 | + "[F": "float[]", |
| 68 | + "[I": "int[]", |
| 69 | + "[J": "long[]", |
| 70 | + "[L": "[]", # array |
| 71 | + "[S": "short[]", |
| 72 | + "[Z": "boolean[]", |
| 73 | + } |
| 74 | + |
| 75 | + if base_type in basetype_mapping: |
| 76 | + return basetype_mapping[base_type] |
| 77 | + # Handle the case of a returned array of an object |
| 78 | + elif base_type.__str__().startswith("[L"): |
| 79 | + return base_type.__str__()[2:-1] + "[]" |
| 80 | + else: |
| 81 | + return base_type |
| 82 | + |
| 83 | + |
| 84 | +def _pretty_string(entry, offset): |
| 85 | + """ |
| 86 | + Print the entry with a specific formatting and aligned style. |
| 87 | +
|
| 88 | + :param entry: Dictionary of class names, modifiers, arguments, and return values. |
| 89 | + :param offset: Offset between the return value and the method. |
| 90 | + """ |
| 91 | + |
| 92 | + # A star implies that the method is a static method |
| 93 | + return_val = f"{entry['returns'].__str__():<{offset}}" |
| 94 | + # Handle whether to print static/instance modifiers |
| 95 | + obj_name = f"{entry['name']}" |
| 96 | + modifier = f"{'*':>4}" if "static" in entry["mods"] else f"{'':>4}" |
| 97 | + |
| 98 | + # Handle fields |
| 99 | + if entry["arguments"] is None: |
| 100 | + return f"{return_val} {modifier} = {obj_name}\n" |
| 101 | + |
| 102 | + # Handle methods with no arguments |
| 103 | + if len(entry["arguments"]) == 0: |
| 104 | + return f"{return_val} {modifier} = {obj_name}()\n" |
| 105 | + else: |
| 106 | + arg_string = ", ".join([r.__str__() for r in entry["arguments"]]) |
| 107 | + return f"{return_val} {modifier} = {obj_name}({arg_string})\n" |
| 108 | + |
| 109 | + |
| 110 | +def _print_data(data, aspect, static: Optional[bool] = None, source: bool = True): |
| 111 | + """ |
| 112 | + Write data to a printed string of class methods with inputs, static modifier, |
| 113 | + arguments, and return values. |
| 114 | +
|
| 115 | + :param table: The table of class members to print. |
| 116 | + :param static: |
| 117 | + Boolean filter on Static or Instance methods. |
| 118 | + Optional, default is None (prints all). |
| 119 | + :param source: Whether to print any available source code. Default True. |
| 120 | + """ |
| 121 | + table = jreflect(data, aspect) |
| 122 | + if len(table) == 0: |
| 123 | + print(f"No {aspect} found") |
| 124 | + return |
| 125 | + |
| 126 | + # Print source code |
| 127 | + offset = max(list(map(lambda entry: len(entry["returns"]), table))) |
| 128 | + all_methods = "" |
| 129 | + if source: |
| 130 | + urlstring = jsource(data) |
| 131 | + print(f"Source code URL: {urlstring}") |
| 132 | + |
| 133 | + # Print methods |
| 134 | + for entry in table: |
| 135 | + entry["returns"] = _map_syntax(entry["returns"]) |
| 136 | + if entry["arguments"]: |
| 137 | + entry["arguments"] = [_map_syntax(e) for e in entry["arguments"]] |
| 138 | + if static is None: |
| 139 | + entry_string = _pretty_string(entry, offset) |
| 140 | + all_methods += entry_string |
| 141 | + |
| 142 | + elif static and "static" in entry["mods"]: |
| 143 | + entry_string = _pretty_string(entry, offset) |
| 144 | + all_methods += entry_string |
| 145 | + elif not static and "static" not in entry["mods"]: |
| 146 | + entry_string = _pretty_string(entry, offset) |
| 147 | + all_methods += entry_string |
| 148 | + else: |
| 149 | + continue |
| 150 | + |
| 151 | + # 4 added to align the asterisk with output. |
| 152 | + print(f"{'':<{offset + 4}}* indicates static modifier") |
| 153 | + print(all_methods) |
0 commit comments