calls.ml 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. open Globals
  2. open DisplayTypes.DisplayMode
  3. open Common
  4. open Ast
  5. open Type
  6. open Typecore
  7. open TyperBase
  8. open Fields
  9. open Error
  10. let is_forced_inline c cf =
  11. match c with
  12. | Some { cl_kind = KAbstractImpl _ } -> true
  13. | Some c when has_class_flag c CExtern -> true
  14. | _ when has_class_field_flag cf CfExtern -> true
  15. | _ -> false
  16. let make_call ctx e params t ?(force_inline=false) p =
  17. try
  18. let ethis,cl,f = match e.eexpr with
  19. | TField (ethis,fa) ->
  20. let co,cf = match fa with
  21. | FInstance(c,_,cf) | FStatic(c,cf) -> Some c,cf
  22. | FAnon cf -> None,cf
  23. | _ -> raise Exit
  24. in
  25. ethis,co,cf
  26. | _ ->
  27. raise Exit
  28. in
  29. if not force_inline then begin
  30. let is_extern_class = match cl with Some c -> (has_class_flag c CExtern) | _ -> false in
  31. if not (Inline.needs_inline ctx is_extern_class f) then raise Exit;
  32. end else begin
  33. match cl with
  34. | None ->
  35. ()
  36. | Some c ->
  37. (* Delay this to filters because that's when cl_descendants is set. *)
  38. ctx.com.callbacks#add_before_save (fun () ->
  39. let rec has_override c =
  40. PMap.mem f.cf_name c.cl_fields
  41. || List.exists has_override c.cl_descendants
  42. in
  43. if List.exists has_override c.cl_descendants then error (Printf.sprintf "Cannot force inline-call to %s because it is overridden" f.cf_name) p
  44. )
  45. end;
  46. let config = Inline.inline_config cl f params t in
  47. ignore(follow f.cf_type); (* force evaluation *)
  48. (match cl, ctx.curclass.cl_kind, params with
  49. | Some c, KAbstractImpl _, { eexpr = TLocal { v_meta = v_meta } } :: _ when c == ctx.curclass ->
  50. if
  51. not (has_class_field_flag f CfConstructor)
  52. && has_meta Meta.This v_meta
  53. && has_class_field_flag f CfModifiesThis
  54. then
  55. if assign_to_this_is_allowed ctx then
  56. (* Current method needs to infer CfModifiesThis flag, since we are calling a method, which modifies `this` *)
  57. add_class_field_flag ctx.curfield CfModifiesThis
  58. else
  59. error ("Abstract 'this' value can only be modified inside an inline function. '" ^ f.cf_name ^ "' modifies 'this'") p;
  60. | _ -> ()
  61. );
  62. let params = List.map (ctx.g.do_optimize ctx) params in
  63. let force_inline = is_forced_inline cl f in
  64. (match f.cf_expr_unoptimized,f.cf_expr with
  65. | Some fd,_
  66. | None,Some { eexpr = TFunction fd } ->
  67. (match Inline.type_inline ctx f fd ethis params t config p force_inline with
  68. | None ->
  69. if force_inline then error "Inline could not be done" p;
  70. raise Exit;
  71. | Some e -> e)
  72. | _ ->
  73. (*
  74. we can't inline because there is most likely a loop in the typing.
  75. this can be caused by mutually recursive vars/functions, some of them
  76. being inlined or not. In that case simply ignore inlining.
  77. *)
  78. raise Exit)
  79. with Exit ->
  80. mk (TCall (e,params)) t p
  81. let mk_array_get_call ctx (cf,tf,r,e1,e2o) c ebase p = match cf.cf_expr with
  82. | None ->
  83. if not (Meta.has Meta.NoExpr cf.cf_meta) then display_error ctx "Recursive array get method" p;
  84. mk (TArray(ebase,e1)) r p
  85. | Some _ ->
  86. let et = type_module_type ctx (TClassDecl c) None p in
  87. let ef = mk (TField(et,(FStatic(c,cf)))) tf p in
  88. make_call ctx ef [ebase;e1] r p
  89. let mk_array_set_call ctx (cf,tf,r,e1,e2o) c ebase p =
  90. let evalue = match e2o with None -> die "" __LOC__ | Some e -> e in
  91. match cf.cf_expr with
  92. | None ->
  93. if not (Meta.has Meta.NoExpr cf.cf_meta) then display_error ctx "Recursive array set method" p;
  94. let ea = mk (TArray(ebase,e1)) r p in
  95. mk (TBinop(OpAssign,ea,evalue)) r p
  96. | Some _ ->
  97. let et = type_module_type ctx (TClassDecl c) None p in
  98. let ef = mk (TField(et,(FStatic(c,cf)))) tf p in
  99. make_call ctx ef [ebase;e1;evalue] r p
  100. let rec unify_call_args' ctx el args r callp inline force_inline =
  101. let in_call_args = ctx.in_call_args in
  102. ctx.in_call_args <- true;
  103. let call_error err p =
  104. raise (Error (Call_error err,p))
  105. in
  106. let arg_error ul name opt p =
  107. let err = Stack (ul,Custom ("For " ^ (if opt then "optional " else "") ^ "function argument '" ^ name ^ "'")) in
  108. call_error (Could_not_unify err) p
  109. in
  110. let mk_pos_infos t =
  111. let infos = mk_infos ctx callp [] in
  112. type_expr ctx infos (WithType.with_type t)
  113. in
  114. let rec default_value name t =
  115. if is_pos_infos t then
  116. mk_pos_infos t
  117. else
  118. null (ctx.t.tnull t) callp
  119. in
  120. let skipped = ref [] in
  121. let invalid_skips = ref [] in
  122. let skip name ul t p =
  123. if not ctx.com.config.pf_can_skip_non_nullable_argument && not (is_nullable t) then
  124. invalid_skips := name :: !invalid_skips;
  125. skipped := (name,ul,p) :: !skipped;
  126. default_value name t
  127. in
  128. (* let force_inline, is_extern = match cf with Some(TInst(c,_),f) -> is_forced_inline (Some c) f, (has_class_flag c CExtern) | _ -> false, false in *)
  129. let type_against name t e =
  130. try
  131. let e = type_expr ctx e (WithType.with_argument t name) in
  132. AbstractCast.cast_or_unify_raise ctx t e e.epos
  133. with Error(l,p) when (match l with Call_error _ | Module_not_found _ -> false | _ -> true) ->
  134. raise (WithTypeError (l,p))
  135. in
  136. let rec loop el args = match el,args with
  137. | [],[] ->
  138. begin match List.rev !invalid_skips with
  139. | [] -> ()
  140. | name :: _ -> call_error (Cannot_skip_non_nullable name) callp;
  141. end;
  142. []
  143. | _,[name,false,t] when (match follow t with TAbstract({a_path = ["haxe";"extern"],"Rest"},_) -> true | _ -> false) ->
  144. begin match follow t with
  145. | TAbstract({a_path=(["haxe";"extern"],"Rest")},[t]) ->
  146. (try List.map (fun e -> type_against name t e,false) el with WithTypeError(ul,p) -> arg_error ul name false p)
  147. | _ ->
  148. die "" __LOC__
  149. end
  150. | [],(_,false,_) :: _ ->
  151. call_error (Not_enough_arguments args) callp
  152. | [],(name,true,t) :: args ->
  153. begin match loop [] args with
  154. | [] when not (inline && (ctx.g.doinline || force_inline)) && not ctx.com.config.pf_pad_nulls ->
  155. if is_pos_infos t then [mk_pos_infos t,true]
  156. else []
  157. | args ->
  158. let e_def = default_value name t in
  159. (e_def,true) :: args
  160. end
  161. | (e,p) :: el, [] ->
  162. begin match List.rev !skipped with
  163. | [] ->
  164. if ctx.is_display_file && not (Diagnostics.is_diagnostics_run ctx.com p) then begin
  165. ignore(type_expr ctx (e,p) WithType.value);
  166. loop el []
  167. end else call_error Too_many_arguments p
  168. | (s,ul,p) :: _ -> arg_error ul s true p
  169. end
  170. | e :: el,(name,opt,t) :: args ->
  171. begin try
  172. let e = type_against name t e in
  173. (e,opt) :: loop el args
  174. with
  175. WithTypeError (ul,p)->
  176. if opt && List.length el < List.length args then
  177. let e_def = skip name ul t p in
  178. (e_def,true) :: loop (e :: el) args
  179. else
  180. match List.rev !skipped with
  181. | [] -> arg_error ul name opt p
  182. | (s,ul,p) :: _ -> arg_error ul s true p
  183. end
  184. in
  185. let el = try loop el args with exc -> ctx.in_call_args <- in_call_args; raise exc; in
  186. ctx.in_call_args <- in_call_args;
  187. el,TFun(args,r)
  188. let unify_call_args ctx el args r p inline force_inline =
  189. let el,tf = unify_call_args' ctx el args r p inline force_inline in
  190. List.map fst el,tf
  191. type overload_kind =
  192. | OverloadProper (* @:overload or overload *)
  193. | OverloadMeta (* @:overload(function() {}) *)
  194. | OverloadNone
  195. let unify_field_call ctx fa el_typed el p inline =
  196. let expand_overloads cf =
  197. cf :: cf.cf_overloads
  198. in
  199. let candidates,co,static,map,tmap = match fa.fa_host with
  200. | FHStatic c ->
  201. expand_overloads fa.fa_field,Some c,true,(fun t -> t),(fun t -> t)
  202. | FHAnon ->
  203. expand_overloads fa.fa_field,None,false,(fun t -> t),(fun t -> t)
  204. | FHInstance(c,tl) ->
  205. let cf = fa.fa_field in
  206. let cfl = if has_class_field_flag cf CfConstructor || not (has_class_field_flag cf CfOverload) then
  207. cf :: cf.cf_overloads
  208. else
  209. List.map (fun (t,cf) ->
  210. cf
  211. ) (Overloads.get_overloads ctx.com c cf.cf_name)
  212. in
  213. cfl,Some c,false,TClass.get_map_function c tl,(fun t -> t)
  214. | FHAbstract(a,tl,c) ->
  215. let map = apply_params a.a_params tl in
  216. let tmap = if has_class_field_flag fa.fa_field CfConstructor then (fun t -> t) else (fun t -> map a.a_this) in
  217. expand_overloads fa.fa_field,Some c,true,map,tmap
  218. in
  219. let is_forced_inline = is_forced_inline co fa.fa_field in
  220. let overload_kind = if has_class_field_flag fa.fa_field CfOverload then OverloadProper
  221. else if fa.fa_field.cf_overloads <> [] then OverloadMeta
  222. else OverloadNone
  223. in
  224. let attempt_call cf =
  225. let monos = Monomorph.spawn_constrained_monos map cf.cf_params in
  226. let t = map (apply_params cf.cf_params monos cf.cf_type) in
  227. match follow t with
  228. | TFun(args,ret) ->
  229. let rec loop acc_el acc_args tmap args el_typed = match args,el_typed with
  230. | ((_,opt,t0) as arg) :: args,e :: el_typed ->
  231. begin try
  232. unify_raise ctx (tmap e.etype) t0 e.epos;
  233. with Error(Unify _ as msg,p) ->
  234. let call_error = Call_error(Could_not_unify msg) in
  235. raise(Error(call_error,p))
  236. end;
  237. loop ((e,opt) :: acc_el) (arg :: acc_args) (fun t -> t) args el_typed
  238. | _ ->
  239. List.rev acc_el,List.rev acc_args,args
  240. in
  241. let el_typed,args_typed,args = loop [] [] tmap args el_typed in
  242. let el,_ = unify_call_args' ctx el args ret p inline is_forced_inline in
  243. let el = el_typed @ el in
  244. let tf = TFun(args_typed @ args,ret) in
  245. let mk_call () =
  246. let ef = mk (TField(fa.fa_on,FieldAccess.apply_fa cf fa.fa_host)) t fa.fa_pos in
  247. let el = List.map fst el in
  248. make_call ctx ef el ret ~force_inline:inline p
  249. in
  250. make_field_call_candidate el ret monos tf cf mk_call
  251. | t ->
  252. error (s_type (print_context()) t ^ " cannot be called") p
  253. in
  254. let maybe_raise_unknown_ident cerr p =
  255. let rec loop err =
  256. match err with
  257. | Unknown_ident _ -> error (error_msg err) p
  258. | Stack (e1,e2) -> (loop e1; loop e2)
  259. | _ -> ()
  260. in
  261. match cerr with Could_not_unify err -> loop err | _ -> ()
  262. in
  263. let attempt_calls candidates =
  264. let rec loop candidates = match candidates with
  265. | [] -> [],[]
  266. | cf :: candidates ->
  267. let known_monos = List.map (fun (m,_) ->
  268. m,m.tm_type,m.tm_constraints
  269. ) ctx.monomorphs.perfunction in
  270. let current_monos = ctx.monomorphs.perfunction in
  271. begin try
  272. let candidate = attempt_call cf in
  273. ctx.monomorphs.perfunction <- current_monos;
  274. if overload_kind = OverloadProper then begin
  275. let candidates,failures = loop candidates in
  276. candidate :: candidates,failures
  277. end else
  278. [candidate],[]
  279. with Error ((Call_error cerr as err),p) ->
  280. List.iter (fun (m,t,constr) ->
  281. if t != m.tm_type then m.tm_type <- t;
  282. if constr != m.tm_constraints then m.tm_constraints <- constr;
  283. ) known_monos;
  284. ctx.monomorphs.perfunction <- current_monos;
  285. maybe_raise_unknown_ident cerr p;
  286. let candidates,failures = loop candidates in
  287. candidates,(cf,err,p) :: failures
  288. end
  289. in
  290. loop candidates
  291. in
  292. let fail_fun () =
  293. let tf = TFun(List.map (fun _ -> ("",false,t_dynamic)) el,t_dynamic) in
  294. let call () =
  295. let ef = mk (TField(fa.fa_on,FieldAccess.apply_fa fa.fa_field fa.fa_host)) tf fa.fa_pos in
  296. mk (TCall(ef,[])) t_dynamic p
  297. in
  298. make_field_call_candidate [] t_dynamic [] tf fa.fa_field call
  299. in
  300. let maybe_check_access cf =
  301. (* type_field doesn't check access for overloads, so let's check it here *)
  302. begin match co with
  303. | Some c ->
  304. check_field_access ctx c cf static p;
  305. | None ->
  306. ()
  307. end;
  308. in
  309. match candidates with
  310. | [cf] ->
  311. if overload_kind = OverloadProper then maybe_check_access cf;
  312. begin try
  313. attempt_call cf
  314. with Error _ when ctx.com.display.dms_error_policy = EPIgnore ->
  315. fail_fun();
  316. end
  317. | _ ->
  318. let candidates,failures = attempt_calls candidates in
  319. let fail () =
  320. let failures = List.map (fun (cf,err,p) -> cf,error_msg err,p) failures in
  321. let failures = remove_duplicates (fun (_,msg1,_) (_,msg2,_) -> msg1 <> msg2) failures in
  322. begin match failures with
  323. | [_,msg,p] ->
  324. error msg p
  325. | _ ->
  326. display_error ctx "Could not find a suitable overload, reasons follow" p;
  327. List.iter (fun (cf,msg,p2) ->
  328. display_error ctx ("Overload resolution failed for " ^ (s_type (print_context()) cf.cf_type)) p;
  329. display_error ctx msg p2;
  330. ) failures;
  331. error "End of overload failure reasons" p
  332. end
  333. in
  334. if overload_kind = OverloadProper then begin match Overloads.Resolution.reduce_compatible candidates with
  335. | [] -> fail()
  336. | [fcc] ->
  337. maybe_check_access fcc.fc_field;
  338. fcc
  339. | fcc :: l ->
  340. display_error ctx "Ambiguous overload, candidates follow" p;
  341. let st = s_type (print_context()) in
  342. List.iter (fun fcc ->
  343. display_error ctx (Printf.sprintf "... %s" (st fcc.fc_type)) fcc.fc_field.cf_name_pos;
  344. ) (fcc :: l);
  345. fcc
  346. end else begin match List.rev candidates with
  347. | [] -> fail()
  348. | fcc :: _ -> fcc
  349. end
  350. let type_generic_function ctx fa el_typed el with_type p =
  351. let c,stat = match fa.fa_host with
  352. | FHInstance(c,tl) -> c,false
  353. | FHStatic c -> c,true
  354. | FHAbstract(a,tl,c) -> c,true
  355. | _ -> die "" __LOC__
  356. in
  357. let cf = fa.fa_field in
  358. if cf.cf_params = [] then error "Function has no type parameters and cannot be generic" p;
  359. let fcc = unify_field_call ctx fa el_typed el p false in
  360. begin match with_type with
  361. | WithType.WithType(t,_) -> unify ctx fcc.fc_ret t p
  362. | _ -> ()
  363. end;
  364. let monos = fcc.fc_monos in
  365. List.iter (fun t -> match follow t with
  366. | TMono m -> safe_mono_close ctx m p
  367. | _ -> ()
  368. ) monos;
  369. let el = List.map fst fcc.fc_args in
  370. (try
  371. let gctx = Generic.make_generic ctx cf.cf_params monos p in
  372. let name = cf.cf_name ^ "_" ^ gctx.Generic.name in
  373. let unify_existing_field tcf pcf = try
  374. unify_raise ctx tcf fcc.fc_type p
  375. with Error(Unify _,_) as err ->
  376. display_error ctx ("Cannot create field " ^ name ^ " due to type mismatch") p;
  377. display_error ctx (compl_msg "Conflicting field was defined here") pcf;
  378. raise err
  379. in
  380. let fa = try
  381. let cf2 = if stat then
  382. let cf2 = PMap.find name c.cl_statics in
  383. unify_existing_field cf2.cf_type cf2.cf_pos;
  384. cf2
  385. else
  386. let cf2 = PMap.find name c.cl_fields in
  387. unify_existing_field cf2.cf_type cf2.cf_pos;
  388. cf2
  389. in
  390. {fa with fa_field = cf2}
  391. (*
  392. java.Lib.array() relies on the ability to shadow @:generic function for certain types
  393. see https://github.com/HaxeFoundation/haxe/issues/8393#issuecomment-508685760
  394. *)
  395. (* if cf.cf_name_pos = cf2.cf_name_pos then
  396. cf2
  397. else
  398. error ("Cannot specialize @:generic because the generated function name is already used: " ^ name) p *)
  399. with Not_found ->
  400. let finalize_field c cf2 =
  401. ignore(follow cf.cf_type);
  402. let rec check e = match e.eexpr with
  403. | TNew({cl_kind = KTypeParameter _} as c,_,_) when not (TypeloadCheck.is_generic_parameter ctx c) ->
  404. display_error ctx "Only generic type parameters can be constructed" e.epos;
  405. display_error ctx "While specializing this call" p;
  406. | _ ->
  407. Type.iter check e
  408. in
  409. cf2.cf_expr <- (match cf.cf_expr with
  410. | None ->
  411. display_error ctx "Recursive @:generic function" p; None;
  412. | Some e ->
  413. let e = Generic.generic_substitute_expr gctx e in
  414. check e;
  415. Some e
  416. );
  417. cf2.cf_kind <- cf.cf_kind;
  418. if not (has_class_field_flag cf CfPublic) then remove_class_field_flag cf2 CfPublic;
  419. cf2.cf_meta <- (Meta.NoCompletion,[],p) :: (Meta.NoUsing,[],p) :: (Meta.GenericInstance,[],p) :: cf.cf_meta
  420. in
  421. let mk_cf2 name =
  422. mk_field ~static:stat name fcc.fc_type cf.cf_pos cf.cf_name_pos
  423. in
  424. if stat then begin
  425. if Meta.has Meta.GenericClassPerMethod c.cl_meta then begin
  426. let c = Generic.static_method_container gctx c cf p in
  427. let cf2 = try
  428. let cf2 = PMap.find cf.cf_name c.cl_statics in
  429. unify_existing_field cf2.cf_type cf2.cf_pos;
  430. cf2
  431. with Not_found ->
  432. let cf2 = mk_cf2 cf.cf_name in
  433. c.cl_statics <- PMap.add cf2.cf_name cf2 c.cl_statics;
  434. c.cl_ordered_statics <- cf2 :: c.cl_ordered_statics;
  435. finalize_field c cf2;
  436. cf2
  437. in
  438. {fa with fa_host = FHStatic c;fa_field = cf2;fa_on = Builder.make_static_this c p}
  439. end else begin
  440. let cf2 = mk_cf2 name in
  441. c.cl_statics <- PMap.add cf2.cf_name cf2 c.cl_statics;
  442. c.cl_ordered_statics <- cf2 :: c.cl_ordered_statics;
  443. finalize_field c cf2;
  444. {fa with fa_field = cf2}
  445. end
  446. end else begin
  447. let cf2 = mk_cf2 name in
  448. if has_class_field_flag cf CfOverride then add_class_field_flag cf2 CfOverride;
  449. c.cl_fields <- PMap.add cf2.cf_name cf2 c.cl_fields;
  450. c.cl_ordered_fields <- cf2 :: c.cl_ordered_fields;
  451. finalize_field c cf2;
  452. {fa with fa_field = cf2}
  453. end
  454. in
  455. let e = FieldAccess.get_field_expr fa FCall in
  456. make_call ctx e el fcc.fc_ret p
  457. with Generic.Generic_Exception (msg,p) ->
  458. error msg p)
  459. let abstract_using_param_type sea = match follow sea.se_this.etype with
  460. | TAbstract(a,tl) when has_class_field_flag sea.se_access.fa_field CfImpl -> apply_params a.a_params tl a.a_this
  461. | _ -> sea.se_this.etype
  462. class call_dispatcher
  463. (ctx : typer)
  464. (mode : access_mode)
  465. (with_type : WithType.t)
  466. (p : pos)
  467. =
  468. let is_set = match mode with MSet _ -> true | _ -> false in
  469. let check_assign () = if is_set then invalid_assign p in
  470. object(self)
  471. method private make_field_call (fa : field_access) (el_typed : texpr list) (el : expr list) =
  472. let fcc = unify_field_call ctx fa el_typed el p fa.fa_inline in
  473. if has_class_field_flag fcc.fc_field CfAbstract then begin match fa.fa_on.eexpr with
  474. | TConst TSuper -> display_error ctx (Printf.sprintf "abstract method %s cannot be accessed directly" fcc.fc_field.cf_name) p;
  475. | _ -> ()
  476. end;
  477. fcc.fc_data()
  478. method private macro_call (ethis : texpr) (cf : tclass_field) (el : expr list) =
  479. if ctx.macro_depth > 300 then error "Stack overflow" p;
  480. ctx.macro_depth <- ctx.macro_depth + 1;
  481. ctx.with_type_stack <- with_type :: ctx.with_type_stack;
  482. let ethis_f = ref (fun () -> ()) in
  483. let f = (match ethis.eexpr with
  484. | TTypeExpr (TClassDecl c) ->
  485. DeprecationCheck.check_cf ctx.com cf p;
  486. (match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name el p with
  487. | None -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
  488. | Some (EMeta((Meta.MergeBlock,_,_),(EBlock el,_)),_) -> (fun () -> let e = (!type_block_ref) ctx el with_type p in mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos)
  489. | Some e -> (fun() -> type_expr ~mode ctx e with_type))
  490. | _ ->
  491. (* member-macro call : since we will make a static call, let's find the actual class and not its subclass *)
  492. (match follow ethis.etype with
  493. | TInst (c,_) ->
  494. let rec loop c =
  495. if PMap.mem cf.cf_name c.cl_fields then
  496. let eparam,f = push_this ctx ethis in
  497. ethis_f := f;
  498. let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name (eparam :: el) p with
  499. | None -> (fun() -> type_expr ~mode ctx (EConst (Ident "null"),p) WithType.value)
  500. | Some e -> (fun() -> type_expr ~mode ctx e WithType.value)
  501. in
  502. e
  503. else
  504. match c.cl_super with
  505. | None -> die "" __LOC__
  506. | Some (csup,_) -> loop csup
  507. in
  508. loop c
  509. | _ -> die "" __LOC__))
  510. in
  511. ctx.macro_depth <- ctx.macro_depth - 1;
  512. ctx.with_type_stack <- List.tl ctx.with_type_stack;
  513. let old = ctx.on_error in
  514. ctx.on_error <- (fun ctx msg ep ->
  515. (* display additional info in the case the error is not part of our original call *)
  516. if ep.pfile <> p.pfile || ep.pmax < p.pmin || ep.pmin > p.pmax then begin
  517. TypeloadFields.locate_macro_error := false;
  518. old ctx msg ep;
  519. TypeloadFields.locate_macro_error := true;
  520. ctx.com.error (compl_msg "Called from macro here") p;
  521. end else
  522. old ctx msg ep;
  523. );
  524. let e = try
  525. f()
  526. with exc ->
  527. ctx.on_error <- old;
  528. !ethis_f();
  529. raise exc
  530. in
  531. let e = Diagnostics.secure_generated_code ctx e in
  532. ctx.on_error <- old;
  533. !ethis_f();
  534. e
  535. (* Calls `e` with arguments `el`. Does not inspect the callee expression, so it should only be
  536. used with actual expression calls and not with something like field calls. *)
  537. method expr_call (e : texpr) (el : expr list) =
  538. check_assign();
  539. let rec loop t = match follow t with
  540. | TFun (args,r) ->
  541. let el, tfunc = unify_call_args ctx el args r p false false in
  542. let r = match tfunc with TFun(_,r) -> r | _ -> die "" __LOC__ in
  543. mk (TCall (e,el)) r p
  544. | TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta ->
  545. loop (Abstract.get_underlying_type a tl)
  546. | TMono _ ->
  547. let t = mk_mono() in
  548. let el = List.map (fun e -> type_expr ctx e WithType.value) el in
  549. unify ctx (tfun (List.map (fun e -> e.etype) el) t) e.etype e.epos;
  550. mk (TCall (e,el)) t p
  551. | t ->
  552. let el = List.map (fun e -> type_expr ctx e WithType.value) el in
  553. let t = if t == t_dynamic then
  554. t_dynamic
  555. else if ctx.untyped then
  556. mk_mono()
  557. else
  558. error (s_type (print_context()) e.etype ^ " cannot be called") e.epos
  559. in
  560. mk (TCall (e,el)) t p
  561. in
  562. loop e.etype
  563. (* Calls the resolve method represented by `sea` with an additional string-expression argument `name`. *)
  564. method resolve_call (sea : static_extension_access) (name : string) =
  565. let eparam = sea.se_this in
  566. let e_name = Texpr.Builder.make_string ctx.t name null_pos in
  567. self#field_call sea.se_access [eparam;e_name] []
  568. method setter_call fa el_typed el =
  569. let fa_set = match FieldAccess.resolve_accessor fa (MSet None) with
  570. | AccessorFound fa -> fa
  571. | _ -> error "Could not resolve accessor" p
  572. in
  573. let dispatcher = new call_dispatcher ctx (MCall el) with_type p in
  574. dispatcher#field_call fa_set el_typed el
  575. (* Calls the field represented by `fa` with the typed arguments `el_typed` and the syntactic arguments `el`.
  576. This function inspects the nature of the field being called and dispatches the call accordingly:
  577. * If the field is `@:generic`, call `type_generic_function`.
  578. * If the field is a non-macro method, call it via `make_field_call`.
  579. * If the field is a property, resolve the accessor (depending on `mode`) and recurse onto it.
  580. * Otherwise, call the field as a normal expression via `expr_call`.
  581. *)
  582. method field_call (fa : field_access) (el_typed : texpr list) (el : expr list) =
  583. match fa.fa_field.cf_kind with
  584. | Method (MethNormal | MethInline | MethDynamic) ->
  585. check_assign();
  586. if has_class_field_flag fa.fa_field CfGeneric then begin
  587. type_generic_function ctx fa el_typed el with_type p
  588. end else
  589. self#make_field_call fa el_typed el
  590. | Method MethMacro ->
  591. begin match el_typed with
  592. | [] ->
  593. self#macro_call fa.fa_on fa.fa_field el
  594. | el_typed ->
  595. let cur = ctx.this_stack in
  596. let el' = List.map (fun e -> fst (push_this ctx e)) el_typed in
  597. let e = self#macro_call fa.fa_on fa.fa_field (el' @ el) in
  598. ctx.this_stack <- cur;
  599. e
  600. end;
  601. | Var v ->
  602. begin match (if is_set then v.v_write else v.v_read) with
  603. | AccCall ->
  604. begin match FieldAccess.resolve_accessor fa mode with
  605. | AccessorFound fa' ->
  606. let t = FieldAccess.get_map_function fa fa.fa_field.cf_type in
  607. let e = self#field_call fa' el_typed el in
  608. if not (type_iseq_strict t e.etype) then mk (TCast(e,None)) t e.epos else e
  609. | AccessorAnon ->
  610. (* Anons might not have the accessor defined and rely on FDynamic in such cases *)
  611. let e = fa.fa_on in
  612. let t = FieldAccess.get_map_function fa fa.fa_field.cf_type in
  613. let tf = tfun (List.map (fun e -> e.etype) el_typed) t in
  614. make_call ctx (mk (TField (e,quick_field_dynamic e.etype ("get_" ^ fa.fa_field.cf_name))) tf p) el_typed t p
  615. | AccessorNotFound ->
  616. error ("Could not resolve accessor") fa.fa_pos
  617. | AccessorInvalid ->
  618. die "Trying to resolve accessor on field that isn't AccCall" __LOC__
  619. end
  620. | _ ->
  621. self#expr_call (FieldAccess.get_field_expr fa FCall) el
  622. end
  623. end
  624. let rec acc_get ctx g p =
  625. let inline_read fa =
  626. let cf = fa.fa_field in
  627. (* do not create a closure for static calls *)
  628. let apply_params = match fa.fa_host with
  629. | FHStatic c ->
  630. (fun t -> t)
  631. | FHInstance(c,tl) ->
  632. (fun t -> t)
  633. | FHAbstract(a,tl,c) ->
  634. if a.a_enum then begin
  635. (* Enum abstracts have to apply their type parameters because they are basically statics with type params (#8700). *)
  636. let monos = Monomorph.spawn_constrained_monos (fun t -> t) a.a_params in
  637. apply_params a.a_params monos;
  638. end else
  639. (fun t -> t)
  640. | _ ->
  641. die "" __LOC__
  642. in
  643. ignore(follow cf.cf_type); (* force computing *)
  644. begin match cf.cf_kind,cf.cf_expr with
  645. | _ when not (ctx.com.display.dms_inline) ->
  646. FieldAccess.get_field_expr fa FRead
  647. | Method _,_->
  648. let chk_class c = ((has_class_flag c CExtern) || has_class_field_flag cf CfExtern) && not (Meta.has Meta.Runtime cf.cf_meta) in
  649. let wrap_extern c =
  650. let c2 =
  651. let m = c.cl_module in
  652. let mpath = (fst m.m_path @ ["_" ^ snd m.m_path],(snd m.m_path) ^ "_Impl_") in
  653. try
  654. let rec loop mtl = match mtl with
  655. | (TClassDecl c) :: _ when c.cl_path = mpath -> c
  656. | _ :: mtl -> loop mtl
  657. | [] -> raise Not_found
  658. in
  659. loop c.cl_module.m_types
  660. with Not_found ->
  661. let c2 = mk_class c.cl_module mpath c.cl_pos null_pos in
  662. c.cl_module.m_types <- (TClassDecl c2) :: c.cl_module.m_types;
  663. c2
  664. in
  665. let cf = try
  666. PMap.find cf.cf_name c2.cl_statics
  667. with Not_found ->
  668. let cf = {cf with cf_kind = Method MethNormal} in
  669. c2.cl_statics <- PMap.add cf.cf_name cf c2.cl_statics;
  670. c2.cl_ordered_statics <- cf :: c2.cl_ordered_statics;
  671. cf
  672. in
  673. let e_t = type_module_type ctx (TClassDecl c2) None p in
  674. FieldAccess.get_field_expr (FieldAccess.create e_t cf (FHStatic c2) true p) FRead
  675. in
  676. let e_def = FieldAccess.get_field_expr fa FRead in
  677. begin match follow fa.fa_on.etype with
  678. | TInst (c,_) when chk_class c ->
  679. display_error ctx "Can't create closure on an extern inline member method" p;
  680. e_def
  681. | TAnon a ->
  682. begin match !(a.a_status) with
  683. | Statics c when has_class_field_flag cf CfExtern ->
  684. display_error ctx "Cannot create closure on @:extern inline method" p;
  685. e_def
  686. | Statics c when chk_class c -> wrap_extern c
  687. | _ -> e_def
  688. end
  689. | _ -> e_def
  690. end
  691. | Var _,Some e ->
  692. let rec loop e = Type.map_expr loop { e with epos = p; etype = apply_params e.etype } in
  693. let e = loop e in
  694. let e = Inline.inline_metadata e cf.cf_meta in
  695. let tf = apply_params cf.cf_type in
  696. if not (type_iseq tf e.etype) then mk (TCast(e,None)) tf e.epos
  697. else e
  698. | Var _,None when ctx.com.display.dms_display ->
  699. FieldAccess.get_field_expr fa FRead
  700. | Var _,None ->
  701. error "Recursive inline is not supported" p
  702. end
  703. in
  704. let dispatcher () = new call_dispatcher ctx MGet WithType.value p in
  705. match g with
  706. | AKNo f -> error ("Field " ^ f ^ " cannot be accessed for reading") p
  707. | AKExpr e -> e
  708. | AKAccess _ -> die "" __LOC__
  709. | AKResolve(sea,name) ->
  710. (dispatcher ())#resolve_call sea name
  711. | AKUsingAccessor sea | AKUsingField sea when ctx.in_display ->
  712. (* Generate a TField node so we can easily match it for position/usage completion (issue #1968) *)
  713. let e_field = FieldAccess.get_field_expr sea.se_access FGet in
  714. (* TODO *)
  715. (* let ec = {ec with eexpr = (TMeta((Meta.StaticExtension,[],null_pos),ec))} in *)
  716. let t = match follow e_field.etype with
  717. | TFun (_ :: args,ret) -> TFun(args,ret)
  718. | t -> t
  719. in
  720. {e_field with etype = t}
  721. | AKField fa ->
  722. begin match fa.fa_field.cf_kind with
  723. | Method MethMacro ->
  724. (* If we are in display mode, we're probably hovering a macro call subject. Just generate a normal field. *)
  725. if ctx.in_display then
  726. FieldAccess.get_field_expr fa FRead
  727. else
  728. error "Invalid macro access" p
  729. | _ ->
  730. if fa.fa_inline then
  731. inline_read fa
  732. else
  733. FieldAccess.get_field_expr fa FRead
  734. end
  735. | AKAccessor fa ->
  736. (dispatcher())#field_call fa [] []
  737. | AKUsingAccessor sea ->
  738. (dispatcher())#field_call sea.se_access [sea.se_this] []
  739. | AKUsingField sea ->
  740. let e = sea.se_this in
  741. let e_field = FieldAccess.get_field_expr sea.se_access FGet in
  742. (* build a closure with first parameter applied *)
  743. (match follow e_field.etype with
  744. | TFun ((_,_,t0) :: args,ret) ->
  745. let te = abstract_using_param_type sea in
  746. unify ctx te t0 e.epos;
  747. let tcallb = TFun (args,ret) in
  748. let twrap = TFun ([("_e",false,e.etype)],tcallb) in
  749. (* arguments might not have names in case of variable fields of function types, so we generate one (issue #2495) *)
  750. let args = List.map (fun (n,o,t) ->
  751. let t = if o then ctx.t.tnull t else t in
  752. o,if n = "" then gen_local ctx t e.epos else alloc_var VGenerated n t e.epos (* TODO: var pos *)
  753. ) args in
  754. let ve = alloc_var VGenerated "_e" e.etype e.epos in
  755. let ecall = make_call ctx e_field (List.map (fun v -> mk (TLocal v) v.v_type p) (ve :: List.map snd args)) ret p in
  756. let ecallb = mk (TFunction {
  757. tf_args = List.map (fun (o,v) -> v,if o then Some (Texpr.Builder.make_null v.v_type v.v_pos) else None) args;
  758. tf_type = ret;
  759. tf_expr = (match follow ret with | TAbstract ({a_path = [],"Void"},_) -> ecall | _ -> mk (TReturn (Some ecall)) t_dynamic p);
  760. }) tcallb p in
  761. let ewrap = mk (TFunction {
  762. tf_args = [ve,None];
  763. tf_type = tcallb;
  764. tf_expr = mk (TReturn (Some ecallb)) t_dynamic p;
  765. }) twrap p in
  766. make_call ctx ewrap [e] tcallb p
  767. | _ -> die "" __LOC__)
  768. let build_call ?(mode=MGet) ctx acc el (with_type:WithType.t) p =
  769. let dispatch = new call_dispatcher ctx mode with_type p in
  770. match acc with
  771. | AKField fa ->
  772. dispatch#field_call fa [] el
  773. | AKUsingField sea ->
  774. let eparam = sea.se_this in
  775. dispatch#field_call sea.se_access [eparam] el
  776. | AKResolve(sea,name) ->
  777. dispatch#expr_call (dispatch#resolve_call sea name) el
  778. | AKNo _ | AKAccess _ ->
  779. ignore(acc_get ctx acc p);
  780. error ("Unexpected access mode, please report this: " ^ (s_access_kind acc)) p
  781. | AKAccessor fa ->
  782. let e = dispatch#field_call fa [] [] in
  783. dispatch#expr_call e el
  784. | AKUsingAccessor sea ->
  785. let e = dispatch#field_call sea.se_access [sea.se_this] [] in
  786. dispatch#expr_call e el
  787. | AKExpr e ->
  788. dispatch#expr_call e el
  789. let rec needs_temp_var e =
  790. match e.eexpr with
  791. | TLocal _ | TTypeExpr _ | TConst _ -> false
  792. | TField (e, _) | TParenthesis e -> needs_temp_var e
  793. | _ -> true
  794. let call_to_string ctx ?(resume=false) e =
  795. let gen_to_string e =
  796. (* Ignore visibility of the toString field. *)
  797. ctx.meta <- (Meta.PrivateAccess,[],e.epos) :: ctx.meta;
  798. let acc = type_field (TypeFieldConfig.create resume) ctx e "toString" e.epos (MCall []) (WithType.with_type ctx.t.tstring) in
  799. ctx.meta <- List.tl ctx.meta;
  800. build_call ctx acc [] (WithType.with_type ctx.t.tstring) e.epos
  801. in
  802. if ctx.com.config.pf_static && not (is_nullable e.etype) then
  803. gen_to_string e
  804. else begin (* generate `if(e == null) 'null' else e.toString()` *)
  805. let string_null = mk (TConst (TString "null")) ctx.t.tstring e.epos in
  806. if needs_temp_var e then
  807. let tmp = alloc_var VGenerated "tmp" e.etype e.epos in
  808. let tmp_local = mk (TLocal tmp) tmp.v_type tmp.v_pos in
  809. let check_null = mk (TBinop (OpEq, tmp_local, mk (TConst TNull) tmp.v_type tmp.v_pos)) ctx.t.tbool e.epos in
  810. {
  811. eexpr = TBlock([
  812. mk (TVar (tmp, Some e)) tmp.v_type tmp.v_pos;
  813. mk (TIf (check_null, string_null, Some (gen_to_string tmp_local))) ctx.t.tstring tmp.v_pos;
  814. ]);
  815. etype = ctx.t.tstring;
  816. epos = e.epos;
  817. }
  818. else
  819. let check_null = mk (TBinop (OpEq, e, mk (TConst TNull) e.etype e.epos)) ctx.t.tbool e.epos in
  820. mk (TIf (check_null, string_null, Some (gen_to_string e))) ctx.t.tstring e.epos
  821. end
  822. let type_bind ctx (e : texpr) (args,ret) params p =
  823. let vexpr v = mk (TLocal v) v.v_type p in
  824. let acount = ref 0 in
  825. let alloc_name n =
  826. if n = "" && not ctx.is_display_file then begin
  827. incr acount;
  828. "a" ^ string_of_int !acount;
  829. end else
  830. n
  831. in
  832. let rec loop args params given_args missing_args ordered_args = match args, params with
  833. | [], [] -> given_args,missing_args,ordered_args
  834. | [], _ -> error "Too many callback arguments" p
  835. | (n,o,t) :: args , [] when o ->
  836. let a = if is_pos_infos t then
  837. let infos = mk_infos ctx p [] in
  838. ordered_args @ [type_expr ctx infos (WithType.with_argument t n)]
  839. else if ctx.com.config.pf_pad_nulls then
  840. (ordered_args @ [(mk (TConst TNull) t_dynamic p)])
  841. else
  842. ordered_args
  843. in
  844. loop args [] given_args missing_args a
  845. | (n,o,t) :: _ , (EConst(Ident "_"),p) :: _ when not ctx.com.config.pf_can_skip_non_nullable_argument && o && not (is_nullable t) ->
  846. error "Usage of _ is not supported for optional non-nullable arguments" p
  847. | (n,o,t) :: args , ([] as params)
  848. | (n,o,t) :: args , (EConst(Ident "_"),_) :: params ->
  849. let v = alloc_var VGenerated (alloc_name n) (if o then ctx.t.tnull t else t) p in
  850. loop args params given_args (missing_args @ [v,o]) (ordered_args @ [vexpr v])
  851. | (n,o,t) :: args , param :: params ->
  852. let e = type_expr ctx param (WithType.with_argument t n) in
  853. let e = AbstractCast.cast_or_unify ctx t e (pos param) in
  854. let v = alloc_var VGenerated (alloc_name n) t (pos param) in
  855. loop args params (given_args @ [v,o,Some e]) missing_args (ordered_args @ [vexpr v])
  856. in
  857. let given_args,missing_args,ordered_args = loop args params [] [] [] in
  858. let var_decls = List.map (fun (v,_,e_opt) -> mk (TVar(v,e_opt)) ctx.t.tvoid v.v_pos) given_args in
  859. let e,var_decls =
  860. let is_immutable_method cf =
  861. match cf.cf_kind with Method k -> k <> MethDynamic | _ -> false
  862. in
  863. match e.eexpr with
  864. | TFunction _ | TLocal { v_kind = VUser TVOLocalFunction } ->
  865. e,var_decls
  866. | TField(_,(FStatic(_,cf) | FInstance(_,_,cf))) when is_immutable_method cf ->
  867. e,var_decls
  868. | _ ->
  869. let e_var = alloc_var VGenerated "`" e.etype e.epos in
  870. (mk (TLocal e_var) e.etype e.epos), (mk (TVar(e_var,Some e)) ctx.t.tvoid e.epos) :: var_decls
  871. in
  872. let call = make_call ctx e ordered_args ret p in
  873. let body =
  874. if ExtType.is_void (follow ret) then call
  875. else mk (TReturn(Some call)) ret p
  876. in
  877. let arg_default optional t =
  878. if optional then Some (Texpr.Builder.make_null t null_pos)
  879. else None
  880. in
  881. let fn = {
  882. tf_args = List.map (fun (v,o) -> v,arg_default o v.v_type) missing_args;
  883. tf_type = ret;
  884. tf_expr = body;
  885. } in
  886. let t = TFun(List.map (fun (v,o) -> v.v_name,o,v.v_type) missing_args,ret) in
  887. {
  888. eexpr = TBlock (var_decls @ [mk (TFunction fn) t p]);
  889. etype = t;
  890. epos = p;
  891. }
  892. let array_access ctx e1 e2 mode p =
  893. let has_abstract_array_access = ref false in
  894. try
  895. (match follow e1.etype with
  896. | TAbstract ({a_impl = Some c} as a,pl) when a.a_array <> [] ->
  897. begin match mode with
  898. | MSet _ ->
  899. (* resolve later *)
  900. AKAccess (a,pl,c,e1,e2)
  901. | _ ->
  902. has_abstract_array_access := true;
  903. let e = mk_array_get_call ctx (AbstractCast.find_array_access ctx a pl e2 None p) c e1 p in
  904. AKExpr e
  905. end
  906. | _ -> raise Not_found)
  907. with Not_found ->
  908. let base_ok = ref true in
  909. let rec loop ?(skip_abstract=false) et =
  910. match skip_abstract,follow et with
  911. | _, TInst ({ cl_array_access = Some t; cl_params = pl },tl) ->
  912. apply_params pl tl t
  913. | _, TInst ({ cl_super = Some (c,stl); cl_params = pl },tl) ->
  914. apply_params pl tl (loop (TInst (c,stl)))
  915. | _, TInst ({ cl_path = [],"ArrayAccess" },[t]) ->
  916. t
  917. | _, TInst ({ cl_path = [],"Array"},[t]) when t == t_dynamic ->
  918. t_dynamic
  919. | false, TAbstract(a,tl) when Meta.has Meta.ArrayAccess a.a_meta ->
  920. let at = apply_params a.a_params tl a.a_this in
  921. let skip_abstract = fast_eq et at in
  922. loop ~skip_abstract at
  923. | _, _ ->
  924. let pt = spawn_monomorph ctx p in
  925. let t = ctx.t.tarray pt in
  926. begin try
  927. unify_raise ctx et t p
  928. with Error(Unify _,_) ->
  929. if not ctx.untyped then begin
  930. let msg = if !has_abstract_array_access then
  931. "No @:arrayAccess function accepts an argument of " ^ (s_type (print_context()) e2.etype)
  932. else
  933. "Array access is not allowed on " ^ (s_type (print_context()) e1.etype)
  934. in
  935. base_ok := false;
  936. raise_or_display_message ctx msg e1.epos;
  937. end
  938. end;
  939. pt
  940. in
  941. let pt = loop e1.etype in
  942. if !base_ok then unify ctx e2.etype ctx.t.tint e2.epos;
  943. AKExpr (mk (TArray (e1,e2)) pt p)
  944. (*
  945. given chain of fields as the `path` argument and an `access_mode->access_kind` getter for some starting expression as `e`,
  946. return a new `access_mode->access_kind` getter for the whole field access chain.
  947. *)
  948. let field_chain ctx path access mode with_type =
  949. let rec loop access path = match path with
  950. | [] ->
  951. access
  952. | [(name,_,p)] ->
  953. let e = acc_get ctx access p in
  954. type_field_default_cfg ctx e name p mode with_type
  955. | (name,_,p) :: path ->
  956. let e = acc_get ctx access p in
  957. let access = type_field_default_cfg ctx e name p MGet WithType.value in
  958. loop access path
  959. in
  960. loop access path