typeload.ml 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. (*
  2. * Haxe Compiler
  3. * Copyright (c)2005-2008 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 warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *)
  19. open Ast
  20. open Type
  21. open Common
  22. open Typecore
  23. let type_constant ctx c p =
  24. match c with
  25. | Int s ->
  26. (try
  27. mk (TConst (TInt (Int32.of_string s))) ctx.api.tint p
  28. with
  29. _ -> mk (TConst (TFloat s)) ctx.api.tfloat p)
  30. | Float f -> mk (TConst (TFloat f)) ctx.api.tfloat p
  31. | String s -> mk (TConst (TString s)) ctx.api.tstring p
  32. | Ident "true" -> mk (TConst (TBool true)) ctx.api.tbool p
  33. | Ident "false" -> mk (TConst (TBool false)) ctx.api.tbool p
  34. | Ident "null" -> mk (TConst TNull) (ctx.api.tnull (mk_mono())) p
  35. | _ -> assert false
  36. let type_function_param ctx t e opt p =
  37. match e with
  38. | None ->
  39. if opt then ctx.api.tnull t, Some (EConst (Ident "null"),p) else t, None
  40. | Some e ->
  41. t, Some e
  42. let exc_protect f =
  43. let rec r = ref (fun() ->
  44. try
  45. f r
  46. with
  47. | Error (Protect _,_) as e -> raise e
  48. | Error (m,p) -> raise (Error (Protect m,p))
  49. ) in
  50. r
  51. let type_static_var ctx t e p =
  52. ctx.in_static <- true;
  53. let e = type_expr ctx e true in
  54. unify ctx e.etype t p;
  55. (* specific case for UInt statics *)
  56. match t with
  57. | TType ({ t_path = ([],"UInt") },[]) -> { e with etype = t }
  58. | _ -> e
  59. (** since load_type is used in PASS2 , it cannot access the structure of a type **)
  60. let load_type_def ctx p tpath =
  61. let no_pack = fst tpath = [] in
  62. try
  63. List.find (fun t ->
  64. let tp = t_path t in
  65. tp = tpath || (no_pack && snd tp = snd tpath)
  66. ) ctx.local_types
  67. with
  68. Not_found ->
  69. let tpath, m = (try
  70. if not no_pack then raise Exit;
  71. (match fst ctx.current.mpath with
  72. | [] -> raise Exit
  73. | x :: _ ->
  74. (* this can occur due to haxe remoting : a module can be
  75. already defined in the "js" package and is not allowed
  76. to access the js classes *)
  77. try
  78. (match PMap.find x ctx.com.package_rules with
  79. | Forbidden -> raise Exit
  80. | _ -> ())
  81. with Not_found -> ());
  82. let tpath2 = fst ctx.current.mpath , snd tpath in
  83. tpath2, ctx.api.load_module tpath2 p
  84. with
  85. | Error (Module_not_found _,p2) when p == p2 -> tpath, ctx.api.load_module tpath p
  86. | Exit -> tpath, ctx.api.load_module tpath p
  87. ) in
  88. try
  89. List.find (fun t -> not (t_private t) && t_path t = tpath) m.mtypes
  90. with
  91. Not_found -> error ("Module " ^ s_type_path tpath ^ " does not define type " ^ snd tpath) p
  92. let rec load_normal_type ctx t p allow_no_params =
  93. try
  94. if t.tpackage <> [] then raise Not_found;
  95. let pt = List.assoc t.tname ctx.type_params in
  96. if t.tparams <> [] then error ("Class type parameter " ^ t.tname ^ " can't have parameters") p;
  97. pt
  98. with Not_found ->
  99. let types , path , f = ctx.api.build_instance (load_type_def ctx p (t.tpackage,t.tname)) p in
  100. if allow_no_params && t.tparams = [] then
  101. f (List.map (fun (name,t) ->
  102. match follow t with
  103. | TInst (c,_) -> if c.cl_implements = [] then mk_mono() else error ("Type parameter " ^ name ^ " need constraint") p
  104. | _ -> assert false
  105. ) types)
  106. else if path = ([],"Dynamic") then
  107. match t.tparams with
  108. | [] -> t_dynamic
  109. | [TPType t] -> TDynamic (load_type ctx p t)
  110. | _ -> error "Too many parameters for Dynamic" p
  111. else begin
  112. if List.length types <> List.length t.tparams then error ("Invalid number of type parameters for " ^ s_type_path path) p;
  113. let tparams = List.map (fun t ->
  114. match t with
  115. | TPConst c ->
  116. let name, const = (match c with
  117. | String s -> "S" ^ s, TString s
  118. | Int i -> "I" ^ i, TInt (Int32.of_string i)
  119. | Float f -> "F" ^ f, TFloat f
  120. | _ -> assert false
  121. ) in
  122. let c = mk_class ([],name) p None false in
  123. c.cl_kind <- KConstant const;
  124. TInst (c,[])
  125. | TPType t -> load_type ctx p t
  126. ) t.tparams in
  127. let params = List.map2 (fun t (name,t2) ->
  128. let isconst = (match t with TInst ({ cl_kind = KConstant _ },_) -> true | _ -> false) in
  129. if isconst <> (name = "Const") && t != t_dynamic then error (if isconst then "Constant value unexpected here" else "Constant value excepted as type parameter") p;
  130. match follow t2 with
  131. | TInst ({ cl_implements = [] }, []) ->
  132. t
  133. | TInst (c,[]) ->
  134. let r = exc_protect (fun r ->
  135. r := (fun() -> t);
  136. List.iter (fun (i,params) ->
  137. unify ctx t (apply_params types tparams (TInst (i,params))) p
  138. ) c.cl_implements;
  139. t
  140. ) in
  141. ctx.delays := [(fun () -> ignore(!r()))] :: !(ctx.delays);
  142. TLazy r
  143. | _ -> assert false
  144. ) tparams types in
  145. f params
  146. end
  147. and load_type ctx p t =
  148. match t with
  149. | TPParent t -> load_type ctx p t
  150. | TPNormal t -> load_normal_type ctx t p false
  151. | TPExtend (t,l) ->
  152. (match load_type ctx p (TPAnonymous l) with
  153. | TAnon a ->
  154. let rec loop t =
  155. match follow t with
  156. | TInst (c,tl) ->
  157. let c2 = mk_class (fst c.cl_path,"+" ^ snd c.cl_path) p None true in
  158. PMap.iter (fun f _ ->
  159. try
  160. ignore(class_field c f);
  161. error ("Cannot redefine field " ^ f) p
  162. with
  163. Not_found -> ()
  164. ) a.a_fields;
  165. (* do NOT tag as extern - for protect *)
  166. c2.cl_kind <- KExtension (c,tl);
  167. c2.cl_super <- Some (c,tl);
  168. c2.cl_fields <- a.a_fields;
  169. TInst (c2,[])
  170. | TMono _ ->
  171. error "Please ensure correct initialization of cascading signatures" p
  172. | TAnon a2 ->
  173. PMap.iter (fun f _ ->
  174. if PMap.mem f a2.a_fields then error ("Cannot redefine field " ^ f) p
  175. ) a.a_fields;
  176. mk_anon (PMap.foldi PMap.add a.a_fields a2.a_fields)
  177. | _ -> error "Cannot only extend classes and anonymous" p
  178. in
  179. loop (load_normal_type ctx t p false)
  180. | _ -> assert false)
  181. | TPAnonymous l ->
  182. let rec loop acc (n,pub,f,p) =
  183. if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p;
  184. let t , get, set = (match f with
  185. | AFVar t ->
  186. load_type ctx p t, NormalAccess, NormalAccess
  187. | AFFun (tl,t) ->
  188. let t = load_type ctx p t in
  189. let args = List.map (fun (name,o,t) -> name , o, load_type ctx p t) tl in
  190. TFun (args,t), NormalAccess, MethodAccess false
  191. | AFProp (t,i1,i2) ->
  192. let access m get =
  193. match m with
  194. | "null" -> NoAccess
  195. | "never" -> NeverAccess
  196. | "default" -> NormalAccess
  197. | "dynamic" -> CallAccess ((if get then "get_" else "set_") ^ n)
  198. | _ -> CallAccess m
  199. in
  200. load_type ctx p t, access i1 true, access i2 false
  201. ) in
  202. PMap.add n {
  203. cf_name = n;
  204. cf_type = t;
  205. cf_public = (match pub with None -> true | Some p -> p);
  206. cf_get = get;
  207. cf_set = set;
  208. cf_params = [];
  209. cf_expr = None;
  210. cf_doc = None;
  211. } acc
  212. in
  213. mk_anon (List.fold_left loop PMap.empty l)
  214. | TPFunction (args,r) ->
  215. match args with
  216. | [TPNormal { tpackage = []; tparams = []; tname = "Void" }] ->
  217. TFun ([],load_type ctx p r)
  218. | _ ->
  219. TFun (List.map (fun t -> "",false,load_type ctx p t) args,load_type ctx p r)
  220. let hide_types ctx =
  221. let old_locals = ctx.local_types in
  222. let old_type_params = ctx.type_params in
  223. ctx.local_types <- ctx.std.mtypes;
  224. ctx.type_params <- [];
  225. (fun() ->
  226. ctx.local_types <- old_locals;
  227. ctx.type_params <- old_type_params;
  228. )
  229. let load_core_type ctx name =
  230. let show = hide_types ctx in
  231. let t = load_normal_type ctx { tpackage = []; tname = name; tparams = [] } null_pos false in
  232. show();
  233. t
  234. let t_iterator ctx =
  235. let show = hide_types ctx in
  236. match load_type_def ctx null_pos ([],"Iterator") with
  237. | TTypeDecl t ->
  238. show();
  239. if List.length t.t_types <> 1 then assert false;
  240. let pt = mk_mono() in
  241. apply_params t.t_types [pt] t.t_type, pt
  242. | _ ->
  243. assert false
  244. let load_type_opt ?(opt=false) ctx p t =
  245. let t = (match t with None -> mk_mono() | Some t -> load_type ctx p t) in
  246. if opt then ctx.api.tnull t else t
  247. (* ---------------------------------------------------------------------- *)
  248. (* Structure check *)
  249. let valid_redefinition ctx f1 t1 f2 t2 =
  250. let valid t1 t2 =
  251. type_eq EqStrict t1 t2;
  252. if is_null t1 <> is_null t2 then raise (Unify_error [Cannot_unify (t1,t2)]);
  253. in
  254. let t1, t2 = (match f1.cf_params, f2.cf_params with
  255. | [], [] -> t1, t2
  256. | l1, l2 when List.length l1 = List.length l2 ->
  257. let monos = List.map (fun _ -> mk_mono()) l1 in
  258. apply_params l1 monos t1, apply_params l2 monos t2
  259. | _ -> t1, t2
  260. ) in
  261. match follow t1, follow t2 with
  262. | TFun (args1,r1) , TFun (args2,r2) when List.length args1 = List.length args2 ->
  263. List.iter2 (fun (n,o1,a1) (_,o2,a2) ->
  264. if o1 <> o2 then raise (Unify_error [Not_matching_optional n]);
  265. valid a1 a2;
  266. ) args1 args2;
  267. valid r1 r2;
  268. | _ , _ ->
  269. (* in case args differs, or if an interface var *)
  270. valid t1 t2
  271. let check_overriding ctx c p () =
  272. match c.cl_super with
  273. | None ->
  274. (match c.cl_overrides with
  275. | [] -> ()
  276. | i :: _ ->
  277. display_error ctx ("Field " ^ i ^ " is declared 'override' but doesn't override any field") p)
  278. | Some (csup,params) ->
  279. PMap.iter (fun i f ->
  280. try
  281. let t , f2 = raw_class_field (fun f -> f.cf_type) csup i in
  282. ignore(follow f.cf_type); (* force evaluation *)
  283. let p = (match f.cf_expr with None -> p | Some e -> e.epos) in
  284. if not (List.mem i c.cl_overrides) then
  285. display_error ctx ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass") p
  286. else if f.cf_public <> f2.cf_public then
  287. display_error ctx ("Field " ^ i ^ " has different visibility (public/private) than superclass one") p
  288. else if f2.cf_get = InlineAccess then
  289. display_error ctx ("Field " ^ i ^ " is inlined and cannot be overridden") p
  290. else if f2.cf_get <> f.cf_get || f2.cf_set <> f.cf_set then
  291. display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p
  292. else try
  293. let t = apply_params csup.cl_types params t in
  294. valid_redefinition ctx f f.cf_type f2 t
  295. with
  296. Unify_error l ->
  297. display_error ctx ("Field " ^ i ^ " overload parent class with different or incomplete type") p;
  298. display_error ctx (error_msg (Unify l)) p;
  299. with
  300. Not_found ->
  301. if List.mem i c.cl_overrides then display_error ctx ("Field " ^ i ^ " is declared 'override' but doesn't override any field") p
  302. ) c.cl_fields
  303. let class_field_no_interf c i =
  304. try
  305. let f = PMap.find i c.cl_fields in
  306. f.cf_type , f
  307. with Not_found ->
  308. match c.cl_super with
  309. | None ->
  310. raise Not_found
  311. | Some (c,tl) ->
  312. (* rec over class_field *)
  313. let t , f = raw_class_field (fun f -> f.cf_type) c i in
  314. apply_params c.cl_types tl t , f
  315. let rec check_interface ctx c p intf params =
  316. PMap.iter (fun i f ->
  317. try
  318. let t2, f2 = class_field_no_interf c i in
  319. ignore(follow f2.cf_type); (* force evaluation *)
  320. let p = (match f2.cf_expr with None -> p | Some e -> e.epos) in
  321. if f.cf_public && not f2.cf_public then
  322. display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
  323. else if f2.cf_get <> f.cf_get || (f2.cf_set <> f.cf_set && (f2.cf_set,f.cf_set) <> (NeverAccess,NoAccess)) then
  324. display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path) p
  325. else try
  326. valid_redefinition ctx f2 t2 f (apply_params intf.cl_types params f.cf_type)
  327. with
  328. Unify_error l ->
  329. display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
  330. display_error ctx (error_msg (Unify l)) p;
  331. with
  332. Not_found ->
  333. if not c.cl_interface then display_error ctx ("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing") p
  334. ) intf.cl_fields;
  335. List.iter (fun (i2,p2) ->
  336. check_interface ctx c p i2 (List.map (apply_params intf.cl_types params) p2)
  337. ) intf.cl_implements
  338. let check_interfaces ctx c p () =
  339. match c.cl_path with
  340. | "Proxy" :: _ , _ -> ()
  341. | _ ->
  342. List.iter (fun (intf,params) -> check_interface ctx c p intf params) c.cl_implements
  343. let rec return_flow ctx e =
  344. let error() = display_error ctx "A return is missing here" e.epos; raise Exit in
  345. let return_flow = return_flow ctx in
  346. match e.eexpr with
  347. | TReturn _ | TThrow _ -> ()
  348. | TParenthesis e ->
  349. return_flow e
  350. | TBlock el ->
  351. let rec loop = function
  352. | [] -> error()
  353. | [e] -> return_flow e
  354. | { eexpr = TReturn _ } :: _ | { eexpr = TThrow _ } :: _ -> ()
  355. | _ :: l -> loop l
  356. in
  357. loop el
  358. | TIf (_,e1,Some e2) ->
  359. return_flow e1;
  360. return_flow e2;
  361. | TSwitch (v,cases,Some e) ->
  362. List.iter (fun (_,e) -> return_flow e) cases;
  363. return_flow e
  364. | TSwitch (e,cases,None) when (match follow e.etype with TEnum _ -> true | _ -> false) ->
  365. List.iter (fun (_,e) -> return_flow e) cases;
  366. | TMatch (_,_,cases,def) ->
  367. List.iter (fun (_,_,e) -> return_flow e) cases;
  368. (match def with None -> () | Some e -> return_flow e)
  369. | TTry (e,cases) ->
  370. return_flow e;
  371. List.iter (fun (_,_,e) -> return_flow e) cases;
  372. | _ ->
  373. error()
  374. (* ---------------------------------------------------------------------- *)
  375. (* PASS 1 & 2 : Module and Class Structure *)
  376. let set_heritance ctx c herits p =
  377. let rec loop = function
  378. | HPrivate | HExtern | HInterface ->
  379. ()
  380. | HExtends t ->
  381. if c.cl_super <> None then error "Cannot extend several classes" p;
  382. let t = load_normal_type ctx t p false in
  383. (match follow t with
  384. | TInst ({ cl_path = [],"Array" },_)
  385. | TInst ({ cl_path = [],"String" },_)
  386. | TInst ({ cl_path = [],"Date" },_)
  387. | TInst ({ cl_path = [],"Xml" },_) when ((not (platform ctx.com Cpp)) && (match c.cl_path with "mt" :: _ , _ -> false | _ -> true)) ->
  388. error "Cannot extend basic class" p;
  389. | TInst (cl,params) ->
  390. if is_parent c cl then error "Recursive class" p;
  391. if c.cl_interface then error "Cannot extend an interface" p;
  392. if cl.cl_interface then error "Cannot extend by using an interface" p;
  393. c.cl_super <- Some (cl,params)
  394. | _ -> error "Should extend by using a class" p)
  395. | HImplements t ->
  396. let t = load_normal_type ctx t p false in
  397. (match follow t with
  398. | TInst ({ cl_path = [],"ArrayAccess"; cl_extern = true; },[t]) ->
  399. if c.cl_array_access <> None then error "Duplicate array access" p;
  400. c.cl_array_access <- Some t
  401. | TInst (cl,params) ->
  402. if is_parent c cl then error "Recursive class" p;
  403. c.cl_implements <- (cl, params) :: c.cl_implements
  404. | TDynamic t ->
  405. if c.cl_dynamic <> None then error "Cannot have several dynamics" p;
  406. c.cl_dynamic <- Some t
  407. | _ -> error "Should implement by using an interface or a class" p)
  408. in
  409. (*
  410. resolve imports before calling build_inheritance, since it requires full paths.
  411. that means that typedefs are not working, but that's a fair limitation
  412. *)
  413. let rec resolve_imports t =
  414. match t.tpackage with
  415. | _ :: _ -> t
  416. | [] ->
  417. try
  418. let lt = List.find (fun lt -> snd (t_path lt) = t.tname) ctx.local_types in
  419. { t with tpackage = fst (t_path lt) }
  420. with
  421. Not_found -> t
  422. in
  423. let herits = List.map (function
  424. | HExtends t -> HExtends (resolve_imports t)
  425. | HImplements t -> HImplements (resolve_imports t)
  426. | h -> h
  427. ) herits in
  428. List.iter loop (List.filter ((!build_inheritance) ctx c p) herits)
  429. let type_type_params ctx path p (n,flags) =
  430. let c = mk_class (fst path @ [snd path],n) p None false in
  431. c.cl_kind <- KTypeParameter;
  432. let t = TInst (c,[]) in
  433. match flags with
  434. | [] -> n, t
  435. | _ ->
  436. let r = exc_protect (fun r ->
  437. r := (fun _ -> t);
  438. set_heritance ctx c (List.map (fun t -> HImplements t) flags) p;
  439. t
  440. ) in
  441. ctx.delays := [(fun () -> ignore(!r()))] :: !(ctx.delays);
  442. n, TLazy r
  443. let type_function ctx args ret static constr f p =
  444. let locals = save_locals ctx in
  445. let fargs = List.map (fun (n,c,t) ->
  446. let c = (match c with
  447. | None -> None
  448. | Some e ->
  449. let p = pos e in
  450. let e = ctx.api.optimize (type_expr ctx e true) in
  451. unify ctx e.etype t p;
  452. match e.eexpr with
  453. | TConst c -> Some c
  454. | _ -> error "Parameter default value should be constant" p
  455. ) in
  456. let n = add_local ctx n t in
  457. n, c, t
  458. ) args in
  459. let old_ret = ctx.ret in
  460. let old_static = ctx.in_static in
  461. let old_constr = ctx.in_constructor in
  462. let old_opened = ctx.opened in
  463. ctx.in_static <- static;
  464. ctx.in_constructor <- constr;
  465. ctx.ret <- ret;
  466. ctx.opened <- [];
  467. let e = type_expr ctx f.f_expr false in
  468. let rec loop e =
  469. match e.eexpr with
  470. | TReturn (Some _) -> raise Exit
  471. | TFunction _ -> ()
  472. | _ -> Type.iter loop e
  473. in
  474. let have_ret = (try loop e; false with Exit -> true) in
  475. if have_ret then
  476. (try return_flow ctx e with Exit -> ())
  477. else
  478. unify ctx ret ctx.api.tvoid p;
  479. let rec loop e =
  480. match e.eexpr with
  481. | TCall ({ eexpr = TConst TSuper },_) -> raise Exit
  482. | TFunction _ -> ()
  483. | _ -> Type.iter loop e
  484. in
  485. if constr && (match ctx.curclass.cl_super with None -> false | Some (cl,_) -> cl.cl_constructor <> None) then
  486. (try
  487. loop e;
  488. error "Missing super constructor call" p
  489. with
  490. Exit -> ());
  491. locals();
  492. List.iter (fun r -> r := Closed) ctx.opened;
  493. ctx.ret <- old_ret;
  494. ctx.in_static <- old_static;
  495. ctx.in_constructor <- old_constr;
  496. ctx.opened <- old_opened;
  497. e , fargs
  498. let init_class ctx c p herits fields =
  499. ctx.type_params <- c.cl_types;
  500. c.cl_extern <- List.mem HExtern herits;
  501. c.cl_interface <- List.mem HInterface herits;
  502. set_heritance ctx c herits p;
  503. let tthis = TInst (c,List.map snd c.cl_types) in
  504. let rec extends_public c =
  505. List.exists (fun (c,_) -> c.cl_path = (["haxe"],"Public") || extends_public c) c.cl_implements ||
  506. match c.cl_super with
  507. | None -> false
  508. | Some (c,_) -> extends_public c
  509. in
  510. let extends_public = extends_public c in
  511. let is_public access parent =
  512. if List.mem APrivate access then
  513. false
  514. else if List.mem APublic access then
  515. true
  516. else match parent with
  517. | Some { cf_public = p } -> p
  518. | _ -> c.cl_extern || c.cl_interface || extends_public
  519. in
  520. let rec get_parent c name =
  521. match c.cl_super with
  522. | None -> None
  523. | Some (csup,_) ->
  524. try
  525. Some (PMap.find name csup.cl_fields)
  526. with
  527. Not_found -> get_parent csup name
  528. in
  529. let type_opt ctx p t =
  530. match t with
  531. | None when c.cl_extern || c.cl_interface ->
  532. display_error ctx "Type required for extern classes and interfaces" p;
  533. t_dynamic
  534. | _ ->
  535. load_type_opt ctx p t
  536. in
  537. let rec has_field f = function
  538. | None -> false
  539. | Some (c,_) ->
  540. PMap.exists f c.cl_fields || has_field f c.cl_super || List.exists (fun i -> has_field f (Some i)) c.cl_implements
  541. in
  542. let loop_cf f p =
  543. match f with
  544. | FVar (name,doc,access,t,e) ->
  545. let stat = List.mem AStatic access in
  546. let inline = List.mem AInline access in
  547. if not stat && has_field name c.cl_super then error ("Redefinition of variable " ^ name ^ " in subclass is not allowed") p;
  548. if inline && not stat then error "Inline variable must be static" p;
  549. if inline && e = None then error "Inline variable must be initialized" p;
  550. let t = (match t with
  551. | None ->
  552. if not stat then display_error ctx ("Type required for member variable " ^ name) p;
  553. mk_mono()
  554. | Some t ->
  555. let old = ctx.type_params in
  556. if stat then ctx.type_params <- [];
  557. let t = load_type ctx p t in
  558. if stat then ctx.type_params <- old;
  559. t
  560. ) in
  561. let cf = {
  562. cf_name = name;
  563. cf_doc = doc;
  564. cf_type = t;
  565. cf_get = if inline then InlineAccess else NormalAccess;
  566. cf_set = if inline then NeverAccess else NormalAccess;
  567. cf_expr = None;
  568. cf_public = is_public access None;
  569. cf_params = [];
  570. } in
  571. let delay = (match e with
  572. | None -> (fun() -> ())
  573. | Some e ->
  574. let ctx = { ctx with curclass = c; tthis = tthis } in
  575. let r = exc_protect (fun r ->
  576. r := (fun() -> t);
  577. if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
  578. cf.cf_expr <- Some (type_static_var ctx t e p);
  579. t
  580. ) in
  581. cf.cf_type <- TLazy r;
  582. (fun () -> ignore(!r()))
  583. ) in
  584. access, false, cf, delay
  585. | FFun (name,doc,access,params,f) ->
  586. let params = List.map (fun (n,flags) ->
  587. match flags with
  588. | [] ->
  589. type_type_params ctx ([],name) p (n,[])
  590. | _ -> error "This notation is not allowed because it can't be checked" p
  591. ) params in
  592. let stat = List.mem AStatic access in
  593. let inline = List.mem AInline access in
  594. let parent = (if not stat then get_parent c name else None) in
  595. let dynamic = List.mem ADynamic access || (match parent with Some { cf_set = MethodAccess true } -> true | _ -> false) in
  596. let ctx = { ctx with
  597. curclass = c;
  598. curmethod = name;
  599. tthis = tthis;
  600. type_params = if stat then params else params @ ctx.type_params;
  601. } in
  602. let ret = type_opt ctx p f.f_type in
  603. let args = List.map (fun (name,opt,t,c) ->
  604. let t, c = type_function_param ctx (type_opt ctx p t) c opt p in
  605. name, c, t
  606. ) f.f_args in
  607. let t = TFun (fun_args args,ret) in
  608. let constr = (name = "new") in
  609. if constr && c.cl_interface then error "An interface cannot have a constructor" p;
  610. if c.cl_interface && not stat && (match f.f_expr with EBlock [] , _ -> false | _ -> true) then error "An interface method cannot have a body" p;
  611. if constr then (match f.f_type with
  612. | None | Some (TPNormal { tpackage = []; tname = "Void" }) -> ()
  613. | _ -> error "A class constructor can't have a return value" p
  614. );
  615. let cf = {
  616. cf_name = name;
  617. cf_doc = doc;
  618. cf_type = t;
  619. cf_get = if inline then InlineAccess else NormalAccess;
  620. cf_set = (if inline then NeverAccess else MethodAccess dynamic);
  621. cf_expr = None;
  622. cf_public = is_public access parent;
  623. cf_params = params;
  624. } in
  625. let r = exc_protect (fun r ->
  626. r := (fun() -> t);
  627. if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
  628. let e , fargs = type_function ctx args ret stat constr f p in
  629. let f = {
  630. tf_args = fargs;
  631. tf_type = ret;
  632. tf_expr = e;
  633. } in
  634. if stat && name = "__init__" then c.cl_init <- Some e;
  635. cf.cf_expr <- Some (mk (TFunction f) t p);
  636. t
  637. ) in
  638. let delay = (
  639. if (c.cl_extern || c.cl_interface) && cf.cf_name <> "__init__" then
  640. (fun() -> ())
  641. else begin
  642. cf.cf_type <- TLazy r;
  643. (fun() -> ignore((!r)()))
  644. end
  645. ) in
  646. access, constr, cf, delay
  647. | FProp (name,doc,access,get,set,t) ->
  648. let ret = load_type ctx p t in
  649. let check_get = ref (fun() -> ()) in
  650. let check_set = ref (fun() -> ()) in
  651. let check_method m t () =
  652. try
  653. let t2 = (if List.mem AStatic access then (PMap.find m c.cl_statics).cf_type else fst (class_field c m)) in
  654. unify_raise ctx t2 t p;
  655. with
  656. | Error (Unify l,_) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ name),Unify l),p))
  657. | Not_found -> if not c.cl_interface then error ("Method " ^ m ^ " required by property " ^ name ^ " is missing") p
  658. in
  659. let get = (match get with
  660. | "null" -> NoAccess
  661. | "dynamic" -> CallAccess ("get_" ^ name)
  662. | "never" -> NeverAccess
  663. | "default" -> NormalAccess
  664. | _ ->
  665. check_get := check_method get (TFun ([],ret));
  666. CallAccess get
  667. ) in
  668. let set = (match set with
  669. | "null" ->
  670. (* standard flash library read-only variables can't be accessed for writing, even in subclasses *)
  671. if c.cl_extern && (match c.cl_path with "flash" :: _ , _ -> true | _ -> false) && Common.defined ctx.com "flash9" then
  672. NeverAccess
  673. else
  674. NoAccess
  675. | "never" -> NeverAccess
  676. | "dynamic" -> CallAccess ("set_" ^ name)
  677. | "default" -> NormalAccess
  678. | _ ->
  679. check_set := check_method set (TFun (["",false,ret],ret));
  680. CallAccess set
  681. ) in
  682. if set = NormalAccess && (match get with CallAccess _ -> true | _ -> false) then error "Unsupported property combination" p;
  683. let cf = {
  684. cf_name = name;
  685. cf_doc = doc;
  686. cf_get = get;
  687. cf_set = set;
  688. cf_expr = None;
  689. cf_type = ret;
  690. cf_public = is_public access None;
  691. cf_params = [];
  692. } in
  693. access, false, cf, (fun() -> (!check_get)(); (!check_set)())
  694. in
  695. let fl = List.map (fun (f,p) ->
  696. let access , constr, f , delayed = loop_cf f p in
  697. let is_static = List.mem AStatic access in
  698. if is_static && f.cf_name = "name" && Common.defined ctx.com "js" then error "This identifier cannot be used in Javascript for statics" p;
  699. if (is_static || constr) && c.cl_interface && f.cf_name <> "__init__" then error "You can't declare static fields in interfaces" p;
  700. if constr then begin
  701. if c.cl_constructor <> None then error "Duplicate constructor" p;
  702. c.cl_constructor <- Some f;
  703. end else if not is_static || f.cf_name <> "__init__" then begin
  704. if PMap.mem f.cf_name (if is_static then c.cl_statics else c.cl_fields) then error ("Duplicate class field declaration : " ^ f.cf_name) p;
  705. if PMap.exists f.cf_name (if is_static then c.cl_fields else c.cl_statics) then error ("Same field name can't be use for both static and instance : " ^ f.cf_name) p;
  706. if is_static then begin
  707. c.cl_statics <- PMap.add f.cf_name f c.cl_statics;
  708. c.cl_ordered_statics <- f :: c.cl_ordered_statics;
  709. end else begin
  710. c.cl_fields <- PMap.add f.cf_name f c.cl_fields;
  711. c.cl_ordered_fields <- f :: c.cl_ordered_fields;
  712. if List.mem AOverride access then c.cl_overrides <- f.cf_name :: c.cl_overrides;
  713. end;
  714. end;
  715. delayed
  716. ) fields in
  717. c.cl_ordered_statics <- List.rev c.cl_ordered_statics;
  718. c.cl_ordered_fields <- List.rev c.cl_ordered_fields;
  719. (*
  720. define a default inherited constructor.
  721. This is actually pretty tricky since we can't assume that the constructor of the
  722. superclass has been defined yet because type structure is not stabilized wrt recursion.
  723. *)
  724. let rec define_constructor ctx c =
  725. try
  726. Some (Hashtbl.find ctx.constructs c.cl_path)
  727. with Not_found ->
  728. match c.cl_super with
  729. | None -> None
  730. | Some (csuper,_) ->
  731. match define_constructor ctx csuper with
  732. | None -> None
  733. | Some (acc,pl,f) as infos ->
  734. let p = c.cl_pos in
  735. let esuper = (ECall ((EConst (Ident "super"),p),List.map (fun (n,_,_,_) -> (EConst (Ident n),p)) f.f_args),p) in
  736. let acc = (if csuper.cl_extern && acc = [] then [APublic] else acc) in
  737. let fnew = { f with f_expr = esuper; f_args = List.map (fun (a,opt,t,def) ->
  738. (*
  739. we are removing the type and letting the type inference
  740. work because the current package is not the same as the superclass one
  741. or there might be private and/or imported types
  742. if we are an extern class then we need a type
  743. if the type is Dynamic also because it would not propagate
  744. if we have a package declaration, we are sure it's fully qualified
  745. *)
  746. let rec is_qualified = function
  747. | TPNormal t -> is_qual_name t
  748. | TPParent t -> is_qualified t
  749. | TPFunction (tl,t) -> List.for_all is_qualified tl && is_qualified t
  750. | TPAnonymous fl -> List.for_all (fun (_,_,f,_) -> is_qual_field f) fl
  751. | TPExtend (t,fl) -> is_qual_name t && List.for_all (fun (_,_,f,_) -> is_qual_field f) fl
  752. and is_qual_field = function
  753. | AFVar t -> is_qualified t
  754. | AFProp (t,_,_) -> is_qualified t
  755. | AFFun (pl,t) -> List.for_all (fun (_,_,t) -> is_qualified t) pl && is_qualified t
  756. and is_qual_name t =
  757. match t.tpackage with
  758. | [] -> t.tname = "Dynamic" && List.for_all is_qual_param t.tparams
  759. | _ :: _ -> true
  760. and is_qual_param = function
  761. | TPType t -> is_qualified t
  762. | TPConst _ -> false (* prevent multiple incompatible types *)
  763. in
  764. let t = (match t with
  765. | Some t when is_qualified t -> Some t
  766. | _ -> None
  767. ) in
  768. a,opt,t,def
  769. ) f.f_args } in
  770. let _, _, cf, delayed = loop_cf (FFun ("new",None,acc,pl,fnew)) p in
  771. c.cl_constructor <- Some cf;
  772. Hashtbl.add ctx.constructs c.cl_path (acc,pl,f);
  773. ctx.delays := [delayed] :: !(ctx.delays);
  774. infos
  775. in
  776. (*
  777. extern classes will browse superclass to find a constructor
  778. *)
  779. if not c.cl_extern then ignore(define_constructor ctx c);
  780. fl
  781. let type_module ctx m tdecls loadp =
  782. (* PASS 1 : build module structure - does not load any module or type - should be atomic ! *)
  783. let decls = ref [] in
  784. let decl_with_name name p priv =
  785. let tpath = if priv then (fst m @ ["_" ^ snd m], name) else (fst m, name) in
  786. if priv then begin
  787. if List.exists (fun t -> tpath = t_path t) (!decls) then error ("Type name " ^ name ^ " is alreday defined in this module") p;
  788. tpath
  789. end else try
  790. let m2 = Hashtbl.find ctx.types_module tpath in
  791. if m <> m2 && String.lowercase (s_type_path m2) = String.lowercase (s_type_path m) then error ("Module " ^ s_type_path m2 ^ " is loaded with a different case than " ^ s_type_path m) loadp;
  792. error ("Type name " ^ s_type_path tpath ^ " is redefined from module " ^ s_type_path m2) p
  793. with
  794. Not_found ->
  795. Hashtbl.add ctx.types_module (fst m,name) m;
  796. tpath
  797. in
  798. List.iter (fun (d,p) ->
  799. match d with
  800. | EImport _ | EUsing _ -> ()
  801. | EClass d ->
  802. let priv = List.mem HPrivate d.d_flags in
  803. let path = decl_with_name d.d_name p priv in
  804. let c = mk_class path p d.d_doc priv in
  805. (* store the constructor for later usage *)
  806. List.iter (fun (cf,_) ->
  807. match cf with
  808. | FFun ("new",_,acc,pl,f) -> Hashtbl.add ctx.constructs path (acc,pl,f)
  809. | _ -> ()
  810. ) d.d_data;
  811. decls := TClassDecl c :: !decls
  812. | EEnum d ->
  813. let priv = List.mem EPrivate d.d_flags in
  814. let path = decl_with_name d.d_name p priv in
  815. let e = {
  816. e_path = path;
  817. e_pos = p;
  818. e_doc = d.d_doc;
  819. e_types = [];
  820. e_private = priv;
  821. e_extern = List.mem EExtern d.d_flags || d.d_data = [];
  822. e_constrs = PMap.empty;
  823. e_names = [];
  824. } in
  825. decls := TEnumDecl e :: !decls
  826. | ETypedef d ->
  827. let priv = List.mem EPrivate d.d_flags in
  828. let path = decl_with_name d.d_name p priv in
  829. let t = {
  830. t_path = path;
  831. t_pos = p;
  832. t_doc = d.d_doc;
  833. t_private = priv;
  834. t_types = [];
  835. t_type = mk_mono();
  836. } in
  837. decls := TTypeDecl t :: !decls
  838. ) tdecls;
  839. let m = {
  840. mpath = m;
  841. mtypes = List.rev !decls;
  842. mimports = [];
  843. } in
  844. Hashtbl.add ctx.modules m.mpath m;
  845. (* PASS 2 : build types structure - does not type any expression ! *)
  846. let ctx = {
  847. com = ctx.com;
  848. api = ctx.api;
  849. modules = ctx.modules;
  850. delays = ctx.delays;
  851. constructs = ctx.constructs;
  852. types_module = ctx.types_module;
  853. curclass = ctx.curclass;
  854. tthis = ctx.tthis;
  855. std = ctx.std;
  856. ret = ctx.ret;
  857. doinline = ctx.doinline;
  858. current = m;
  859. locals = PMap.empty;
  860. locals_map = PMap.empty;
  861. locals_map_inv = PMap.empty;
  862. local_types = ctx.std.mtypes @ m.mtypes;
  863. local_using = [];
  864. type_params = [];
  865. curmethod = "";
  866. super_call = false;
  867. in_constructor = false;
  868. in_static = false;
  869. in_display = false;
  870. in_loop = false;
  871. untyped = false;
  872. opened = [];
  873. param_type = None;
  874. } in
  875. let delays = ref [] in
  876. let get_class name =
  877. let c = List.find (fun d -> match d with TClassDecl { cl_path = _ , n } -> n = name | _ -> false) m.mtypes in
  878. match c with TClassDecl c -> c | _ -> assert false
  879. in
  880. let get_enum name =
  881. let e = List.find (fun d -> match d with TEnumDecl { e_path = _ , n } -> n = name | _ -> false) m.mtypes in
  882. match e with TEnumDecl e -> e | _ -> assert false
  883. in
  884. let get_tdef name =
  885. let s = List.find (fun d -> match d with TTypeDecl { t_path = _ , n } -> n = name | _ -> false) m.mtypes in
  886. match s with TTypeDecl s -> s | _ -> assert false
  887. in
  888. (* here is an additional PASS 1 phase, which handle the type parameters declaration, with lazy contraints *)
  889. List.iter (fun (d,p) ->
  890. match d with
  891. | EImport _ | EUsing _ -> ()
  892. | EClass d ->
  893. let c = get_class d.d_name in
  894. c.cl_types <- List.map (type_type_params ctx c.cl_path p) d.d_params;
  895. | EEnum d ->
  896. let e = get_enum d.d_name in
  897. e.e_types <- List.map (type_type_params ctx e.e_path p) d.d_params;
  898. | ETypedef d ->
  899. let t = get_tdef d.d_name in
  900. t.t_types <- List.map (type_type_params ctx t.t_path p) d.d_params;
  901. ) tdecls;
  902. (* back to PASS2 *)
  903. List.iter (fun (d,p) ->
  904. match d with
  905. | EImport (pack,name,topt) ->
  906. let md = ctx.api.load_module (pack,name) p in
  907. let types = List.filter (fun t -> not (t_private t)) md.mtypes in
  908. (match topt with
  909. | None -> ctx.local_types <- ctx.local_types @ types
  910. | Some t ->
  911. try
  912. let t = List.find (fun tdecl -> snd (t_path tdecl) = t) types in
  913. ctx.local_types <- ctx.local_types @ [t]
  914. with
  915. Not_found -> error ("Module " ^ s_type_path (pack,name) ^ " does not define type " ^ t) p
  916. );
  917. m.mimports <- (md,topt) :: m.mimports;
  918. | EUsing (pack,name) ->
  919. let md = ctx.api.load_module (pack,name) p in
  920. let types = List.filter (fun t -> not (t_private t)) md.mtypes in
  921. ctx.local_using <- ctx.local_using @ types;
  922. | EClass d ->
  923. let c = get_class d.d_name in
  924. delays := !delays @ check_overriding ctx c p :: check_interfaces ctx c p :: init_class ctx c p d.d_flags d.d_data
  925. | EEnum d ->
  926. let e = get_enum d.d_name in
  927. ctx.type_params <- e.e_types;
  928. let et = TEnum (e,List.map snd e.e_types) in
  929. let names = ref [] in
  930. let index = ref 0 in
  931. List.iter (fun (c,doc,t,p) ->
  932. if c = "name" && Common.defined ctx.com "js" then error "This identifier cannot be used in Javascript" p;
  933. let t = (match t with
  934. | [] -> et
  935. | l ->
  936. let pnames = ref PMap.empty in
  937. TFun (List.map (fun (s,opt,t) ->
  938. if PMap.mem s (!pnames) then error ("Duplicate parameter '" ^ s ^ "' in enum constructor " ^ c) p;
  939. pnames := PMap.add s () (!pnames);
  940. s, opt, load_type_opt ~opt ctx p (Some t)
  941. ) l, et)
  942. ) in
  943. if PMap.mem c e.e_constrs then error ("Duplicate constructor " ^ c) p;
  944. e.e_constrs <- PMap.add c {
  945. ef_name = c;
  946. ef_type = t;
  947. ef_pos = p;
  948. ef_doc = doc;
  949. ef_index = !index;
  950. } e.e_constrs;
  951. incr index;
  952. names := c :: !names;
  953. ) d.d_data;
  954. e.e_names <- List.rev !names;
  955. | ETypedef d ->
  956. let t = get_tdef d.d_name in
  957. ctx.type_params <- t.t_types;
  958. let tt = load_type ctx p d.d_data in
  959. if t.t_type == follow tt then error "Recursive typedef is not allowed" p;
  960. (match t.t_type with
  961. | TMono r ->
  962. (match !r with
  963. | None -> r := Some tt;
  964. | Some _ -> assert false);
  965. | _ -> assert false);
  966. ) tdecls;
  967. (* PASS 3 : type checking, delayed until all modules and types are built *)
  968. ctx.delays := !delays :: !(ctx.delays);
  969. m.mimports <- List.rev m.mimports;
  970. m
  971. let parse_module ctx m p =
  972. let remap = ref (fst m) in
  973. let file = (match m with
  974. | [] , name -> name
  975. | x :: l , name ->
  976. let x = (try
  977. match PMap.find x ctx.com.package_rules with
  978. | Forbidden -> error ("You can't access the " ^ x ^ " package with current compilation flags (for " ^ s_type_path m ^ ")") p;
  979. | Directory d -> d
  980. | Remap d -> remap := d :: l; d
  981. with Not_found -> x
  982. ) in
  983. String.concat "/" (x :: l) ^ "/" ^ name
  984. ) ^ ".hx" in
  985. let file = (try Common.find_file ctx.com file with Not_found -> raise (Error (Module_not_found m,p))) in
  986. let ch = (try open_in_bin file with _ -> error ("Could not open " ^ file) p) in
  987. let t = Common.timer "parsing" in
  988. let pack , decls = (try Parser.parse ctx.com (Lexing.from_channel ch) file with e -> close_in ch; t(); raise e) in
  989. t();
  990. close_in ch;
  991. if ctx.com.verbose then print_endline ("Parsed " ^ file);
  992. if pack <> !remap then begin
  993. let spack m = if m = [] then "<empty>" else String.concat "." m in
  994. if p == Ast.null_pos then
  995. error ("Invalid commandline class : " ^ s_type_path m ^ " should be " ^ s_type_path (pack,snd m)) p
  996. else
  997. error ("Invalid package : " ^ spack (fst m) ^ " should be " ^ spack pack) p
  998. end;
  999. if !remap <> fst m then
  1000. (* build typedefs to redirect to real package *)
  1001. List.rev (List.fold_left (fun acc (t,p) ->
  1002. let build f d =
  1003. let priv = List.mem f d.d_flags in
  1004. (ETypedef {
  1005. d_name = d.d_name;
  1006. d_doc = None;
  1007. d_params = d.d_params;
  1008. d_flags = if priv then [EPrivate] else [];
  1009. d_data = TPNormal (if priv then { tpackage = []; tname = "Dynamic"; tparams = []; } else
  1010. {
  1011. tpackage = !remap;
  1012. tname = d.d_name;
  1013. tparams = List.map (fun (s,_) ->
  1014. TPType (TPNormal { tpackage = []; tname = s; tparams = [] })
  1015. ) d.d_params;
  1016. });
  1017. },p) :: acc
  1018. in
  1019. match t with
  1020. | EClass d -> build HPrivate d
  1021. | EEnum d -> build EPrivate d
  1022. | ETypedef d -> build EPrivate d
  1023. | EImport _ | EUsing _ -> acc
  1024. ) [(EImport (!remap, snd m, None),null_pos)] decls)
  1025. else
  1026. decls
  1027. let load_module ctx m p =
  1028. try
  1029. Hashtbl.find ctx.modules m
  1030. with
  1031. Not_found ->
  1032. let decls = parse_module ctx m p in
  1033. type_module ctx m decls p