typeload.ml 31 KB

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