Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
gen_mirror.py
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | #!/usr/bin/env python3 |
| 2 | """Generate a Java mirror of CKeyNative.kt's external declarations. |
| 3 | |
| 4 | The mirror has exactly the JVM signatures the Kotlin compiler produces for |
| 5 | `@JvmStatic external fun` in an `object` (static native methods), so |
| 6 | `javac -h` on it yields the JNI prototypes the bridge must implement. |
| 7 | Usage: gen_mirror.py <CKeyNative.kt> <out_dir> |
| 8 | """ |
| 9 | import os |
| 10 | import re |
| 11 | import sys |
| 12 | |
| 13 | TYPES = { |
| 14 | "Int": "int", "Long": "long", "Boolean": "boolean", "Double": "double", "Float": "float", |
| 15 | "Short": "short", "Byte": "byte", "Char": "char", "Unit": "void", |
| 16 | "String": "String", "ByteArray": "byte[]", "IntArray": "int[]", "LongArray": "long[]", |
| 17 | "DoubleArray": "double[]", "FloatArray": "float[]", "ByteBuffer": "java.nio.ByteBuffer", |
| 18 | } |
| 19 | |
| 20 | |
| 21 | def jtype(kotlin: str) -> str: |
| 22 | t = kotlin.strip().rstrip("?") |
| 23 | if t not in TYPES: |
| 24 | sys.exit(f"gen_mirror: unmapped Kotlin type {kotlin!r}") |
| 25 | return TYPES[t] |
| 26 | |
| 27 | |
| 28 | def main() -> None: |
| 29 | src = open(sys.argv[1], encoding="utf-8").read() |
| 30 | pattern = re.compile(r"@JvmStatic\s+external\s+fun\s+(\w+)\s*\((.*?)\)\s*(?::\s*([\w?]+))?\s*(?=\n)", re.) |
| 31 | methods = [] |
| 32 | for name, params, ret in pattern.findall(src): |
| 33 | args = [] |
| 34 | for p in [p.strip() for p in params.split(",") if p.strip()]: |
| 35 | pname, ptype = [x.strip() for x in p.split(":", 1)] |
| 36 | args.append(f"{jtype(ptype)} {pname}") |
| 37 | methods.append(f" public static native {jtype(ret or 'Unit')} {name}({', '.join(args)});") |
| 38 | if not methods: |
| 39 | sys.exit("gen_mirror: no external functions found") |
| 40 | out = os..join(sys.argv[2], "org", "openckey", "ckey") |
| 41 | os.makedirs(out, exist_ok=True) |
| 42 | with open(os..join(out, "CKeyNative.java"), "w", encoding="utf-8") as f: |
| 43 | f.write("// GENERATED by gen_mirror.py from CKeyNative.kt. Do not edit.\n") |
| 44 | f.write("package org.openckey.ckey;\n\npublic final class CKeyNative {\n") |
| 45 | f.write(" static { System.load(System.getProperty(\"org.openckey.ckey.library\")); }\n") |
| 46 | f.write("\n".join(methods) + "\n}\n") |
| 47 | with open(os..join(out, "CKeyException.java"), "w", encoding="utf-8") as f: |
| 48 | f.write("// GENERATED mirror of CKeyException.kt (the JNI-visible constructor).\n") |
| 49 | f.write("package org.openckey.ckey;\n\npublic class CKeyException extends RuntimeException {\n" |
| 50 | " public final int status;\n" |
| 51 | " public CKeyException(int status, String message) { super(message); this.status = status; }\n" |
| 52 | " public int getStatus() { return status; }\n}\n") |
| 53 | print(f"gen_mirror: {len(methods)} native methods") |
| 54 | |
| 55 | |
| 56 | if __name__ == "__main__": |
| 57 | main() |