type.ml 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. (*
  2. * Haxe Compiler
  3. * Copyright (c)2005 Nicolas Cannasse
  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 warraTFnty 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *)
  19. open Ast
  20. type path = string list * string
  21. type field_kind =
  22. | Var of var_kind
  23. | Method of method_kind
  24. and var_kind = {
  25. v_read : var_access;
  26. v_write : var_access;
  27. }
  28. and var_access =
  29. | AccNormal
  30. | AccNo (* can't be accessed outside of the class itself and its subclasses *)
  31. | AccNever (* can't be accessed, even in subclasses *)
  32. | AccResolve (* call resolve("field") when accessed *)
  33. | AccCall of string (* perform a method call when accessed *)
  34. | AccInline (* similar to Normal but inline when accessed *)
  35. | AccRequire of string (* set when @:require(cond) fails *)
  36. and method_kind =
  37. | MethNormal
  38. | MethInline
  39. | MethDynamic
  40. | MethMacro
  41. type t =
  42. | TMono of t option ref
  43. | TEnum of tenum * tparams
  44. | TInst of tclass * tparams
  45. | TType of tdef * tparams
  46. | TFun of (string * bool * t) list * t
  47. | TAnon of tanon
  48. | TDynamic of t
  49. | TLazy of (unit -> t) ref
  50. and tparams = t list
  51. and type_params = (string * t) list
  52. and tconstant =
  53. | TInt of int32
  54. | TFloat of string
  55. | TString of string
  56. | TBool of bool
  57. | TNull
  58. | TThis
  59. | TSuper
  60. and tvar = {
  61. v_id : int;
  62. mutable v_name : string;
  63. mutable v_type : t;
  64. mutable v_capture : bool;
  65. mutable v_extra : (type_params * texpr option) option;
  66. }
  67. and tfunc = {
  68. tf_args : (tvar * tconstant option) list;
  69. tf_type : t;
  70. tf_expr : texpr;
  71. }
  72. and anon_status =
  73. | Closed
  74. | Opened
  75. | Const
  76. | Statics of tclass
  77. | EnumStatics of tenum
  78. and tanon = {
  79. mutable a_fields : (string, tclass_field) PMap.t;
  80. a_status : anon_status ref;
  81. }
  82. and texpr_expr =
  83. | TConst of tconstant
  84. | TLocal of tvar
  85. | TEnumField of tenum * string
  86. | TArray of texpr * texpr
  87. | TBinop of Ast.binop * texpr * texpr
  88. | TField of texpr * string
  89. | TClosure of texpr * string
  90. | TTypeExpr of module_type
  91. | TParenthesis of texpr
  92. | TObjectDecl of (string * texpr) list
  93. | TArrayDecl of texpr list
  94. | TCall of texpr * texpr list
  95. | TNew of tclass * tparams * texpr list
  96. | TUnop of Ast.unop * Ast.unop_flag * texpr
  97. | TFunction of tfunc
  98. | TVars of (tvar * texpr option) list
  99. | TBlock of texpr list
  100. | TFor of tvar * texpr * texpr
  101. | TIf of texpr * texpr * texpr option
  102. | TWhile of texpr * texpr * Ast.while_flag
  103. | TSwitch of texpr * (texpr list * texpr) list * texpr option
  104. | TMatch of texpr * (tenum * tparams) * (int list * tvar option list option * texpr) list * texpr option
  105. | TTry of texpr * (tvar * texpr) list
  106. | TReturn of texpr option
  107. | TBreak
  108. | TContinue
  109. | TThrow of texpr
  110. | TCast of texpr * module_type option
  111. and texpr = {
  112. eexpr : texpr_expr;
  113. etype : t;
  114. epos : Ast.pos;
  115. }
  116. and tclass_field = {
  117. cf_name : string;
  118. mutable cf_type : t;
  119. cf_public : bool;
  120. cf_pos : pos;
  121. mutable cf_doc : Ast.documentation;
  122. mutable cf_meta : metadata;
  123. mutable cf_kind : field_kind;
  124. cf_params : type_params;
  125. mutable cf_expr : texpr option;
  126. mutable cf_overloads : tclass_field list;
  127. }
  128. and tclass_kind =
  129. | KNormal
  130. | KTypeParameter
  131. | KExtension of tclass * tparams
  132. | KExpr of Ast.expr
  133. | KGeneric
  134. | KGenericInstance of tclass * tparams
  135. | KMacroType
  136. and metadata = Ast.metadata
  137. and tinfos = {
  138. mt_path : path;
  139. mt_module : module_def;
  140. mt_pos : Ast.pos;
  141. mt_private : bool;
  142. mt_doc : Ast.documentation;
  143. mutable mt_meta : metadata;
  144. }
  145. and tclass = {
  146. mutable cl_path : path;
  147. mutable cl_module : module_def;
  148. mutable cl_pos : Ast.pos;
  149. mutable cl_private : bool;
  150. mutable cl_doc : Ast.documentation;
  151. mutable cl_meta : metadata;
  152. mutable cl_kind : tclass_kind;
  153. mutable cl_extern : bool;
  154. mutable cl_interface : bool;
  155. mutable cl_types : type_params;
  156. mutable cl_super : (tclass * tparams) option;
  157. mutable cl_implements : (tclass * tparams) list;
  158. mutable cl_fields : (string , tclass_field) PMap.t;
  159. mutable cl_statics : (string, tclass_field) PMap.t;
  160. mutable cl_ordered_statics : tclass_field list;
  161. mutable cl_ordered_fields : tclass_field list;
  162. mutable cl_dynamic : t option;
  163. mutable cl_array_access : t option;
  164. mutable cl_constructor : tclass_field option;
  165. mutable cl_init : texpr option;
  166. mutable cl_overrides : string list;
  167. mutable cl_restore : unit -> unit;
  168. }
  169. and tenum_field = {
  170. ef_name : string;
  171. ef_type : t;
  172. ef_pos : Ast.pos;
  173. ef_doc : Ast.documentation;
  174. ef_index : int;
  175. mutable ef_meta : metadata;
  176. }
  177. and tenum = {
  178. mutable e_path : path;
  179. e_module : module_def;
  180. e_pos : Ast.pos;
  181. e_private : bool;
  182. e_doc : Ast.documentation;
  183. mutable e_meta : metadata;
  184. mutable e_extern : bool;
  185. mutable e_types : type_params;
  186. mutable e_constrs : (string , tenum_field) PMap.t;
  187. mutable e_names : string list;
  188. }
  189. and tdef = {
  190. t_path : path;
  191. t_module : module_def;
  192. t_pos : Ast.pos;
  193. t_private : bool;
  194. t_doc : Ast.documentation;
  195. mutable t_meta : metadata;
  196. mutable t_types : type_params;
  197. mutable t_type : t;
  198. }
  199. and module_type =
  200. | TClassDecl of tclass
  201. | TEnumDecl of tenum
  202. | TTypeDecl of tdef
  203. and module_def = {
  204. m_id : int;
  205. m_path : path;
  206. mutable m_types : module_type list;
  207. m_extra : module_def_extra;
  208. }
  209. and module_def_extra = {
  210. m_file : string;
  211. m_sign : string;
  212. mutable m_time : float;
  213. mutable m_dirty : bool;
  214. mutable m_added : int;
  215. mutable m_mark : int;
  216. mutable m_deps : (int,module_def) PMap.t;
  217. mutable m_processed : int;
  218. mutable m_kind : module_kind;
  219. mutable m_binded_res : (string, string) PMap.t;
  220. mutable m_macro_calls : string list;
  221. }
  222. and module_kind =
  223. | MCode
  224. | MMacro
  225. | MFake
  226. let alloc_var =
  227. let uid = ref 0 in
  228. (fun n t -> incr uid; { v_name = n; v_type = t; v_id = !uid; v_capture = false; v_extra = None })
  229. let alloc_mid =
  230. let mid = ref 0 in
  231. (fun() -> incr mid; !mid)
  232. let mk e t p = { eexpr = e; etype = t; epos = p }
  233. let mk_block e =
  234. match e.eexpr with
  235. | TBlock (_ :: _) -> e
  236. | _ -> mk (TBlock [e]) e.etype e.epos
  237. let null t p = mk (TConst TNull) t p
  238. let mk_mono() = TMono (ref None)
  239. let rec t_dynamic = TDynamic t_dynamic
  240. let tfun pl r = TFun (List.map (fun t -> "",false,t) pl,r)
  241. let fun_args l = List.map (fun (a,c,t) -> a, c <> None, t) l
  242. let mk_class m path pos =
  243. {
  244. cl_path = path;
  245. cl_module = m;
  246. cl_pos = pos;
  247. cl_doc = None;
  248. cl_meta = [];
  249. cl_private = false;
  250. cl_kind = KNormal;
  251. cl_extern = false;
  252. cl_interface = false;
  253. cl_types = [];
  254. cl_super = None;
  255. cl_implements = [];
  256. cl_fields = PMap.empty;
  257. cl_ordered_statics = [];
  258. cl_ordered_fields = [];
  259. cl_statics = PMap.empty;
  260. cl_dynamic = None;
  261. cl_array_access = None;
  262. cl_constructor = None;
  263. cl_init = None;
  264. cl_overrides = [];
  265. cl_restore = (fun() -> ());
  266. }
  267. let module_extra file sign time kind =
  268. {
  269. m_file = file;
  270. m_sign = sign;
  271. m_dirty = false;
  272. m_added = 0;
  273. m_mark = 0;
  274. m_time = time;
  275. m_processed = 0;
  276. m_deps = PMap.empty;
  277. m_kind = kind;
  278. m_binded_res = PMap.empty;
  279. m_macro_calls = [];
  280. }
  281. let null_module = {
  282. m_id = alloc_mid();
  283. m_path = [] , "";
  284. m_types = [];
  285. m_extra = module_extra "" "" 0. MFake;
  286. }
  287. let null_class =
  288. let c = mk_class null_module ([],"") Ast.null_pos in
  289. c.cl_private <- true;
  290. c
  291. let add_dependency m mdep =
  292. if m != null_module && m != mdep then m.m_extra.m_deps <- PMap.add mdep.m_id mdep m.m_extra.m_deps
  293. let arg_name (a,_) = a.v_name
  294. let t_infos t : tinfos =
  295. match t with
  296. | TClassDecl c -> Obj.magic c
  297. | TEnumDecl e -> Obj.magic e
  298. | TTypeDecl t -> Obj.magic t
  299. let t_path t = (t_infos t).mt_path
  300. let print_context() = ref []
  301. let is_closed a = !(a.a_status) <> Opened
  302. let rec s_type ctx t =
  303. match t with
  304. | TMono r ->
  305. (match !r with
  306. | None -> Printf.sprintf "Unknown<%d>" (try List.assq t (!ctx) with Not_found -> let n = List.length !ctx in ctx := (t,n) :: !ctx; n)
  307. | Some t -> s_type ctx t)
  308. | TEnum (e,tl) ->
  309. Ast.s_type_path e.e_path ^ s_type_params ctx tl
  310. | TInst (c,tl) ->
  311. Ast.s_type_path c.cl_path ^ s_type_params ctx tl
  312. | TType (t,tl) ->
  313. Ast.s_type_path t.t_path ^ s_type_params ctx tl
  314. | TFun ([],t) ->
  315. "Void -> " ^ s_fun ctx t false
  316. | TFun (l,t) ->
  317. String.concat " -> " (List.map (fun (s,b,t) ->
  318. (if b then "?" else "") ^ (if s = "" then "" else s ^ " : ") ^ s_fun ctx t true
  319. ) l) ^ " -> " ^ s_fun ctx t false
  320. | TAnon a ->
  321. let fl = PMap.fold (fun f acc -> ((if List.exists (function ":optional",_,_ -> true | _ -> false) f.cf_meta then " ?" else " ") ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in
  322. "{" ^ (if not (is_closed a) then "+" else "") ^ String.concat "," fl ^ " }"
  323. | TDynamic t2 ->
  324. "Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
  325. | TLazy f ->
  326. s_type ctx (!f())
  327. and s_fun ctx t void =
  328. match t with
  329. | TFun _ ->
  330. "(" ^ s_type ctx t ^ ")"
  331. | TEnum ({ e_path = ([],"Void") },[]) when void ->
  332. "(" ^ s_type ctx t ^ ")"
  333. | TMono r ->
  334. (match !r with
  335. | None -> s_type ctx t
  336. | Some t -> s_fun ctx t void)
  337. | TLazy f ->
  338. s_fun ctx (!f()) void
  339. | _ ->
  340. s_type ctx t
  341. and s_type_params ctx = function
  342. | [] -> ""
  343. | l -> "<" ^ String.concat ", " (List.map (s_type ctx) l) ^ ">"
  344. let s_access = function
  345. | AccNormal -> "default"
  346. | AccNo -> "null"
  347. | AccNever -> "never"
  348. | AccResolve -> "resolve"
  349. | AccCall m -> m
  350. | AccInline -> "inline"
  351. | AccRequire n -> "require " ^ n
  352. let s_kind = function
  353. | Var { v_read = AccNormal; v_write = AccNormal } -> "var"
  354. | Var v -> "(" ^ s_access v.v_read ^ "," ^ s_access v.v_write ^ ")"
  355. | Method m ->
  356. match m with
  357. | MethNormal -> "method"
  358. | MethDynamic -> "dynamic method"
  359. | MethInline -> "inline method"
  360. | MethMacro -> "macro method"
  361. let rec is_parent csup c =
  362. if c == csup || List.exists (fun (i,_) -> i == csup) c.cl_implements then
  363. true
  364. else match c.cl_super with
  365. | None -> false
  366. | Some (c,_) -> is_parent csup c
  367. let map loop t =
  368. match t with
  369. | TMono r ->
  370. (match !r with
  371. | None -> t
  372. | Some t -> loop t) (* erase*)
  373. | TEnum (_,[]) | TInst (_,[]) | TType (_,[]) ->
  374. t
  375. | TEnum (e,tl) ->
  376. TEnum (e, List.map loop tl)
  377. | TInst (c,tl) ->
  378. TInst (c, List.map loop tl)
  379. | TType (t2,tl) ->
  380. TType (t2,List.map loop tl)
  381. | TFun (tl,r) ->
  382. TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r)
  383. | TAnon a ->
  384. TAnon {
  385. a_fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields;
  386. a_status = a.a_status;
  387. }
  388. | TLazy f ->
  389. let ft = !f() in
  390. let ft2 = loop ft in
  391. if ft == ft2 then t else ft2
  392. | TDynamic t2 ->
  393. if t == t2 then t else TDynamic (loop t2)
  394. (* substitute parameters with other types *)
  395. let apply_params cparams params t =
  396. match cparams with
  397. | [] -> t
  398. | _ ->
  399. let rec loop l1 l2 =
  400. match l1, l2 with
  401. | [] , [] -> []
  402. | (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
  403. | (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
  404. | _ -> assert false
  405. in
  406. let subst = loop cparams params in
  407. let rec loop t =
  408. try
  409. List.assq t subst
  410. with Not_found ->
  411. match t with
  412. | TMono r ->
  413. (match !r with
  414. | None -> t
  415. | Some t -> loop t)
  416. | TEnum (e,tl) ->
  417. (match tl with
  418. | [] -> t
  419. | _ -> TEnum (e,List.map loop tl))
  420. | TType (t2,tl) ->
  421. (match tl with
  422. | [] -> t
  423. | _ -> TType (t2,List.map loop tl))
  424. | TInst (c,tl) ->
  425. (match tl with
  426. | [] ->
  427. t
  428. | [TMono r] ->
  429. (match !r with
  430. | Some tt when t == tt ->
  431. (* for dynamic *)
  432. let pt = mk_mono() in
  433. let t = TInst (c,[pt]) in
  434. (match pt with TMono r -> r := Some t | _ -> assert false);
  435. t
  436. | _ -> TInst (c,List.map loop tl))
  437. | _ ->
  438. TInst (c,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
  450. t
  451. else
  452. ft2
  453. | TDynamic t2 ->
  454. if t == t2 then
  455. t
  456. else
  457. TDynamic (loop t2)
  458. in
  459. loop t
  460. let rec follow t =
  461. match t with
  462. | TMono r ->
  463. (match !r with
  464. | Some t -> follow t
  465. | _ -> t)
  466. | TLazy f ->
  467. follow (!f())
  468. | TType (t,tl) ->
  469. follow (apply_params t.t_types tl t.t_type)
  470. | _ -> t
  471. let rec is_nullable ?(no_lazy=false) = function
  472. | TMono r ->
  473. (match !r with None -> false | Some t -> is_nullable t)
  474. | TType ({ t_path = ([],"Null") },[_]) ->
  475. true
  476. | TLazy f ->
  477. if no_lazy then raise Exit else is_nullable (!f())
  478. | TType (t,tl) ->
  479. is_nullable (apply_params t.t_types tl t.t_type)
  480. | TFun _ ->
  481. false
  482. (*
  483. Type parameters will most of the time be nullable objects, so we don't want to make it hard for users
  484. to have to specify Null<T> all over the place, so while they could be a basic type, let's assume they will not.
  485. This will still cause issues with inlining and haxe.rtti.Generic. In that case proper explicit Null<T> is required to
  486. work correctly with basic types. This could still be fixed by redoing a nullability inference on the typed AST.
  487. | TInst ({ cl_kind = KTypeParameter },_) -> false
  488. *)
  489. | TInst ({ cl_path = (["haxe"],"Int32") },[])
  490. | TInst ({ cl_path = ([],"Int") },[])
  491. | TInst ({ cl_path = ([],"Float") },[])
  492. | TEnum ({ e_path = ([],"Bool") },[]) -> false
  493. | _ ->
  494. true
  495. let rec is_null = function
  496. | TMono r ->
  497. (match !r with None -> false | Some t -> is_null t)
  498. | TType ({ t_path = ([],"Null") },[t]) ->
  499. not (is_nullable t)
  500. | TLazy f ->
  501. is_null (!f())
  502. | TType (t,tl) ->
  503. is_null (apply_params t.t_types tl t.t_type)
  504. | _ ->
  505. false
  506. let rec link e a b =
  507. (* tell if setting a == b will create a type-loop *)
  508. let rec loop t =
  509. if t == a then
  510. true
  511. else match t with
  512. | TMono t -> (match !t with None -> false | Some t -> loop t)
  513. | TEnum (_,tl) -> List.exists loop tl
  514. | TInst (_,tl) | TType (_,tl) -> List.exists loop tl
  515. | TFun (tl,t) -> List.exists (fun (_,_,t) -> loop t) tl || loop t
  516. | TDynamic t2 ->
  517. if t == t2 then
  518. false
  519. else
  520. loop t2
  521. | TLazy f ->
  522. loop (!f())
  523. | TAnon a ->
  524. try
  525. PMap.iter (fun _ f -> if loop f.cf_type then raise Exit) a.a_fields;
  526. false
  527. with
  528. Exit -> true
  529. in
  530. (* tell is already a ~= b *)
  531. if loop b then
  532. (follow b) == a
  533. else
  534. match b with
  535. | TDynamic _ -> true
  536. | _ -> e := Some b; true
  537. let monomorphs eparams t =
  538. apply_params eparams (List.map (fun _ -> mk_mono()) eparams) t
  539. let rec fast_eq a b =
  540. if a == b then
  541. true
  542. else match a , b with
  543. | TFun (l1,r1) , TFun (l2,r2) ->
  544. List.for_all2 (fun (_,_,t1) (_,_,t2) -> fast_eq t1 t2) l1 l2 && fast_eq r1 r2
  545. | TType (t1,l1), TType (t2,l2) ->
  546. t1 == t2 && List.for_all2 fast_eq l1 l2
  547. | TEnum (e1,l1), TEnum (e2,l2) ->
  548. e1 == e2 && List.for_all2 fast_eq l1 l2
  549. | TInst (c1,l1), TInst (c2,l2) ->
  550. c1 == c2 && List.for_all2 fast_eq l1 l2
  551. | _ , _ ->
  552. false
  553. (* perform unification with subtyping.
  554. the first type is always the most down in the class hierarchy
  555. it's also the one that is pointed by the position.
  556. It's actually a typecheck of A :> B where some mutations can happen *)
  557. type unify_error =
  558. | Cannot_unify of t * t
  559. | Invalid_field_type of string
  560. | Has_no_field of t * string
  561. | Has_no_runtime_field of t * string
  562. | Has_extra_field of t * string
  563. | Invalid_kind of string * field_kind * field_kind
  564. | Invalid_visibility of string
  565. | Not_matching_optional of string
  566. | Cant_force_optional
  567. | Invariant_parameter of t * t
  568. | Constraint_failure of string
  569. | Missing_overload of tclass_field * t
  570. | Unify_custom of string
  571. exception Unify_error of unify_error list
  572. let cannot_unify a b = Cannot_unify (a,b)
  573. let invalid_field n = Invalid_field_type n
  574. let invalid_kind n a b = Invalid_kind (n,a,b)
  575. let invalid_visibility n = Invalid_visibility n
  576. let has_no_field t n = Has_no_field (t,n)
  577. let has_extra_field t n = Has_extra_field (t,n)
  578. let error l = raise (Unify_error l)
  579. let has_meta m ml = List.exists (fun (m2,_,_) -> m = m2) ml
  580. let no_meta = []
  581. (*
  582. we can restrict access as soon as both are runtime-compatible
  583. *)
  584. let unify_access a1 a2 =
  585. a1 = a2 || match a1, a2 with
  586. | _, AccNo | _, AccNever -> true
  587. | AccInline, AccNormal -> true
  588. | _ -> false
  589. let direct_access = function
  590. | AccNo | AccNever | AccNormal | AccInline | AccRequire _ -> true
  591. | AccResolve | AccCall _ -> false
  592. let unify_kind k1 k2 =
  593. k1 = k2 || match k1, k2 with
  594. | Var v1, Var v2 -> unify_access v1.v_read v2.v_read && unify_access v1.v_write v2.v_write
  595. | Var v, Method m ->
  596. (match v.v_read, v.v_write, m with
  597. | AccNormal, _, MethNormal -> true
  598. | AccNormal, AccNormal, MethDynamic -> true
  599. | _ -> false)
  600. | Method m, Var v ->
  601. (match m with
  602. | MethDynamic -> direct_access v.v_read && direct_access v.v_write
  603. | MethMacro -> false
  604. | MethNormal | MethInline ->
  605. match v.v_write with
  606. | AccNo | AccNever -> true
  607. | _ -> false)
  608. | Method m1, Method m2 ->
  609. match m1,m2 with
  610. | MethInline, MethNormal
  611. | MethDynamic, MethNormal -> true
  612. | _ -> false
  613. let eq_stack = ref []
  614. type eq_kind =
  615. | EqStrict
  616. | EqCoreType
  617. | EqRightDynamic
  618. | EqBothDynamic
  619. let rec type_eq param a b =
  620. if a == b then
  621. ()
  622. else match a , b with
  623. | TLazy f , _ -> type_eq param (!f()) b
  624. | _ , TLazy f -> type_eq param a (!f())
  625. | TMono t , _ ->
  626. (match !t with
  627. | None -> if param = EqCoreType || not (link t a b) then error [cannot_unify a b]
  628. | Some t -> type_eq param t b)
  629. | _ , TMono t ->
  630. (match !t with
  631. | None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
  632. | Some t -> type_eq param a t)
  633. | TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 ->
  634. List.iter2 (type_eq param) tl1 tl2
  635. | TType (t,tl) , _ when param <> EqCoreType ->
  636. type_eq param (apply_params t.t_types tl t.t_type) b
  637. | _ , TType (t,tl) when param <> EqCoreType ->
  638. if List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack) then
  639. ()
  640. else begin
  641. eq_stack := (a,b) :: !eq_stack;
  642. try
  643. type_eq param a (apply_params t.t_types tl t.t_type);
  644. eq_stack := List.tl !eq_stack;
  645. with
  646. Unify_error l ->
  647. eq_stack := List.tl !eq_stack;
  648. error (cannot_unify a b :: l)
  649. end
  650. | TEnum (e1,tl1) , TEnum (e2,tl2) ->
  651. if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b];
  652. List.iter2 (type_eq param) tl1 tl2
  653. | TInst (c1,tl1) , TInst (c2,tl2) ->
  654. 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];
  655. List.iter2 (type_eq param) tl1 tl2
  656. | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
  657. (try
  658. type_eq param r1 r2;
  659. List.iter2 (fun (n,o1,t1) (_,o2,t2) ->
  660. if o1 <> o2 then error [Not_matching_optional n];
  661. type_eq param t1 t2
  662. ) l1 l2
  663. with
  664. Unify_error l -> error (cannot_unify a b :: l))
  665. | TDynamic a , TDynamic b ->
  666. type_eq param a b
  667. | TAnon a1, TAnon a2 ->
  668. (try
  669. PMap.iter (fun n f1 ->
  670. try
  671. let f2 = PMap.find n a2.a_fields in
  672. 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];
  673. try
  674. type_eq param f1.cf_type f2.cf_type
  675. with
  676. Unify_error l -> error (invalid_field n :: l)
  677. with
  678. Not_found ->
  679. if is_closed a2 then error [has_no_field b n];
  680. if not (link (ref None) b f1.cf_type) then error [cannot_unify a b];
  681. a2.a_fields <- PMap.add n f1 a2.a_fields
  682. ) a1.a_fields;
  683. PMap.iter (fun n f2 ->
  684. if not (PMap.mem n a1.a_fields) then begin
  685. if is_closed a1 then error [has_no_field a n];
  686. if not (link (ref None) a f2.cf_type) then error [cannot_unify a b];
  687. a1.a_fields <- PMap.add n f2 a1.a_fields
  688. end;
  689. ) a2.a_fields;
  690. with
  691. Unify_error l -> error (cannot_unify a b :: l))
  692. | _ , _ ->
  693. if b == t_dynamic && (param = EqRightDynamic || param = EqBothDynamic) then
  694. ()
  695. else if a == t_dynamic && param = EqBothDynamic then
  696. ()
  697. else
  698. error [cannot_unify a b]
  699. let type_iseq a b =
  700. try
  701. type_eq EqStrict a b;
  702. true
  703. with
  704. Unify_error _ -> false
  705. let unify_stack = ref []
  706. let field_type f =
  707. match f.cf_params with
  708. | [] -> f.cf_type
  709. | l -> monomorphs l f.cf_type
  710. let rec raw_class_field build_type c i =
  711. try
  712. let f = PMap.find i c.cl_fields in
  713. build_type f , f
  714. with Not_found -> try
  715. match c.cl_super with
  716. | None ->
  717. raise Not_found
  718. | Some (c,tl) ->
  719. let t , f = raw_class_field build_type c i in
  720. apply_params c.cl_types tl t , f
  721. with Not_found ->
  722. let rec loop = function
  723. | [] ->
  724. raise Not_found
  725. | (c,tl) :: l ->
  726. try
  727. let t , f = raw_class_field build_type c i in
  728. apply_params c.cl_types tl t, f
  729. with
  730. Not_found -> loop l
  731. in
  732. loop c.cl_implements
  733. let class_field = raw_class_field field_type
  734. let rec get_constructor build_type c =
  735. match c.cl_constructor, c.cl_super with
  736. | Some c, _ -> build_type c, c
  737. | None, None -> raise Not_found
  738. | None, Some (csup,cparams) ->
  739. let t, c = get_constructor build_type csup in
  740. apply_params csup.cl_types cparams t, c
  741. let rec unify a b =
  742. if a == b then
  743. ()
  744. else match a, b with
  745. | TLazy f , _ -> unify (!f()) b
  746. | _ , TLazy f -> unify a (!f())
  747. | TMono t , _ ->
  748. (match !t with
  749. | None -> if not (link t a b) then error [cannot_unify a b]
  750. | Some t -> unify t b)
  751. | _ , TMono t ->
  752. (match !t with
  753. | None -> if not (link t b a) then error [cannot_unify a b]
  754. | Some t -> unify a t)
  755. | TType (t,tl) , _ ->
  756. if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin
  757. try
  758. unify_stack := (a,b) :: !unify_stack;
  759. unify (apply_params t.t_types tl t.t_type) b;
  760. unify_stack := List.tl !unify_stack;
  761. with
  762. Unify_error l ->
  763. unify_stack := List.tl !unify_stack;
  764. error (cannot_unify a b :: l)
  765. end
  766. | _ , TType (t,tl) ->
  767. if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin
  768. try
  769. unify_stack := (a,b) :: !unify_stack;
  770. unify a (apply_params t.t_types tl t.t_type);
  771. unify_stack := List.tl !unify_stack;
  772. with
  773. Unify_error l ->
  774. unify_stack := List.tl !unify_stack;
  775. error (cannot_unify a b :: l)
  776. end
  777. | TEnum (ea,tl1) , TEnum (eb,tl2) ->
  778. if ea != eb then error [cannot_unify a b];
  779. unify_types a b tl1 tl2
  780. | TInst (c1,tl1) , TInst (c2,tl2) ->
  781. let rec loop c tl =
  782. if c == c2 then begin
  783. unify_types a b tl tl2;
  784. true
  785. end else (match c.cl_super with
  786. | None -> false
  787. | Some (cs,tls) ->
  788. loop cs (List.map (apply_params c.cl_types tl) tls)
  789. ) || List.exists (fun (cs,tls) ->
  790. loop cs (List.map (apply_params c.cl_types tl) tls)
  791. ) c.cl_implements
  792. in
  793. if not (loop c1 tl1) then error [cannot_unify a b]
  794. | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
  795. (try
  796. unify r1 r2;
  797. List.iter2 (fun (_,o1,t1) (_,o2,t2) ->
  798. if o1 && not o2 then error [Cant_force_optional];
  799. unify t1 t2
  800. ) l2 l1 (* contravariance *)
  801. with
  802. Unify_error l -> error (cannot_unify a b :: l))
  803. | TInst (c,tl) , TAnon an ->
  804. (try
  805. PMap.iter (fun n f2 ->
  806. let ft, f1 = (try class_field c n with Not_found -> error [has_no_field a n]) in
  807. if not (unify_kind f1.cf_kind f2.cf_kind) then error [invalid_kind n f1.cf_kind f2.cf_kind];
  808. if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
  809. (try
  810. unify_with_access (apply_params c.cl_types tl ft) f2
  811. with
  812. Unify_error l -> error (invalid_field n :: l));
  813. List.iter (fun f2o ->
  814. if not (List.exists (fun f1o -> type_iseq f1o.cf_type f2o.cf_type) (f1 :: f1.cf_overloads))
  815. then error [Missing_overload (f1, f2o.cf_type)]
  816. ) f2.cf_overloads;
  817. (match f1.cf_kind with
  818. | Method MethInline ->
  819. if (c.cl_extern || has_meta ":extern" f1.cf_meta) && not (has_meta ":runtime" f1.cf_meta) then error [Has_no_runtime_field (a,n)];
  820. (* mark as used so it's not removed by DCE *)
  821. if not (has_meta ":?used" f1.cf_meta) then f1.cf_meta <- (":?used",[],f1.cf_pos) :: f1.cf_meta;
  822. | _ -> ());
  823. ) an.a_fields;
  824. if !(an.a_status) = Opened then an.a_status := Closed;
  825. with
  826. Unify_error l -> error (cannot_unify a b :: l))
  827. | TAnon a1, TAnon a2 ->
  828. (try
  829. PMap.iter (fun n f2 ->
  830. try
  831. let f1 = PMap.find n a1.a_fields in
  832. if not (unify_kind f1.cf_kind f2.cf_kind) then
  833. (match !(a1.a_status), f1.cf_kind, f2.cf_kind with
  834. | Opened, Var { v_read = AccNormal; v_write = AccNo }, Var { v_read = AccNormal; v_write = AccNormal } ->
  835. f1.cf_kind <- f2.cf_kind;
  836. | _ -> error [invalid_kind n f1.cf_kind f2.cf_kind]);
  837. if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
  838. try
  839. unify_with_access f1.cf_type f2;
  840. with
  841. Unify_error l -> error (invalid_field n :: l)
  842. with
  843. Not_found ->
  844. match !(a1.a_status) with
  845. | Opened ->
  846. if not (link (ref None) a f2.cf_type) then error [];
  847. a1.a_fields <- PMap.add n f2 a1.a_fields
  848. | Const when has_meta ":optional" f2.cf_meta ->
  849. ()
  850. | _ ->
  851. error [has_no_field a n];
  852. ) a2.a_fields;
  853. (match !(a1.a_status) with
  854. | Const when not (PMap.is_empty a2.a_fields) ->
  855. PMap.iter (fun n _ -> if not (PMap.mem n a2.a_fields) then error [has_extra_field a n]) a1.a_fields;
  856. | Opened ->
  857. a1.a_status := Closed
  858. | _ -> ());
  859. (match !(a2.a_status) with
  860. | Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error [])
  861. | EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
  862. | Opened -> a2.a_status := Closed
  863. | _ -> ())
  864. with
  865. Unify_error l -> error (cannot_unify a b :: l))
  866. | TAnon an, TInst ({ cl_path = [],"Class" },[pt]) ->
  867. (match !(an.a_status) with
  868. | Statics cl -> unify (TInst (cl,List.map snd cl.cl_types)) pt
  869. | _ -> error [cannot_unify a b])
  870. | TAnon an, TInst ({ cl_path = [],"Enum" },[pt]) ->
  871. (match !(an.a_status) with
  872. | EnumStatics e -> unify (TEnum (e,List.map snd e.e_types)) pt
  873. | _ -> error [cannot_unify a b])
  874. | TEnum _, TInst ({ cl_path = [],"EnumValue" },[]) ->
  875. ()
  876. | TDynamic t , _ ->
  877. if t == a then
  878. ()
  879. else (match b with
  880. | TDynamic t2 ->
  881. if t2 != b then
  882. (try
  883. type_eq EqRightDynamic t t2
  884. with
  885. Unify_error l -> error (cannot_unify a b :: l));
  886. | _ ->
  887. error [cannot_unify a b])
  888. | _ , TDynamic t ->
  889. if t == b then
  890. ()
  891. else (match a with
  892. | TDynamic t2 ->
  893. if t2 != a then
  894. (try
  895. type_eq EqRightDynamic t t2
  896. with
  897. Unify_error l -> error (cannot_unify a b :: l));
  898. | TAnon an ->
  899. (try
  900. (match !(an.a_status) with
  901. | Statics _ | EnumStatics _ -> error []
  902. | Opened -> an.a_status := Closed
  903. | _ -> ());
  904. PMap.iter (fun _ f ->
  905. try
  906. type_eq EqStrict (field_type f) t
  907. with Unify_error l ->
  908. error (invalid_field f.cf_name :: l)
  909. ) an.a_fields
  910. with Unify_error l ->
  911. error (cannot_unify a b :: l))
  912. | _ ->
  913. error [cannot_unify a b])
  914. | _ , _ ->
  915. error [cannot_unify a b]
  916. and unify_types a b tl1 tl2 =
  917. List.iter2 (fun t1 t2 ->
  918. try
  919. type_eq EqRightDynamic t1 t2
  920. with Unify_error l ->
  921. let err = cannot_unify a b in
  922. error (try unify t1 t2; (err :: (Invariant_parameter (t1,t2)) :: l) with _ -> err :: l)
  923. ) tl1 tl2
  924. and unify_with_access t1 f2 =
  925. match f2.cf_kind with
  926. (* write only *)
  927. | Var { v_read = AccNo } | Var { v_read = AccNever } -> unify f2.cf_type t1
  928. (* read only *)
  929. | Method MethNormal | Method MethInline | Var { v_write = AccNo } | Var { v_write = AccNever } -> unify t1 f2.cf_type
  930. (* read/write *)
  931. | _ -> type_eq EqBothDynamic t1 f2.cf_type
  932. let iter f e =
  933. match e.eexpr with
  934. | TConst _
  935. | TLocal _
  936. | TEnumField _
  937. | TBreak
  938. | TContinue
  939. | TTypeExpr _ ->
  940. ()
  941. | TArray (e1,e2)
  942. | TBinop (_,e1,e2)
  943. | TFor (_,e1,e2)
  944. | TWhile (e1,e2,_) ->
  945. f e1;
  946. f e2;
  947. | TThrow e
  948. | TField (e,_)
  949. | TClosure (e,_)
  950. | TParenthesis e
  951. | TCast (e,_)
  952. | TUnop (_,_,e) ->
  953. f e
  954. | TArrayDecl el
  955. | TNew (_,_,el)
  956. | TBlock el ->
  957. List.iter f el
  958. | TObjectDecl fl ->
  959. List.iter (fun (_,e) -> f e) fl
  960. | TCall (e,el) ->
  961. f e;
  962. List.iter f el
  963. | TVars vl ->
  964. List.iter (fun (_,e) -> match e with None -> () | Some e -> f e) vl
  965. | TFunction fu ->
  966. f fu.tf_expr
  967. | TIf (e,e1,e2) ->
  968. f e;
  969. f e1;
  970. (match e2 with None -> () | Some e -> f e)
  971. | TSwitch (e,cases,def) ->
  972. f e;
  973. List.iter (fun (el,e2) -> List.iter f el; f e2) cases;
  974. (match def with None -> () | Some e -> f e)
  975. | TMatch (e,_,cases,def) ->
  976. f e;
  977. List.iter (fun (_,_,e) -> f e) cases;
  978. (match def with None -> () | Some e -> f e)
  979. | TTry (e,catches) ->
  980. f e;
  981. List.iter (fun (_,e) -> f e) catches
  982. | TReturn eo ->
  983. (match eo with None -> () | Some e -> f e)
  984. let map_expr f e =
  985. match e.eexpr with
  986. | TConst _
  987. | TLocal _
  988. | TEnumField _
  989. | TBreak
  990. | TContinue
  991. | TTypeExpr _ ->
  992. e
  993. | TArray (e1,e2) ->
  994. { e with eexpr = TArray (f e1,f e2) }
  995. | TBinop (op,e1,e2) ->
  996. { e with eexpr = TBinop (op,f e1,f e2) }
  997. | TFor (v,e1,e2) ->
  998. { e with eexpr = TFor (v,f e1,f e2) }
  999. | TWhile (e1,e2,flag) ->
  1000. { e with eexpr = TWhile (f e1,f e2,flag) }
  1001. | TThrow e1 ->
  1002. { e with eexpr = TThrow (f e1) }
  1003. | TField (e1,v) ->
  1004. { e with eexpr = TField (f e1,v) }
  1005. | TClosure (e1,v) ->
  1006. { e with eexpr = TClosure (f e1,v) }
  1007. | TParenthesis e1 ->
  1008. { e with eexpr = TParenthesis (f e1) }
  1009. | TUnop (op,pre,e1) ->
  1010. { e with eexpr = TUnop (op,pre,f e1) }
  1011. | TArrayDecl el ->
  1012. { e with eexpr = TArrayDecl (List.map f el) }
  1013. | TNew (t,pl,el) ->
  1014. { e with eexpr = TNew (t,pl,List.map f el) }
  1015. | TBlock el ->
  1016. { e with eexpr = TBlock (List.map f el) }
  1017. | TObjectDecl el ->
  1018. { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) }
  1019. | TCall (e1,el) ->
  1020. { e with eexpr = TCall (f e1, List.map f el) }
  1021. | TVars vl ->
  1022. { e with eexpr = TVars (List.map (fun (v,e) -> v , match e with None -> None | Some e -> Some (f e)) vl) }
  1023. | TFunction fu ->
  1024. { e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } }
  1025. | TIf (ec,e1,e2) ->
  1026. { e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)) }
  1027. | TSwitch (e1,cases,def) ->
  1028. { 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)) }
  1029. | TMatch (e1,t,cases,def) ->
  1030. { 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)) }
  1031. | TTry (e1,catches) ->
  1032. { e with eexpr = TTry (f e1, List.map (fun (v,e) -> v, f e) catches) }
  1033. | TReturn eo ->
  1034. { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) }
  1035. | TCast (e1,t) ->
  1036. { e with eexpr = TCast (f e1,t) }
  1037. let map_expr_type f ft fv e =
  1038. match e.eexpr with
  1039. | TConst _
  1040. | TEnumField _
  1041. | TBreak
  1042. | TContinue
  1043. | TTypeExpr _ ->
  1044. { e with etype = ft e.etype }
  1045. | TLocal v ->
  1046. { e with eexpr = TLocal (fv v); etype = ft e.etype }
  1047. | TArray (e1,e2) ->
  1048. { e with eexpr = TArray (f e1,f e2); etype = ft e.etype }
  1049. | TBinop (op,e1,e2) ->
  1050. { e with eexpr = TBinop (op,f e1,f e2); etype = ft e.etype }
  1051. | TFor (v,e1,e2) ->
  1052. { e with eexpr = TFor (fv v,f e1,f e2); etype = ft e.etype }
  1053. | TWhile (e1,e2,flag) ->
  1054. { e with eexpr = TWhile (f e1,f e2,flag); etype = ft e.etype }
  1055. | TThrow e1 ->
  1056. { e with eexpr = TThrow (f e1); etype = ft e.etype }
  1057. | TField (e1,v) ->
  1058. { e with eexpr = TField (f e1,v); etype = ft e.etype }
  1059. | TClosure (e1,v) ->
  1060. { e with eexpr = TClosure (f e1,v); etype = ft e.etype }
  1061. | TParenthesis e1 ->
  1062. { e with eexpr = TParenthesis (f e1); etype = ft e.etype }
  1063. | TUnop (op,pre,e1) ->
  1064. { e with eexpr = TUnop (op,pre,f e1); etype = ft e.etype }
  1065. | TArrayDecl el ->
  1066. { e with eexpr = TArrayDecl (List.map f el); etype = ft e.etype }
  1067. | TNew (_,_,el) ->
  1068. let et = ft e.etype in
  1069. (* make sure that we use the class corresponding to the replaced type *)
  1070. let c, pl = (match follow et with TInst (c,pl) -> (c,pl) | _ -> assert false) in
  1071. { e with eexpr = TNew (c,pl,List.map f el); etype = et }
  1072. | TBlock el ->
  1073. { e with eexpr = TBlock (List.map f el); etype = ft e.etype }
  1074. | TObjectDecl el ->
  1075. { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el); etype = ft e.etype }
  1076. | TCall (e1,el) ->
  1077. { e with eexpr = TCall (f e1, List.map f el); etype = ft e.etype }
  1078. | TVars vl ->
  1079. { 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 }
  1080. | TFunction fu ->
  1081. let fu = {
  1082. tf_expr = f fu.tf_expr;
  1083. tf_args = List.map (fun (v,o) -> fv v, o) fu.tf_args;
  1084. tf_type = ft fu.tf_type;
  1085. } in
  1086. { e with eexpr = TFunction fu; etype = ft e.etype }
  1087. | TIf (ec,e1,e2) ->
  1088. { e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1089. | TSwitch (e1,cases,def) ->
  1090. { 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 }
  1091. | TMatch (e1,(en,pl),cases,def) ->
  1092. let map_case (cl,params,e) =
  1093. let params = match params with
  1094. | None -> None
  1095. | Some l -> Some (List.map (function None -> None | Some v -> Some (fv v)) l)
  1096. in
  1097. cl, params, f e
  1098. in
  1099. { 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 }
  1100. | TTry (e1,catches) ->
  1101. { e with eexpr = TTry (f e1, List.map (fun (v,e) -> fv v, f e) catches); etype = ft e.etype }
  1102. | TReturn eo ->
  1103. { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype }
  1104. | TCast (e1,t) ->
  1105. { e with eexpr = TCast (f e1,t); etype = ft e.etype }
  1106. let s_expr_kind e =
  1107. match e.eexpr with
  1108. | TConst _ -> "Const"
  1109. | TLocal _ -> "Local"
  1110. | TEnumField _ -> "EnumField"
  1111. | TArray (_,_) -> "Array"
  1112. | TBinop (_,_,_) -> "Binop"
  1113. | TField (_,_) -> "Field"
  1114. | TClosure _ -> "Closure"
  1115. | TTypeExpr _ -> "TypeExpr"
  1116. | TParenthesis _ -> "Parenthesis"
  1117. | TObjectDecl _ -> "ObjectDecl"
  1118. | TArrayDecl _ -> "ArrayDecl"
  1119. | TCall (_,_) -> "Call"
  1120. | TNew (_,_,_) -> "New"
  1121. | TUnop (_,_,_) -> "Unop"
  1122. | TFunction _ -> "Function"
  1123. | TVars _ -> "Vars"
  1124. | TBlock _ -> "Block"
  1125. | TFor (_,_,_) -> "For"
  1126. | TIf (_,_,_) -> "If"
  1127. | TWhile (_,_,_) -> "While"
  1128. | TSwitch (_,_,_) -> "Switch"
  1129. | TMatch (_,_,_,_) -> "Match"
  1130. | TTry (_,_) -> "Try"
  1131. | TReturn _ -> "Return"
  1132. | TBreak -> "Break"
  1133. | TContinue -> "Continue"
  1134. | TThrow _ -> "Throw"
  1135. | TCast _ -> "Cast"
  1136. let rec s_expr s_type e =
  1137. let sprintf = Printf.sprintf in
  1138. let slist f l = String.concat "," (List.map f l) in
  1139. let loop = s_expr s_type in
  1140. let s_const = function
  1141. | TInt i -> Int32.to_string i
  1142. | TFloat s -> s ^ "f"
  1143. | TString s -> sprintf "\"%s\"" (Ast.s_escape s)
  1144. | TBool b -> if b then "true" else "false"
  1145. | TNull -> "null"
  1146. | TThis -> "this"
  1147. | TSuper -> "super"
  1148. in
  1149. let s_var v = v.v_name ^ ":" ^ string_of_int v.v_id in
  1150. let str = (match e.eexpr with
  1151. | TConst c ->
  1152. "Const " ^ s_const c
  1153. | TLocal v ->
  1154. "Local " ^ s_var v
  1155. | TEnumField (e,f) ->
  1156. sprintf "EnumField %s.%s" (s_type_path e.e_path) f
  1157. | TArray (e1,e2) ->
  1158. sprintf "%s[%s]" (loop e1) (loop e2)
  1159. | TBinop (op,e1,e2) ->
  1160. sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
  1161. | TField (e,f) ->
  1162. sprintf "%s.%s" (loop e) f
  1163. | TClosure (e,s) ->
  1164. sprintf "Closure (%s,%s)" (loop e) s
  1165. | TTypeExpr m ->
  1166. sprintf "TypeExpr %s" (s_type_path (t_path m))
  1167. | TParenthesis e ->
  1168. sprintf "Parenthesis %s" (loop e)
  1169. | TObjectDecl fl ->
  1170. sprintf "ObjectDecl {%s)" (slist (fun (f,e) -> sprintf "%s : %s" f (loop e)) fl)
  1171. | TArrayDecl el ->
  1172. sprintf "ArrayDecl [%s]" (slist loop el)
  1173. | TCall (e,el) ->
  1174. sprintf "Call %s(%s)" (loop e) (slist loop el)
  1175. | TNew (c,pl,el) ->
  1176. sprintf "New %s%s(%s)" (s_type_path c.cl_path) (match pl with [] -> "" | l -> sprintf "<%s>" (slist s_type l)) (slist loop el)
  1177. | TUnop (op,f,e) ->
  1178. (match f with
  1179. | Prefix -> sprintf "(%s %s)" (s_unop op) (loop e)
  1180. | Postfix -> sprintf "(%s %s)" (loop e) (s_unop op))
  1181. | TFunction f ->
  1182. 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
  1183. sprintf "Function(%s) : %s = %s" args (s_type f.tf_type) (loop f.tf_expr)
  1184. | TVars vl ->
  1185. 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)
  1186. | TBlock el ->
  1187. sprintf "Block {\n%s}" (String.concat "" (List.map (fun e -> sprintf "%s;\n" (loop e)) el))
  1188. | TFor (v,econd,e) ->
  1189. sprintf "For (%s : %s in %s,%s)" (s_var v) (s_type v.v_type) (loop econd) (loop e)
  1190. | TIf (e,e1,e2) ->
  1191. sprintf "If (%s,%s%s)" (loop e) (loop e1) (match e2 with None -> "" | Some e -> "," ^ loop e)
  1192. | TWhile (econd,e,flag) ->
  1193. (match flag with
  1194. | NormalWhile -> sprintf "While (%s,%s)" (loop econd) (loop e)
  1195. | DoWhile -> sprintf "DoWhile (%s,%s)" (loop e) (loop econd))
  1196. | TSwitch (e,cases,def) ->
  1197. 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)
  1198. | TMatch (e,(en,tparams),cases,def) ->
  1199. let args vl = slist (function None -> "_" | Some v -> sprintf "%s : %s" (s_var v) (s_type v.v_type)) vl in
  1200. 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
  1201. sprintf "Match %s (%s,(%s)%s)" (s_type (TEnum (en,tparams))) (loop e) cases (match def with None -> "" | Some e -> "," ^ loop e)
  1202. | TTry (e,cl) ->
  1203. 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)
  1204. | TReturn None ->
  1205. "Return"
  1206. | TReturn (Some e) ->
  1207. sprintf "Return %s" (loop e)
  1208. | TBreak ->
  1209. "Break"
  1210. | TContinue ->
  1211. "Continue"
  1212. | TThrow e ->
  1213. "Throw " ^ (loop e)
  1214. | TCast (e,t) ->
  1215. sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e)
  1216. ) in
  1217. sprintf "(%s : %s)" str (s_type e.etype)