Skip to content

Commit

Permalink
allow closure creation on extern static inline methods (closes HaxeFo…
Browse files Browse the repository at this point in the history
  • Loading branch information
Simn committed Apr 3, 2014
1 parent ce688a7 commit a39486d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
26 changes: 26 additions & 0 deletions tests/unit/issues/Issue2813.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package unit.issues;
import unit.Test;

private extern class Ext {
static inline var v = "foo";

public function new() { }

public inline function test():Void { }

static inline function test2():String {
return v;
}
}

class Issue2813 extends Test {
function test() {
var f = Ext.test2;
eq("foo", f());

t(unit.TestType.typeError({
var e = new Ext();
var f = e.test;
}));
}
}
46 changes: 40 additions & 6 deletions typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -768,12 +768,46 @@ let rec acc_get ctx g p =
else
error "Recursive inline is not supported" p
| Some { eexpr = TFunction _ } ->
let chk_class c = if (c.cl_extern || Meta.has Meta.Extern f.cf_meta) && not (Meta.has Meta.Runtime f.cf_meta) then display_error ctx "Can't create closure on an inline extern method" p in
(match follow e.etype with
| TInst (c,_) -> chk_class c
| TAnon a -> (match !(a.a_status) with Statics c -> chk_class c | _ -> ())
| _ -> ());
mk (TField (e,cmode)) t p
let chk_class c = (c.cl_extern || Meta.has Meta.Extern f.cf_meta) && not (Meta.has Meta.Runtime f.cf_meta) in
let wrap_extern c =
let c2 =
let m = c.cl_module in
let mpath = (fst m.m_path @ ["_" ^ snd m.m_path],(snd m.m_path) ^ "_Impl_") in
try
let rec loop mtl = match mtl with
| (TClassDecl c) :: _ when c.cl_path = mpath -> c
| _ :: mtl -> loop mtl
| [] -> raise Not_found
in
loop c.cl_module.m_types
with Not_found ->
let c2 = mk_class c.cl_module mpath c.cl_pos in
c.cl_module.m_types <- (TClassDecl c2) :: c.cl_module.m_types;
c2
in
let cf = try
PMap.find f.cf_name c2.cl_statics
with Not_found ->
let cf = {f with cf_kind = Method MethNormal} in
c2.cl_statics <- PMap.add cf.cf_name cf c2.cl_statics;
c2.cl_ordered_statics <- cf :: c2.cl_ordered_statics;
cf
in
let e_t = type_module_type ctx (TClassDecl c2) None p in
mk (TField(e_t,FStatic(c2,cf))) t p
in
let e_def = mk (TField (e,cmode)) t p in
begin match follow e.etype with
| TInst (c,_) when chk_class c ->
display_error ctx "Can't create closure on an extern inline member method" p;
e_def
| TAnon a ->
begin match !(a.a_status) with
| Statics c when chk_class c -> wrap_extern c
| _ -> e_def
end
| _ -> e_def
end
| Some e ->
let rec loop e = Type.map_expr loop { e with epos = p } in
loop e)
Expand Down

0 comments on commit a39486d

Please sign in to comment.