genjson.ml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. open Ast
  2. open Globals
  3. open Type
  4. open Meta
  5. type generation_mode =
  6. | GMFull
  7. | GMWithoutDoc
  8. | GMMinimum
  9. type context = {
  10. generation_mode : generation_mode;
  11. generate_abstract_impl : bool;
  12. request : JsonRequest.json_request option
  13. }
  14. let jnull = Json.JNull
  15. let jstring s = Json.JString s
  16. let jint i = Json.JInt i
  17. let jfloat f = Json.JFloat f
  18. let jbool b = Json.JBool b
  19. let jarray l = Json.JArray l
  20. let jobject l = Json.JObject l
  21. let jtodo = Json.JNull
  22. let jopt f o = Option.map_default f Json.JNull o
  23. let jlist f o = jarray (List.map f o)
  24. let generate_package_path' pack = [
  25. ("pack",jarray (List.map jstring pack))
  26. ]
  27. let generate_package_path pack = jobject (generate_package_path' pack)
  28. let generate_module_path' mpath =
  29. ("moduleName",jstring (snd mpath)) ::
  30. generate_package_path' (fst mpath)
  31. let generate_module_path mpath = jobject (generate_module_path' mpath)
  32. let generate_type_path' mpath tpath meta =
  33. ("typeName",jstring (snd tpath)) ::
  34. generate_module_path' mpath
  35. let generate_type_path mpath tpath meta =
  36. let rec loop = function
  37. | [] -> tpath
  38. | (Meta.RealPath,[(Ast.EConst (Ast.String(s,_)),_)],_) :: _ -> parse_path s
  39. | _ :: l -> loop l
  40. in
  41. let tpath = loop meta in
  42. jobject (generate_type_path' mpath tpath meta)
  43. let generate_adt ctx tpath name args =
  44. let field = ("kind",jstring name) in
  45. let fields = match args with
  46. | None -> [field]
  47. | Some arg -> [field;("args",arg)]
  48. in
  49. jobject fields
  50. let field_name name meta =
  51. try
  52. begin match Meta.get Meta.RealPath meta with
  53. | _,[EConst (String (s,_)),_],_ -> s
  54. | _ -> raise Not_found
  55. end;
  56. with Not_found ->
  57. name
  58. let class_ref ctx c = generate_type_path c.cl_module.m_path c.cl_path c.cl_meta
  59. let enum_ref ctx en = generate_type_path en.e_module.m_path en.e_path en.e_meta
  60. let typedef_ref ctx td = generate_type_path td.t_module.m_path td.t_path td.t_meta
  61. let abstract_ref ctx a = generate_type_path a.a_module.m_path a.a_path a.a_meta
  62. let moduletype_ref ctx mt =
  63. let infos = t_infos mt in
  64. generate_type_path infos.mt_module.m_path infos.mt_path infos.mt_meta
  65. let classfield_ref ctx cf = jstring (field_name cf.cf_name cf.cf_meta)
  66. let enumfield_ref ctx ef = jstring (field_name ef.ef_name ef.ef_meta)
  67. let local_ref ctx v = jint v.v_id
  68. let generate_pos ctx p =
  69. jobject [
  70. "file",jstring p.pfile;
  71. "min",jint p.pmin;
  72. "max",jint p.pmax;
  73. ]
  74. let generate_expr_pos ctx p =
  75. jtodo
  76. let generate_doc ctx d = match ctx.generation_mode with
  77. | GMFull -> jopt jstring (gen_doc_text_opt d)
  78. | GMWithoutDoc | GMMinimum -> jnull
  79. (** return a range JSON structure for given position
  80. positions are 0-based and the result object looks like this:
  81. {
  82. start: {line: 0, character: 0},
  83. end: {line: 3, character: 42},
  84. }
  85. *)
  86. let pos_to_range p =
  87. let l1, p1, l2, p2 = Lexer.get_pos_coords p in
  88. let to_json l c = jobject [("line", jint (l - 1)); ("character", jint (c - 1))] in
  89. [
  90. ("start", to_json l1 p1);
  91. ("end", to_json l2 p2);
  92. ]
  93. let generate_pos_as_range p =
  94. if p.pmin = -1 then jnull
  95. else jobject (pos_to_range p)
  96. let generate_pos_as_location p =
  97. if p.pmin = -1 then
  98. jnull
  99. else
  100. jobject [("file",jstring (Path.get_real_path p.pfile));"range",generate_pos_as_range p]
  101. (* AST expr *)
  102. let rec generate_binop ctx op =
  103. let name,args = match op with
  104. | OpAdd -> "OpAdd",None
  105. | OpMult -> "OpMult",None
  106. | OpDiv -> "OpDiv",None
  107. | OpSub -> "OpSub",None
  108. | OpAssign -> "OpAssign",None
  109. | OpEq -> "OpEq",None
  110. | OpNotEq -> "OpNotEq",None
  111. | OpGt -> "OpGt",None
  112. | OpGte -> "OpGte",None
  113. | OpLt -> "OpLt",None
  114. | OpLte -> "OpLte",None
  115. | OpAnd -> "OpAnd",None
  116. | OpOr -> "OpOr",None
  117. | OpXor -> "OpXor",None
  118. | OpBoolAnd -> "OpBoolAnd",None
  119. | OpBoolOr -> "OpBoolOr",None
  120. | OpShl -> "OpShl",None
  121. | OpShr -> "OpShr",None
  122. | OpUShr -> "OpUShr",None
  123. | OpMod -> "OpMod",None
  124. | OpAssignOp op -> "OpAssignOp", (Some (generate_binop ctx op))
  125. | OpInterval -> "OpInterval",None
  126. | OpArrow -> "OpArrow",None
  127. | OpIn -> "OpIn",None
  128. in
  129. generate_adt ctx (Some (["haxe";"macro"],"Binop")) name args
  130. let generate_unop ctx op =
  131. let name = match op with
  132. | Increment -> "OpIncrement"
  133. | Decrement -> "OpDecrement"
  134. | Not -> "OpNot"
  135. | Neg -> "OpNeg"
  136. | NegBits -> "OpNegBits"
  137. | Spread -> "OpSpread"
  138. in
  139. jstring name
  140. let rec generate_expr ctx e =
  141. jtodo
  142. (* metadata *)
  143. and generate_metadata_entry ctx (m,el,p) =
  144. jobject [
  145. "name",jstring (Meta.to_string m);
  146. "args",jlist (generate_expr ctx) el;
  147. "pos",generate_pos ctx p;
  148. ]
  149. and generate_metadata ctx ml =
  150. let ml = List.filter (fun (m,_,_) ->
  151. let (_,(_,flags)) = Meta.get_info m in
  152. not (List.mem UsedInternally flags)
  153. ) ml in
  154. jlist (generate_metadata_entry ctx) ml
  155. and generate_minimum_metadata ctx ml =
  156. match ctx.request with
  157. | None -> None
  158. | Some request ->
  159. match request#get_requested_meta_list with
  160. | None -> None
  161. | Some requested ->
  162. let ml =
  163. List.filter
  164. (fun (m,_,_) -> List.exists (fun r -> r = to_string m) requested)
  165. ml
  166. in
  167. Some (jlist (generate_metadata_entry ctx) ml)
  168. (* AST.ml structures *)
  169. let rec generate_ast_type_param ctx tp = jobject [
  170. "name",jstring (fst tp.tp_name);
  171. "params",jlist (generate_ast_type_param ctx) tp.tp_params;
  172. "constraints",jtodo;
  173. "metadata",generate_metadata ctx tp.tp_meta
  174. ]
  175. (* type instance *)
  176. let rec generate_type ctx t =
  177. let rec loop t = match t with
  178. | TMono r ->
  179. begin match r.tm_type with
  180. | None -> "TMono",None
  181. | Some t -> loop t
  182. end
  183. | TLazy f ->
  184. (* return_partial_type := true; *)
  185. let t = lazy_type f in
  186. (* return_partial_type := false; *)
  187. loop t
  188. | TDynamic t -> "TDynamic",Some (if t == t_dynamic then jnull else generate_type ctx t)
  189. | TInst(c,tl) -> "TInst",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)
  190. | TEnum(en,tl) -> "TEnum",Some (generate_type_path_with_params ctx en.e_module.m_path en.e_path tl en.e_meta)
  191. | TType(td,tl) -> "TType",Some (generate_type_path_with_params ctx td.t_module.m_path td.t_path tl td.t_meta)
  192. | TAbstract(a,tl) -> "TAbstract",Some (generate_type_path_with_params ctx a.a_module.m_path a.a_path tl a.a_meta)
  193. | TAnon an -> "TAnonymous", Some(generate_anon ctx an)
  194. | TFun(tl,tr) -> "TFun", Some (jobject (generate_function_signature ctx tl tr))
  195. in
  196. let name,args = loop t in
  197. generate_adt ctx None name args
  198. and generate_anon_status ctx status =
  199. let name,args = match status with
  200. | Closed -> "AClosed",None
  201. | Const -> "AConst",None
  202. | Extend tl -> "AExtend", Some (generate_types ctx tl)
  203. | Statics c -> "AClassStatics",Some (class_ref ctx c)
  204. | EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
  205. | AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
  206. in
  207. generate_adt ctx None name args
  208. and generate_anon ctx an =
  209. let generate_anon_fields () =
  210. let fields = PMap.fold (fun cf acc -> generate_class_field ctx CFSMember cf :: acc) an.a_fields [] in
  211. jarray fields
  212. in
  213. jobject [
  214. "fields",generate_anon_fields();
  215. "status",generate_anon_status ctx !(an.a_status);
  216. ]
  217. and generate_function_argument ctx (name,opt,t) =
  218. jobject [
  219. "name",jstring name;
  220. "opt",jbool opt;
  221. "t",generate_type ctx t;
  222. ]
  223. and generate_function_signature ctx tl tr =
  224. [
  225. "args",jlist (generate_function_argument ctx) tl;
  226. "ret",generate_type ctx tr;
  227. ]
  228. and generate_types ctx tl =
  229. jlist (generate_type ctx) tl
  230. and generate_type_path_with_params ctx mpath tpath tl meta =
  231. jobject [
  232. "path",generate_type_path mpath tpath meta;
  233. "params",generate_types ctx tl;
  234. ]
  235. (* type parameter *)
  236. and generate_type_parameter ctx (s,t) =
  237. let generate_constraints () = match follow t with
  238. | TInst({cl_kind = KTypeParameter tl},_) -> generate_types ctx tl
  239. | _ -> die "" __LOC__
  240. in
  241. jobject [
  242. "name",jstring s;
  243. "constraints",generate_constraints ();
  244. ]
  245. (* texpr *)
  246. and generate_tvar ctx v =
  247. let generate_extra ve =
  248. let (params,eo) = (ve.v_params,ve.v_expr) in
  249. jobject (
  250. ("params",jlist (generate_type_parameter ctx) params) ::
  251. (match eo with
  252. | None -> []
  253. | Some e -> ["expr",jobject [
  254. ("string",jstring (s_expr_pretty false "" false (s_type (print_context())) e))
  255. ]]);
  256. ) in
  257. let fields = [
  258. "id",jint v.v_id;
  259. "name",jstring v.v_name;
  260. "type",generate_type ctx v.v_type;
  261. "capture",jbool (has_var_flag v VCaptured);
  262. "extra",jopt generate_extra v.v_extra;
  263. "meta",generate_metadata ctx v.v_meta;
  264. "pos",generate_pos ctx v.v_pos;
  265. "isFinal",jbool (has_var_flag v VFinal);
  266. "isInline",jbool (match v.v_extra with Some {v_expr = Some _} -> true | _ -> false);
  267. ] in
  268. let origin_to_int = function
  269. | TVOLocalVariable -> 0
  270. | TVOArgument -> 1
  271. | TVOForVariable -> 2
  272. | TVOPatternVariable -> 3
  273. | TVOCatchVariable -> 4
  274. | TVOLocalFunction -> 5
  275. in
  276. let fields = match v.v_kind with
  277. | VUser origin -> ("origin",jint (origin_to_int origin)) :: fields
  278. | _ -> fields
  279. in
  280. jobject fields
  281. and generate_tconstant ctx ct =
  282. let name,args = match ct with
  283. | TInt i32 -> "TInt",Some (jstring (Int32.to_string i32))
  284. | TFloat s -> "TFloat",Some (jstring s)
  285. | TString s -> "TString",Some (jstring s)
  286. | TBool b -> "TBool",Some (jbool b)
  287. | TNull -> "TNull",None
  288. | TThis -> "TThis",None
  289. | TSuper -> "TSuper",None
  290. in
  291. generate_adt ctx None name args
  292. and generate_tfunction ctx tf =
  293. let generate_arg (v,cto) = jobject [
  294. "v",generate_tvar ctx v;
  295. "value",jopt (generate_texpr ctx) cto;
  296. ] in
  297. jobject [
  298. "args",jlist generate_arg tf.tf_args;
  299. "ret",generate_type ctx tf.tf_type;
  300. "expr",generate_expr ctx tf.tf_expr;
  301. ]
  302. and generate_texpr ctx e =
  303. jtodo
  304. (* let name,args = match e.eexpr with
  305. | TConst ct ->
  306. "TConst",Some (generate_tconstant ctx ct)
  307. | TLocal v ->
  308. "TLocal",Some (local_ref ctx v)
  309. | TArray(e1,e2) ->
  310. "TArray",Some (jobject [
  311. "expr1",generate_texpr ctx e1;
  312. "expr2",generate_texpr ctx e2;
  313. ])
  314. | TBinop(op,e1,e2) ->
  315. "TBinop",Some (jobject [
  316. "op",generate_binop ctx op;
  317. "expr1",generate_texpr ctx e1;
  318. "expr2",generate_texpr ctx e2;
  319. ]);
  320. | TField(e1,fa) ->
  321. "TField",Some (jobject [
  322. "expr",generate_texpr ctx e1;
  323. "name",jstring (field_name fa);
  324. (* TODO *)
  325. ]);
  326. | TTypeExpr mt ->
  327. "TTypeExpr",Some (moduletype_ref ctx mt)
  328. | TParenthesis e1 ->
  329. "TParenthesis",Some (generate_texpr ctx e1)
  330. | TObjectDecl fl ->
  331. let generate_quote_status qs =
  332. let name = match qs with
  333. | DoubleQuotes -> "DoubleQuotes"
  334. | NoQuotes -> "NoQuotes"
  335. in
  336. generate_adt ctx None name None
  337. in
  338. let generate_key (name,pos,qs) = jobject [
  339. "name",jstring name;
  340. "pos",generate_expr_pos ctx pos;
  341. "quoteStatus",generate_quote_status qs;
  342. ] in
  343. let generate_entry (key,value) = jobject [
  344. "key",generate_key key;
  345. "value",generate_texpr ctx value;
  346. ] in
  347. let fields = List.map generate_entry fl in
  348. "TObjectDecl",Some (jarray fields)
  349. | TArrayDecl el ->
  350. let fields = List.map (generate_texpr ctx) el in
  351. "TArrayDecl",Some (jarray fields)
  352. | TCall(e1,el) ->
  353. let args = List.map (generate_texpr ctx) el in
  354. "TCall",Some (jobject [
  355. "expr",generate_texpr ctx e1;
  356. "args",jarray args;
  357. ]);
  358. | TNew(c,tl,el) ->
  359. let args = List.map (generate_texpr ctx) el in
  360. "TNew",Some (jobject [
  361. "path",generate_type_path_with_params ctx c.cl_path tl;
  362. "args",jarray args;
  363. ]);
  364. | TUnop(op,flag,e1) ->
  365. "TUnop",Some (jobject [
  366. "op",generate_unop ctx op;
  367. "prefix",jbool (flag = Prefix);
  368. "expr",generate_texpr ctx e1;
  369. ]);
  370. | TFunction tf ->
  371. "TFunction",Some (generate_tfunction ctx tf)
  372. | TVar(v,eo) ->
  373. "TVar",Some (jobject [
  374. "v",generate_tvar ctx v;
  375. "expr",jopt (generate_texpr ctx) eo;
  376. ])
  377. | TBlock el ->
  378. let el = List.map (generate_texpr ctx) el in
  379. "TBlock",Some (jarray el)
  380. | TFor(v,e1,e2) ->
  381. "TFor",Some (jobject [
  382. "v",generate_tvar ctx v;
  383. "expr1",generate_texpr ctx e1;
  384. "expr2",generate_texpr ctx e2;
  385. ]);
  386. | TIf(e1,e2,eo) ->
  387. "TIf",Some (jobject [
  388. "eif",generate_texpr ctx e1;
  389. "ethen",generate_expr ctx e1;
  390. "eelse",jopt (generate_expr ctx) eo;
  391. ]);
  392. | TWhile(e1,e2,flag) ->
  393. "TWhile",Some (jobject [
  394. "econd",generate_texpr ctx e1;
  395. "ebody",generate_texpr ctx e2;
  396. "isDoWhile",jbool (flag = DoWhile);
  397. ]);
  398. | TSwitch(e1,cases,edef) ->
  399. let generate_case (el,e) = jobject [
  400. "patterns",jlist (generate_texpr ctx) el;
  401. "expr",generate_texpr ctx e;
  402. ] in
  403. "TSwitch",Some (jobject [
  404. "subject",generate_texpr ctx e1;
  405. "cases",jlist generate_case cases;
  406. "def",jopt (generate_texpr ctx) edef;
  407. ])
  408. | TTry(e1,catches) ->
  409. let generate_catch (v,e) = jobject [
  410. "v",generate_tvar ctx v;
  411. "expr",generate_texpr ctx e;
  412. ] in
  413. "TTry",Some (jobject [
  414. "expr",generate_texpr ctx e1;
  415. "catches",jlist generate_catch catches;
  416. ])
  417. | TReturn eo ->
  418. "TReturn",Option.map (generate_texpr ctx) eo
  419. | TBreak ->
  420. "TBreak",None
  421. | TContinue ->
  422. "TContinue",None
  423. | TThrow e1 ->
  424. "TThrow",Some (generate_texpr ctx e1)
  425. | TCast(e1,mto) ->
  426. "TCast",Some (jobject [
  427. "expr",generate_texpr ctx e1;
  428. "moduleType",jopt (moduletype_ref ctx) mto;
  429. ]);
  430. | TMeta(m,e1) ->
  431. "TMeta",Some (jobject [
  432. "meta",generate_metadata_entry ctx m;
  433. "expr",generate_texpr ctx e1;
  434. ])
  435. | TEnumParameter(e1,ef,i) ->
  436. "TEnumParameter",Some (jobject [
  437. "expr",generate_texpr ctx e1;
  438. "enumField",enumfield_ref ctx ef;
  439. "index",jint i;
  440. ]);
  441. | TEnumIndex e1 ->
  442. "TEnumIndex",Some (generate_texpr ctx e1)
  443. | TIdent s ->
  444. "TIdent",Some (jstring s)
  445. in
  446. jobject [
  447. "expr",generate_adt ctx None name args;
  448. (* TODO: pos? *)
  449. "type",generate_type ctx e.etype;
  450. ] *)
  451. (* fields *)
  452. and generate_class_field' ctx cfs cf =
  453. let generate_class_kind () =
  454. let generate_var_access va =
  455. let name,args = match va with
  456. | AccNormal -> "AccNormal",None
  457. | AccNo -> "AccNo",None
  458. | AccNever -> "AccNever",None
  459. | AccCtor -> "AccCtor",None
  460. | AccCall -> "AccCall",None
  461. | AccInline -> "AccInline",None
  462. | AccRequire(s,so) -> "AccRequire",Some (jobject ["require",jstring s;"message",jopt jstring so])
  463. in
  464. generate_adt ctx None name args
  465. in
  466. let generate_method_kind m =
  467. let name = match m with
  468. | MethNormal -> "MethNormal"
  469. | MethInline -> "MethInline"
  470. | MethDynamic -> "MethDynamic"
  471. | MethMacro -> "MethMacro"
  472. in
  473. jstring name
  474. in
  475. let name,args = match cf.cf_kind with
  476. | Var vk -> "FVar",Some (jobject ["read",generate_var_access vk.v_read;"write",generate_var_access vk.v_write])
  477. | Method m -> "FMethod", Some (generate_method_kind m)
  478. in
  479. generate_adt ctx None name args
  480. in
  481. let expr = match ctx.generation_mode with
  482. | GMFull | GMWithoutDoc ->
  483. let value = match cf.cf_kind with
  484. | Method _ -> None
  485. | Var _ ->
  486. try
  487. begin match Meta.get Meta.Value cf.cf_meta with
  488. | (_,[e],_) -> Some e
  489. | _ -> None
  490. end
  491. with Not_found ->
  492. None
  493. in
  494. begin match value with
  495. | None ->
  496. if Meta.has (Meta.Custom ":testHack") cf.cf_meta then begin match cf.cf_expr with
  497. | Some e -> jobject ["testHack",jstring (s_expr_pretty false "" false (s_type (print_context())) e)] (* TODO: haha *)
  498. | None -> jnull
  499. end else
  500. jnull
  501. | Some e -> jobject ["string",jstring (Ast.Printer.s_expr e)]
  502. end
  503. | GMMinimum ->
  504. jnull
  505. in
  506. [
  507. "name",jstring (field_name cf.cf_name cf.cf_meta);
  508. "type",generate_type ctx cf.cf_type;
  509. "isPublic",jbool (has_class_field_flag cf CfPublic);
  510. "isFinal",jbool (has_class_field_flag cf CfFinal);
  511. "params",jlist (generate_type_parameter ctx) cf.cf_params;
  512. "meta",generate_metadata ctx cf.cf_meta;
  513. "kind",generate_class_kind ();
  514. "expr",expr;
  515. "pos",generate_pos ctx cf.cf_pos;
  516. "doc",generate_doc ctx cf.cf_doc;
  517. "overloads",jlist (generate_class_field ctx cfs) cf.cf_overloads;
  518. "scope",jint (Obj.magic cfs);
  519. ]
  520. and generate_class_field ctx cfs cf =
  521. jobject (generate_class_field' ctx cfs cf)
  522. let generate_enum_field ctx ef =
  523. jobject [
  524. "name",jstring (field_name ef.ef_name ef.ef_meta);
  525. "type",generate_type ctx ef.ef_type;
  526. "pos",generate_pos ctx ef.ef_pos;
  527. "meta",generate_metadata ctx ef.ef_meta;
  528. "index",jint ef.ef_index;
  529. "doc",generate_doc ctx ef.ef_doc;
  530. "params",jlist (generate_type_parameter ctx) ef.ef_params;
  531. ]
  532. (* module type *)
  533. let generate_module_type_fields ctx inf =
  534. [
  535. "pack",jlist jstring (fst inf.mt_path);
  536. "name",jstring (snd inf.mt_path);
  537. "moduleName",jstring (snd inf.mt_module.m_path);
  538. "pos",generate_pos ctx inf.mt_pos;
  539. "isPrivate",jbool inf.mt_private;
  540. "params",jlist (generate_type_parameter ctx) inf.mt_params;
  541. "meta",generate_metadata ctx inf.mt_meta;
  542. "doc",generate_doc ctx inf.mt_doc;
  543. ]
  544. let generate_class ctx c =
  545. let generate_class_kind ck =
  546. let ctor,args = match ck with
  547. | KNormal -> "KNormal",None
  548. | KTypeParameter tl -> "KTypeParameter",Some (generate_types ctx tl)
  549. | KExpr e -> "KExpr",Some (generate_expr ctx e)
  550. | KGeneric -> "KGeneric",None
  551. | KGenericInstance(c,tl) -> "KGenericInstance",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)
  552. | KMacroType -> "KMacroType",None
  553. | KGenericBuild _ -> "KGenericBuild",None
  554. | KAbstractImpl a -> "KAbstractImpl",Some (abstract_ref ctx a)
  555. | KModuleFields m -> "KModuleFields",Some (generate_module_path m.m_path)
  556. in
  557. generate_adt ctx (Some (["haxe";"macro"],"ClassKind")) ctor args
  558. in
  559. let generate_class_relation (c,tl) =
  560. jobject [
  561. "path",class_ref ctx c;
  562. "params",generate_types ctx tl;
  563. ]
  564. in
  565. [
  566. "kind",generate_class_kind c.cl_kind;
  567. "isInterface",jbool (has_class_flag c CInterface);
  568. "superClass",jopt generate_class_relation c.cl_super;
  569. "interfaces",jlist generate_class_relation c.cl_implements;
  570. "fields",jlist (generate_class_field ctx CFSMember) c.cl_ordered_fields;
  571. "statics",jlist (generate_class_field ctx CFSStatic) c.cl_ordered_statics;
  572. "constructor",jopt (generate_class_field ctx CFSConstructor) c.cl_constructor;
  573. "init",jopt (generate_texpr ctx) c.cl_init;
  574. "overrides",jlist (classfield_ref ctx) (List.filter (fun cf -> has_class_field_flag cf CfOverride) c.cl_ordered_fields);
  575. "isExtern",jbool (has_class_flag c CExtern);
  576. "isFinal",jbool (has_class_flag c CFinal);
  577. ]
  578. let generate_enum ctx e =
  579. let generate_enum_constructors () =
  580. jarray (List.map (fun s ->
  581. let ef = PMap.find s e.e_constrs in
  582. generate_enum_field ctx ef
  583. ) e.e_names)
  584. in
  585. [
  586. "constructors",generate_enum_constructors ();
  587. "isExtern",jbool e.e_extern;
  588. ]
  589. let generate_typedef ctx td =
  590. [
  591. "type",generate_type ctx td.t_type;
  592. ]
  593. let generate_abstract ctx a =
  594. let generate_cast_relation t cfo =
  595. jobject [
  596. "t",generate_type ctx t;
  597. "field",jopt (classfield_ref ctx) cfo
  598. ]
  599. in
  600. let generate_casts fields casts =
  601. let l1 = List.map (fun (t,cf) -> generate_cast_relation t (Some cf)) fields in
  602. let l2 = List.map (fun t -> generate_cast_relation t None) casts in
  603. jarray (l1 @ l2)
  604. in
  605. let generate_binop (op,cf) =
  606. jobject [
  607. "op",generate_binop ctx op;
  608. "field",classfield_ref ctx cf;
  609. ]
  610. in
  611. let generate_unop (op,flag,cf) =
  612. jobject [
  613. "op",generate_unop ctx op;
  614. "postFix",jbool (flag = Postfix);
  615. "field",classfield_ref ctx cf;
  616. ]
  617. in
  618. let impl = match a.a_impl with
  619. | None -> jnull
  620. | Some c ->
  621. if ctx.generate_abstract_impl then jobject (generate_class ctx c)
  622. else class_ref ctx c
  623. in
  624. [
  625. "type",generate_type ctx a.a_this;
  626. "impl",impl;
  627. "binops",jlist generate_binop a.a_ops;
  628. "unops",jlist generate_unop a.a_unops;
  629. "from",generate_casts a.a_from_field a.a_from;
  630. "to",generate_casts a.a_to_field a.a_to;
  631. "array",jlist (classfield_ref ctx) a.a_array;
  632. "read",jopt (classfield_ref ctx) a.a_read;
  633. "write",jopt (classfield_ref ctx) a.a_write;
  634. ]
  635. let generate_module_type ctx mt =
  636. let fields1 = generate_module_type_fields ctx (t_infos mt) in
  637. let kind,fields2 = match mt with
  638. | TClassDecl c -> "class",generate_class ctx c
  639. | TEnumDecl e -> "enum",generate_enum ctx e
  640. | TTypeDecl t -> "typedef",generate_typedef ctx t
  641. | TAbstractDecl a -> "abstract",generate_abstract ctx a
  642. in
  643. let fields1 = ("kind",jstring kind) :: fields1 @ [("args",jobject fields2)] in
  644. jobject fields1
  645. (* module *)
  646. let generate_module ctx m =
  647. jobject [
  648. "id",jint m.m_id;
  649. "path",generate_module_path m.m_path;
  650. "types",jlist (fun mt -> generate_type_path m.m_path (t_infos mt).mt_path (t_infos mt).mt_meta) m.m_types;
  651. "file",jstring (Path.UniqueKey.lazy_path m.m_extra.m_file);
  652. "sign",jstring (Digest.to_hex m.m_extra.m_sign);
  653. "dependencies",jarray (PMap.fold (fun m acc -> (jobject [
  654. "path",jstring (s_type_path m.m_path);
  655. "sign",jstring (Digest.to_hex m.m_extra.m_sign);
  656. ]) :: acc) m.m_extra.m_deps []);
  657. ]
  658. let create_context ?jsonrpc gm = {
  659. generation_mode = gm;
  660. generate_abstract_impl = false;
  661. request = match jsonrpc with None -> None | Some jsonrpc -> Some (new JsonRequest.json_request jsonrpc)
  662. }
  663. let generate types file =
  664. let t = Timer.timer ["generate";"json";"construct"] in
  665. let ctx = create_context GMFull in
  666. let json = jarray (List.map (generate_module_type ctx) types) in
  667. t();
  668. let t = Timer.timer ["generate";"json";"write"] in
  669. let ch = open_out_bin file in
  670. Json.write_json (output_string ch) json;
  671. close_out ch;
  672. t()