type.ml 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627
  1. (*
  2. * Copyright (C)2005-2013 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. *)
  22. open Ast
  23. type path = string list * string
  24. type field_kind =
  25. | Var of var_kind
  26. | Method of method_kind
  27. and var_kind = {
  28. v_read : var_access;
  29. v_write : var_access;
  30. }
  31. and var_access =
  32. | AccNormal
  33. | AccNo (* can't be accessed outside of the class itself and its subclasses *)
  34. | AccNever (* can't be accessed, even in subclasses *)
  35. | AccResolve (* call resolve("field") when accessed *)
  36. | AccCall (* perform a method call when accessed *)
  37. | AccInline (* similar to Normal but inline when accessed *)
  38. | AccRequire of string * string option (* set when @:require(cond) fails *)
  39. and method_kind =
  40. | MethNormal
  41. | MethInline
  42. | MethDynamic
  43. | MethMacro
  44. type t =
  45. | TMono of t option ref
  46. | TEnum of tenum * tparams
  47. | TInst of tclass * tparams
  48. | TType of tdef * tparams
  49. | TFun of (string * bool * t) list * t
  50. | TAnon of tanon
  51. | TDynamic of t
  52. | TLazy of (unit -> t) ref
  53. | TAbstract of tabstract * tparams
  54. and tparams = t list
  55. and type_params = (string * t) list
  56. and tconstant =
  57. | TInt of int32
  58. | TFloat of string
  59. | TString of string
  60. | TBool of bool
  61. | TNull
  62. | TThis
  63. | TSuper
  64. and tvar = {
  65. mutable v_id : int;
  66. mutable v_name : string;
  67. mutable v_type : t;
  68. mutable v_capture : bool;
  69. mutable v_extra : (type_params * texpr option) option;
  70. }
  71. and tfunc = {
  72. tf_args : (tvar * tconstant option) list;
  73. tf_type : t;
  74. tf_expr : texpr;
  75. }
  76. and anon_status =
  77. | Closed
  78. | Opened
  79. | Const
  80. | Statics of tclass
  81. | EnumStatics of tenum
  82. | AbstractStatics of tabstract
  83. and tanon = {
  84. mutable a_fields : (string, tclass_field) PMap.t;
  85. a_status : anon_status ref;
  86. }
  87. and texpr_expr =
  88. | TConst of tconstant
  89. | TLocal of tvar
  90. | TArray of texpr * texpr
  91. | TBinop of Ast.binop * texpr * texpr
  92. | TField of texpr * tfield_access
  93. | TTypeExpr of module_type
  94. | TParenthesis of texpr
  95. | TObjectDecl of (string * texpr) list
  96. | TArrayDecl of texpr list
  97. | TCall of texpr * texpr list
  98. | TNew of tclass * tparams * texpr list
  99. | TUnop of Ast.unop * Ast.unop_flag * texpr
  100. | TFunction of tfunc
  101. | TVars of (tvar * texpr option) list
  102. | TBlock of texpr list
  103. | TFor of tvar * texpr * texpr
  104. | TIf of texpr * texpr * texpr option
  105. | TWhile of texpr * texpr * Ast.while_flag
  106. | TSwitch of texpr * (texpr list * texpr) list * texpr option
  107. | TMatch of texpr * (tenum * tparams) * (int list * tvar option list option * texpr) list * texpr option
  108. | TTry of texpr * (tvar * texpr) list
  109. | TReturn of texpr option
  110. | TBreak
  111. | TContinue
  112. | TThrow of texpr
  113. | TCast of texpr * module_type option
  114. and tfield_access =
  115. | FInstance of tclass * tclass_field
  116. | FStatic of tclass * tclass_field
  117. | FAnon of tclass_field
  118. | FDynamic of string
  119. | FClosure of tclass option * tclass_field (* None class = TAnon *)
  120. | FEnum of tenum * tenum_field
  121. and texpr = {
  122. eexpr : texpr_expr;
  123. etype : t;
  124. epos : Ast.pos;
  125. }
  126. and tclass_field = {
  127. cf_name : string;
  128. mutable cf_type : t;
  129. mutable cf_public : bool;
  130. cf_pos : pos;
  131. mutable cf_doc : Ast.documentation;
  132. mutable cf_meta : metadata;
  133. mutable cf_kind : field_kind;
  134. mutable cf_params : type_params;
  135. mutable cf_expr : texpr option;
  136. mutable cf_overloads : tclass_field list;
  137. }
  138. and tclass_kind =
  139. | KNormal
  140. | KTypeParameter of t list
  141. | KExtension of tclass * tparams
  142. | KExpr of Ast.expr
  143. | KGeneric
  144. | KGenericInstance of tclass * tparams
  145. | KMacroType
  146. | KAbstractImpl of tabstract
  147. and metadata = Ast.metadata
  148. and tinfos = {
  149. mt_path : path;
  150. mt_module : module_def;
  151. mt_pos : Ast.pos;
  152. mt_private : bool;
  153. mt_doc : Ast.documentation;
  154. mutable mt_meta : metadata;
  155. mt_types : type_params;
  156. }
  157. and tclass = {
  158. mutable cl_path : path;
  159. mutable cl_module : module_def;
  160. mutable cl_pos : Ast.pos;
  161. mutable cl_private : bool;
  162. mutable cl_doc : Ast.documentation;
  163. mutable cl_meta : metadata;
  164. mutable cl_types : type_params;
  165. mutable cl_kind : tclass_kind;
  166. mutable cl_extern : bool;
  167. mutable cl_interface : bool;
  168. mutable cl_super : (tclass * tparams) option;
  169. mutable cl_implements : (tclass * tparams) list;
  170. mutable cl_fields : (string , tclass_field) PMap.t;
  171. mutable cl_statics : (string, tclass_field) PMap.t;
  172. mutable cl_ordered_statics : tclass_field list;
  173. mutable cl_ordered_fields : tclass_field list;
  174. mutable cl_dynamic : t option;
  175. mutable cl_array_access : t option;
  176. mutable cl_constructor : tclass_field option;
  177. mutable cl_init : texpr option;
  178. mutable cl_overrides : tclass_field list;
  179. mutable cl_build : unit -> unit;
  180. mutable cl_restore : unit -> unit;
  181. }
  182. and tenum_field = {
  183. ef_name : string;
  184. ef_type : t;
  185. ef_pos : Ast.pos;
  186. ef_doc : Ast.documentation;
  187. ef_index : int;
  188. ef_params : type_params;
  189. mutable ef_meta : metadata;
  190. }
  191. and tenum = {
  192. mutable e_path : path;
  193. e_module : module_def;
  194. e_pos : Ast.pos;
  195. e_private : bool;
  196. e_doc : Ast.documentation;
  197. mutable e_meta : metadata;
  198. mutable e_types : type_params;
  199. mutable e_extern : bool;
  200. mutable e_constrs : (string , tenum_field) PMap.t;
  201. mutable e_names : string list;
  202. }
  203. and tdef = {
  204. t_path : path;
  205. t_module : module_def;
  206. t_pos : Ast.pos;
  207. t_private : bool;
  208. t_doc : Ast.documentation;
  209. mutable t_meta : metadata;
  210. mutable t_types : type_params;
  211. mutable t_type : t;
  212. }
  213. and tabstract = {
  214. a_path : path;
  215. a_module : module_def;
  216. a_pos : Ast.pos;
  217. a_private : bool;
  218. a_doc : Ast.documentation;
  219. mutable a_meta : metadata;
  220. mutable a_types : type_params;
  221. mutable a_ops : (Ast.binop * tclass_field) list;
  222. mutable a_unops : (Ast.unop * unop_flag * tclass_field) list;
  223. mutable a_impl : tclass option;
  224. mutable a_this : t;
  225. mutable a_from : (t * tclass_field option) list;
  226. mutable a_array : tclass_field list;
  227. mutable a_to : (t * tclass_field option) list;
  228. }
  229. and module_type =
  230. | TClassDecl of tclass
  231. | TEnumDecl of tenum
  232. | TTypeDecl of tdef
  233. | TAbstractDecl of tabstract
  234. and module_def = {
  235. m_id : int;
  236. m_path : path;
  237. mutable m_types : module_type list;
  238. m_extra : module_def_extra;
  239. }
  240. and module_def_extra = {
  241. m_file : string;
  242. m_sign : string;
  243. mutable m_time : float;
  244. mutable m_dirty : bool;
  245. mutable m_added : int;
  246. mutable m_mark : int;
  247. mutable m_deps : (int,module_def) PMap.t;
  248. mutable m_processed : int;
  249. mutable m_kind : module_kind;
  250. mutable m_binded_res : (string, string) PMap.t;
  251. mutable m_macro_calls : string list;
  252. }
  253. and module_kind =
  254. | MCode
  255. | MMacro
  256. | MFake
  257. let alloc_var =
  258. let uid = ref 0 in
  259. (fun n t -> incr uid; { v_name = n; v_type = t; v_id = !uid; v_capture = false; v_extra = None })
  260. let alloc_mid =
  261. let mid = ref 0 in
  262. (fun() -> incr mid; !mid)
  263. let mk e t p = { eexpr = e; etype = t; epos = p }
  264. let mk_block e =
  265. match e.eexpr with
  266. | TBlock (_ :: _) -> e
  267. | _ -> mk (TBlock [e]) e.etype e.epos
  268. let null t p = mk (TConst TNull) t p
  269. let mk_mono() = TMono (ref None)
  270. let rec t_dynamic = TDynamic t_dynamic
  271. let tfun pl r = TFun (List.map (fun t -> "",false,t) pl,r)
  272. let fun_args l = List.map (fun (a,c,t) -> a, c <> None, t) l
  273. let field_name f =
  274. match f with
  275. | FAnon f | FInstance (_,f) | FStatic (_,f) | FClosure (_,f) -> f.cf_name
  276. | FEnum (_,f) -> f.ef_name
  277. | FDynamic n -> n
  278. let extract_field = function
  279. | FAnon f | FInstance (_,f) | FStatic (_,f) | FClosure (_,f) -> Some f
  280. | _ -> None
  281. let mk_class m path pos =
  282. {
  283. cl_path = path;
  284. cl_module = m;
  285. cl_pos = pos;
  286. cl_doc = None;
  287. cl_meta = [];
  288. cl_private = false;
  289. cl_kind = KNormal;
  290. cl_extern = false;
  291. cl_interface = false;
  292. cl_types = [];
  293. cl_super = None;
  294. cl_implements = [];
  295. cl_fields = PMap.empty;
  296. cl_ordered_statics = [];
  297. cl_ordered_fields = [];
  298. cl_statics = PMap.empty;
  299. cl_dynamic = None;
  300. cl_array_access = None;
  301. cl_constructor = None;
  302. cl_init = None;
  303. cl_overrides = [];
  304. cl_build = (fun() -> ());
  305. cl_restore = (fun() -> ());
  306. }
  307. let module_extra file sign time kind =
  308. {
  309. m_file = file;
  310. m_sign = sign;
  311. m_dirty = false;
  312. m_added = 0;
  313. m_mark = 0;
  314. m_time = time;
  315. m_processed = 0;
  316. m_deps = PMap.empty;
  317. m_kind = kind;
  318. m_binded_res = PMap.empty;
  319. m_macro_calls = [];
  320. }
  321. let mk_field name t p = {
  322. cf_name = name;
  323. cf_type = t;
  324. cf_pos = p;
  325. cf_doc = None;
  326. cf_meta = [];
  327. cf_public = true;
  328. cf_kind = Var { v_read = AccNormal; v_write = AccNormal };
  329. cf_expr = None;
  330. cf_params = [];
  331. cf_overloads = [];
  332. }
  333. let null_module = {
  334. m_id = alloc_mid();
  335. m_path = [] , "";
  336. m_types = [];
  337. m_extra = module_extra "" "" 0. MFake;
  338. }
  339. let null_class =
  340. let c = mk_class null_module ([],"") Ast.null_pos in
  341. c.cl_private <- true;
  342. c
  343. let null_field = mk_field "" t_dynamic Ast.null_pos
  344. let add_dependency m mdep =
  345. if m != null_module && m != mdep then m.m_extra.m_deps <- PMap.add mdep.m_id mdep m.m_extra.m_deps
  346. let arg_name (a,_) = a.v_name
  347. let t_infos t : tinfos =
  348. match t with
  349. | TClassDecl c -> Obj.magic c
  350. | TEnumDecl e -> Obj.magic e
  351. | TTypeDecl t -> Obj.magic t
  352. | TAbstractDecl a -> Obj.magic a
  353. let t_path t = (t_infos t).mt_path
  354. let print_context() = ref []
  355. let is_closed a = !(a.a_status) <> Opened
  356. let rec s_type ctx t =
  357. match t with
  358. | TMono r ->
  359. (match !r with
  360. | None -> Printf.sprintf "Unknown<%d>" (try List.assq t (!ctx) with Not_found -> let n = List.length !ctx in ctx := (t,n) :: !ctx; n)
  361. | Some t -> s_type ctx t)
  362. | TEnum (e,tl) ->
  363. Ast.s_type_path e.e_path ^ s_type_params ctx tl
  364. | TInst (c,tl) ->
  365. Ast.s_type_path c.cl_path ^ s_type_params ctx tl
  366. | TType (t,tl) ->
  367. Ast.s_type_path t.t_path ^ s_type_params ctx tl
  368. | TAbstract (a,tl) ->
  369. Ast.s_type_path a.a_path ^ s_type_params ctx tl
  370. | TFun ([],t) ->
  371. "Void -> " ^ s_fun ctx t false
  372. | TFun (l,t) ->
  373. String.concat " -> " (List.map (fun (s,b,t) ->
  374. (if b then "?" else "") ^ (if s = "" then "" else s ^ " : ") ^ s_fun ctx t true
  375. ) l) ^ " -> " ^ s_fun ctx t false
  376. | TAnon a ->
  377. let fl = PMap.fold (fun f acc -> ((if Meta.has Meta.Optional f.cf_meta then " ?" else " ") ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in
  378. "{" ^ (if not (is_closed a) then "+" else "") ^ String.concat "," fl ^ " }"
  379. | TDynamic t2 ->
  380. "Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
  381. | TLazy f ->
  382. s_type ctx (!f())
  383. and s_fun ctx t void =
  384. match t with
  385. | TFun _ ->
  386. "(" ^ s_type ctx t ^ ")"
  387. | TAbstract ({ a_path = ([],"Void") },[]) when void ->
  388. "(" ^ s_type ctx t ^ ")"
  389. | TMono r ->
  390. (match !r with
  391. | None -> s_type ctx t
  392. | Some t -> s_fun ctx t void)
  393. | TLazy f ->
  394. s_fun ctx (!f()) void
  395. | _ ->
  396. s_type ctx t
  397. and s_type_params ctx = function
  398. | [] -> ""
  399. | l -> "<" ^ String.concat ", " (List.map (s_type ctx) l) ^ ">"
  400. let s_access = function
  401. | AccNormal -> "default"
  402. | AccNo -> "null"
  403. | AccNever -> "never"
  404. | AccResolve -> "resolve"
  405. | AccCall -> "accessor"
  406. | AccInline -> "inline"
  407. | AccRequire (n,_) -> "require " ^ n
  408. let s_kind = function
  409. | Var { v_read = AccNormal; v_write = AccNormal } -> "var"
  410. | Var v -> "(" ^ s_access v.v_read ^ "," ^ s_access v.v_write ^ ")"
  411. | Method m ->
  412. match m with
  413. | MethNormal -> "method"
  414. | MethDynamic -> "dynamic method"
  415. | MethInline -> "inline method"
  416. | MethMacro -> "macro method"
  417. let rec is_parent csup c =
  418. if c == csup || List.exists (fun (i,_) -> is_parent csup i) c.cl_implements then
  419. true
  420. else match c.cl_super with
  421. | None -> false
  422. | Some (c,_) -> is_parent csup c
  423. let map loop t =
  424. match t with
  425. | TMono r ->
  426. (match !r with
  427. | None -> t
  428. | Some t -> loop t) (* erase*)
  429. | TEnum (_,[]) | TInst (_,[]) | TType (_,[]) ->
  430. t
  431. | TEnum (e,tl) ->
  432. TEnum (e, List.map loop tl)
  433. | TInst (c,tl) ->
  434. TInst (c, List.map loop tl)
  435. | TType (t2,tl) ->
  436. TType (t2,List.map loop tl)
  437. | TAbstract (a,tl) ->
  438. TAbstract (a,List.map loop tl)
  439. | TFun (tl,r) ->
  440. TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r)
  441. | TAnon a ->
  442. TAnon {
  443. a_fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields;
  444. a_status = a.a_status;
  445. }
  446. | TLazy f ->
  447. let ft = !f() in
  448. let ft2 = loop ft in
  449. if ft == ft2 then t else ft2
  450. | TDynamic t2 ->
  451. if t == t2 then t else TDynamic (loop t2)
  452. (* substitute parameters with other types *)
  453. let apply_params cparams params t =
  454. match cparams with
  455. | [] -> t
  456. | _ ->
  457. let rec loop l1 l2 =
  458. match l1, l2 with
  459. | [] , [] -> []
  460. | (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
  461. | (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
  462. | _ -> assert false
  463. in
  464. let subst = loop cparams params in
  465. let rec loop t =
  466. try
  467. List.assq t subst
  468. with Not_found ->
  469. match t with
  470. | TMono r ->
  471. (match !r with
  472. | None -> t
  473. | Some t -> loop t)
  474. | TEnum (e,tl) ->
  475. (match tl with
  476. | [] -> t
  477. | _ -> TEnum (e,List.map loop tl))
  478. | TType (t2,tl) ->
  479. (match tl with
  480. | [] -> t
  481. | _ -> TType (t2,List.map loop tl))
  482. | TAbstract (a,tl) ->
  483. (match tl with
  484. | [] -> t
  485. | _ -> TAbstract (a,List.map loop tl))
  486. | TInst (c,tl) ->
  487. (match tl with
  488. | [] ->
  489. t
  490. | [TMono r] ->
  491. (match !r with
  492. | Some tt when t == tt ->
  493. (* for dynamic *)
  494. let pt = mk_mono() in
  495. let t = TInst (c,[pt]) in
  496. (match pt with TMono r -> r := Some t | _ -> assert false);
  497. t
  498. | _ -> TInst (c,List.map loop tl))
  499. | _ ->
  500. TInst (c,List.map loop tl))
  501. | TFun (tl,r) ->
  502. TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r)
  503. | TAnon a ->
  504. TAnon {
  505. a_fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields;
  506. a_status = a.a_status;
  507. }
  508. | TLazy f ->
  509. let ft = !f() in
  510. let ft2 = loop ft in
  511. if ft == ft2 then
  512. t
  513. else
  514. ft2
  515. | TDynamic t2 ->
  516. if t == t2 then
  517. t
  518. else
  519. TDynamic (loop t2)
  520. in
  521. loop t
  522. let rec follow t =
  523. match t with
  524. | TMono r ->
  525. (match !r with
  526. | Some t -> follow t
  527. | _ -> t)
  528. | TLazy f ->
  529. follow (!f())
  530. | TType (t,tl) ->
  531. follow (apply_params t.t_types tl t.t_type)
  532. | _ -> t
  533. let rec is_nullable ?(no_lazy=false) = function
  534. | TMono r ->
  535. (match !r with None -> false | Some t -> is_nullable t)
  536. | TType ({ t_path = ([],"Null") },[_]) ->
  537. true
  538. | TLazy f ->
  539. if no_lazy then raise Exit else is_nullable (!f())
  540. | TType (t,tl) ->
  541. is_nullable (apply_params t.t_types tl t.t_type)
  542. | TFun _ ->
  543. false
  544. (*
  545. Type parameters will most of the time be nullable objects, so we don't want to make it hard for users
  546. to have to specify Null<T> all over the place, so while they could be a basic type, let's assume they will not.
  547. This will still cause issues with inlining and haxe.rtti.Generic. In that case proper explicit Null<T> is required to
  548. work correctly with basic types. This could still be fixed by redoing a nullability inference on the typed AST.
  549. | TInst ({ cl_kind = KTypeParameter },_) -> false
  550. *)
  551. | TAbstract (a,_) -> not (Meta.has Meta.NotNull a.a_meta)
  552. | _ ->
  553. true
  554. let rec is_null = function
  555. | TMono r ->
  556. (match !r with None -> false | Some t -> is_null t)
  557. | TType ({ t_path = ([],"Null") },[t]) ->
  558. not (is_nullable t)
  559. | TLazy f ->
  560. is_null (!f())
  561. | TType (t,tl) ->
  562. is_null (apply_params t.t_types tl t.t_type)
  563. | _ ->
  564. false
  565. let rec has_mono t = match t with
  566. | TMono r ->
  567. (match !r with None -> true | Some t -> has_mono t)
  568. | TInst(_,pl) | TEnum(_,pl) | TAbstract(_,pl) | TType(_,pl) ->
  569. List.exists has_mono pl
  570. | TDynamic _ ->
  571. false
  572. | TFun(args,r) ->
  573. has_mono r || List.exists (fun (_,_,t) -> has_mono t) args
  574. | TAnon a ->
  575. PMap.fold (fun cf b -> has_mono cf.cf_type && b) a.a_fields true
  576. | TLazy r ->
  577. has_mono (!r())
  578. let rec link e a b =
  579. (* tell if setting a == b will create a type-loop *)
  580. let rec loop t =
  581. if t == a then
  582. true
  583. else match t with
  584. | TMono t -> (match !t with None -> false | Some t -> loop t)
  585. | TEnum (_,tl) -> List.exists loop tl
  586. | TInst (_,tl) | TType (_,tl) | TAbstract (_,tl) -> List.exists loop tl
  587. | TFun (tl,t) -> List.exists (fun (_,_,t) -> loop t) tl || loop t
  588. | TDynamic t2 ->
  589. if t == t2 then
  590. false
  591. else
  592. loop t2
  593. | TLazy f ->
  594. loop (!f())
  595. | TAnon a ->
  596. try
  597. PMap.iter (fun _ f -> if loop f.cf_type then raise Exit) a.a_fields;
  598. false
  599. with
  600. Exit -> true
  601. in
  602. (* tell is already a ~= b *)
  603. if loop b then
  604. (follow b) == a
  605. else if b == t_dynamic then
  606. true
  607. else begin
  608. e := Some b;
  609. true
  610. end
  611. let monomorphs eparams t =
  612. apply_params eparams (List.map (fun _ -> mk_mono()) eparams) t
  613. let rec fast_eq a b =
  614. if a == b then
  615. true
  616. else match a , b with
  617. | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
  618. List.for_all2 (fun (_,_,t1) (_,_,t2) -> fast_eq t1 t2) l1 l2 && fast_eq r1 r2
  619. | TType (t1,l1), TType (t2,l2) ->
  620. t1 == t2 && List.for_all2 fast_eq l1 l2
  621. | TEnum (e1,l1), TEnum (e2,l2) ->
  622. e1 == e2 && List.for_all2 fast_eq l1 l2
  623. | TInst (c1,l1), TInst (c2,l2) ->
  624. c1 == c2 && List.for_all2 fast_eq l1 l2
  625. | TAbstract (a1,l1), TAbstract (a2,l2) ->
  626. a1 == a2 && List.for_all2 fast_eq l1 l2
  627. | _ , _ ->
  628. false
  629. (* perform unification with subtyping.
  630. the first type is always the most down in the class hierarchy
  631. it's also the one that is pointed by the position.
  632. It's actually a typecheck of A :> B where some mutations can happen *)
  633. type unify_error =
  634. | Cannot_unify of t * t
  635. | Invalid_field_type of string
  636. | Has_no_field of t * string
  637. | Has_no_runtime_field of t * string
  638. | Has_extra_field of t * string
  639. | Invalid_kind of string * field_kind * field_kind
  640. | Invalid_visibility of string
  641. | Not_matching_optional of string
  642. | Cant_force_optional
  643. | Invariant_parameter of t * t
  644. | Constraint_failure of string
  645. | Missing_overload of tclass_field * t
  646. | Unify_custom of string
  647. exception Unify_error of unify_error list
  648. let cannot_unify a b = Cannot_unify (a,b)
  649. let invalid_field n = Invalid_field_type n
  650. let invalid_kind n a b = Invalid_kind (n,a,b)
  651. let invalid_visibility n = Invalid_visibility n
  652. let has_no_field t n = Has_no_field (t,n)
  653. let has_extra_field t n = Has_extra_field (t,n)
  654. let error l = raise (Unify_error l)
  655. let has_meta m ml = List.exists (fun (m2,_,_) -> m = m2) ml
  656. let get_meta m ml = List.find (fun (m2,_,_) -> m = m2) ml
  657. let no_meta = []
  658. (*
  659. we can restrict access as soon as both are runtime-compatible
  660. *)
  661. let unify_access a1 a2 =
  662. a1 = a2 || match a1, a2 with
  663. | _, AccNo | _, AccNever -> true
  664. | AccInline, AccNormal -> true
  665. | _ -> false
  666. let direct_access = function
  667. | AccNo | AccNever | AccNormal | AccInline | AccRequire _ -> true
  668. | AccResolve | AccCall -> false
  669. let unify_kind k1 k2 =
  670. k1 = k2 || match k1, k2 with
  671. | Var v1, Var v2 -> unify_access v1.v_read v2.v_read && unify_access v1.v_write v2.v_write
  672. | Var v, Method m ->
  673. (match v.v_read, v.v_write, m with
  674. | AccNormal, _, MethNormal -> true
  675. | AccNormal, AccNormal, MethDynamic -> true
  676. | _ -> false)
  677. | Method m, Var v ->
  678. (match m with
  679. | MethDynamic -> direct_access v.v_read && direct_access v.v_write
  680. | MethMacro -> false
  681. | MethNormal | MethInline ->
  682. match v.v_write with
  683. | AccNo | AccNever -> true
  684. | _ -> false)
  685. | Method m1, Method m2 ->
  686. match m1,m2 with
  687. | MethInline, MethNormal
  688. | MethDynamic, MethNormal -> true
  689. | _ -> false
  690. let eq_stack = ref []
  691. type eq_kind =
  692. | EqStrict
  693. | EqCoreType
  694. | EqRightDynamic
  695. | EqBothDynamic
  696. let rec type_eq param a b =
  697. if a == b then
  698. ()
  699. else match a , b with
  700. | TLazy f , _ -> type_eq param (!f()) b
  701. | _ , TLazy f -> type_eq param a (!f())
  702. | TMono t , _ ->
  703. (match !t with
  704. | None -> if param = EqCoreType || not (link t a b) then error [cannot_unify a b]
  705. | Some t -> type_eq param t b)
  706. | _ , TMono t ->
  707. (match !t with
  708. | None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
  709. | Some t -> type_eq param a t)
  710. | TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 ->
  711. List.iter2 (type_eq param) tl1 tl2
  712. | TType (t,tl) , _ when param <> EqCoreType ->
  713. type_eq param (apply_params t.t_types tl t.t_type) b
  714. | _ , TType (t,tl) when param <> EqCoreType ->
  715. if List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack) then
  716. ()
  717. else begin
  718. eq_stack := (a,b) :: !eq_stack;
  719. try
  720. type_eq param a (apply_params t.t_types tl t.t_type);
  721. eq_stack := List.tl !eq_stack;
  722. with
  723. Unify_error l ->
  724. eq_stack := List.tl !eq_stack;
  725. error (cannot_unify a b :: l)
  726. end
  727. | TEnum (e1,tl1) , TEnum (e2,tl2) ->
  728. if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b];
  729. List.iter2 (type_eq param) tl1 tl2
  730. | TInst (c1,tl1) , TInst (c2,tl2) ->
  731. if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then error [cannot_unify a b];
  732. List.iter2 (type_eq param) tl1 tl2
  733. | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
  734. (try
  735. type_eq param r1 r2;
  736. List.iter2 (fun (n,o1,t1) (_,o2,t2) ->
  737. if o1 <> o2 then error [Not_matching_optional n];
  738. type_eq param t1 t2
  739. ) l1 l2
  740. with
  741. Unify_error l -> error (cannot_unify a b :: l))
  742. | TDynamic a , TDynamic b ->
  743. type_eq param a b
  744. | TAbstract (a1,tl1) , TAbstract (a2,tl2) ->
  745. if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then error [cannot_unify a b];
  746. List.iter2 (type_eq param) tl1 tl2
  747. | TAnon a1, TAnon a2 ->
  748. (try
  749. PMap.iter (fun n f1 ->
  750. try
  751. let f2 = PMap.find n a2.a_fields in
  752. if f1.cf_kind <> f2.cf_kind && (param = EqStrict || param = EqCoreType || not (unify_kind f1.cf_kind f2.cf_kind)) then error [invalid_kind n f1.cf_kind f2.cf_kind];
  753. try
  754. type_eq param f1.cf_type f2.cf_type
  755. with
  756. Unify_error l -> error (invalid_field n :: l)
  757. with
  758. Not_found ->
  759. if is_closed a2 then error [has_no_field b n];
  760. if not (link (ref None) b f1.cf_type) then error [cannot_unify a b];
  761. a2.a_fields <- PMap.add n f1 a2.a_fields
  762. ) a1.a_fields;
  763. PMap.iter (fun n f2 ->
  764. if not (PMap.mem n a1.a_fields) then begin
  765. if is_closed a1 then error [has_no_field a n];
  766. if not (link (ref None) a f2.cf_type) then error [cannot_unify a b];
  767. a1.a_fields <- PMap.add n f2 a1.a_fields
  768. end;
  769. ) a2.a_fields;
  770. with
  771. Unify_error l -> error (cannot_unify a b :: l))
  772. | _ , _ ->
  773. if b == t_dynamic && (param = EqRightDynamic || param = EqBothDynamic) then
  774. ()
  775. else if a == t_dynamic && param = EqBothDynamic then
  776. ()
  777. else
  778. error [cannot_unify a b]
  779. let type_iseq a b =
  780. try
  781. type_eq EqStrict a b;
  782. true
  783. with
  784. Unify_error _ -> false
  785. let unify_stack = ref []
  786. let abstract_cast_stack = ref []
  787. let is_extern_field f =
  788. match f.cf_kind with
  789. | Method _ -> false
  790. | Var { v_read = AccNormal | AccInline | AccNo } | Var { v_write = AccNormal | AccNo } -> false
  791. | _ -> not (Meta.has Meta.IsVar f.cf_meta)
  792. let field_type f =
  793. match f.cf_params with
  794. | [] -> f.cf_type
  795. | l -> monomorphs l f.cf_type
  796. let rec raw_class_field build_type c i =
  797. try
  798. let f = PMap.find i c.cl_fields in
  799. Some c, build_type f , f
  800. with Not_found -> try (match c.cl_constructor with
  801. | Some ctor when i = "new" -> Some c, build_type ctor,ctor
  802. | _ -> raise Not_found)
  803. with Not_found -> try
  804. match c.cl_super with
  805. | None ->
  806. raise Not_found
  807. | Some (c,tl) ->
  808. let c2 , t , f = raw_class_field build_type c i in
  809. c2, apply_params c.cl_types tl t , f
  810. with Not_found ->
  811. match c.cl_kind with
  812. | KTypeParameter tl ->
  813. let rec loop = function
  814. | [] ->
  815. raise Not_found
  816. | t :: ctl ->
  817. match follow t with
  818. | TAnon a ->
  819. (try
  820. let f = PMap.find i a.a_fields in
  821. None, build_type f, f
  822. with
  823. Not_found -> loop ctl)
  824. | TInst (c,pl) ->
  825. (try
  826. let c2, t , f = raw_class_field build_type c i in
  827. c2, apply_params c.cl_types pl t, f
  828. with
  829. Not_found -> loop ctl)
  830. | _ ->
  831. loop ctl
  832. in
  833. loop tl
  834. | _ ->
  835. if not c.cl_interface then raise Not_found;
  836. (*
  837. an interface can implements other interfaces without
  838. having to redeclare its fields
  839. *)
  840. let rec loop = function
  841. | [] ->
  842. raise Not_found
  843. | (c,tl) :: l ->
  844. try
  845. let c2, t , f = raw_class_field build_type c i in
  846. c2, apply_params c.cl_types tl t, f
  847. with
  848. Not_found -> loop l
  849. in
  850. loop c.cl_implements
  851. let class_field = raw_class_field field_type
  852. let quick_field t n =
  853. match follow t with
  854. | TInst (c,_) ->
  855. let c, _, f = raw_class_field (fun f -> f.cf_type) c n in
  856. (match c with None -> FAnon f | Some c -> FInstance (c,f))
  857. | TAnon a ->
  858. (match !(a.a_status) with
  859. | EnumStatics e ->
  860. assert false (* to replace with FEnum later *)
  861. | Statics c ->
  862. FStatic (c,PMap.find n c.cl_statics)
  863. | AbstractStatics _ ->
  864. assert false
  865. | _ ->
  866. FAnon (PMap.find n a.a_fields))
  867. | TDynamic _ ->
  868. FDynamic n
  869. | TEnum _ | TMono _ | TAbstract _ | TFun _ ->
  870. raise Not_found
  871. | TLazy _ | TType _ ->
  872. assert false
  873. let quick_field_dynamic t s =
  874. try quick_field t s
  875. with Not_found -> FDynamic s
  876. let rec get_constructor build_type c =
  877. match c.cl_constructor, c.cl_super with
  878. | Some c, _ -> build_type c, c
  879. | None, None -> raise Not_found
  880. | None, Some (csup,cparams) ->
  881. let t, c = get_constructor build_type csup in
  882. apply_params csup.cl_types cparams t, c
  883. let rec unify a b =
  884. if a == b then
  885. ()
  886. else match a, b with
  887. | TLazy f , _ -> unify (!f()) b
  888. | _ , TLazy f -> unify a (!f())
  889. | TMono t , _ ->
  890. (match !t with
  891. | None -> if not (link t a b) then error [cannot_unify a b]
  892. | Some t -> unify t b)
  893. | _ , TMono t ->
  894. (match !t with
  895. | None -> if not (link t b a) then error [cannot_unify a b]
  896. | Some t -> unify a t)
  897. | TType (t,tl) , _ ->
  898. if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin
  899. try
  900. unify_stack := (a,b) :: !unify_stack;
  901. unify (apply_params t.t_types tl t.t_type) b;
  902. unify_stack := List.tl !unify_stack;
  903. with
  904. Unify_error l ->
  905. unify_stack := List.tl !unify_stack;
  906. error (cannot_unify a b :: l)
  907. end
  908. | _ , TType (t,tl) ->
  909. if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin
  910. try
  911. unify_stack := (a,b) :: !unify_stack;
  912. unify a (apply_params t.t_types tl t.t_type);
  913. unify_stack := List.tl !unify_stack;
  914. with
  915. Unify_error l ->
  916. unify_stack := List.tl !unify_stack;
  917. error (cannot_unify a b :: l)
  918. end
  919. | TEnum (ea,tl1) , TEnum (eb,tl2) ->
  920. if ea != eb then error [cannot_unify a b];
  921. unify_types a b tl1 tl2
  922. | TAbstract (a1,tl1) , TAbstract (a2,tl2) when a1 == a2 ->
  923. unify_types a b tl1 tl2
  924. | TAbstract ({a_path=[],"Void"},_) , _
  925. | _ , TAbstract ({a_path=[],"Void"},_) ->
  926. error [cannot_unify a b]
  927. | TAbstract (a1,tl1) , TAbstract (a2,tl2) ->
  928. if not (List.exists (unify_to_field a1 tl1 b) a1.a_to) && not (List.exists (unify_from_field a2 tl2 a b) a2.a_from) then error [cannot_unify a b]
  929. | TInst (c1,tl1) , TInst (c2,tl2) ->
  930. let rec loop c tl =
  931. if c == c2 then begin
  932. unify_types a b tl tl2;
  933. true
  934. end else (match c.cl_super with
  935. | None -> false
  936. | Some (cs,tls) ->
  937. loop cs (List.map (apply_params c.cl_types tl) tls)
  938. ) || List.exists (fun (cs,tls) ->
  939. loop cs (List.map (apply_params c.cl_types tl) tls)
  940. ) c.cl_implements
  941. || (match c.cl_kind with
  942. | KTypeParameter pl -> List.exists (fun t -> match follow t with TInst (cs,tls) -> loop cs (List.map (apply_params c.cl_types tl) tls) | _ -> false) pl
  943. | _ -> false)
  944. in
  945. if not (loop c1 tl1) then error [cannot_unify a b]
  946. | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
  947. let i = ref 0 in
  948. (try
  949. (match r2 with
  950. | TAbstract ({a_path=[],"Void"},_) -> ()
  951. | _ -> unify r1 r2; incr i);
  952. List.iter2 (fun (_,o1,t1) (_,o2,t2) ->
  953. if o1 && not o2 then error [Cant_force_optional];
  954. unify t1 t2;
  955. incr i
  956. ) l2 l1 (* contravariance *)
  957. with
  958. Unify_error l ->
  959. let msg = if !i = 0 then "Cannot unify return types" else "Cannot unify argument " ^ (string_of_int !i) in
  960. error (cannot_unify a b :: Unify_custom msg :: l))
  961. | TInst (c,tl) , TAnon an ->
  962. if PMap.is_empty an.a_fields then (match c.cl_kind with
  963. | KTypeParameter pl ->
  964. (* one of the constraints must unify with { } *)
  965. if not (List.exists (fun t -> match t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b]
  966. | _ -> ());
  967. (try
  968. PMap.iter (fun n f2 ->
  969. let _, ft, f1 = (try class_field c n with Not_found -> error [has_no_field a n]) in
  970. if not (unify_kind f1.cf_kind f2.cf_kind) then error [invalid_kind n f1.cf_kind f2.cf_kind];
  971. if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
  972. (try
  973. unify_with_access (apply_params c.cl_types tl ft) f2
  974. with
  975. Unify_error l -> error (invalid_field n :: l));
  976. List.iter (fun f2o ->
  977. if not (List.exists (fun f1o -> type_iseq f1o.cf_type f2o.cf_type) (f1 :: f1.cf_overloads))
  978. then error [Missing_overload (f1, f2o.cf_type)]
  979. ) f2.cf_overloads;
  980. (* we mark the field as :?used because it might be used through the structure *)
  981. if not (Meta.has Meta.MaybeUsed f1.cf_meta) then f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta;
  982. (match f1.cf_kind with
  983. | Method MethInline ->
  984. if (c.cl_extern || Meta.has Meta.Extern f1.cf_meta) && not (Meta.has Meta.Runtime f1.cf_meta) then error [Has_no_runtime_field (a,n)];
  985. | _ -> ());
  986. ) an.a_fields;
  987. (match !(an.a_status) with
  988. | Opened -> an.a_status := Closed;
  989. | Statics _ | EnumStatics _ | AbstractStatics _ -> error []
  990. | Closed | Const -> ())
  991. with
  992. Unify_error l -> error (cannot_unify a b :: l))
  993. | TAnon a1, TAnon a2 ->
  994. (try
  995. PMap.iter (fun n f2 ->
  996. try
  997. let f1 = PMap.find n a1.a_fields in
  998. if not (unify_kind f1.cf_kind f2.cf_kind) then
  999. (match !(a1.a_status), f1.cf_kind, f2.cf_kind with
  1000. | Opened, Var { v_read = AccNormal; v_write = AccNo }, Var { v_read = AccNormal; v_write = AccNormal } ->
  1001. f1.cf_kind <- f2.cf_kind;
  1002. | _ -> error [invalid_kind n f1.cf_kind f2.cf_kind]);
  1003. if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
  1004. try
  1005. unify_with_access f1.cf_type f2;
  1006. (match !(a1.a_status) with
  1007. | Statics c when not (Meta.has Meta.MaybeUsed f1.cf_meta) -> f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
  1008. | _ -> ());
  1009. with
  1010. Unify_error l -> error (invalid_field n :: l)
  1011. with
  1012. Not_found ->
  1013. match !(a1.a_status) with
  1014. | Opened ->
  1015. if not (link (ref None) a f2.cf_type) then error [];
  1016. a1.a_fields <- PMap.add n f2 a1.a_fields
  1017. | Const when Meta.has Meta.Optional f2.cf_meta ->
  1018. ()
  1019. | _ ->
  1020. error [has_no_field a n];
  1021. ) a2.a_fields;
  1022. (match !(a1.a_status) with
  1023. | Const when not (PMap.is_empty a2.a_fields) ->
  1024. PMap.iter (fun n _ -> if not (PMap.mem n a2.a_fields) then error [has_extra_field a n]) a1.a_fields;
  1025. | Opened ->
  1026. a1.a_status := Closed
  1027. | _ -> ());
  1028. (match !(a2.a_status) with
  1029. | Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error [])
  1030. | EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
  1031. | AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
  1032. | Opened -> a2.a_status := Closed
  1033. | Const | Closed -> ())
  1034. with
  1035. Unify_error l -> error (cannot_unify a b :: l))
  1036. | TAnon an, TAbstract ({ a_path = [],"Class" },[pt]) ->
  1037. (match !(an.a_status) with
  1038. | Statics cl -> unify (TInst (cl,List.map (fun _ -> mk_mono()) cl.cl_types)) pt
  1039. | _ -> error [cannot_unify a b])
  1040. | TAnon an, TAbstract ({ a_path = [],"Enum" },[pt]) ->
  1041. (match !(an.a_status) with
  1042. | EnumStatics e -> unify (TEnum (e,List.map (fun _ -> mk_mono()) e.e_types)) pt
  1043. | _ -> error [cannot_unify a b])
  1044. | TEnum _, TAbstract ({ a_path = [],"EnumValue" },[]) ->
  1045. ()
  1046. | TDynamic t , _ ->
  1047. if t == a then
  1048. ()
  1049. else (match b with
  1050. | TDynamic t2 ->
  1051. if t2 != b then
  1052. (try
  1053. type_eq EqRightDynamic t t2
  1054. with
  1055. Unify_error l -> error (cannot_unify a b :: l));
  1056. | _ ->
  1057. error [cannot_unify a b])
  1058. | _ , TDynamic t ->
  1059. if t == b then
  1060. ()
  1061. else (match a with
  1062. | TDynamic t2 ->
  1063. if t2 != a then
  1064. (try
  1065. type_eq EqRightDynamic t t2
  1066. with
  1067. Unify_error l -> error (cannot_unify a b :: l));
  1068. | TAnon an ->
  1069. (try
  1070. (match !(an.a_status) with
  1071. | Statics _ | EnumStatics _ -> error []
  1072. | Opened -> an.a_status := Closed
  1073. | _ -> ());
  1074. PMap.iter (fun _ f ->
  1075. try
  1076. type_eq EqStrict (field_type f) t
  1077. with Unify_error l ->
  1078. error (invalid_field f.cf_name :: l)
  1079. ) an.a_fields
  1080. with Unify_error l ->
  1081. error (cannot_unify a b :: l))
  1082. | _ ->
  1083. error [cannot_unify a b])
  1084. | TAbstract (aa,tl), _ ->
  1085. if not (List.exists (unify_to_field aa tl b) aa.a_to) then error [cannot_unify a b];
  1086. | TInst ({ cl_kind = KTypeParameter ctl } as c,pl), TAbstract _ ->
  1087. (* one of the constraints must satisfy the abstract *)
  1088. if not (List.exists (fun t ->
  1089. let t = apply_params c.cl_types pl t in
  1090. try unify t b; true with Unify_error _ -> false
  1091. ) ctl) then error [cannot_unify a b];
  1092. | _, TAbstract (bb,tl) ->
  1093. if not (List.exists (unify_from_field bb tl a b) bb.a_from) then error [cannot_unify a b]
  1094. | _ , _ ->
  1095. error [cannot_unify a b]
  1096. and unify_from_field ab tl a b (t,cfo) =
  1097. if (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!abstract_cast_stack)) then false else begin
  1098. abstract_cast_stack := (a,b) :: !abstract_cast_stack;
  1099. let unify_func = match follow a with TAbstract({a_impl = Some _},_) when ab.a_impl <> None -> type_eq EqStrict | _ -> unify in
  1100. let b = try begin match cfo with
  1101. | Some cf -> (match follow cf.cf_type with
  1102. | TFun(_,r) ->
  1103. let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
  1104. let map t = apply_params ab.a_types tl (apply_params cf.cf_params monos t) in
  1105. unify_func a (map t);
  1106. unify (map r) b;
  1107. | _ -> assert false)
  1108. | _ ->
  1109. unify_func a (apply_params ab.a_types tl t)
  1110. end;
  1111. true
  1112. with Unify_error _ -> false
  1113. in
  1114. abstract_cast_stack := List.tl !abstract_cast_stack;
  1115. b
  1116. end
  1117. and unify_to_field ab tl b (t,cfo) =
  1118. let a = TAbstract(ab,tl) in
  1119. if (List.exists (fun (b2,a2) -> fast_eq a a2 && fast_eq b b2) (!abstract_cast_stack)) then false else begin
  1120. abstract_cast_stack := (b,a) :: !abstract_cast_stack;
  1121. let unify_func = match follow b with TAbstract({a_impl = Some _},_) when ab.a_impl <> None -> type_eq EqStrict | _ -> unify in
  1122. let b = try begin match cfo with
  1123. | Some cf -> (match follow cf.cf_type with
  1124. | TFun((_,_,ta) :: _,_) ->
  1125. let monos = List.map (fun _ -> mk_mono()) cf.cf_params in
  1126. let map t = apply_params ab.a_types tl (apply_params cf.cf_params monos t) in
  1127. let athis = map ab.a_this in
  1128. (* we cannot allow implicit casts when the this type is not completely known yet *)
  1129. if has_mono athis then raise (Unify_error []);
  1130. type_eq EqStrict athis (map ta);
  1131. (* immediate constraints checking is ok here because we know there are no monomorphs *)
  1132. List.iter2 (fun m (name,t) -> match follow t with
  1133. | TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
  1134. List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> unify m (map tc) ) constr
  1135. | _ -> ()
  1136. ) monos cf.cf_params;
  1137. unify_func (map t) b;
  1138. | _ -> assert false)
  1139. | _ ->
  1140. unify_func (apply_params ab.a_types tl t) b;
  1141. end;
  1142. true
  1143. with Unify_error _ -> false
  1144. in
  1145. abstract_cast_stack := List.tl !abstract_cast_stack;
  1146. b
  1147. end
  1148. and unify_types a b tl1 tl2 =
  1149. List.iter2 (fun t1 t2 ->
  1150. try
  1151. type_eq EqRightDynamic t1 t2
  1152. with Unify_error l ->
  1153. let err = cannot_unify a b in
  1154. (try (match follow t1, follow t2 with
  1155. | TAbstract({a_impl = Some _} as a1,pl1),TAbstract({a_impl = Some _ } as a2,pl2) ->
  1156. type_eq EqStrict (apply_params a1.a_types pl1 a1.a_this) (apply_params a2.a_types pl2 a2.a_this)
  1157. | TAbstract({a_impl = Some _} as a,pl),t -> type_eq EqStrict (apply_params a.a_types pl a.a_this) t
  1158. | t,TAbstract({a_impl = Some _ } as a,pl) -> type_eq EqStrict t (apply_params a.a_types pl a.a_this)
  1159. | _ -> raise (Unify_error l))
  1160. with Unify_error _ ->
  1161. error (err :: (Invariant_parameter (t1,t2)) :: l))
  1162. ) tl1 tl2
  1163. and unify_with_access t1 f2 =
  1164. match f2.cf_kind with
  1165. (* write only *)
  1166. | Var { v_read = AccNo } | Var { v_read = AccNever } -> unify f2.cf_type t1
  1167. (* read only *)
  1168. | Method MethNormal | Method MethInline | Var { v_write = AccNo } | Var { v_write = AccNever } -> unify t1 f2.cf_type
  1169. (* read/write *)
  1170. | _ -> type_eq EqBothDynamic t1 f2.cf_type
  1171. let iter f e =
  1172. match e.eexpr with
  1173. | TConst _
  1174. | TLocal _
  1175. | TBreak
  1176. | TContinue
  1177. | TTypeExpr _ ->
  1178. ()
  1179. | TArray (e1,e2)
  1180. | TBinop (_,e1,e2)
  1181. | TFor (_,e1,e2)
  1182. | TWhile (e1,e2,_) ->
  1183. f e1;
  1184. f e2;
  1185. | TThrow e
  1186. | TField (e,_)
  1187. | TParenthesis e
  1188. | TCast (e,_)
  1189. | TUnop (_,_,e) ->
  1190. f e
  1191. | TArrayDecl el
  1192. | TNew (_,_,el)
  1193. | TBlock el ->
  1194. List.iter f el
  1195. | TObjectDecl fl ->
  1196. List.iter (fun (_,e) -> f e) fl
  1197. | TCall (e,el) ->
  1198. f e;
  1199. List.iter f el
  1200. | TVars vl ->
  1201. List.iter (fun (_,e) -> match e with None -> () | Some e -> f e) vl
  1202. | TFunction fu ->
  1203. f fu.tf_expr
  1204. | TIf (e,e1,e2) ->
  1205. f e;
  1206. f e1;
  1207. (match e2 with None -> () | Some e -> f e)
  1208. | TSwitch (e,cases,def) ->
  1209. f e;
  1210. List.iter (fun (el,e2) -> List.iter f el; f e2) cases;
  1211. (match def with None -> () | Some e -> f e)
  1212. | TMatch (e,_,cases,def) ->
  1213. f e;
  1214. List.iter (fun (_,_,e) -> f e) cases;
  1215. (match def with None -> () | Some e -> f e)
  1216. | TTry (e,catches) ->
  1217. f e;
  1218. List.iter (fun (_,e) -> f e) catches
  1219. | TReturn eo ->
  1220. (match eo with None -> () | Some e -> f e)
  1221. let map_expr f e =
  1222. match e.eexpr with
  1223. | TConst _
  1224. | TLocal _
  1225. | TBreak
  1226. | TContinue
  1227. | TTypeExpr _ ->
  1228. e
  1229. | TArray (e1,e2) ->
  1230. { e with eexpr = TArray (f e1,f e2) }
  1231. | TBinop (op,e1,e2) ->
  1232. { e with eexpr = TBinop (op,f e1,f e2) }
  1233. | TFor (v,e1,e2) ->
  1234. { e with eexpr = TFor (v,f e1,f e2) }
  1235. | TWhile (e1,e2,flag) ->
  1236. { e with eexpr = TWhile (f e1,f e2,flag) }
  1237. | TThrow e1 ->
  1238. { e with eexpr = TThrow (f e1) }
  1239. | TField (e1,v) ->
  1240. { e with eexpr = TField (f e1,v) }
  1241. | TParenthesis e1 ->
  1242. { e with eexpr = TParenthesis (f e1) }
  1243. | TUnop (op,pre,e1) ->
  1244. { e with eexpr = TUnop (op,pre,f e1) }
  1245. | TArrayDecl el ->
  1246. { e with eexpr = TArrayDecl (List.map f el) }
  1247. | TNew (t,pl,el) ->
  1248. { e with eexpr = TNew (t,pl,List.map f el) }
  1249. | TBlock el ->
  1250. { e with eexpr = TBlock (List.map f el) }
  1251. | TObjectDecl el ->
  1252. { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) }
  1253. | TCall (e1,el) ->
  1254. { e with eexpr = TCall (f e1, List.map f el) }
  1255. | TVars vl ->
  1256. { e with eexpr = TVars (List.map (fun (v,e) -> v , match e with None -> None | Some e -> Some (f e)) vl) }
  1257. | TFunction fu ->
  1258. { e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } }
  1259. | TIf (ec,e1,e2) ->
  1260. { e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)) }
  1261. | TSwitch (e1,cases,def) ->
  1262. { e with eexpr = TSwitch (f e1, List.map (fun (el,e2) -> List.map f el, f e2) cases, match def with None -> None | Some e -> Some (f e)) }
  1263. | TMatch (e1,t,cases,def) ->
  1264. { e with eexpr = TMatch (f e1, t, List.map (fun (cl,params,e) -> cl, params, f e) cases, match def with None -> None | Some e -> Some (f e)) }
  1265. | TTry (e1,catches) ->
  1266. { e with eexpr = TTry (f e1, List.map (fun (v,e) -> v, f e) catches) }
  1267. | TReturn eo ->
  1268. { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) }
  1269. | TCast (e1,t) ->
  1270. { e with eexpr = TCast (f e1,t) }
  1271. let map_expr_type f ft fv e =
  1272. match e.eexpr with
  1273. | TConst _
  1274. | TBreak
  1275. | TContinue
  1276. | TTypeExpr _ ->
  1277. { e with etype = ft e.etype }
  1278. | TLocal v ->
  1279. { e with eexpr = TLocal (fv v); etype = ft e.etype }
  1280. | TArray (e1,e2) ->
  1281. { e with eexpr = TArray (f e1,f e2); etype = ft e.etype }
  1282. | TBinop (op,e1,e2) ->
  1283. { e with eexpr = TBinop (op,f e1,f e2); etype = ft e.etype }
  1284. | TFor (v,e1,e2) ->
  1285. { e with eexpr = TFor (fv v,f e1,f e2); etype = ft e.etype }
  1286. | TWhile (e1,e2,flag) ->
  1287. { e with eexpr = TWhile (f e1,f e2,flag); etype = ft e.etype }
  1288. | TThrow e1 ->
  1289. { e with eexpr = TThrow (f e1); etype = ft e.etype }
  1290. | TField (e1,v) ->
  1291. { e with eexpr = TField (f e1,v); etype = ft e.etype }
  1292. | TParenthesis e1 ->
  1293. { e with eexpr = TParenthesis (f e1); etype = ft e.etype }
  1294. | TUnop (op,pre,e1) ->
  1295. { e with eexpr = TUnop (op,pre,f e1); etype = ft e.etype }
  1296. | TArrayDecl el ->
  1297. { e with eexpr = TArrayDecl (List.map f el); etype = ft e.etype }
  1298. | TNew (_,_,el) ->
  1299. let et = ft e.etype in
  1300. (* make sure that we use the class corresponding to the replaced type *)
  1301. let c, pl = (match follow et with TInst (c,pl) -> (c,pl) | TAbstract({a_impl = Some c},pl) -> c,pl | t -> error [has_no_field t "new"]) in
  1302. { e with eexpr = TNew (c,pl,List.map f el); etype = et }
  1303. | TBlock el ->
  1304. { e with eexpr = TBlock (List.map f el); etype = ft e.etype }
  1305. | TObjectDecl el ->
  1306. { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el); etype = ft e.etype }
  1307. | TCall (e1,el) ->
  1308. { e with eexpr = TCall (f e1, List.map f el); etype = ft e.etype }
  1309. | TVars vl ->
  1310. { e with eexpr = TVars (List.map (fun (v,e) -> fv v, match e with None -> None | Some e -> Some (f e)) vl); etype = ft e.etype }
  1311. | TFunction fu ->
  1312. let fu = {
  1313. tf_expr = f fu.tf_expr;
  1314. tf_args = List.map (fun (v,o) -> fv v, o) fu.tf_args;
  1315. tf_type = ft fu.tf_type;
  1316. } in
  1317. { e with eexpr = TFunction fu; etype = ft e.etype }
  1318. | TIf (ec,e1,e2) ->
  1319. { e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1320. | TSwitch (e1,cases,def) ->
  1321. { e with eexpr = TSwitch (f e1, List.map (fun (el,e2) -> List.map f el, f e2) cases, match def with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1322. | TMatch (e1,(en,pl),cases,def) ->
  1323. let map_case (cl,params,e) =
  1324. let params = match params with
  1325. | None -> None
  1326. | Some l -> Some (List.map (function None -> None | Some v -> Some (fv v)) l)
  1327. in
  1328. cl, params, f e
  1329. in
  1330. { e with eexpr = TMatch (f e1, (en,List.map ft pl), List.map map_case cases, match def with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1331. | TTry (e1,catches) ->
  1332. { e with eexpr = TTry (f e1, List.map (fun (v,e) -> fv v, f e) catches); etype = ft e.etype }
  1333. | TReturn eo ->
  1334. { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1335. | TCast (e1,t) ->
  1336. { e with eexpr = TCast (f e1,t); etype = ft e.etype }
  1337. let s_expr_kind e =
  1338. match e.eexpr with
  1339. | TConst _ -> "Const"
  1340. | TLocal _ -> "Local"
  1341. | TArray (_,_) -> "Array"
  1342. | TBinop (_,_,_) -> "Binop"
  1343. | TField (_,_) -> "Field"
  1344. | TTypeExpr _ -> "TypeExpr"
  1345. | TParenthesis _ -> "Parenthesis"
  1346. | TObjectDecl _ -> "ObjectDecl"
  1347. | TArrayDecl _ -> "ArrayDecl"
  1348. | TCall (_,_) -> "Call"
  1349. | TNew (_,_,_) -> "New"
  1350. | TUnop (_,_,_) -> "Unop"
  1351. | TFunction _ -> "Function"
  1352. | TVars _ -> "Vars"
  1353. | TBlock _ -> "Block"
  1354. | TFor (_,_,_) -> "For"
  1355. | TIf (_,_,_) -> "If"
  1356. | TWhile (_,_,_) -> "While"
  1357. | TSwitch (_,_,_) -> "Switch"
  1358. | TMatch (_,_,_,_) -> "Match"
  1359. | TTry (_,_) -> "Try"
  1360. | TReturn _ -> "Return"
  1361. | TBreak -> "Break"
  1362. | TContinue -> "Continue"
  1363. | TThrow _ -> "Throw"
  1364. | TCast _ -> "Cast"
  1365. let s_const = function
  1366. | TInt i -> Int32.to_string i
  1367. | TFloat s -> s ^ "f"
  1368. | TString s -> Printf.sprintf "\"%s\"" (Ast.s_escape s)
  1369. | TBool b -> if b then "true" else "false"
  1370. | TNull -> "null"
  1371. | TThis -> "this"
  1372. | TSuper -> "super"
  1373. let rec s_expr s_type e =
  1374. let sprintf = Printf.sprintf in
  1375. let slist f l = String.concat "," (List.map f l) in
  1376. let loop = s_expr s_type in
  1377. let s_var v = v.v_name ^ ":" ^ string_of_int v.v_id ^ if v.v_capture then "[c]" else "" in
  1378. let str = (match e.eexpr with
  1379. | TConst c ->
  1380. "Const " ^ s_const c
  1381. | TLocal v ->
  1382. "Local " ^ s_var v
  1383. | TArray (e1,e2) ->
  1384. sprintf "%s[%s]" (loop e1) (loop e2)
  1385. | TBinop (op,e1,e2) ->
  1386. sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
  1387. | TField (e,f) ->
  1388. let fstr = (match f with
  1389. | FStatic (c,f) -> "static(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ ")"
  1390. | FInstance (c,f) -> "inst(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ " : " ^ s_type f.cf_type ^ ")"
  1391. | FClosure (c,f) -> "closure(" ^ (match c with None -> f.cf_name | Some c -> s_type_path c.cl_path ^ "." ^ f.cf_name) ^ ")"
  1392. | FAnon f -> "anon(" ^ f.cf_name ^ ")"
  1393. | FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")"
  1394. | FDynamic f -> "dynamic(" ^ f ^ ")"
  1395. ) in
  1396. sprintf "%s.%s" (loop e) fstr
  1397. | TTypeExpr m ->
  1398. sprintf "TypeExpr %s" (s_type_path (t_path m))
  1399. | TParenthesis e ->
  1400. sprintf "Parenthesis %s" (loop e)
  1401. | TObjectDecl fl ->
  1402. sprintf "ObjectDecl {%s)" (slist (fun (f,e) -> sprintf "%s : %s" f (loop e)) fl)
  1403. | TArrayDecl el ->
  1404. sprintf "ArrayDecl [%s]" (slist loop el)
  1405. | TCall (e,el) ->
  1406. sprintf "Call %s(%s)" (loop e) (slist loop el)
  1407. | TNew (c,pl,el) ->
  1408. sprintf "New %s%s(%s)" (s_type_path c.cl_path) (match pl with [] -> "" | l -> sprintf "<%s>" (slist s_type l)) (slist loop el)
  1409. | TUnop (op,f,e) ->
  1410. (match f with
  1411. | Prefix -> sprintf "(%s %s)" (s_unop op) (loop e)
  1412. | Postfix -> sprintf "(%s %s)" (loop e) (s_unop op))
  1413. | TFunction f ->
  1414. let args = slist (fun (v,o) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in
  1415. sprintf "Function(%s) : %s = %s" args (s_type f.tf_type) (loop f.tf_expr)
  1416. | TVars vl ->
  1417. sprintf "Vars %s" (slist (fun (v,eo) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match eo with None -> "" | Some e -> " = " ^ loop e)) vl)
  1418. | TBlock el ->
  1419. sprintf "Block {\n%s}" (String.concat "" (List.map (fun e -> sprintf "%s;\n" (loop e)) el))
  1420. | TFor (v,econd,e) ->
  1421. sprintf "For (%s : %s in %s,%s)" (s_var v) (s_type v.v_type) (loop econd) (loop e)
  1422. | TIf (e,e1,e2) ->
  1423. sprintf "If (%s,%s%s)" (loop e) (loop e1) (match e2 with None -> "" | Some e -> "," ^ loop e)
  1424. | TWhile (econd,e,flag) ->
  1425. (match flag with
  1426. | NormalWhile -> sprintf "While (%s,%s)" (loop econd) (loop e)
  1427. | DoWhile -> sprintf "DoWhile (%s,%s)" (loop e) (loop econd))
  1428. | TSwitch (e,cases,def) ->
  1429. sprintf "Switch (%s,(%s)%s)" (loop e) (slist (fun (cl,e) -> sprintf "case %s: %s" (slist loop cl) (loop e)) cases) (match def with None -> "" | Some e -> "," ^ loop e)
  1430. | TMatch (e,(en,tparams),cases,def) ->
  1431. let args vl = slist (function None -> "_" | Some v -> sprintf "%s : %s" (s_var v) (s_type v.v_type)) vl in
  1432. let cases = slist (fun (il,vl,e) -> sprintf "case %s%s : %s" (slist string_of_int il) (match vl with None -> "" | Some vl -> sprintf "(%s)" (args vl)) (loop e)) cases in
  1433. sprintf "Match %s (%s,(%s)%s)" (s_type (TEnum (en,tparams))) (loop e) cases (match def with None -> "" | Some e -> "," ^ loop e)
  1434. | TTry (e,cl) ->
  1435. sprintf "Try %s(%s) " (loop e) (slist (fun (v,e) -> sprintf "catch( %s : %s ) %s" (s_var v) (s_type v.v_type) (loop e)) cl)
  1436. | TReturn None ->
  1437. "Return"
  1438. | TReturn (Some e) ->
  1439. sprintf "Return %s" (loop e)
  1440. | TBreak ->
  1441. "Break"
  1442. | TContinue ->
  1443. "Continue"
  1444. | TThrow e ->
  1445. "Throw " ^ (loop e)
  1446. | TCast (e,t) ->
  1447. sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e)
  1448. ) in
  1449. sprintf "(%s : %s)" str (s_type e.etype)
  1450. let rec s_expr_pretty tabs s_type e =
  1451. let sprintf = Printf.sprintf in
  1452. let loop = s_expr_pretty tabs s_type in
  1453. let slist f l = String.concat "," (List.map f l) in
  1454. match e.eexpr with
  1455. | TConst c -> s_const c
  1456. | TLocal v -> v.v_name
  1457. | TArray (e1,e2) -> sprintf "%s[%s]" (loop e1) (loop e2)
  1458. | TBinop (op,e1,e2) -> sprintf "%s %s %s" (loop e1) (s_binop op) (loop e2)
  1459. | TField (e1,s) -> sprintf "%s.%s" (loop e1) (field_name s)
  1460. | TTypeExpr mt -> (s_type_path (t_path mt))
  1461. | TParenthesis e1 -> sprintf "(%s)" (loop e1)
  1462. | TObjectDecl fl -> sprintf "{%s}" (slist (fun (f,e) -> sprintf "%s : %s" f (loop e)) fl)
  1463. | TArrayDecl el -> sprintf "[%s]" (slist loop el)
  1464. | TCall (e1,el) -> sprintf "%s(%s)" (loop e1) (slist loop el)
  1465. | TNew (c,pl,el) ->
  1466. sprintf "new %s(%s)" (s_type_path c.cl_path) (slist loop el)
  1467. | TUnop (op,f,e) ->
  1468. (match f with
  1469. | Prefix -> sprintf "%s %s" (s_unop op) (loop e)
  1470. | Postfix -> sprintf "%s %s" (loop e) (s_unop op))
  1471. | TFunction f ->
  1472. let args = slist (fun (v,o) -> sprintf "%s:%s%s" v.v_name (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in
  1473. sprintf "function(%s) = %s" args (loop f.tf_expr)
  1474. | TVars vl ->
  1475. sprintf "var %s" (slist (fun (v,eo) -> sprintf "%s%s" v.v_name (match eo with None -> "" | Some e -> " = " ^ loop e)) vl)
  1476. | TBlock el ->
  1477. let ntabs = tabs ^ "\t" in
  1478. let s = sprintf "{\n%s" (String.concat "" (List.map (fun e -> sprintf "%s%s;\n" ntabs (s_expr_pretty ntabs s_type e)) el)) in
  1479. s ^ tabs ^ "}"
  1480. | TFor (v,econd,e) ->
  1481. sprintf "for (%s in %s) %s" v.v_name (loop econd) (loop e)
  1482. | TIf (e,e1,e2) ->
  1483. sprintf "if (%s)%s%s)" (loop e) (loop e1) (match e2 with None -> "" | Some e -> " else " ^ loop e)
  1484. | TWhile (econd,e,flag) ->
  1485. (match flag with
  1486. | NormalWhile -> sprintf "while (%s) %s" (loop econd) (loop e)
  1487. | DoWhile -> sprintf "do (%s) while(%s)" (loop e) (loop econd))
  1488. | TSwitch (e,cases,def) ->
  1489. let ntabs = tabs ^ "\t" in
  1490. let s = sprintf "switch (%s) {\n%s%s" (loop e) (slist (fun (cl,e) -> sprintf "%scase %s: %s\n" ntabs (slist loop cl) (s_expr_pretty ntabs s_type e)) cases) (match def with None -> "" | Some e -> ntabs ^ "default: " ^ (s_expr_pretty ntabs s_type e) ^ "\n") in
  1491. s ^ tabs ^ "}"
  1492. | TMatch (e,(en,tparams),cases,def) ->
  1493. let ntabs = tabs ^ "\t" in
  1494. let cases = slist (fun (il,vl,e) ->
  1495. let ctor i = (PMap.find (List.nth en.e_names i) en.e_constrs).ef_name in
  1496. let ctors = String.concat "," (List.map ctor il) in
  1497. begin match vl with
  1498. | None ->
  1499. sprintf "%scase %s: %s\n" ntabs ctors (s_expr_pretty ntabs s_type e)
  1500. | Some vl ->
  1501. sprintf "%scase %s(%s): %s\n" ntabs ctors (String.concat "," (List.map (fun v -> match v with None -> "_" | Some v -> v.v_name) vl)) (s_expr_pretty ntabs s_type e)
  1502. end
  1503. ) cases in
  1504. let s = sprintf "switch (%s) {\n%s%s" (loop e) cases (match def with None -> "" | Some e -> ntabs ^ "default: " ^ (s_expr_pretty ntabs s_type e) ^ "\n") in
  1505. s ^ tabs ^ "}"
  1506. | TTry (e,cl) ->
  1507. sprintf "try %s%s" (loop e) (slist (fun (v,e) -> sprintf "catch( %s : %s ) %s" v.v_name (s_type v.v_type) (loop e)) cl)
  1508. | TReturn None ->
  1509. "return"
  1510. | TReturn (Some e) ->
  1511. sprintf "return %s" (loop e)
  1512. | TBreak ->
  1513. "break"
  1514. | TContinue ->
  1515. "continue"
  1516. | TThrow e ->
  1517. "throw " ^ (loop e)
  1518. | TCast (e,None) ->
  1519. sprintf "cast %s" (loop e)
  1520. | TCast (e,Some mt) ->
  1521. sprintf "cast (%s,%s)" (loop e) (s_type_path (t_path mt))