|
@@ -1977,14 +1977,32 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
|
match follow acc.etype with
|
|
|
| TFun ([],it) ->
|
|
|
unify ctx it t e1.epos;
|
|
|
- make_call ctx acc [] t e1.epos
|
|
|
+ make_call ctx acc [] it e1.epos
|
|
|
| _ ->
|
|
|
display_error ctx "The field iterator is not a method" e1.epos;
|
|
|
mk (TConst TNull) t_dynamic p
|
|
|
)
|
|
|
) in
|
|
|
let e2 = type_expr ~need_val:false ctx e2 in
|
|
|
- mk (TFor (i,e1,e2)) ctx.t.tvoid p
|
|
|
+ (* can we inline hasNext() ? *)
|
|
|
+ (try
|
|
|
+ let c,pl = (match follow e1.etype with TInst (c,pl) -> c,pl | _ -> raise Exit) in
|
|
|
+ let ft, fhasnext = (try class_field ctx c pl "hasNext" p with Not_found -> raise Exit) in
|
|
|
+ if fhasnext.cf_kind <> Method MethInline then raise Exit;
|
|
|
+ let tmp = gen_local ctx e1.etype in
|
|
|
+ let eit = mk (TLocal tmp) e1.etype p in
|
|
|
+ let ehasnext = make_call ctx (mk (TField (eit,"hasNext")) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in
|
|
|
+ let enext = mk (TVars [i,Some (make_call ctx (mk (TField (eit,"next")) (TFun ([],pt)) p) [] pt p)]) ctx.t.tvoid p in
|
|
|
+ let eblock = (match e2.eexpr with
|
|
|
+ | TBlock el -> { e2 with eexpr = TBlock (enext :: el) }
|
|
|
+ | _ -> mk (TBlock [enext;e2]) ctx.t.tvoid p
|
|
|
+ ) in
|
|
|
+ mk (TBlock [
|
|
|
+ mk (TVars [tmp,Some e1]) ctx.t.tvoid p;
|
|
|
+ mk (TWhile (ehasnext,eblock,NormalWhile)) ctx.t.tvoid p
|
|
|
+ ]) ctx.t.tvoid p
|
|
|
+ with Exit ->
|
|
|
+ mk (TFor (i,e1,e2)) ctx.t.tvoid p)
|
|
|
) in
|
|
|
ctx.in_loop <- old_loop;
|
|
|
old_locals();
|