type.ml 53 KB

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