114
122
let argstr = "Function " ^ (match name with None -> "" | Some n -> "'" ^ n ^ "' ") ^ "requires " ^ (if args = [] then "no arguments" else "arguments : " ^ String.concat ", " (List.map format_arg args)) in
115
123
display_error ctx (txt ^ " arguments\n" ^ argstr) p
117
let arg_error ul name opt =
125
let arg_error ul name opt p =
118
126
raise (Error (Stack (Unify ul,Custom ("For " ^ (if opt then "optional " else "") ^ "function argument '" ^ name ^ "'")), p))
120
128
let rec no_opt = function
223
232
t_private = true;
224
233
t_types = e.e_types;
226
mk (TTypeExpr (TEnumDecl e)) (TType (t_tmp,types)) p
235
let e = mk (TTypeExpr (TEnumDecl e)) (TType (t_tmp,types)) p in
236
check_locals_masking ctx e;
228
239
let t = apply_params s.t_types (List.map (fun _ -> mk_mono()) s.t_types) s.t_type in
229
240
match follow t with
230
241
| TEnum (e,params) ->
231
loop (TEnumDecl e) (Some params)
242
type_module_type ctx (TEnumDecl e) (Some params) p
232
243
| TInst (c,params) ->
233
loop (TClassDecl c) (Some params)
244
type_module_type ctx (TClassDecl c) (Some params) p
235
error (s_type_path tpath ^ " is not a value") p
237
let e = loop (Typeload.load_type_def ctx p tpath) None in
238
check_locals_masking ctx e;
246
error (s_type_path s.t_path ^ " is not a value") p
248
let type_type ctx tpath p =
249
type_module_type ctx (Typeload.load_type_def ctx p tpath) None p
241
251
let get_constructor c p =
254
264
with Not_found ->
255
265
error (s_type_path c.cl_path ^ " does not have a constructor") p
267
let make_call ctx e params t p =
269
if not ctx.doinline then raise Exit;
270
let ethis, fname = (match e.eexpr with TField (ethis,fname) -> ethis, fname | _ -> raise Exit) in
271
let f = (match follow ethis.etype with
272
| TInst (c,params) -> snd (try class_field c fname with Not_found -> raise Exit)
273
| TAnon a -> (try PMap.find fname a.a_fields with Not_found -> raise Exit)
276
if f.cf_get <> InlineAccess then raise Exit;
277
ignore(follow f.cf_type); (* force evaluation *)
278
(match f.cf_expr with
279
| Some { eexpr = TFunction fd } ->
280
(match Optimizer.type_inline ctx f fd ethis params t p with
284
error "Recursive inline is not supported" p)
286
mk (TCall (e,params)) t p
288
let rec acc_get ctx g p =
259
290
| AccNo f -> error ("Field " ^ f ^ " cannot be accessed for reading") p
261
292
| AccSet _ -> assert false
294
(* build a closure with first parameter applied *)
295
(match follow et.etype with
296
| TFun (_ :: args,ret) ->
297
let tcallb = TFun (args,ret) in
298
let twrap = TFun ([("_e",false,e.etype)],tcallb) in
299
let ecall = make_call ctx et (List.map (fun (n,_,t) -> mk (TLocal n) t p) (("_e",false,e.etype) :: args)) ret p in
300
let ecallb = mk (TFunction {
301
tf_args = List.map (fun (n,_,t) -> n,None,t) args;
303
tf_expr = mk (TReturn (Some ecall)) t_dynamic p;
305
let ewrap = mk (TFunction {
306
tf_args = [("_e",None,e.etype)];
308
tf_expr = mk (TReturn (Some ecallb)) t_dynamic p;
310
make_call ctx ewrap [e] tcallb p
262
312
| AccInline (e,f,t) ->
263
313
ignore(follow f.cf_type); (* force computing *)
264
314
match f.cf_expr with
265
315
| None -> error "Recursive inline is not supported" p
266
| Some { eexpr = TFunction _ } -> mk (TField (e,f.cf_name)) t p
316
| Some { eexpr = TFunction _ } -> mk (TClosure (e,f.cf_name)) t p
268
318
let rec loop e = Type.map_expr loop { e with epos = p } in
271
let field_access ctx get f t e p =
272
match if get then f.cf_get else f.cf_set with
321
let field_access ctx mode f t e p =
322
match (match mode with MGet | MCall -> f.cf_get | MSet -> f.cf_set) with
274
324
let normal = AccExpr (mk (TField (e,f.cf_name)) t p) in
275
325
(match follow e.etype with
280
330
| _ -> if ctx.untyped then normal else AccNo f.cf_name)
282
332
if ctx.untyped then normal else AccNo f.cf_name)
283
| MethodCantAccess when not ctx.untyped ->
333
| MethodAccess false when not ctx.untyped ->
284
334
error "Cannot rebind this method : please use 'dynamic' before method declaration" p
285
| NormalAccess | MethodCantAccess ->
286
AccExpr (mk (TField (e,f.cf_name)) t p)
335
| NormalAccess | MethodAccess _ ->
337
creates a closure if we're reading a normal method
338
or a read-only variable (which could be a method)
340
(match mode, f.cf_set with
341
| MGet, MethodAccess _ -> AccExpr (mk (TClosure (e,f.cf_name)) t p)
342
| MGet, NoAccess | MGet, NeverAccess when (match follow t with TFun _ -> true | _ -> false) -> AccExpr (mk (TClosure (e,f.cf_name)) t p)
343
| _ -> AccExpr (mk (TField (e,f.cf_name)) t p))
288
345
if m = ctx.curmethod && (match e.eexpr with TConst TThis -> true | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then
289
let prefix = if Common.defined ctx.com "as3gen" then "$" else "" in
346
let prefix = if Common.defined ctx.com "as3" then "$" else "" in
290
347
AccExpr (mk (TField (e,prefix ^ f.cf_name)) t p)
292
AccExpr (mk (TCall (mk (TField (e,m)) (tfun [] t) p,[])) t p)
348
else if mode = MSet then
294
349
AccSet (e,m,t,f.cf_name)
351
AccExpr (make_call ctx (mk (TField (e,m)) (tfun [] t) p) [] t p)
295
352
| ResolveAccess ->
296
353
let fstring = mk (TConst (TString f.cf_name)) ctx.api.tstring p in
297
354
let tresolve = tfun [ctx.api.tstring] t in
298
AccExpr (mk (TCall (mk (TField (e,"resolve")) tresolve p,[fstring])) t p)
355
AccExpr (make_call ctx (mk (TField (e,"resolve")) tresolve p) [fstring] t p)
301
358
| InlineAccess ->
302
359
AccInline (e,f,t)
304
let type_ident ctx i is_type p get =
361
let type_ident ctx i is_type p mode =
308
365
AccExpr (mk (TConst (TBool true)) ctx.api.tbool p)
313
370
AccExpr (mk (TConst (TBool false)) ctx.api.tbool p)
317
374
if not ctx.untyped && ctx.in_static then error "Cannot access this from a static function" p;
319
376
AccExpr (mk (TConst TThis) ctx.tthis p)
323
if not ctx.super_call then
326
380
let t = (match ctx.curclass.cl_super with
327
| None -> error "Current class does not have a superclass" p
328
| Some (c,params) -> TInst(c,params)
381
| None -> error "Current class does not have a superclass" p
382
| Some (c,params) -> TInst(c,params)
330
384
if ctx.in_static then error "Cannot access super from a static function" p;
331
ctx.super_call <- false;
385
if mode = MSet || not ctx.super_call then
388
ctx.super_call <- false;
333
389
AccExpr (mk (TConst TSuper) t p)
338
393
AccExpr (null (mk_mono()) p)
342
397
let infos = mk_infos ctx p [] in
343
398
let e = type_expr ctx infos true in
345
400
AccExpr { e with etype = Typeload.load_normal_type ctx { tpackage = ["haxe"]; tname = "PosInfos"; tparams = [] } p false }
353
408
(* member variable lookup *)
354
409
if ctx.in_static then raise Not_found;
355
410
let t , f = class_field ctx.curclass i in
356
field_access ctx get f t (mk (TConst TThis) ctx.tthis p) p
411
field_access ctx mode f t (mk (TConst TThis) ctx.tthis p) p
357
412
with Not_found -> try
358
413
(* static variable lookup *)
359
414
let f = PMap.find i ctx.curclass.cl_statics in
360
415
let e = type_type ctx ctx.curclass.cl_path p in
361
field_access ctx get f (field_type f) e p
416
field_access ctx mode f (field_type f) e p
362
417
with Not_found -> try
363
418
(* lookup imported *)
440
let type_field ctx e i p get =
495
let rec type_field ctx e i p mode =
497
if mode = MSet then raise Not_found;
498
let rec loop = function
501
| TEnumDecl _ :: l | TTypeDecl _ :: l ->
503
| TClassDecl c :: l ->
505
let f = PMap.find i c.cl_statics in
506
let t = field_type f in
508
| TFun ((_,_,t0) :: args,r) ->
509
(try unify_raise ctx e.etype t0 p with Error (Unify _,_) -> raise Not_found);
510
let et = type_module_type ctx (TClassDecl c) None p in
511
AccUsing (mk (TField (et,i)) t p,e)
512
| _ -> raise Not_found)
442
519
if not ctx.untyped then display_error ctx (s_type (print_context()) e.etype ^ " has no field " ^ i) p;
443
520
AccExpr (mk (TField (e,i)) (mk_mono()) p)
448
525
match c.cl_dynamic with
450
527
let t = apply_params c.cl_types params t in
451
if get && PMap.mem "resolve" c.cl_fields then
452
AccExpr (mk (TCall (mk (TField (e,"resolve")) (tfun [ctx.api.tstring] t) p,[Typeload.type_constant ctx (String i) p])) t p)
528
if mode = MGet && PMap.mem "resolve" c.cl_fields then
529
AccExpr (make_call ctx (mk (TField (e,"resolve")) (tfun [ctx.api.tstring] t) p) [Typeload.type_constant ctx (String i) p] t p)
454
531
AccExpr (mk (TField (e,i)) t p)
563
644
let rec type_binop ctx op e1 e2 p =
566
let e1 = type_access ctx (fst e1) (snd e1) false in
567
let e2 = type_expr_with_type ctx e2 (match e1 with AccNo _ | AccInline _ -> None | AccExpr e | AccSet(e,_,_,_) -> Some e.etype) in
647
let e1 = type_access ctx (fst e1) (snd e1) MSet in
648
let e2 = type_expr_with_type ctx e2 (match e1 with AccNo _ | AccInline _ | AccUsing _ -> None | AccExpr e | AccSet(e,_,_,_) -> Some e.etype) in
569
650
| AccNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p
578
659
mk (TBinop (op,e1,e2)) e1.etype p
579
660
| AccSet (e,m,t,_) ->
580
661
unify ctx e2.etype t p;
581
mk (TCall (mk (TField (e,m)) (tfun [t] t) p,[e2])) t p
662
make_call ctx (mk (TField (e,m)) (tfun [t] t) p) [e2] t p
663
| AccInline _ | AccUsing _ ->
584
665
| OpAssignOp op ->
585
(match type_access ctx (fst e1) (snd e1) false with
666
(match type_access ctx (fst e1) (snd e1) MSet with
586
667
| AccNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p
588
669
let eop = type_binop ctx op e1 e2 p in
589
670
(match eop.eexpr with
590
671
| TBinop (_,_,e2) ->
591
unify ctx e2.etype e.etype p;
672
unify ctx eop.etype e.etype p;
592
673
check_assign ctx e;
593
674
mk (TBinop (OpAssignOp op,e,e2)) e.etype p;
957
1038
let cases = List.map matchs cases in
958
1039
mk (TMatch (e,(en,enparams),List.map indexes cases,def)) t p
960
and type_access ctx e p get =
1041
and type_access ctx e p mode =
962
1043
| EConst (Ident s) ->
963
type_ident ctx s false p get
1044
type_ident ctx s false p mode
964
1045
| EConst (Type s) ->
965
type_ident ctx s true p get
1046
type_ident ctx s true p mode
968
1049
let fields path e =
969
1050
List.fold_left (fun e (f,_,p) ->
970
let e = acc_get (e true) p in
1051
let e = acc_get ctx (e MGet) p in
971
1052
type_field ctx e f p
1169
1250
unify_raise ctx e1.etype t e1.epos;
1171
1252
with Error (Unify _,_) ->
1172
let acc = acc_get (type_field ctx e1 "iterator" e1.epos true) e1.epos in
1253
let acc = acc_get ctx (type_field ctx e1 "iterator" e1.epos MCall) e1.epos in
1173
1254
match follow acc.etype with
1174
1255
| TFun ([],it) ->
1175
1256
unify ctx it t e1.epos;
1176
mk (TCall (acc,[])) t e1.epos
1257
make_call ctx acc [] t e1.epos
1178
1259
error "The field iterator is not a method" e1.epos
1487
add 'using' methods compatible with this type
1489
let rec loop acc = function
1492
let acc = ref (loop acc l) in
1495
let rec dup t = Type.map dup t in
1497
match follow (field_type f) with
1498
| TFun ((_,_,t) :: args, ret) when (try unify_raise ctx (dup e.etype) t e.epos; true with _ -> false) ->
1499
let f = { f with cf_type = TFun (args,ret); cf_params = [] } in
1500
acc := PMap.add f.cf_name f (!acc)
1502
) c.cl_ordered_statics
1506
let use_methods = loop PMap.empty ctx.local_using in
1507
let t = (if PMap.is_empty use_methods then t else match follow t with
1508
| TFun _ -> t (* don't provide use methods for functions *)
1509
| TAnon a -> TAnon { a_fields = PMap.fold (fun f acc -> PMap.add f.cf_name f acc) a.a_fields use_methods; a_status = ref Closed; }
1510
| _ -> TAnon { a_fields = use_methods; a_status = ref Closed }
1405
1512
raise (Display t)
1406
1513
| EDisplayNew t ->
1407
1514
let t = Typeload.load_normal_type ctx t p true in
1485
1592
| EField ((EConst (Ident "super"),_),_) , _ | EType ((EConst (Ident "super"),_),_) , _ -> ctx.super_call <- true
1487
match type_access ctx (fst e) (snd e) true with
1594
match type_access ctx (fst e) (snd e) MCall with
1488
1595
| AccInline (ethis,f,t) ->
1489
1596
let params, tret = (match follow t with
1490
1597
| TFun (args,r) -> unify_call_params ctx (Some f.cf_name) el args p true, r
1491
1598
| _ -> error (s_type (print_context()) t ^ " cannot be called") p
1493
ignore(follow f.cf_type); (* force evaluation *)
1494
(match f.cf_expr with
1495
| Some { eexpr = TFunction fd } ->
1496
let i = if ctx.doinline then Optimizer.type_inline ctx f fd ethis params tret p else None in
1498
| None -> mk (TCall (mk (TField (ethis,f.cf_name)) t p,params)) tret p
1500
| _ -> error "Recursive inline is not supported" p)
1600
make_call ctx (mk (TField (ethis,f.cf_name)) t p) params tret p
1601
| AccUsing (et,eparam) ->
1602
let fname = (match et.eexpr with TField (_,f) -> f | _ -> assert false) in
1603
let params, tret = (match follow et.etype with
1604
| TFun ( _ :: args,r) -> unify_call_params ctx (Some fname) el args p false, r
1607
make_call ctx et (eparam::params) tret p
1502
let e = acc_get acc p in
1609
let e = acc_get ctx acc p in
1503
1610
let el , t = (match follow e.etype with
1504
1611
| TFun (args,r) ->
1505
1612
let el = unify_call_params ctx (match e.eexpr with TField (_,f) -> Some f | _ -> None) el args p false in