jData.ml 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. (*
  2. * This file is part of JavaLib
  3. * Copyright (c)2004-2012 Nicolas Cannasse and Caue Waneck
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *)
  19. type jpath = (string list) * string
  20. type jversion = int * int (* minor + major *)
  21. (** unqualified names cannot have the characters '.', ';', '[' or '/' *)
  22. type unqualified_name = string
  23. type jwildcard =
  24. | WExtends (* + *)
  25. | WSuper (* - *)
  26. | WNone
  27. type jtype_argument =
  28. | TType of jwildcard * jsignature
  29. | TAny (* * *)
  30. and jsignature =
  31. | TByte (* B *)
  32. | TChar (* C *)
  33. | TDouble (* D *)
  34. | TFloat (* F *)
  35. | TInt (* I *)
  36. | TLong (* J *)
  37. | TShort (* S *)
  38. | TBool (* Z *)
  39. | TObject of jpath * jtype_argument list (* L Classname *)
  40. | TObjectInner of (string list) * (string * jtype_argument list) list (* L Classname ClassTypeSignatureSuffix *)
  41. | TArray of jsignature * int option (* [ *)
  42. | TMethod of jmethod_signature (* ( *)
  43. | TTypeParameter of string (* T *)
  44. (* ( jsignature list ) ReturnDescriptor (| V | jsignature) *)
  45. and jmethod_signature = jsignature list * jsignature option
  46. (* InvokeDynamic-specific: Method handle *)
  47. type reference_type =
  48. | RGetField (* constant must be ConstField *)
  49. | RGetStatic (* constant must be ConstField *)
  50. | RPutField (* constant must be ConstField *)
  51. | RPutStatic (* constant must be ConstField *)
  52. | RInvokeVirtual (* constant must be Method *)
  53. | RInvokeStatic (* constant must be Method *)
  54. | RInvokeSpecial (* constant must be Method *)
  55. | RNewInvokeSpecial (* constant must be Method with name <init> *)
  56. | RInvokeInterface (* constant must be InterfaceMethod *)
  57. (* TODO *)
  58. type bootstrap_method = int
  59. type jconstant =
  60. (** references a class or an interface - jpath must be encoded as StringUtf8 *)
  61. | ConstClass of jpath (* tag = 7 *)
  62. (** field reference *)
  63. | ConstField of (jpath * unqualified_name * jsignature) (* tag = 9 *)
  64. (** method reference; string can be special "<init>" and "<clinit>" values *)
  65. | ConstMethod of (jpath * unqualified_name * jmethod_signature) (* tag = 10 *)
  66. (** interface method reference *)
  67. | ConstInterfaceMethod of (jpath * unqualified_name * jmethod_signature) (* tag = 11 *)
  68. (** constant values *)
  69. | ConstString of string (* tag = 8 *)
  70. | ConstInt of int32 (* tag = 3 *)
  71. | ConstFloat of float (* tag = 4 *)
  72. | ConstLong of int64 (* tag = 5 *)
  73. | ConstDouble of float (* tag = 6 *)
  74. (** name and type: used to represent a field or method, without indicating which class it belongs to *)
  75. | ConstNameAndType of unqualified_name * jsignature
  76. (** UTF8 encoded strings. Note that when reading/writing, take into account Utf8 modifications of java *)
  77. (* (http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7) *)
  78. | ConstUtf8 of string
  79. (** invokeDynamic-specific *)
  80. | ConstMethodHandle of (reference_type * jconstant) (* tag = 15 *)
  81. | ConstMethodType of jmethod_signature (* tag = 16 *)
  82. | ConstDynamic of (bootstrap_method * unqualified_name * jsignature) (* tag = 17 *)
  83. | ConstInvokeDynamic of (bootstrap_method * unqualified_name * jsignature) (* tag = 18 *)
  84. | ConstModule of unqualified_name (* tag = 19 *)
  85. | ConstPackage of unqualified_name (* tag = 20 *)
  86. | ConstUnusable
  87. type jaccess_flag =
  88. | JPublic (* 0x0001 *)
  89. | JPrivate (* 0x0002 *)
  90. | JProtected (* 0x0004 *)
  91. | JStatic (* 0x0008 *)
  92. | JFinal (* 0x0010 *)
  93. | JSynchronized (* 0x0020 *)
  94. | JVolatile (* 0x0040 *)
  95. | JTransient (* 0x0080 *)
  96. (** added if created by the compiler *)
  97. | JSynthetic (* 0x1000 *)
  98. | JEnum (* 0x4000 *)
  99. | JUnusable (* should not be present *)
  100. (** class flags *)
  101. | JSuper (* 0x0020 *)
  102. | JInterface (* 0x0200 *)
  103. | JAbstract (* 0x0400 *)
  104. | JAnnotation (* 0x2000 *)
  105. | JModule (* 0x8000 *)
  106. (** method flags *)
  107. | JBridge (* 0x0040 *)
  108. | JVarArgs (* 0x0080 *)
  109. | JNative (* 0x0100 *)
  110. | JStrict (* 0x0800 *)
  111. type jaccess = jaccess_flag list
  112. (* type parameter name, extends signature, implements signatures *)
  113. type jtypes = (string * jsignature option * jsignature list) list
  114. type jannotation = {
  115. ann_type : jsignature;
  116. ann_elements : (string * jannotation_value) list;
  117. }
  118. and jannotation_value =
  119. | ValConst of jsignature * jconstant (* B, C, D, E, F, I, J, S, Z, s *)
  120. | ValEnum of jsignature * string (* e *)
  121. | ValClass of jsignature (* c *) (* V -> Void *)
  122. | ValAnnotation of jannotation (* @ *)
  123. | ValArray of jannotation_value list (* [ *)
  124. type jlocal = {
  125. ld_start_pc : int;
  126. ld_length : int;
  127. ld_name : string;
  128. ld_descriptor : string;
  129. ld_index : int;
  130. }
  131. type jattribute =
  132. | AttrDeprecated
  133. | AttrVisibleAnnotations of jannotation list
  134. | AttrInvisibleAnnotations of jannotation list
  135. | AttrLocalVariableTable of jlocal list
  136. | AttrMethodParameters of (string * int) list
  137. | AttrUnknown of string * string
  138. type jcode = jattribute list (* TODO *)
  139. type jfield_kind =
  140. | JKField
  141. | JKMethod
  142. type jfield = {
  143. jf_name : string;
  144. jf_kind : jfield_kind;
  145. (* signature, as used by the vm *)
  146. jf_vmsignature : jsignature;
  147. (* actual signature, as used in java code *)
  148. jf_signature : jsignature;
  149. jf_throws : jsignature list;
  150. jf_types : jtypes;
  151. jf_flags : jaccess;
  152. jf_attributes : jattribute list;
  153. jf_constant : jconstant option;
  154. jf_code : jcode option;
  155. }
  156. type jclass = {
  157. cversion : jversion;
  158. cpath : jpath;
  159. csuper : jsignature;
  160. cflags : jaccess;
  161. cinterfaces : jsignature list;
  162. cfields : jfield list;
  163. cmethods : jfield list;
  164. cattributes : jattribute list;
  165. cinner_types : (jpath * jpath option * string option * jaccess) list;
  166. ctypes : jtypes;
  167. }
  168. (* reading/writing *)
  169. type utf8ref = int
  170. type classref = int
  171. type nametyperef = int
  172. type dynref = int
  173. type bootstrapref = int
  174. type jconstant_raw =
  175. | KClass of utf8ref (* 7 *)
  176. | KFieldRef of (classref * nametyperef) (* 9 *)
  177. | KMethodRef of (classref * nametyperef) (* 10 *)
  178. | KInterfaceMethodRef of (classref * nametyperef) (* 11 *)
  179. | KString of utf8ref (* 8 *)
  180. | KInt of int32 (* 3 *)
  181. | KFloat of float (* 4 *)
  182. | KLong of int64 (* 5 *)
  183. | KDouble of float (* 6 *)
  184. | KNameAndType of (utf8ref * utf8ref) (* 12 *)
  185. | KUtf8String of string (* 1 *)
  186. | KMethodHandle of (reference_type * dynref) (* 15 *)
  187. | KMethodType of utf8ref (* 16 *)
  188. | KDynamic of (bootstrapref * nametyperef) (* 17 *)
  189. | KInvokeDynamic of (bootstrapref * nametyperef) (* 18 *)
  190. | KModule of utf8ref (* 19 *)
  191. | KPackage of utf8ref (* 20 *)
  192. | KUnusable
  193. (* jData debugging *)
  194. let is_override_attrib = (function
  195. (* TODO: pass anotations as @:meta *)
  196. | AttrVisibleAnnotations ann ->
  197. List.exists (function
  198. | { ann_type = TObject( (["java";"lang"], "Override"), [] ) } ->
  199. true
  200. | _ -> false
  201. ) ann
  202. | _ -> false
  203. )
  204. let is_override field =
  205. List.exists is_override_attrib field.jf_attributes
  206. let path_s = function
  207. | (pack,name) -> String.concat "." (pack @ [name])
  208. let rec s_sig = function
  209. | TByte (* B *) -> "byte"
  210. | TChar (* C *) -> "char"
  211. | TDouble (* D *) -> "double"
  212. | TFloat (* F *) -> "float"
  213. | TInt (* I *) -> "int"
  214. | TLong (* J *) -> "long"
  215. | TShort (* S *) -> "short"
  216. | TBool (* Z *) -> "bool"
  217. | TObject(path,args) -> path_s path ^ s_args args
  218. | TObjectInner (sl, sjargl) -> String.concat "." sl ^ "." ^ (String.concat "." (List.map (fun (s,arg) -> s ^ s_args arg) sjargl))
  219. | TArray (s,i) -> s_sig s ^ "[" ^ (match i with | None -> "" | Some i -> string_of_int i) ^ "]"
  220. | TMethod (sigs, sopt) -> (match sopt with | None -> "" | Some s -> s_sig s ^ " ") ^ "(" ^ String.concat ", " (List.map s_sig sigs) ^ ")"
  221. | TTypeParameter s -> s
  222. and s_args = function
  223. | [] -> ""
  224. | args -> "<" ^ String.concat ", " (List.map (fun t ->
  225. match t with
  226. | TAny -> "*"
  227. | TType (wc, s) ->
  228. (match wc with
  229. | WNone -> ""
  230. | WExtends -> "+"
  231. | WSuper -> "-") ^
  232. (s_sig s))
  233. args) ^ ">"
  234. let s_field f = (if is_override f then "override " else "") ^ s_sig f.jf_signature ^ " " ^ f.jf_name
  235. let s_fields fs = "{ \n\t" ^ String.concat "\n\t" (List.map s_field fs) ^ "\n}"