(.using [library [lux {"-" Type} ["[0]" ffi {"+" import: do_to}] [control ["[0]" function]] [data ["[0]" product] ["[0]" text ["%" format {"+" format}]] [collection ["[0]" array {"+" Array}] ["[0]" list ("[1]@[0]" functor)]]] [math [number ["i" int]]] [target [jvm [encoding ["[0]" name]] ["[0]" type {"+" Type Constraint} [category {"+" Class Value Method}] ["[0]" signature] ["[0]" descriptor]]]]]] ["[0]" //]) (def: signature (|>> type.signature signature.signature)) (def: descriptor (|>> type.descriptor descriptor.descriptor)) (def: class_name (|>> type.descriptor descriptor.class_name name.read)) (import: java/lang/Object) (import: java/lang/String) (import: org/objectweb/asm/Opcodes ["[1]::[0]" ("static" ACC_PUBLIC int) ("static" ACC_PROTECTED int) ("static" ACC_PRIVATE int) ("static" ACC_TRANSIENT int) ("static" ACC_VOLATILE int) ("static" ACC_ABSTRACT int) ("static" ACC_FINAL int) ("static" ACC_STATIC int) ("static" ACC_SYNCHRONIZED int) ("static" ACC_STRICT int) ("static" ACC_SUPER int) ("static" ACC_INTERFACE int) ("static" V1_1 int) ("static" V1_2 int) ("static" V1_3 int) ("static" V1_4 int) ("static" V1_5 int) ("static" V1_6 int) ("static" V1_7 int) ("static" V1_8 int)]) (import: org/objectweb/asm/FieldVisitor ["[1]::[0]" (visitEnd [] void)]) (import: org/objectweb/asm/MethodVisitor ["[1]::[0]" (visitCode [] void) (visitMaxs [int int] void) (visitEnd [] void)]) (import: org/objectweb/asm/ClassWriter ["[1]::[0]" ("static" COMPUTE_MAXS int) ("static" COMPUTE_FRAMES int) (new [int]) (visit [int int java/lang/String java/lang/String java/lang/String [java/lang/String]] void) (visitEnd [] void) (visitField [int java/lang/String java/lang/String java/lang/String java/lang/Object] org/objectweb/asm/FieldVisitor) (visitMethod [int java/lang/String java/lang/String java/lang/String [java/lang/String]] org/objectweb/asm/MethodVisitor) (toByteArray [] [byte])]) (def: (string_array values) (-> (List Text) (Array Text)) (let [output (ffi.array java/lang/String (list.size values))] (exec (list@each (function (_ [idx value]) (ffi.write! idx value output)) (list.enumeration values)) output))) (def: (version_flag version) (-> //.Version Int) (case version {//.#V1_1} (org/objectweb/asm/Opcodes::V1_1) {//.#V1_2} (org/objectweb/asm/Opcodes::V1_2) {//.#V1_3} (org/objectweb/asm/Opcodes::V1_3) {//.#V1_4} (org/objectweb/asm/Opcodes::V1_4) {//.#V1_5} (org/objectweb/asm/Opcodes::V1_5) {//.#V1_6} (org/objectweb/asm/Opcodes::V1_6) {//.#V1_7} (org/objectweb/asm/Opcodes::V1_7) {//.#V1_8} (org/objectweb/asm/Opcodes::V1_8))) (def: (visibility_flag visibility) (-> //.Visibility Int) (case visibility {//.#Public} (org/objectweb/asm/Opcodes::ACC_PUBLIC) {//.#Protected} (org/objectweb/asm/Opcodes::ACC_PROTECTED) {//.#Private} (org/objectweb/asm/Opcodes::ACC_PRIVATE) {//.#Default} +0)) (def: (class_flags config) (-> //.Class_Config Int) ($_ i.+ (if (value@ //.#finalC config) (org/objectweb/asm/Opcodes::ACC_FINAL) +0))) (def: (method_flags config) (-> //.Method_Config Int) ($_ i.+ (if (value@ //.#staticM config) (org/objectweb/asm/Opcodes::ACC_STATIC) +0) (if (value@ //.#finalM config) (org/objectweb/asm/Opcodes::ACC_FINAL) +0) (if (value@ //.#synchronizedM config) (org/objectweb/asm/Opcodes::ACC_SYNCHRONIZED) +0) (if (value@ //.#strictM config) (org/objectweb/asm/Opcodes::ACC_STRICT) +0))) (def: (field_flags config) (-> //.Field_Config Int) ($_ i.+ (if (value@ //.#staticF config) (org/objectweb/asm/Opcodes::ACC_STATIC) +0) (if (value@ //.#finalF config) (org/objectweb/asm/Opcodes::ACC_FINAL) +0) (if (value@ //.#transientF config) (org/objectweb/asm/Opcodes::ACC_TRANSIENT) +0) (if (value@ //.#volatileF config) (org/objectweb/asm/Opcodes::ACC_VOLATILE) +0))) (def: param_signature (-> (Type Class) Text) (|>> ..signature (format ":"))) (def: (formal_param [name super interfaces]) (-> Constraint Text) (format name (param_signature super) (|> interfaces (list@each param_signature) (text.interposed "")))) (def: (constraints_signature constraints super interfaces) (-> (List Constraint) (Type Class) (List (Type Class)) Text) (let [formal_params (if (list.empty? constraints) "" (format "<" (|> constraints (list@each formal_param) (text.interposed "")) ">"))] (format formal_params (..signature super) (|> interfaces (list@each ..signature) (text.interposed ""))))) (def: class_computes Int ($_ i.+ (org/objectweb/asm/ClassWriter::COMPUTE_MAXS) ... (org/objectweb/asm/ClassWriter::COMPUTE_FRAMES) )) (def: binary_name (|>> name.internal name.read)) (template [ ] [(def: .public ( version visibility config name constraints super interfaces definitions) (-> //.Version //.Visibility //.Class_Config Text (List Constraint) (Type Class) (List (Type Class)) //.Def (ffi.type [byte])) (let [writer (|> (do_to (org/objectweb/asm/ClassWriter::new class_computes) (org/objectweb/asm/ClassWriter::visit (version_flag version) ($_ i.+ (org/objectweb/asm/Opcodes::ACC_SUPER) (visibility_flag visibility) (class_flags config)) (..binary_name name) (constraints_signature constraints super interfaces) (..class_name super) (|> interfaces (list@each ..class_name) string_array))) definitions) _ (org/objectweb/asm/ClassWriter::visitEnd writer)] (org/objectweb/asm/ClassWriter::toByteArray writer)))] [class +0] [abstract (org/objectweb/asm/Opcodes::ACC_ABSTRACT)] ) (def: $Object (Type Class) (type.class "java.lang.Object" (list))) (def: .public (interface version visibility config name constraints interfaces definitions) (-> //.Version //.Visibility //.Class_Config Text (List Constraint) (List (Type Class)) //.Def (ffi.type [byte])) (let [writer (|> (do_to (org/objectweb/asm/ClassWriter::new class_computes) (org/objectweb/asm/ClassWriter::visit (version_flag version) ($_ i.+ (org/objectweb/asm/Opcodes::ACC_ABSTRACT) (org/objectweb/asm/Opcodes::ACC_INTERFACE) (visibility_flag visibility) (class_flags config)) (..binary_name name) (constraints_signature constraints $Object interfaces) (..class_name $Object) (|> interfaces (list@each ..class_name) string_array))) definitions) _ (org/objectweb/asm/ClassWriter::visitEnd writer)] (org/objectweb/asm/ClassWriter::toByteArray writer))) (def: .public (method visibility config name type then) (-> //.Visibility //.Method_Config Text (Type Method) //.Inst //.Def) (function (_ writer) (let [=method (org/objectweb/asm/ClassWriter::visitMethod ($_ i.+ (visibility_flag visibility) (method_flags config)) (..binary_name name) (..descriptor type) (..signature type) (string_array (list)) writer) _ (org/objectweb/asm/MethodVisitor::visitCode =method) _ (then =method) _ (org/objectweb/asm/MethodVisitor::visitMaxs +0 +0 =method) _ (org/objectweb/asm/MethodVisitor::visitEnd =method)] writer))) (def: .public (abstract_method visibility config name type) (-> //.Visibility //.Method_Config Text (Type Method) //.Def) (function (_ writer) (let [=method (org/objectweb/asm/ClassWriter::visitMethod ($_ i.+ (visibility_flag visibility) (method_flags config) (org/objectweb/asm/Opcodes::ACC_ABSTRACT)) (..binary_name name) (..descriptor type) (..signature type) (string_array (list)) writer) _ (org/objectweb/asm/MethodVisitor::visitEnd =method)] writer))) (def: .public (field visibility config name type) (-> //.Visibility //.Field_Config Text (Type Value) //.Def) (function (_ writer) (let [=field (do_to (org/objectweb/asm/ClassWriter::visitField ($_ i.+ (visibility_flag visibility) (field_flags config)) (..binary_name name) (..descriptor type) (..signature type) (ffi.null) writer) (org/objectweb/asm/FieldVisitor::visitEnd))] writer))) (template [ ] [(def: .public ( visibility config name value) (-> //.Visibility //.Field_Config Text //.Def) (function (_ writer) (let [=field (do_to (org/objectweb/asm/ClassWriter::visitField ($_ i.+ (visibility_flag visibility) (field_flags config)) (..binary_name name) (..descriptor ) (..signature ) ( value) writer) (org/objectweb/asm/FieldVisitor::visitEnd))] writer)))] [boolean_field Bit type.boolean function.identity] [byte_field Int type.byte ffi.long_to_byte] [short_field Int type.short ffi.long_to_short] [int_field Int type.int ffi.long_to_int] [long_field Int type.long function.identity] [float_field Frac type.float ffi.double_to_float] [double_field Frac type.double function.identity] [char_field Nat type.char (|>> .int ffi.long_to_int ffi.int_to_char)] [string_field Text (type.class "java.lang.String" (list)) function.identity] ) (def: .public (fuse defs) (-> (List //.Def) //.Def) (case defs {.#End} function.identity {.#Item singleton {.#End}} singleton {.#Item head tail} (function.composite (fuse tail) head)))