typeloadModule.ml 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. (*
  2. The Haxe Compiler
  3. Copyright (C) 2005-2019 Haxe Foundation
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. *)
  16. (* Initial typing of modules and their types. *)
  17. open Globals
  18. open Ast
  19. open Filename
  20. open Type
  21. open Typecore
  22. open DisplayTypes.DisplayMode
  23. open DisplayTypes.CompletionResultKind
  24. open Common
  25. open Typeload
  26. open Error
  27. let get_policy ctx mpath =
  28. let sl1 = full_dot_path2 mpath mpath in
  29. List.fold_left (fun acc (sl2,policy,recursive) -> if match_path recursive sl1 sl2 then policy @ acc else acc) [] ctx.g.module_check_policies
  30. let make_module ctx mpath file loadp =
  31. let m = {
  32. m_id = alloc_mid();
  33. m_path = mpath;
  34. m_types = [];
  35. m_statics = None;
  36. m_extra = module_extra (Path.get_full_path file) (Define.get_signature ctx.com.defines) (file_time file) (if ctx.in_macro then MMacro else MCode) (get_policy ctx mpath);
  37. } in
  38. m
  39. let add_module ctx m p =
  40. List.iter (TypeloadCheck.check_module_types ctx m p) m.m_types;
  41. Hashtbl.add ctx.g.modules m.m_path m
  42. module StrictMeta = struct
  43. let get_native_repr md pos =
  44. let path, meta = match md with
  45. | TClassDecl cl -> cl.cl_path, cl.cl_meta
  46. | TEnumDecl e -> e.e_path, e.e_meta
  47. | TTypeDecl t -> t.t_path, t.t_meta
  48. | TAbstractDecl a -> a.a_path, a.a_meta
  49. in
  50. let rec loop acc = function
  51. | (Meta.JavaCanonical,[EConst(String(pack,_)),_; EConst(String(name,_)),_],_) :: _ ->
  52. ExtString.String.nsplit pack ".", name
  53. | (Meta.Native,[EConst(String(name,_)),_],_) :: meta ->
  54. loop (Ast.parse_path name) meta
  55. | _ :: meta ->
  56. loop acc meta
  57. | [] ->
  58. acc
  59. in
  60. let pack, name = loop path meta in
  61. match pack with
  62. | [] ->
  63. (EConst(Ident(name)), pos)
  64. | hd :: tl ->
  65. let rec loop pack expr = match pack with
  66. | hd :: tl ->
  67. loop tl (EField(expr,hd),pos)
  68. | [] ->
  69. (EField(expr,name),pos)
  70. in
  71. loop tl (EConst(Ident(hd)),pos)
  72. let rec process_meta_argument ?(toplevel=true) ctx expr = match expr.eexpr with
  73. | TField(e,f) ->
  74. (EField(process_meta_argument ~toplevel:false ctx e,field_name f),expr.epos)
  75. | TConst(TInt i) ->
  76. (EConst(Int (Int32.to_string i)), expr.epos)
  77. | TConst(TFloat f) ->
  78. (EConst(Float f), expr.epos)
  79. | TConst(TString s) ->
  80. (EConst(String(s,SDoubleQuotes)), expr.epos)
  81. | TConst TNull ->
  82. (EConst(Ident "null"), expr.epos)
  83. | TConst(TBool b) ->
  84. (EConst(Ident (string_of_bool b)), expr.epos)
  85. | TCast(e,_) | TMeta(_,e) | TParenthesis(e) ->
  86. process_meta_argument ~toplevel ctx e
  87. | TTypeExpr md when toplevel ->
  88. let p = expr.epos in
  89. if ctx.com.platform = Cs then
  90. (ECall( (EConst(Ident "typeof"), p), [get_native_repr md expr.epos] ), p)
  91. else
  92. (EField(get_native_repr md expr.epos, "class"), p)
  93. | TTypeExpr md ->
  94. get_native_repr md expr.epos
  95. | _ ->
  96. display_error ctx "This expression is too complex to be a strict metadata argument" expr.epos;
  97. (EConst(Ident "null"), expr.epos)
  98. let handle_fields ctx fields_to_check with_type_expr =
  99. List.map (fun ((name,_,_),expr) ->
  100. let pos = snd expr in
  101. let field = (EField(with_type_expr,name), pos) in
  102. let fieldexpr = (EConst(Ident name),pos) in
  103. let left_side = match ctx.com.platform with
  104. | Cs -> field
  105. | Java -> (ECall(field,[]),pos)
  106. | _ -> die "" __LOC__
  107. in
  108. let left = type_expr ctx left_side NoValue in
  109. let right = type_expr ctx expr (WithType.with_type left.etype) in
  110. unify ctx left.etype right.etype (snd expr);
  111. (EBinop(Ast.OpAssign,fieldexpr,process_meta_argument ctx right), pos)
  112. ) fields_to_check
  113. let make_meta ctx texpr extra =
  114. match texpr.eexpr with
  115. | TNew(c,_,el) ->
  116. ECall(get_native_repr (TClassDecl c) texpr.epos, (List.map (process_meta_argument ctx) el) @ extra), texpr.epos
  117. | TTypeExpr(md) ->
  118. ECall(get_native_repr md texpr.epos, extra), texpr.epos
  119. | _ ->
  120. display_error ctx "Unexpected expression" texpr.epos; die "" __LOC__
  121. let get_strict_meta ctx meta params pos =
  122. let pf = ctx.com.platform in
  123. let changed_expr, fields_to_check, ctype = match params with
  124. | [ECall(ef, el),p] ->
  125. (* check last argument *)
  126. let el, fields = match List.rev el with
  127. | (EObjectDecl(decl),_) :: el ->
  128. List.rev el, decl
  129. | _ ->
  130. el, []
  131. in
  132. let tpath = field_to_type_path ctx ef in
  133. if pf = Cs then
  134. (ENew((tpath,snd ef), el), p), fields, CTPath tpath
  135. else
  136. ef, fields, CTPath tpath
  137. | [EConst(Ident i),p as expr] ->
  138. let tpath = { tpackage=[]; tname=i; tparams=[]; tsub=None } in
  139. if pf = Cs then
  140. (ENew((tpath,p), []), p), [], CTPath tpath
  141. else
  142. expr, [], CTPath tpath
  143. | [ (EField(_),p as field) ] ->
  144. let tpath = field_to_type_path ctx field in
  145. if pf = Cs then
  146. (ENew((tpath,p), []), p), [], CTPath tpath
  147. else
  148. field, [], CTPath tpath
  149. | _ ->
  150. display_error ctx "A @:strict metadata must contain exactly one parameter. Please check the documentation for more information" pos;
  151. raise Exit
  152. in
  153. let texpr = type_expr ctx changed_expr NoValue in
  154. let with_type_expr = (ECheckType( (EConst (Ident "null"), pos), (ctype,null_pos) ), pos) in
  155. let extra = handle_fields ctx fields_to_check with_type_expr in
  156. meta, [make_meta ctx texpr extra], pos
  157. let check_strict_meta ctx metas =
  158. let pf = ctx.com.platform in
  159. match pf with
  160. | Cs | Java ->
  161. let ret = ref [] in
  162. List.iter (function
  163. | Meta.AssemblyStrict,params,pos -> (try
  164. ret := get_strict_meta ctx Meta.AssemblyMeta params pos :: !ret
  165. with | Exit -> ())
  166. | Meta.Strict,params,pos -> (try
  167. ret := get_strict_meta ctx Meta.Meta params pos :: !ret
  168. with | Exit -> ())
  169. | _ -> ()
  170. ) metas;
  171. !ret
  172. | _ -> []
  173. end
  174. (*
  175. Build module structure : should be atomic - no type loading is possible
  176. *)
  177. let module_pass_1 ctx m tdecls loadp =
  178. let com = ctx.com in
  179. let decls = ref [] in
  180. let statics = ref [] in
  181. let check_name name meta also_statics p =
  182. DeprecationCheck.check_is com name meta p;
  183. let error prev_pos =
  184. display_error ctx ("Name " ^ name ^ " is already defined in this module") p;
  185. error (compl_msg "Previous declaration here") prev_pos;
  186. in
  187. List.iter (fun (t2,(_,p2)) ->
  188. if snd (t_path t2) = name then error (t_infos t2).mt_name_pos
  189. ) !decls;
  190. if also_statics then
  191. List.iter (fun (d,_) ->
  192. if fst d.d_name = name then error (snd d.d_name)
  193. ) !statics
  194. in
  195. let make_path name priv meta p =
  196. check_name name meta true p;
  197. if priv then (fst m.m_path @ ["_" ^ snd m.m_path], name) else (fst m.m_path, name)
  198. in
  199. let has_declaration = ref false in
  200. let rec make_decl acc decl =
  201. let p = snd decl in
  202. let check_type_name type_name meta =
  203. let module_name = snd m.m_path in
  204. if type_name <> module_name && not (Meta.has Meta.Native meta) then Typecore.check_uppercase_identifier_name ctx type_name "type" p;
  205. in
  206. let acc = (match fst decl with
  207. | EImport _ | EUsing _ ->
  208. if !has_declaration then error "import and using may not appear after a declaration" p;
  209. acc
  210. | EStatic d ->
  211. check_name (fst d.d_name) d.d_meta false (snd d.d_name);
  212. has_declaration := true;
  213. statics := (d,p) :: !statics;
  214. acc;
  215. | EClass d ->
  216. let name = fst d.d_name in
  217. has_declaration := true;
  218. let priv = List.mem HPrivate d.d_flags in
  219. let path = make_path name priv d.d_meta (snd d.d_name) in
  220. let c = mk_class m path p (pos d.d_name) in
  221. (* we shouldn't load any other type until we propertly set cl_build *)
  222. c.cl_build <- (fun() -> error (s_type_path c.cl_path ^ " is not ready to be accessed, separate your type declarations in several files") p);
  223. c.cl_module <- m;
  224. c.cl_private <- priv;
  225. c.cl_doc <- d.d_doc;
  226. c.cl_meta <- d.d_meta;
  227. if List.mem HAbstract d.d_flags then add_class_flag c CAbstract;
  228. List.iter (function
  229. | HExtern -> add_class_flag c CExtern
  230. | HInterface -> add_class_flag c CInterface
  231. | HFinal -> add_class_flag c CFinal
  232. | _ -> ()
  233. ) d.d_flags;
  234. if not (has_class_flag c CExtern) then check_type_name name d.d_meta;
  235. if has_class_flag c CAbstract then begin
  236. if has_class_flag c CInterface then display_error ctx "An interface may not be abstract" c.cl_name_pos;
  237. if has_class_flag c CFinal then display_error ctx "An abstract class may not be final" c.cl_name_pos;
  238. end;
  239. decls := (TClassDecl c, decl) :: !decls;
  240. acc
  241. | EEnum d ->
  242. let name = fst d.d_name in
  243. has_declaration := true;
  244. let priv = List.mem EPrivate d.d_flags in
  245. let path = make_path name priv d.d_meta p in
  246. if Meta.has (Meta.Custom ":fakeEnum") d.d_meta then error "@:fakeEnum enums is no longer supported in Haxe 4, use extern enum abstract instead" p;
  247. let e = {
  248. e_path = path;
  249. e_module = m;
  250. e_pos = p;
  251. e_name_pos = (pos d.d_name);
  252. e_doc = d.d_doc;
  253. e_meta = d.d_meta;
  254. e_params = [];
  255. e_using = [];
  256. e_private = priv;
  257. e_extern = List.mem EExtern d.d_flags;
  258. e_constrs = PMap.empty;
  259. e_names = [];
  260. e_type = enum_module_type m path p;
  261. } in
  262. if not e.e_extern then check_type_name name d.d_meta;
  263. decls := (TEnumDecl e, decl) :: !decls;
  264. acc
  265. | ETypedef d ->
  266. let name = fst d.d_name in
  267. check_type_name name d.d_meta;
  268. has_declaration := true;
  269. let priv = List.mem EPrivate d.d_flags in
  270. let path = make_path name priv d.d_meta p in
  271. let t = {
  272. t_path = path;
  273. t_module = m;
  274. t_pos = p;
  275. t_name_pos = pos d.d_name;
  276. t_doc = d.d_doc;
  277. t_private = priv;
  278. t_params = [];
  279. t_using = [];
  280. t_type = mk_mono();
  281. t_meta = d.d_meta;
  282. } in
  283. (* failsafe in case the typedef is not initialized (see #3933) *)
  284. delay ctx PBuildModule (fun () ->
  285. match t.t_type with
  286. | TMono r -> (match r.tm_type with None -> Monomorph.bind r com.basic.tvoid | _ -> ())
  287. | _ -> ()
  288. );
  289. decls := (TTypeDecl t, decl) :: !decls;
  290. acc
  291. | EAbstract d ->
  292. let name = fst d.d_name in
  293. check_type_name name d.d_meta;
  294. let priv = List.mem AbPrivate d.d_flags in
  295. let path = make_path name priv d.d_meta p in
  296. let a = {
  297. a_path = path;
  298. a_private = priv;
  299. a_module = m;
  300. a_pos = p;
  301. a_name_pos = pos d.d_name;
  302. a_doc = d.d_doc;
  303. a_params = [];
  304. a_using = [];
  305. a_meta = d.d_meta;
  306. a_from = [];
  307. a_to = [];
  308. a_from_field = [];
  309. a_to_field = [];
  310. a_ops = [];
  311. a_unops = [];
  312. a_impl = None;
  313. a_array = [];
  314. a_this = mk_mono();
  315. a_read = None;
  316. a_write = None;
  317. a_call = None;
  318. a_enum = List.mem AbEnum d.d_flags || Meta.has Meta.Enum d.d_meta;
  319. } in
  320. if a.a_enum && not (Meta.has Meta.Enum a.a_meta) then a.a_meta <- (Meta.Enum,[],null_pos) :: a.a_meta;
  321. decls := (TAbstractDecl a, decl) :: !decls;
  322. match d.d_data with
  323. | [] when Meta.has Meta.CoreType a.a_meta ->
  324. a.a_this <- t_dynamic;
  325. acc
  326. | fields ->
  327. let a_t =
  328. let params = List.map (fun t -> TPType (CTPath (mk_type_path ([],fst t.tp_name)),null_pos)) d.d_params in
  329. CTPath (mk_type_path ~params ([],fst d.d_name)),null_pos
  330. in
  331. let rec loop = function
  332. | [] -> a_t
  333. | AbOver t :: _ -> t
  334. | _ :: l -> loop l
  335. in
  336. let this_t = loop d.d_flags in
  337. let fields = List.map (TypeloadFields.transform_abstract_field com this_t a_t a) fields in
  338. let meta = ref [] in
  339. if has_meta Meta.Dce a.a_meta then meta := (Meta.Dce,[],null_pos) :: !meta;
  340. let acc = make_decl acc (EClass { d_name = (fst d.d_name) ^ "_Impl_",snd d.d_name; d_flags = [HPrivate]; d_data = fields; d_doc = None; d_params = []; d_meta = !meta },p) in
  341. (match !decls with
  342. | (TClassDecl c,_) :: _ ->
  343. List.iter (fun m -> match m with
  344. | ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal),_,_) ->
  345. c.cl_meta <- m :: c.cl_meta;
  346. | _ ->
  347. ()
  348. ) a.a_meta;
  349. a.a_impl <- Some c;
  350. c.cl_kind <- KAbstractImpl a;
  351. add_class_flag c CFinal;
  352. | _ -> die "" __LOC__);
  353. acc
  354. ) in
  355. decl :: acc
  356. in
  357. let tdecls = List.fold_left make_decl [] tdecls in
  358. let tdecls =
  359. match !statics with
  360. | [] ->
  361. tdecls
  362. | statics ->
  363. let first_pos = ref null_pos in
  364. let fields = List.map (fun (d,p) ->
  365. first_pos := p;
  366. {
  367. cff_name = d.d_name;
  368. cff_doc = d.d_doc;
  369. cff_pos = p;
  370. cff_meta = d.d_meta;
  371. cff_access = (AStatic,null_pos) :: d.d_flags;
  372. cff_kind = d.d_data;
  373. }
  374. ) statics in
  375. let p = let p = !first_pos in { p with pmax = p.pmin } in
  376. let c = EClass {
  377. d_name = (snd m.m_path) ^ "_Fields_", null_pos;
  378. d_flags = [HPrivate];
  379. d_data = List.rev fields;
  380. d_doc = None;
  381. d_params = [];
  382. d_meta = []
  383. } in
  384. let tdecls = make_decl tdecls (c,p) in
  385. (match !decls with
  386. | (TClassDecl c,_) :: _ ->
  387. assert (m.m_statics = None);
  388. m.m_statics <- Some c;
  389. c.cl_kind <- KModuleFields m;
  390. add_class_flag c CFinal;
  391. | _ -> assert false);
  392. tdecls
  393. in
  394. let decls = List.rev !decls in
  395. decls, List.rev tdecls
  396. let load_enum_field ctx e et is_flat index c =
  397. let p = c.ec_pos in
  398. let params = ref [] in
  399. params := type_type_params ~enum_constructor:true ctx ([],fst c.ec_name) (fun() -> !params) c.ec_pos c.ec_params;
  400. let params = !params in
  401. let ctx = { ctx with type_params = params @ ctx.type_params } in
  402. let rt = (match c.ec_type with
  403. | None -> et
  404. | Some (t,pt) ->
  405. let t = load_complex_type ctx true (t,pt) in
  406. (match follow t with
  407. | TEnum (te,_) when te == e ->
  408. ()
  409. | _ ->
  410. error "Explicit enum type must be of the same enum type" pt);
  411. t
  412. ) in
  413. let t = (match c.ec_args with
  414. | [] -> rt
  415. | l ->
  416. is_flat := false;
  417. let pnames = ref PMap.empty in
  418. TFun (List.map (fun (s,opt,(t,tp)) ->
  419. (match t with CTPath({tpackage=[];tname="Void"}) -> error "Arguments of type Void are not allowed in enum constructors" tp | _ -> ());
  420. if PMap.mem s (!pnames) then error ("Duplicate argument `" ^ s ^ "` in enum constructor " ^ fst c.ec_name) p;
  421. pnames := PMap.add s () (!pnames);
  422. s, opt, load_type_hint ~opt ctx p (Some (t,tp))
  423. ) l, rt, false)
  424. ) in
  425. let f = {
  426. ef_name = fst c.ec_name;
  427. ef_type = t;
  428. ef_pos = p;
  429. ef_name_pos = snd c.ec_name;
  430. ef_doc = c.ec_doc;
  431. ef_index = !index;
  432. ef_params = params;
  433. ef_meta = c.ec_meta;
  434. } in
  435. DeprecationCheck.check_is ctx.com f.ef_name f.ef_meta f.ef_name_pos;
  436. let cf = {
  437. (mk_field f.ef_name f.ef_type p f.ef_name_pos) with
  438. cf_kind = (match follow f.ef_type with
  439. | TFun _ -> Method MethNormal
  440. | _ -> Var { v_read = AccNormal; v_write = AccNo }
  441. );
  442. cf_doc = f.ef_doc;
  443. cf_params = f.ef_params;
  444. } in
  445. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then
  446. DisplayEmitter.display_enum_field ctx e f p;
  447. f,cf
  448. (*
  449. In this pass, we can access load and access other modules types, but we cannot follow them or access their structure
  450. since they have not been setup. We also build a context_init list that will be evaluated the first time we evaluate
  451. an expression into the context
  452. *)
  453. let init_module_type ctx context_init (decl,p) =
  454. let get_type name =
  455. try List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types with Not_found -> die "" __LOC__
  456. in
  457. let commit_import path mode p =
  458. ctx.m.module_imports <- (path,mode) :: ctx.m.module_imports;
  459. if Filename.basename p.pfile <> "import.hx" then ImportHandling.add_import_position ctx p path;
  460. in
  461. let check_path_display path p =
  462. if DisplayPosition.display_position#is_in_file (ctx.com.file_keys#get p.pfile) then DisplayPath.handle_path_display ctx path p
  463. in
  464. let init_import path mode =
  465. check_path_display path p;
  466. let rec loop acc = function
  467. | x :: l when is_lower_ident (fst x) -> loop (x::acc) l
  468. | rest -> List.rev acc, rest
  469. in
  470. let pack, rest = loop [] path in
  471. (match rest with
  472. | [] ->
  473. (match mode with
  474. | IAll ->
  475. ctx.m.wildcard_packages <- (List.map fst pack,p) :: ctx.m.wildcard_packages
  476. | _ ->
  477. (match List.rev path with
  478. (* p spans `import |` (to the display position), so we take the pmax here *)
  479. | [] -> DisplayException.raise_fields (DisplayToplevel.collect ctx TKType NoValue true) CRImport (DisplayTypes.make_subject None {p with pmin = p.pmax})
  480. | (_,p) :: _ -> error "Module name must start with an uppercase letter" p))
  481. | (tname,p2) :: rest ->
  482. let p1 = (match pack with [] -> p2 | (_,p1) :: _ -> p1) in
  483. let p_type = punion p1 p2 in
  484. let md = ctx.g.do_load_module ctx (List.map fst pack,tname) p_type in
  485. let types = md.m_types in
  486. let no_private (t,_) = not (t_infos t).mt_private in
  487. let error_private p = error "Importing private declarations from a module is not allowed" p in
  488. let chk_private t p = if ctx.m.curmod != (t_infos t).mt_module && (t_infos t).mt_private then error_private p in
  489. let has_name name t = snd (t_infos t).mt_path = name in
  490. let get_type tname =
  491. let t = (try List.find (has_name tname) types with Not_found -> error (StringError.string_error tname (List.map (fun mt -> snd (t_infos mt).mt_path) types) ("Module " ^ s_type_path md.m_path ^ " does not define type " ^ tname)) p_type) in
  492. chk_private t p_type;
  493. t
  494. in
  495. let rebind t name p =
  496. if not (name.[0] >= 'A' && name.[0] <= 'Z') then
  497. error "Type aliases must start with an uppercase letter" p;
  498. let _, _, f = ctx.g.do_build_instance ctx t p_type in
  499. (* create a temp private typedef, does not register it in module *)
  500. let mt = TTypeDecl {
  501. t_path = (fst md.m_path @ ["_" ^ snd md.m_path],name);
  502. t_module = ctx.m.curmod;
  503. t_pos = p;
  504. t_name_pos = p;
  505. t_private = true;
  506. t_doc = None;
  507. t_meta = [];
  508. t_params = (t_infos t).mt_params;
  509. t_using = [];
  510. t_type = f (List.map snd (t_infos t).mt_params);
  511. } in
  512. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in p then
  513. DisplayEmitter.display_module_type ctx mt p;
  514. mt
  515. in
  516. let add_static_init t name s =
  517. let name = (match name with None -> s | Some (n,_) -> n) in
  518. match resolve_typedef t with
  519. | TClassDecl c | TAbstractDecl {a_impl = Some c} ->
  520. ignore(c.cl_build());
  521. ignore(PMap.find s c.cl_statics);
  522. ctx.m.module_globals <- PMap.add name (TClassDecl c,s,p) ctx.m.module_globals
  523. | TEnumDecl e ->
  524. ignore(PMap.find s e.e_constrs);
  525. ctx.m.module_globals <- PMap.add name (TEnumDecl e,s,p) ctx.m.module_globals
  526. | _ ->
  527. raise Not_found
  528. in
  529. (match mode with
  530. | INormal | IAsName _ ->
  531. let name = (match mode with IAsName n -> Some n | _ -> None) in
  532. (match rest with
  533. | [] ->
  534. (match name with
  535. | None ->
  536. ctx.m.module_types <- List.filter no_private (List.map (fun t -> t,p) types) @ ctx.m.module_types;
  537. Option.may (fun c ->
  538. context_init#add (fun () ->
  539. ignore(c.cl_build());
  540. List.iter (fun cf ->
  541. if has_class_field_flag cf CfPublic then
  542. ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals
  543. ) c.cl_ordered_statics
  544. );
  545. ) md.m_statics
  546. | Some(newname,pname) ->
  547. ctx.m.module_types <- (rebind (get_type tname) newname pname,p) :: ctx.m.module_types);
  548. | [tsub,p2] ->
  549. let pu = punion p1 p2 in
  550. (try
  551. let tsub = List.find (has_name tsub) types in
  552. chk_private tsub pu;
  553. ctx.m.module_types <- ((match name with None -> tsub | Some(n,pname) -> rebind tsub n pname),p) :: ctx.m.module_types
  554. with Not_found ->
  555. (* this might be a static property, wait later to check *)
  556. let find_main_type_static () =
  557. let tmain = get_type tname in
  558. try
  559. add_static_init tmain name tsub
  560. with Not_found ->
  561. (* TODO: mention module-level declarations in the error message? *)
  562. display_error ctx (s_type_path (t_infos tmain).mt_path ^ " has no field or subtype " ^ tsub) p
  563. in
  564. context_init#add (fun() ->
  565. match md.m_statics with
  566. | Some c ->
  567. (try
  568. ignore(c.cl_build());
  569. let rec loop fl =
  570. match fl with
  571. | [] -> raise Not_found
  572. | cf :: rest ->
  573. if cf.cf_name = tsub then
  574. if not (has_class_field_flag cf CfPublic) then
  575. error_private p
  576. else
  577. let imported_name = match name with None -> tsub | Some (n,pname) -> n in
  578. ctx.m.module_globals <- PMap.add imported_name (TClassDecl c,tsub,p) ctx.m.module_globals;
  579. else
  580. loop rest
  581. in
  582. loop c.cl_ordered_statics
  583. with Not_found ->
  584. find_main_type_static ())
  585. | None ->
  586. find_main_type_static ()
  587. )
  588. )
  589. | (tsub,p2) :: (fname,p3) :: rest ->
  590. (match rest with
  591. | [] -> ()
  592. | (n,p) :: _ -> error ("Unexpected " ^ n) p);
  593. let tsub = get_type tsub in
  594. context_init#add (fun() ->
  595. try
  596. add_static_init tsub name fname
  597. with Not_found ->
  598. display_error ctx (s_type_path (t_infos tsub).mt_path ^ " has no field " ^ fname) (punion p p3)
  599. );
  600. )
  601. | IAll ->
  602. let t = (match rest with
  603. | [] -> get_type tname
  604. | [tsub,_] -> get_type tsub
  605. | _ :: (n,p) :: _ -> error ("Unexpected " ^ n) p
  606. ) in
  607. context_init#add (fun() ->
  608. match resolve_typedef t with
  609. | TClassDecl c
  610. | TAbstractDecl {a_impl = Some c} ->
  611. ignore(c.cl_build());
  612. PMap.iter (fun _ cf -> if not (has_meta Meta.NoImportGlobal cf.cf_meta) then ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals) c.cl_statics
  613. | TEnumDecl e ->
  614. PMap.iter (fun _ c -> if not (has_meta Meta.NoImportGlobal c.ef_meta) then ctx.m.module_globals <- PMap.add c.ef_name (TEnumDecl e,c.ef_name,p) ctx.m.module_globals) e.e_constrs
  615. | _ ->
  616. error "No statics to import from this type" p
  617. )
  618. ))
  619. in
  620. match decl with
  621. | EImport (path,mode) ->
  622. begin try
  623. init_import path mode;
  624. commit_import path mode p;
  625. with Error(err,p) ->
  626. display_error ctx (Error.error_msg err) p
  627. end
  628. | EUsing path ->
  629. check_path_display path p;
  630. let types,filter_classes = handle_using ctx path p in
  631. (* do the import first *)
  632. ctx.m.module_types <- (List.map (fun t -> t,p) types) @ ctx.m.module_types;
  633. context_init#add (fun() -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using)
  634. | EClass d ->
  635. let c = (match get_type (fst d.d_name) with TClassDecl c -> c | _ -> die "" __LOC__) in
  636. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  637. DisplayEmitter.display_module_type ctx (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name);
  638. TypeloadCheck.check_global_metadata ctx c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None;
  639. let herits = d.d_flags in
  640. List.iter (fun (m,_,p) ->
  641. if m = Meta.Final then begin
  642. add_class_flag c CFinal;
  643. (* if p <> null_pos && not (Define.is_haxe3_compat ctx.com.defines) then
  644. ctx.com.warning "`@:final class` is deprecated in favor of `final class`" p; *)
  645. end
  646. ) d.d_meta;
  647. let prev_build_count = ref (!build_count - 1) in
  648. let build() =
  649. let fl = TypeloadCheck.Inheritance.set_heritance ctx c herits p in
  650. let rec build() =
  651. c.cl_build <- (fun()-> Building [c]);
  652. try
  653. List.iter (fun f -> f()) fl;
  654. TypeloadFields.init_class ctx c p context_init d.d_flags d.d_data;
  655. c.cl_build <- (fun()-> Built);
  656. incr build_count;
  657. List.iter (fun (_,t) -> ignore(follow t)) c.cl_params;
  658. Built;
  659. with TypeloadCheck.Build_canceled state ->
  660. c.cl_build <- make_pass ctx build;
  661. let rebuild() =
  662. delay_late ctx PBuildClass (fun() -> ignore(c.cl_build()));
  663. in
  664. (match state with
  665. | Built -> die "" __LOC__
  666. | Building cl ->
  667. if !build_count = !prev_build_count then error ("Loop in class building prevent compiler termination (" ^ String.concat "," (List.map (fun c -> s_type_path c.cl_path) cl) ^ ")") c.cl_pos;
  668. prev_build_count := !build_count;
  669. rebuild();
  670. Building (c :: cl)
  671. | BuildMacro f ->
  672. f := rebuild :: !f;
  673. state);
  674. | exn ->
  675. c.cl_build <- (fun()-> Built);
  676. raise exn
  677. in
  678. build()
  679. in
  680. ctx.pass <- PBuildClass;
  681. ctx.curclass <- c;
  682. c.cl_build <- make_pass ctx build;
  683. ctx.pass <- PBuildModule;
  684. ctx.curclass <- null_class;
  685. delay ctx PBuildClass (fun() -> ignore(c.cl_build()));
  686. if Meta.has Meta.InheritDoc c.cl_meta then
  687. delay ctx PConnectField (fun() -> InheritDoc.build_class_doc ctx c);
  688. if (ctx.com.platform = Java || ctx.com.platform = Cs) && not (has_class_flag c CExtern) then
  689. delay ctx PTypeField (fun () ->
  690. let metas = StrictMeta.check_strict_meta ctx c.cl_meta in
  691. if metas <> [] then c.cl_meta <- metas @ c.cl_meta;
  692. let rec run_field cf =
  693. let metas = StrictMeta.check_strict_meta ctx cf.cf_meta in
  694. if metas <> [] then cf.cf_meta <- metas @ cf.cf_meta;
  695. List.iter run_field cf.cf_overloads
  696. in
  697. List.iter run_field c.cl_ordered_statics;
  698. List.iter run_field c.cl_ordered_fields;
  699. match c.cl_constructor with
  700. | Some f -> run_field f
  701. | _ -> ()
  702. );
  703. | EEnum d ->
  704. let e = (match get_type (fst d.d_name) with TEnumDecl e -> e | _ -> die "" __LOC__) in
  705. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  706. DisplayEmitter.display_module_type ctx (TEnumDecl e) (pos d.d_name);
  707. let ctx = { ctx with type_params = e.e_params } in
  708. let h = (try Some (Hashtbl.find ctx.g.type_patches e.e_path) with Not_found -> None) in
  709. TypeloadCheck.check_global_metadata ctx e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None;
  710. (match h with
  711. | None -> ()
  712. | Some (h,hcl) ->
  713. Hashtbl.iter (fun _ _ -> error "Field type patch not supported for enums" e.e_pos) h;
  714. e.e_meta <- e.e_meta @ hcl.tp_meta);
  715. let constructs = ref d.d_data in
  716. let get_constructs() =
  717. List.map (fun c ->
  718. {
  719. cff_name = c.ec_name;
  720. cff_doc = c.ec_doc;
  721. cff_meta = c.ec_meta;
  722. cff_pos = c.ec_pos;
  723. cff_access = [];
  724. cff_kind = (match c.ec_args, c.ec_params with
  725. | [], [] -> FVar (c.ec_type,None)
  726. | _ -> FFun { f_params = c.ec_params; f_type = c.ec_type; f_expr = None; f_args = List.map (fun (n,o,t) -> (n,null_pos),o,[],Some t,None) c.ec_args });
  727. }
  728. ) (!constructs)
  729. in
  730. TypeloadFields.build_module_def ctx (TEnumDecl e) e.e_meta get_constructs context_init (fun (e,p) ->
  731. match e with
  732. | EVars [{ ev_type = Some (CTAnonymous fields,p); ev_expr = None }] ->
  733. constructs := List.map (fun f ->
  734. let args, params, t = (match f.cff_kind with
  735. | FVar (t,None) -> [], [], t
  736. | FFun { f_params = pl; f_type = t; f_expr = (None|Some (EBlock [],_)); f_args = al } ->
  737. let al = List.map (fun ((n,_),o,_,t,_) -> match t with None -> error "Missing function parameter type" f.cff_pos | Some t -> n,o,t) al in
  738. al, pl, t
  739. | _ ->
  740. error "Invalid enum constructor in @:build result" p
  741. ) in
  742. {
  743. ec_name = f.cff_name;
  744. ec_doc = f.cff_doc;
  745. ec_meta = f.cff_meta;
  746. ec_pos = f.cff_pos;
  747. ec_args = args;
  748. ec_params = params;
  749. ec_type = t;
  750. }
  751. ) fields
  752. | _ -> error "Enum build macro must return a single variable with anonymous object fields" p
  753. );
  754. let et = TEnum (e,List.map snd e.e_params) in
  755. let names = ref [] in
  756. let index = ref 0 in
  757. let is_flat = ref true in
  758. let fields = ref PMap.empty in
  759. List.iter (fun c ->
  760. if PMap.mem (fst c.ec_name) e.e_constrs then error ("Duplicate constructor " ^ fst c.ec_name) (pos c.ec_name);
  761. let f,cf = load_enum_field ctx e et is_flat index c in
  762. e.e_constrs <- PMap.add f.ef_name f e.e_constrs;
  763. fields := PMap.add cf.cf_name cf !fields;
  764. incr index;
  765. names := (fst c.ec_name) :: !names;
  766. if Meta.has Meta.InheritDoc f.ef_meta then
  767. delay ctx PConnectField (fun() -> InheritDoc.build_enum_field_doc ctx f);
  768. ) (!constructs);
  769. e.e_names <- List.rev !names;
  770. e.e_extern <- e.e_extern;
  771. e.e_type.t_params <- e.e_params;
  772. e.e_type.t_type <- mk_anon ~fields:!fields (ref (EnumStatics e));
  773. if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta;
  774. if Meta.has Meta.InheritDoc e.e_meta then
  775. delay ctx PConnectField (fun() -> InheritDoc.build_enum_doc ctx e);
  776. if (ctx.com.platform = Java || ctx.com.platform = Cs) && not e.e_extern then
  777. delay ctx PTypeField (fun () ->
  778. let metas = StrictMeta.check_strict_meta ctx e.e_meta in
  779. e.e_meta <- metas @ e.e_meta;
  780. PMap.iter (fun _ ef ->
  781. let metas = StrictMeta.check_strict_meta ctx ef.ef_meta in
  782. if metas <> [] then ef.ef_meta <- metas @ ef.ef_meta
  783. ) e.e_constrs
  784. );
  785. | ETypedef d ->
  786. let t = (match get_type (fst d.d_name) with TTypeDecl t -> t | _ -> die "" __LOC__) in
  787. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  788. DisplayEmitter.display_module_type ctx (TTypeDecl t) (pos d.d_name);
  789. TypeloadCheck.check_global_metadata ctx t.t_meta (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None;
  790. let ctx = { ctx with type_params = t.t_params } in
  791. let tt = load_complex_type ctx true d.d_data in
  792. let tt = (match fst d.d_data with
  793. | CTExtend _ -> tt
  794. | CTPath { tpackage = ["haxe";"macro"]; tname = "MacroType" } ->
  795. (* we need to follow MacroType immediately since it might define other module types that we will load afterwards *)
  796. if t.t_type == follow tt then error "Recursive typedef is not allowed" p;
  797. tt
  798. | _ ->
  799. if (Meta.has Meta.Eager d.d_meta) then
  800. follow tt
  801. else begin
  802. let rec check_rec tt =
  803. if tt == t.t_type then error "Recursive typedef is not allowed" p;
  804. match tt with
  805. | TMono r ->
  806. (match r.tm_type with
  807. | None -> ()
  808. | Some t -> check_rec t)
  809. | TLazy f ->
  810. check_rec (lazy_type f);
  811. | TType (td,tl) ->
  812. if td == t then error "Recursive typedef is not allowed" p;
  813. check_rec (apply_params td.t_params tl td.t_type)
  814. | _ ->
  815. ()
  816. in
  817. let r = exc_protect ctx (fun r ->
  818. r := lazy_processing (fun() -> tt);
  819. check_rec tt;
  820. tt
  821. ) "typedef_rec_check" in
  822. TLazy r
  823. end
  824. ) in
  825. (match t.t_type with
  826. | TMono r ->
  827. (match r.tm_type with
  828. | None -> Monomorph.bind r tt;
  829. | Some _ -> die "" __LOC__);
  830. | _ -> die "" __LOC__);
  831. TypeloadFields.build_module_def ctx (TTypeDecl t) t.t_meta (fun _ -> []) context_init (fun _ -> ());
  832. if ctx.com.platform = Cs && t.t_meta <> [] then
  833. delay ctx PTypeField (fun () ->
  834. let metas = StrictMeta.check_strict_meta ctx t.t_meta in
  835. if metas <> [] then t.t_meta <- metas @ t.t_meta;
  836. );
  837. | EAbstract d ->
  838. let a = (match get_type (fst d.d_name) with TAbstractDecl a -> a | _ -> die "" __LOC__) in
  839. if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  840. DisplayEmitter.display_module_type ctx (TAbstractDecl a) (pos d.d_name);
  841. TypeloadCheck.check_global_metadata ctx a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None;
  842. let ctx = { ctx with type_params = a.a_params } in
  843. let is_type = ref false in
  844. let load_type t from =
  845. let _, pos = t in
  846. let t = load_complex_type ctx true t in
  847. let t = if not (Meta.has Meta.CoreType a.a_meta) then begin
  848. if !is_type then begin
  849. let r = exc_protect ctx (fun r ->
  850. r := lazy_processing (fun() -> t);
  851. (try (if from then Type.unify t a.a_this else Type.unify a.a_this t) with Unify_error _ -> error "You can only declare from/to with compatible types" pos);
  852. t
  853. ) "constraint" in
  854. TLazy r
  855. end else
  856. error "Missing underlying type declaration or @:coreType declaration" p;
  857. end else begin
  858. if Meta.has Meta.Callable a.a_meta then
  859. error "@:coreType abstracts cannot be @:callable" p;
  860. t
  861. end in
  862. t
  863. in
  864. List.iter (function
  865. | AbFrom t -> a.a_from <- (load_type t true) :: a.a_from
  866. | AbTo t -> a.a_to <- (load_type t false) :: a.a_to
  867. | AbOver t ->
  868. if a.a_impl = None then error "Abstracts with underlying type must have an implementation" a.a_pos;
  869. if Meta.has Meta.CoreType a.a_meta then error "@:coreType abstracts cannot have an underlying type" p;
  870. let at = load_complex_type ctx true t in
  871. delay ctx PForce (fun () ->
  872. let rec loop stack t =
  873. match follow t with
  874. | TAbstract(a,_) when not (Meta.has Meta.CoreType a.a_meta) ->
  875. if List.memq a stack then
  876. error "Abstract underlying type cannot be recursive" a.a_pos
  877. else
  878. loop (a :: stack) a.a_this
  879. | _ -> ()
  880. in
  881. loop [] at
  882. );
  883. a.a_this <- at;
  884. is_type := true;
  885. | AbExtern ->
  886. (match a.a_impl with Some c -> add_class_flag c CExtern | None -> (* Hmmmm.... *) ())
  887. | AbPrivate | AbEnum -> ()
  888. ) d.d_flags;
  889. a.a_from <- List.rev a.a_from;
  890. a.a_to <- List.rev a.a_to;
  891. if not !is_type then begin
  892. if Meta.has Meta.CoreType a.a_meta then
  893. a.a_this <- TAbstract(a,List.map snd a.a_params)
  894. else
  895. error "Abstract is missing underlying type declaration" a.a_pos
  896. end;
  897. if Meta.has Meta.InheritDoc a.a_meta then
  898. delay ctx PConnectField (fun() -> InheritDoc.build_abstract_doc ctx a);
  899. | EStatic _ ->
  900. (* nothing to do here as module fields are collected into a special EClass *)
  901. ()
  902. let module_pass_2 ctx m decls tdecls p =
  903. (* here is an additional PASS 1 phase, which define the type parameters for all module types.
  904. Constraints are handled lazily (no other type is loaded) because they might be recursive anyway *)
  905. List.iter (fun d ->
  906. match d with
  907. | (TClassDecl c, (EClass d, p)) ->
  908. c.cl_params <- type_type_params ctx c.cl_path (fun() -> c.cl_params) p d.d_params;
  909. if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric;
  910. if Meta.has Meta.GenericBuild c.cl_meta then begin
  911. if ctx.in_macro then error "@:genericBuild cannot be used in macros" c.cl_pos;
  912. c.cl_kind <- KGenericBuild d.d_data;
  913. end;
  914. if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType;
  915. | (TEnumDecl e, (EEnum d, p)) ->
  916. e.e_params <- type_type_params ctx e.e_path (fun() -> e.e_params) p d.d_params;
  917. | (TTypeDecl t, (ETypedef d, p)) ->
  918. t.t_params <- type_type_params ctx t.t_path (fun() -> t.t_params) p d.d_params;
  919. | (TAbstractDecl a, (EAbstract d, p)) ->
  920. a.a_params <- type_type_params ctx a.a_path (fun() -> a.a_params) p d.d_params;
  921. | _ ->
  922. die "" __LOC__
  923. ) decls;
  924. (* setup module types *)
  925. let context_init = new TypeloadFields.context_init in
  926. List.iter (init_module_type ctx context_init) tdecls;
  927. (* Make sure that we actually init the context at some point (issue #9012) *)
  928. delay ctx PConnectField (fun () -> context_init#run)
  929. (*
  930. Creates a module context for [m] and types [tdecls] using it.
  931. *)
  932. let type_types_into_module ctx m tdecls p =
  933. let decls, tdecls = module_pass_1 ctx m tdecls p in
  934. let types = List.map fst decls in
  935. List.iter (TypeloadCheck.check_module_types ctx m p) types;
  936. m.m_types <- m.m_types @ types;
  937. (* define the per-module context for the next pass *)
  938. let ctx = {
  939. com = ctx.com;
  940. g = ctx.g;
  941. t = ctx.t;
  942. m = {
  943. curmod = m;
  944. module_types = List.map (fun t -> t,null_pos) ctx.g.std.m_types;
  945. module_using = [];
  946. module_globals = PMap.empty;
  947. wildcard_packages = [];
  948. module_imports = [];
  949. };
  950. is_display_file = (ctx.com.display.dms_kind <> DMNone && DisplayPosition.display_position#is_in_file (Path.UniqueKey.lazy_key m.m_extra.m_file));
  951. bypass_accessor = 0;
  952. meta = [];
  953. this_stack = [];
  954. with_type_stack = [];
  955. call_argument_stack = [];
  956. pass = PBuildModule;
  957. get_build_infos = (fun() -> None);
  958. on_error = (fun ctx msg p -> ctx.com.error msg p);
  959. macro_depth = ctx.macro_depth;
  960. curclass = null_class;
  961. curfield = null_field;
  962. tthis = ctx.tthis;
  963. ret = ctx.ret;
  964. locals = PMap.empty;
  965. type_params = [];
  966. curfun = FunStatic;
  967. untyped = false;
  968. in_macro = ctx.in_macro;
  969. in_display = false;
  970. in_function = false;
  971. in_loop = false;
  972. opened = [];
  973. in_call_args = false;
  974. in_overload_call_args = false;
  975. delayed_display = None;
  976. monomorphs = {
  977. perfunction = [];
  978. };
  979. vthis = None;
  980. memory_marker = Typecore.memory_marker;
  981. } in
  982. if ctx.g.std != null_module then begin
  983. add_dependency m ctx.g.std;
  984. (* this will ensure both String and (indirectly) Array which are basic types which might be referenced *)
  985. ignore(load_core_type ctx "String");
  986. end;
  987. module_pass_2 ctx m decls tdecls p;
  988. ctx
  989. let handle_import_hx ctx m decls p =
  990. let path_split = match List.rev (Path.get_path_parts (Path.UniqueKey.lazy_path m.m_extra.m_file)) with
  991. | [] -> []
  992. | _ :: l -> l
  993. in
  994. let join l = String.concat Path.path_sep (List.rev ("import.hx" :: l)) in
  995. let rec loop path pack = match path,pack with
  996. | _,[] -> [join path]
  997. | (p :: path),(_ :: pack) -> (join (p :: path)) :: (loop path pack)
  998. | _ -> []
  999. in
  1000. let candidates = loop path_split (fst m.m_path) in
  1001. let make_import_module path r =
  1002. Hashtbl.replace ctx.com.parser_cache path r;
  1003. (* We use the file path as module name to make it unique. This may or may not be a good idea... *)
  1004. let m_import = make_module ctx ([],path) path p in
  1005. m_import.m_extra.m_kind <- MImport;
  1006. add_module ctx m_import p;
  1007. m_import
  1008. in
  1009. List.fold_left (fun acc path ->
  1010. let decls = try
  1011. let r = Hashtbl.find ctx.com.parser_cache path in
  1012. let mimport = Hashtbl.find ctx.g.modules ([],path) in
  1013. if mimport.m_extra.m_kind <> MFake then add_dependency m mimport;
  1014. r
  1015. with Not_found ->
  1016. if Sys.file_exists path then begin
  1017. let _,r = match !TypeloadParse.parse_hook ctx.com path p with
  1018. | ParseSuccess(data,_,_) -> data
  1019. | ParseError(_,(msg,p),_) -> Parser.error msg p
  1020. in
  1021. List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> error "Only import and using is allowed in import.hx files" p) r;
  1022. add_dependency m (make_import_module path r);
  1023. r
  1024. end else begin
  1025. let r = [] in
  1026. (* Add empty decls so we don't check the file system all the time. *)
  1027. (make_import_module path r).m_extra.m_kind <- MFake;
  1028. r
  1029. end
  1030. in
  1031. decls @ acc
  1032. ) decls candidates
  1033. (*
  1034. Creates a new module and types [tdecls] into it.
  1035. *)
  1036. let type_module ctx mpath file ?(dont_check_path=false) ?(is_extern=false) tdecls p =
  1037. let m = make_module ctx mpath file p in
  1038. Hashtbl.add ctx.g.modules m.m_path m;
  1039. let tdecls = handle_import_hx ctx m tdecls p in
  1040. let ctx = type_types_into_module ctx m tdecls p in
  1041. if is_extern then m.m_extra.m_kind <- MExtern else if not dont_check_path then Typecore.check_module_path ctx m.m_path p;
  1042. begin if ctx.is_display_file then match ctx.com.display.dms_kind with
  1043. | DMResolve s ->
  1044. DisplayPath.resolve_position_by_path ctx (mk_type_path ([],s)) p
  1045. | _ ->
  1046. ()
  1047. end;
  1048. m
  1049. (* let type_module ctx mpath file ?(is_extern=false) tdecls p =
  1050. let timer = Timer.timer ["typing";"type_module"] in
  1051. Std.finally timer (type_module ctx mpath file ~is_extern tdecls) p *)
  1052. let type_module_hook = ref (fun _ _ _ -> None)
  1053. let load_module ctx m p =
  1054. let m2 = (try
  1055. Hashtbl.find ctx.g.modules m
  1056. with
  1057. Not_found ->
  1058. match !type_module_hook ctx m p with
  1059. | Some m -> m
  1060. | None ->
  1061. let is_extern = ref false in
  1062. let file, decls = (try
  1063. TypeloadParse.parse_module ctx m p
  1064. with Not_found ->
  1065. let rec loop = function
  1066. | [] ->
  1067. raise (Error (Module_not_found m,p))
  1068. | (file,load) :: l ->
  1069. match load m p with
  1070. | None -> loop l
  1071. | Some (_,a) -> file, a
  1072. in
  1073. is_extern := true;
  1074. loop ctx.com.load_extern_type
  1075. ) in
  1076. let is_extern = !is_extern in
  1077. try
  1078. type_module ctx m file ~is_extern decls p
  1079. with Forbid_package (inf,pl,pf) when p <> null_pos ->
  1080. raise (Forbid_package (inf,p::pl,pf))
  1081. ) in
  1082. add_dependency ctx.m.curmod m2;
  1083. if ctx.pass = PTypeField then flush_pass ctx PConnectField "load_module";
  1084. m2
  1085. (* let load_module ctx m p =
  1086. let timer = Timer.timer ["typing";"load_module"] in
  1087. Std.finally timer (load_module ctx m) p *)
  1088. ;;