typeloadModule.ml 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  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 Type
  20. open Typecore
  21. open DisplayTypes.DisplayMode
  22. open Common
  23. open Typeload
  24. open Error
  25. let get_policy g mpath =
  26. let sl1 = full_dot_path2 mpath mpath in
  27. List.fold_left (fun acc (sl2,policy,recursive) -> if match_path recursive sl1 sl2 then policy @ acc else acc) [] g.module_check_policies
  28. let field_of_static_definition d p =
  29. {
  30. cff_name = d.d_name;
  31. cff_doc = d.d_doc;
  32. cff_pos = p;
  33. cff_meta = d.d_meta;
  34. cff_access = (AStatic,null_pos) :: d.d_flags;
  35. cff_kind = d.d_data;
  36. }
  37. module ModuleLevel = struct
  38. let make_module com g mpath file loadp =
  39. let m = {
  40. m_id = alloc_mid();
  41. m_path = mpath;
  42. m_types = [];
  43. m_statics = None;
  44. m_extra = module_extra (Path.get_full_path file) (Define.get_signature com.defines) (file_time file) (if com.is_macro_context then MMacro else MCode) com.compilation_step (get_policy g mpath);
  45. } in
  46. m
  47. let add_module com m p =
  48. com.module_lut#add m.m_path m
  49. (*
  50. Build module structure : should be atomic - no type loading is possible
  51. *)
  52. let create_module_types ctx_m m tdecls loadp =
  53. let com = ctx_m.com in
  54. let imports_and_usings = DynArray.create () in
  55. let module_types = DynArray.create () in
  56. let declarations = DynArray.create () in
  57. let add_declaration decl mt =
  58. DynArray.add declarations (decl,mt);
  59. ctx_m.com.module_lut#add_module_type m mt;
  60. DynArray.add module_types mt;
  61. in
  62. let add_import_declaration i =
  63. DynArray.add imports_and_usings i
  64. in
  65. let statics = ref [] in
  66. let check_name name meta also_statics p =
  67. DeprecationCheck.check_is com ctx_m.m.curmod meta [] name meta p;
  68. let error prev_pos =
  69. raise_typing_error_ext (make_error (Custom ("Name " ^ name ^ " is already defined in this module")) ~sub:[
  70. make_error ~depth:1 (Custom (compl_msg "Previous declaration here")) prev_pos
  71. ] p);
  72. in
  73. DynArray.iter (fun t2 ->
  74. if snd (t_path t2) = name then error (t_infos t2).mt_name_pos
  75. ) module_types;
  76. if also_statics then
  77. List.iter (fun (d,_) ->
  78. if fst d.d_name = name then error (snd d.d_name)
  79. ) !statics
  80. in
  81. let make_path name priv meta p =
  82. check_name name meta true p;
  83. if priv then (fst m.m_path @ ["_" ^ snd m.m_path], name) else (fst m.m_path, name)
  84. in
  85. let has_declaration = ref false in
  86. let check_type_name type_name meta p =
  87. let module_name = snd m.m_path in
  88. if type_name <> module_name && not (Meta.has Meta.Native meta) then Naming.check_uppercase_identifier_name ctx_m.com type_name "type" p;
  89. in
  90. let handle_class_decl d p =
  91. let name = fst d.d_name in
  92. has_declaration := true;
  93. let priv = List.mem HPrivate d.d_flags in
  94. let path = make_path name priv d.d_meta (snd d.d_name) in
  95. let c = mk_class m path p (pos d.d_name) in
  96. (* we shouldn't load any other type until we propertly set cl_build *)
  97. c.cl_build <- (fun() -> raise_typing_error (s_type_path c.cl_path ^ " is not ready to be accessed, separate your type declarations in several files") p);
  98. c.cl_module <- m;
  99. c.cl_private <- priv;
  100. c.cl_doc <- d.d_doc;
  101. c.cl_meta <- d.d_meta;
  102. if List.mem HAbstract d.d_flags then add_class_flag c CAbstract;
  103. List.iter (function
  104. | HExtern -> add_class_flag c CExtern
  105. | HInterface -> add_class_flag c CInterface
  106. | HFinal -> add_class_flag c CFinal
  107. | _ -> ()
  108. ) d.d_flags;
  109. if not (has_class_flag c CExtern) then check_type_name name d.d_meta p;
  110. if has_class_flag c CAbstract then begin
  111. if has_class_flag c CInterface then display_error com "An interface may not be abstract" c.cl_name_pos;
  112. if has_class_flag c CFinal then display_error com "An abstract class may not be final" c.cl_name_pos;
  113. end;
  114. c
  115. in
  116. let make_decl decl =
  117. let p = snd decl in
  118. match fst decl with
  119. | EImport _ | EUsing _ ->
  120. if !has_declaration then raise_typing_error "import and using may not appear after a declaration" p;
  121. add_import_declaration decl
  122. | EStatic d ->
  123. check_name (fst d.d_name) d.d_meta false (snd d.d_name);
  124. has_declaration := true;
  125. statics := (d,p) :: !statics;
  126. | EClass d ->
  127. add_declaration decl (TClassDecl (handle_class_decl d p))
  128. | EEnum d ->
  129. let name = fst d.d_name in
  130. has_declaration := true;
  131. let priv = List.mem EPrivate d.d_flags in
  132. let path = make_path name priv d.d_meta p in
  133. let e = {
  134. (mk_enum m path p (pos d.d_name)) with
  135. e_doc = d.d_doc;
  136. e_meta = d.d_meta;
  137. e_private = priv;
  138. } in
  139. if List.mem EExtern d.d_flags then add_enum_flag e EnExtern else check_type_name name d.d_meta p;
  140. add_declaration decl (TEnumDecl e)
  141. | ETypedef d ->
  142. let name = fst d.d_name in
  143. check_type_name name d.d_meta p;
  144. has_declaration := true;
  145. let priv = List.mem TDPrivate d.d_flags in
  146. let path = make_path name priv d.d_meta p in
  147. let t = {(mk_typedef m path p (pos d.d_name) (mk_mono())) with
  148. t_doc = d.d_doc;
  149. t_private = priv;
  150. t_meta = d.d_meta;
  151. } in
  152. (* failsafe in case the typedef is not initialized (see #3933) *)
  153. delay ctx_m.g PBuildModule (fun () ->
  154. match t.t_type with
  155. | TMono r -> (match r.tm_type with None -> Monomorph.bind r com.basic.tvoid | _ -> ())
  156. | _ -> ()
  157. );
  158. add_declaration decl (TTypeDecl t)
  159. | EAbstract d ->
  160. let name = fst d.d_name in
  161. check_type_name name d.d_meta p;
  162. let priv = List.mem AbPrivate d.d_flags in
  163. let path = make_path name priv d.d_meta p in
  164. let p_enum_meta = Meta.maybe_get_pos Meta.Enum d.d_meta in
  165. let a = {
  166. a_path = path;
  167. a_private = priv;
  168. a_module = m;
  169. a_pos = p;
  170. a_name_pos = pos d.d_name;
  171. a_doc = d.d_doc;
  172. a_params = [];
  173. a_using = [];
  174. a_restore = (fun () -> ());
  175. a_meta = d.d_meta;
  176. a_from = [];
  177. a_to = [];
  178. a_from_field = [];
  179. a_to_field = [];
  180. a_ops = [];
  181. a_unops = [];
  182. a_impl = None;
  183. a_array = [];
  184. a_this = mk_mono();
  185. a_read = None;
  186. a_write = None;
  187. a_call = None;
  188. a_constructor = None;
  189. a_extern = List.mem AbExtern d.d_flags;
  190. a_enum = List.mem AbEnum d.d_flags || p_enum_meta <> None;
  191. } in
  192. begin match p_enum_meta with
  193. | None when a.a_enum -> a.a_meta <- (Meta.Enum,[],null_pos) :: a.a_meta; (* HAXE5: remove *)
  194. | None -> ()
  195. | Some p ->
  196. let options = Warning.from_meta d.d_meta in
  197. module_warning com ctx_m.m.curmod WDeprecatedEnumAbstract options "`@:enum abstract` is deprecated in favor of `enum abstract`" p
  198. end;
  199. add_declaration decl (TAbstractDecl a);
  200. begin match d.d_data with
  201. | [] when Meta.has Meta.CoreType a.a_meta ->
  202. a.a_this <- t_dynamic;
  203. | fields ->
  204. let a_t =
  205. let params = List.map (fun t -> TPType (make_ptp_th (mk_type_path ([],fst t.tp_name)) null_pos)) d.d_params in
  206. make_ptp_ct_null (mk_type_path ~params ([],fst d.d_name)),null_pos
  207. in
  208. let rec loop = function
  209. | [] -> a_t
  210. | AbOver t :: _ -> t
  211. | _ :: l -> loop l
  212. in
  213. let this_t = loop d.d_flags in
  214. let fields = List.map (TypeloadFields.transform_abstract_field com this_t a_t a) fields in
  215. let meta = ref [] in
  216. if has_meta Meta.Dce a.a_meta then meta := (Meta.Dce,[],null_pos) :: !meta;
  217. let c_decl = { 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 } in
  218. let c = handle_class_decl c_decl p in
  219. a.a_impl <- Some c;
  220. c.cl_kind <- KAbstractImpl a;
  221. add_class_flag c CFinal;
  222. add_declaration (EClass c_decl,p) (TClassDecl c);
  223. end;
  224. in
  225. List.iter make_decl tdecls;
  226. begin match !statics with
  227. | [] ->
  228. ()
  229. | statics ->
  230. let first_pos = ref null_pos in
  231. let fields = List.map (fun (d,p) ->
  232. first_pos := p;
  233. field_of_static_definition d p;
  234. ) statics in
  235. let p = let p = !first_pos in { p with pmax = p.pmin } in
  236. let c_def = {
  237. d_name = (snd m.m_path) ^ "_Fields_", null_pos;
  238. d_flags = [HPrivate];
  239. d_data = List.rev fields;
  240. d_doc = None;
  241. d_params = [];
  242. d_meta = []
  243. } in
  244. let c = handle_class_decl c_def p in
  245. assert (m.m_statics = None);
  246. m.m_statics <- Some c;
  247. c.cl_kind <- KModuleFields m;
  248. add_class_flag c CFinal;
  249. add_declaration (EClass c_def,p) (TClassDecl c);
  250. end;
  251. (* During the initial module_lut#add in type_module, m has no m_types yet by design.
  252. We manually add them here. This and module_lut#add itself should be the only places
  253. in the compiler that call add_module_type. *)
  254. m.m_types <- m.m_types @ (DynArray.to_list module_types);
  255. DynArray.to_list imports_and_usings,DynArray.to_list declarations
  256. let handle_import_hx com g m decls p =
  257. let path_split = match List.rev (Path.get_path_parts (Path.UniqueKey.lazy_path m.m_extra.m_file)) with
  258. | [] -> []
  259. | _ :: l -> l
  260. in
  261. let join l = String.concat Path.path_sep (List.rev ("import.hx" :: l)) in
  262. let rec loop path pack = match path,pack with
  263. | _,[] -> [join path]
  264. | (p :: path),(_ :: pack) -> (join (p :: path)) :: (loop path pack)
  265. | _ -> []
  266. in
  267. let candidates = loop path_split (fst m.m_path) in
  268. let make_import_module path r =
  269. com.parser_cache#add path r;
  270. (* We use the file path as module name to make it unique. This may or may not be a good idea... *)
  271. let m_import = make_module com g ([],path) path p in
  272. m_import.m_extra.m_kind <- MImport;
  273. m_import
  274. in
  275. List.fold_left (fun acc path ->
  276. let decls = try
  277. let r = com.parser_cache#find path in
  278. let mimport = com.module_lut#find ([],path) in
  279. if mimport.m_extra.m_kind <> MFake then add_dependency m mimport MDepFromImport;
  280. r
  281. with Not_found ->
  282. if Sys.file_exists path then begin
  283. let _,r = match !TypeloadParse.parse_hook com (ClassPaths.create_resolved_file path com.empty_class_path) p with
  284. | ParseSuccess(data,_) -> data
  285. | ParseError(_,(msg,p),_) -> Parser.error msg p
  286. in
  287. List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> raise_typing_error "Only import and using is allowed in import.hx files" p) r;
  288. let m_import = make_import_module path r in
  289. add_module com m_import p;
  290. add_dependency m m_import MDepFromImport;
  291. r
  292. end else begin
  293. let r = [] in
  294. (* Add empty decls so we don't check the file system all the time. *)
  295. (make_import_module path r).m_extra.m_kind <- MFake;
  296. r
  297. end
  298. in
  299. decls @ acc
  300. ) decls candidates
  301. let init_type_params ctx_m decls =
  302. (* here is an additional PASS 1 phase, which define the type parameters for all module types.
  303. Constraints are handled lazily (no other type is loaded) because they might be recursive anyway *)
  304. List.iter (fun d ->
  305. match d with
  306. | ((EClass d, p),TClassDecl c) ->
  307. c.cl_params <- type_type_params ctx_m TPHType c.cl_path d.d_params;
  308. if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric;
  309. if Meta.has Meta.FunctionalInterface c.cl_meta then begin
  310. if not (has_class_flag c CInterface) then
  311. raise_typing_error "@:functionalInterface is only allowed on interfaces, as the name implies" c.cl_name_pos
  312. else
  313. add_class_flag c CFunctionalInterface
  314. end;
  315. if Meta.has Meta.GenericBuild c.cl_meta then begin
  316. if ctx_m.com.is_macro_context then raise_typing_error "@:genericBuild cannot be used in macros" c.cl_pos;
  317. c.cl_kind <- KGenericBuild d.d_data;
  318. end;
  319. if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType;
  320. | ((EEnum d, p),TEnumDecl e) ->
  321. e.e_params <- type_type_params ctx_m TPHType e.e_path d.d_params;
  322. | ((ETypedef d, p),TTypeDecl t) ->
  323. t.t_params <- type_type_params ctx_m TPHType t.t_path d.d_params;
  324. | ((EAbstract d, p),TAbstractDecl a) ->
  325. a.a_params <- type_type_params ctx_m TPHType a.a_path d.d_params;
  326. | _ ->
  327. die "" __LOC__
  328. ) decls
  329. end
  330. module TypeLevel = struct
  331. let load_enum_field ctx_en e et is_flat index c =
  332. let p = c.ec_pos in
  333. let params = type_type_params ctx_en TPHEnumConstructor ([],fst c.ec_name) c.ec_params in
  334. let ctx_ef = TyperManager.clone_for_enum_field ctx_en (params @ ctx_en.type_params) in
  335. let rt = (match c.ec_type with
  336. | None -> et
  337. | Some (t,pt) ->
  338. let t = load_complex_type ctx_ef true LoadReturn (t,pt) in
  339. (match follow t with
  340. | TEnum (te,_) when te == e ->
  341. ()
  342. | _ ->
  343. raise_typing_error "Explicit enum type must be of the same enum type" pt);
  344. t
  345. ) in
  346. let t = (match c.ec_args with
  347. | [] ->
  348. rt
  349. | l ->
  350. is_flat := false;
  351. let pnames = ref PMap.empty in
  352. TFun (List.map (fun (s,opt,(t,tp)) ->
  353. (match t with CTPath({path = {tpackage=[];tname="Void"}}) -> raise_typing_error "Arguments of type Void are not allowed in enum constructors" tp | _ -> ());
  354. if PMap.mem s (!pnames) then raise_typing_error ("Duplicate argument `" ^ s ^ "` in enum constructor " ^ fst c.ec_name) p;
  355. pnames := PMap.add s () (!pnames);
  356. s, opt, load_type_hint ~opt ctx_ef p LoadNormal (Some (t,tp))
  357. ) l, rt)
  358. ) in
  359. let f = {
  360. ef_name = fst c.ec_name;
  361. ef_type = t;
  362. ef_pos = p;
  363. ef_name_pos = snd c.ec_name;
  364. ef_doc = c.ec_doc;
  365. ef_index = !index;
  366. ef_params = params;
  367. ef_meta = c.ec_meta;
  368. } in
  369. DeprecationCheck.check_is ctx_ef.com ctx_ef.m.curmod e.e_meta f.ef_meta f.ef_name f.ef_meta f.ef_name_pos;
  370. if ctx_ef.m.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then
  371. DisplayEmitter.display_enum_field ctx_ef e f p;
  372. f
  373. let init_class ctx_m c d p =
  374. if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  375. DisplayEmitter.display_module_type ctx_m (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name);
  376. (match c.cl_kind with
  377. | KAbstractImpl _ -> ()
  378. | _ -> TypeloadCheck.check_global_metadata ctx_m c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None
  379. );
  380. let herits = d.d_flags in
  381. List.iter (fun (m,_,p) ->
  382. if m = Meta.Final then begin
  383. add_class_flag c CFinal;
  384. end
  385. ) d.d_meta;
  386. let prev_build_count = ref (ctx_m.g.build_count - 1) in
  387. let cctx = TypeloadFields.create_class_context c p in
  388. let ctx_c = TypeloadFields.create_typer_context_for_class ctx_m cctx p in
  389. let build() =
  390. c.cl_build <- (fun()-> Building [c]);
  391. let fl = TypeloadCheck.Inheritance.set_heritance ctx_c c herits p in
  392. let rec build() =
  393. c.cl_build <- (fun()-> Building [c]);
  394. try
  395. List.iter (fun f -> f()) fl;
  396. TypeloadFields.init_class ctx_c cctx c p d.d_flags d.d_data;
  397. c.cl_build <- (fun()-> Built);
  398. ctx_c.g.build_count <- ctx_c.g.build_count + 1;
  399. List.iter (fun tp -> ignore(follow tp.ttp_type)) c.cl_params;
  400. Built;
  401. with TypeloadCheck.Build_canceled state ->
  402. c.cl_build <- make_pass ctx_c build;
  403. let rebuild() =
  404. delay_late ctx_c.g PBuildClass (fun() -> ignore(c.cl_build()));
  405. in
  406. (match state with
  407. | Built -> die "" __LOC__
  408. | Building cl ->
  409. if ctx_c.g.build_count = !prev_build_count then raise_typing_error ("Loop in class building prevent compiler termination (" ^ String.concat "," (List.map (fun c -> s_type_path c.cl_path) cl) ^ ")") c.cl_pos;
  410. prev_build_count := ctx_c.g.build_count;
  411. rebuild();
  412. Building (c :: cl)
  413. | BuildMacro f ->
  414. f := rebuild :: !f;
  415. state);
  416. | exn ->
  417. c.cl_build <- (fun()-> Built);
  418. raise exn
  419. in
  420. build()
  421. in
  422. c.cl_build <- make_pass ctx_m build;
  423. delay ctx_m.g PBuildClass (fun() -> ignore(c.cl_build()));
  424. if Meta.has Meta.InheritDoc c.cl_meta then
  425. delay ctx_m.g PConnectField (fun() -> InheritDoc.build_class_doc ctx_m c);
  426. if (ctx_m.com.platform = Jvm) && not (has_class_flag c CExtern) then
  427. delay ctx_m.g PTypeField (fun () ->
  428. let metas = StrictMeta.check_strict_meta ctx_m c.cl_meta in
  429. if metas <> [] then c.cl_meta <- metas @ c.cl_meta;
  430. let rec run_field cf =
  431. let metas = StrictMeta.check_strict_meta ctx_m cf.cf_meta in
  432. if metas <> [] then cf.cf_meta <- metas @ cf.cf_meta;
  433. List.iter run_field cf.cf_overloads
  434. in
  435. List.iter run_field c.cl_ordered_statics;
  436. List.iter run_field c.cl_ordered_fields;
  437. match c.cl_constructor with
  438. | Some f -> run_field f
  439. | _ -> ()
  440. )
  441. let init_enum ctx_m e d p =
  442. if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  443. DisplayEmitter.display_module_type ctx_m (TEnumDecl e) (pos d.d_name);
  444. let ctx_en = TyperManager.clone_for_enum ctx_m e in
  445. TypeloadCheck.check_global_metadata ctx_en e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None;
  446. let constructs = ref d.d_data in
  447. let get_constructs() =
  448. List.map (fun c ->
  449. {
  450. cff_name = c.ec_name;
  451. cff_doc = c.ec_doc;
  452. cff_meta = c.ec_meta;
  453. cff_pos = c.ec_pos;
  454. cff_access = [];
  455. cff_kind = (match c.ec_args, c.ec_params with
  456. | [], [] -> FVar (c.ec_type,None)
  457. | _ -> 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 });
  458. }
  459. ) (!constructs)
  460. in
  461. TypeloadFields.build_module_def ctx_en (TEnumDecl e) e.e_meta get_constructs (fun (e,p) ->
  462. match e with
  463. | EVars [{ ev_type = Some (CTAnonymous fields,p); ev_expr = None }] ->
  464. constructs := List.map (fun f ->
  465. let args, params, t = (match f.cff_kind with
  466. | FVar (t,None) -> [], [], t
  467. | FFun { f_params = pl; f_type = t; f_expr = (None|Some (EBlock [],_)); f_args = al } ->
  468. let al = List.map (fun ((n,_),o,_,t,_) -> match t with None -> raise_typing_error "Missing function parameter type" f.cff_pos | Some t -> n,o,t) al in
  469. al, pl, t
  470. | _ ->
  471. raise_typing_error "Invalid enum constructor in @:build result" p
  472. ) in
  473. {
  474. ec_name = f.cff_name;
  475. ec_doc = f.cff_doc;
  476. ec_meta = f.cff_meta;
  477. ec_pos = f.cff_pos;
  478. ec_args = args;
  479. ec_params = params;
  480. ec_type = t;
  481. }
  482. ) fields
  483. | _ -> raise_typing_error "Enum build macro must return a single variable with anonymous object fields" p
  484. );
  485. let et = TEnum (e,extract_param_types e.e_params) in
  486. let names = ref [] in
  487. let index = ref 0 in
  488. let is_flat = ref true in
  489. List.iter (fun c ->
  490. if PMap.mem (fst c.ec_name) e.e_constrs then raise_typing_error ("Duplicate constructor " ^ fst c.ec_name) (pos c.ec_name);
  491. let f = load_enum_field ctx_en e et is_flat index c in
  492. e.e_constrs <- PMap.add f.ef_name f e.e_constrs;
  493. incr index;
  494. names := (fst c.ec_name) :: !names;
  495. if Meta.has Meta.InheritDoc f.ef_meta then
  496. delay ctx_en.g PConnectField (fun() -> InheritDoc.build_enum_field_doc ctx_en f);
  497. ) (!constructs);
  498. e.e_names <- List.rev !names;
  499. unify ctx_en (TType(enum_module_type e,[])) e.e_type p;
  500. if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta;
  501. if Meta.has Meta.InheritDoc e.e_meta then
  502. delay ctx_en.g PConnectField (fun() -> InheritDoc.build_enum_doc ctx_en e);
  503. if (ctx_en.com.platform = Jvm) && not (has_enum_flag e EnExtern) then
  504. delay ctx_en.g PTypeField (fun () ->
  505. let metas = StrictMeta.check_strict_meta ctx_en e.e_meta in
  506. e.e_meta <- metas @ e.e_meta;
  507. PMap.iter (fun _ ef ->
  508. let metas = StrictMeta.check_strict_meta ctx_en ef.ef_meta in
  509. if metas <> [] then ef.ef_meta <- metas @ ef.ef_meta
  510. ) e.e_constrs
  511. )
  512. let init_typedef ctx_m t d p =
  513. if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  514. DisplayEmitter.display_module_type ctx_m (TTypeDecl t) (pos d.d_name);
  515. TypeloadCheck.check_global_metadata ctx_m t.t_meta (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None;
  516. let ctx_td = TyperManager.clone_for_typedef ctx_m t in
  517. let tt = load_complex_type ctx_td true LoadNormal d.d_data in
  518. let tt = (match fst d.d_data with
  519. | CTExtend _ -> tt
  520. | CTPath { path = {tpackage = ["haxe";"macro"]; tname = "MacroType" }} ->
  521. (* we need to follow MacroType immediately since it might define other module types that we will load afterwards *)
  522. if t.t_type == follow tt then raise_typing_error "Recursive typedef is not allowed" p;
  523. tt
  524. | _ ->
  525. if (Meta.has Meta.Eager d.d_meta) then
  526. follow tt
  527. else begin
  528. let rec check_rec tt =
  529. if tt == t.t_type then raise_typing_error "Recursive typedef is not allowed" p;
  530. match tt with
  531. | TMono r ->
  532. (match r.tm_type with
  533. | None -> ()
  534. | Some t -> check_rec t)
  535. | TLazy f ->
  536. check_rec (lazy_type f);
  537. | TType (td,tl) ->
  538. if td == t then raise_typing_error "Recursive typedef is not allowed" p;
  539. check_rec (apply_typedef td tl)
  540. | _ ->
  541. ()
  542. in
  543. let r = make_lazy ctx_td.g tt (fun () ->
  544. check_rec tt;
  545. tt
  546. ) "typedef_rec_check" in
  547. TLazy r
  548. end
  549. ) in
  550. (match t.t_type with
  551. | TMono r ->
  552. (match r.tm_type with
  553. | None -> Monomorph.bind r tt;
  554. | Some t' -> die (Printf.sprintf "typedef %s is already initialized to %s, but new init to %s was attempted" (s_type_path t.t_path) (s_type_kind t') (s_type_kind tt)) __LOC__);
  555. | _ -> die "" __LOC__);
  556. TypeloadFields.build_module_def ctx_td (TTypeDecl t) t.t_meta (fun _ -> []) (fun _ -> ())
  557. let init_abstract ctx_m a d p =
  558. if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then
  559. DisplayEmitter.display_module_type ctx_m (TAbstractDecl a) (pos d.d_name);
  560. TypeloadCheck.check_global_metadata ctx_m a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None;
  561. Option.may (fun c ->
  562. List.iter (fun m -> match m with
  563. | ((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 | Meta.PublicFields),_,_) ->
  564. c.cl_meta <- m :: c.cl_meta;
  565. | _ ->
  566. ()
  567. ) a.a_meta;
  568. ) a.a_impl;
  569. let ctx_a = TyperManager.clone_for_abstract ctx_m a in
  570. let is_type = ref false in
  571. let load_type t from =
  572. let _, pos = t in
  573. let t = load_complex_type ctx_a true LoadNormal t in
  574. let t = if not (Meta.has Meta.CoreType a.a_meta) then begin
  575. if !is_type then begin
  576. let r = make_lazy ctx_a.g t (fun () ->
  577. (try (if from then Type.unify t a.a_this else Type.unify a.a_this t) with Unify_error _ -> raise_typing_error "You can only declare from/to with compatible types" pos);
  578. t
  579. ) "constraint" in
  580. TLazy r
  581. end else
  582. raise_typing_error "Missing underlying type declaration or @:coreType declaration" p;
  583. end else begin
  584. if Meta.has Meta.Callable a.a_meta then
  585. raise_typing_error "@:coreType abstracts cannot be @:callable" p;
  586. t
  587. end in
  588. t
  589. in
  590. List.iter (function
  591. | AbFrom t -> a.a_from <- (load_type t true) :: a.a_from
  592. | AbTo t -> a.a_to <- (load_type t false) :: a.a_to
  593. | AbOver t ->
  594. if a.a_impl = None then raise_typing_error "Abstracts with underlying type must have an implementation" a.a_pos;
  595. if Meta.has Meta.CoreType a.a_meta then raise_typing_error "@:coreType abstracts cannot have an underlying type" p;
  596. let at = load_complex_type ctx_a true LoadNormal t in
  597. delay ctx_a.g PForce (fun () ->
  598. let rec loop stack t =
  599. match follow t with
  600. | TAbstract(a,_) when not (Meta.has Meta.CoreType a.a_meta) ->
  601. if List.memq a stack then
  602. raise_typing_error "Abstract underlying type cannot be recursive" a.a_pos
  603. else
  604. loop (a :: stack) a.a_this
  605. | _ -> ()
  606. in
  607. loop [] at
  608. );
  609. a.a_this <- at;
  610. is_type := true;
  611. | AbExtern ->
  612. (match a.a_impl with Some c -> add_class_flag c CExtern | None -> (* Hmmmm.... *) ())
  613. | AbPrivate | AbEnum -> ()
  614. ) d.d_flags;
  615. a.a_from <- List.rev a.a_from;
  616. a.a_to <- List.rev a.a_to;
  617. if not !is_type then begin
  618. if Meta.has Meta.CoreType a.a_meta then
  619. a.a_this <- TAbstract(a,extract_param_types a.a_params)
  620. else
  621. raise_typing_error "Abstract is missing underlying type declaration" a.a_pos
  622. end;
  623. if Meta.has Meta.InheritDoc a.a_meta then
  624. delay ctx_a.g PConnectField (fun() -> InheritDoc.build_abstract_doc ctx_a a)
  625. (*
  626. In this pass, we can access load and access other modules types, but we cannot follow them or access their structure
  627. since they have not been setup. We also build a list that will be evaluated the first time we evaluate
  628. an expression into the context
  629. *)
  630. let init_module_type ctx_m ((decl,p),tdecl) =
  631. match decl with
  632. | EClass d ->
  633. let c = (match tdecl with TClassDecl c -> c | _ -> die "" __LOC__) in
  634. init_class ctx_m c d p
  635. | EEnum d ->
  636. let e = (match tdecl with TEnumDecl e -> e | _ -> die "" __LOC__) in
  637. init_enum ctx_m e d p
  638. | ETypedef d ->
  639. let t = (match tdecl with TTypeDecl t -> t | _ -> die "" __LOC__) in
  640. init_typedef ctx_m t d p
  641. | EAbstract d ->
  642. let a = (match tdecl with TAbstractDecl a -> a | _ -> die "" __LOC__) in
  643. init_abstract ctx_m a d p
  644. | _ ->
  645. die "" __LOC__
  646. let init_imports_or_using ctx_m (decl,p) =
  647. let com = ctx_m.com in
  648. let check_path_display path p =
  649. if DisplayPosition.display_position#is_in_file (com.file_keys#get p.pfile) then DisplayPath.handle_path_display ctx_m path p
  650. in
  651. match decl with
  652. | EImport (path,mode) ->
  653. begin try
  654. check_path_display path p;
  655. ImportHandling.init_import ctx_m path mode p;
  656. ImportHandling.commit_import ctx_m path mode p;
  657. with Error err ->
  658. display_error_ext com err
  659. end
  660. | EUsing path ->
  661. check_path_display path p;
  662. ImportHandling.init_using ctx_m path p
  663. | _ ->
  664. die "" __LOC__
  665. end
  666. let make_curmod com g m =
  667. let rl = g.root_typer.m.import_resolution#clone_as ["import";s_type_path m.m_path] in
  668. {
  669. curmod = m;
  670. import_resolution = rl;
  671. own_resolution = None;
  672. enum_with_type = None;
  673. module_using = [];
  674. import_statements = [];
  675. is_display_file = (com.display.dms_kind <> DMNone && DisplayPosition.display_position#is_in_file (Path.UniqueKey.lazy_key m.m_extra.m_file));
  676. }
  677. (*
  678. Creates a module context for [m] and types [tdecls] using it.
  679. *)
  680. let type_types_into_module com g m tdecls p =
  681. let ctx_m = TyperManager.clone_for_module g.root_typer (make_curmod com g m) in
  682. let imports_and_usings,decls = ModuleLevel.create_module_types ctx_m m tdecls p in
  683. ModuleLevel.init_type_params ctx_m decls;
  684. List.iter (TypeLevel.init_imports_or_using ctx_m) imports_and_usings;
  685. (* setup module types *)
  686. List.iter (TypeLevel.init_module_type ctx_m) decls;
  687. (* Make sure that we actually init the context at some point (issue #9012) *)
  688. delay ctx_m.g PConnectField (fun () -> ctx_m.m.import_resolution#resolve_lazies);
  689. ctx_m
  690. (*
  691. Creates a new module and types [tdecls] into it.
  692. *)
  693. let type_module com g mpath file ?(dont_check_path=false) ?(is_extern=false) tdecls p =
  694. let m = ModuleLevel.make_module com g mpath file p in
  695. com.module_lut#add m.m_path m;
  696. let tdecls = ModuleLevel.handle_import_hx com g m tdecls p in
  697. let ctx_m = type_types_into_module com g m tdecls p in
  698. if is_extern then m.m_extra.m_kind <- MExtern else if not dont_check_path then Naming.check_module_path ctx_m.com m.m_path p;
  699. m
  700. class hxb_reader_api_typeload
  701. (com : context)
  702. (g : typer_globals)
  703. (load_module : context -> typer_globals -> path -> pos -> module_def)
  704. (p : pos)
  705. = object(self)
  706. method make_module (path : path) (file : string) =
  707. let m = ModuleLevel.make_module com g path file p in
  708. m.m_extra.m_processed <- 1;
  709. m
  710. method add_module (m : module_def) =
  711. com.module_lut#add m.m_path m
  712. method resolve_type (pack : string list) (mname : string) (tname : string) =
  713. let m = load_module com g (pack,mname) p in
  714. List.find (fun t -> snd (t_path t) = tname) m.m_types
  715. method resolve_module (path : path) =
  716. load_module com g path p
  717. method basic_types =
  718. com.basic
  719. method get_var_id (i : int) =
  720. (* The v_id in .hxb has no relation to this context, make a new one. *)
  721. let uid = fst alloc_var' in
  722. Atomic.incr uid;
  723. Atomic.get uid
  724. method read_expression_eagerly (cf : tclass_field) =
  725. com.is_macro_context || match cf.cf_kind with
  726. | Var _ ->
  727. true
  728. | Method _ ->
  729. delay g PTypeField (fun () -> ignore(follow cf.cf_type));
  730. false
  731. method make_lazy_type t f =
  732. TLazy (make_lazy g t f "typeload-api")
  733. end
  734. let rec load_hxb_module com g path p =
  735. let read file bytes =
  736. try
  737. let api = (new hxb_reader_api_typeload com g load_module' p :> HxbReaderApi.hxb_reader_api) in
  738. let reader = new HxbReader.hxb_reader path com.hxb_reader_stats (if Common.defined com Define.HxbTimes then Some com.timer_ctx else None) in
  739. let read = reader#read api bytes in
  740. let m = read EOT in
  741. delay g PConnectField (fun () ->
  742. ignore(read EOM);
  743. );
  744. m
  745. with e ->
  746. Printf.eprintf "\x1b[30;41mError loading %s from %s\x1b[0m\n" (snd path) file;
  747. let msg = Printexc.to_string e and stack = Printexc.get_backtrace () in
  748. Printf.eprintf " => %s\n%s\n" msg stack;
  749. raise e
  750. in
  751. let target = Common.platform_name_macro com in
  752. let rec loop l = match l with
  753. | hxb_lib :: l ->
  754. begin match hxb_lib#get_bytes target path with
  755. | Some bytes ->
  756. read hxb_lib#get_file_path bytes
  757. | None ->
  758. loop l
  759. end
  760. | [] ->
  761. raise Not_found
  762. in
  763. loop com.hxb_libs
  764. and load_module' com g m p =
  765. try
  766. (* Check current context *)
  767. com.module_lut#find m
  768. with Not_found ->
  769. (* Check cache *)
  770. match !TypeloadCacheHook.type_module_hook com (delay g) m p with
  771. | GoodModule m ->
  772. m
  773. | BinaryModule _ ->
  774. die "" __LOC__ (* The server builds those *)
  775. | NoModule | BadModule _ -> try
  776. load_hxb_module com g m p
  777. with Not_found ->
  778. let raise_not_found () = raise_error_msg (Module_not_found m) p in
  779. if com.module_nonexistent_lut#mem m then raise_not_found();
  780. if g.load_only_cached_modules then raise_not_found();
  781. let is_extern = ref false in
  782. let file, decls = try
  783. (* Try parsing *)
  784. let rfile,decls = TypeloadParse.parse_module com m p in
  785. rfile.file,decls
  786. with Not_found ->
  787. (* Nothing to parse, try loading extern type *)
  788. let rec loop = function
  789. | [] ->
  790. com.module_nonexistent_lut#add m true;
  791. raise_not_found()
  792. | (file,load) :: l ->
  793. match load m p with
  794. | None -> loop l
  795. | Some (_,a) -> file, a
  796. in
  797. is_extern := true;
  798. loop com.load_extern_type
  799. in
  800. let is_extern = !is_extern in
  801. type_module com g m file ~is_extern decls p
  802. let load_module ?(origin:module_dep_origin = MDepFromTyping) ctx m p =
  803. let m2 = load_module' ctx.com ctx.g m p in
  804. add_dependency ~skip_postprocess:true ctx.m.curmod m2 origin;
  805. if ctx.pass = PTypeField then flush_pass ctx.g PConnectField ("load_module",fst m @ [snd m]);
  806. m2
  807. ;;