Skip to content

Commit

Permalink
deal with same-class-calls in abstract closures (closes HaxeFoundatio…
Browse files Browse the repository at this point in the history
  • Loading branch information
Simn committed Apr 2, 2014
1 parent 51ace6b commit e441609
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
22 changes: 22 additions & 0 deletions tests/unit/issues/Issue2823.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package unit.issues;
import unit.Test;

private abstract MyAbstract(Int) {
public inline function new() {
this = 1;
}

public function test() {
var f = function() return get();
return f;
}

function get() return this;
}

class Issue2823 extends Test {
function test() {
var a = new MyAbstract();
eq(1, a.test()());
}
}
3 changes: 2 additions & 1 deletion typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ type current_fun =
| FunMember
| FunStatic
| FunConstructor
| FunMemberLocal
| FunMemberAbstract
| FunMemberClassLocal
| FunMemberAbstractLocal

type macro_mode =
| MExpr
Expand Down
26 changes: 17 additions & 9 deletions typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -798,17 +798,20 @@ let get_this ctx p =
match ctx.curfun with
| FunStatic ->
error "Cannot access this from a static function" p
| FunMemberLocal ->
let v = (match ctx.vthis with
| FunMemberClassLocal | FunMemberAbstractLocal ->
let v = match ctx.vthis with
| None ->
(* we might be in a closure of an abstract member, so check for local "this" first *)
let v = try PMap.find "this" ctx.locals with Not_found -> gen_local ctx ctx.tthis in
let v = if ctx.curfun = FunMemberAbstractLocal then
PMap.find "this" ctx.locals
else
gen_local ctx ctx.tthis
in
ctx.vthis <- Some v;
v
| Some v ->
ctx.locals <- PMap.add v.v_name v ctx.locals;
v
) in
in
mk (TLocal v) ctx.tthis p
| FunMemberAbstract ->
let v = (try PMap.find "this" ctx.locals with Not_found -> assert false) in
Expand All @@ -832,8 +835,8 @@ let field_access ctx mode f fmode t e p =
match f.cf_kind with
| Method m ->
if mode = MSet && m <> MethDynamic && not ctx.untyped then error "Cannot rebind this method : please use 'dynamic' before method declaration" p;
begin match e.eexpr with
| TTypeExpr(TClassDecl ({cl_kind = KAbstractImpl a} as c)) when c == ctx.curclass && ctx.curfun = FunMemberAbstract && Meta.has Meta.Impl f.cf_meta ->
begin match ctx.curfun,e.eexpr with
| (FunMemberAbstract | FunMemberAbstractLocal),TTypeExpr(TClassDecl ({cl_kind = KAbstractImpl a} as c)) when c == ctx.curclass && Meta.has Meta.Impl f.cf_meta ->
let e = mk (TField(e,fmode)) t p in
let ethis = get_this ctx p in
let ethis = {ethis with etype = TAbstract(a,List.map (fun _ -> mk_mono()) a.a_types)} in
Expand Down Expand Up @@ -1003,7 +1006,7 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
| FunMember | FunConstructor -> ()
| FunMemberAbstract -> error "Cannot access super inside an abstract function" p
| FunStatic -> error "Cannot access super inside a static function" p;
| FunMemberLocal -> error "Cannot access super inside a local function" p);
| FunMemberClassLocal | FunMemberAbstractLocal -> error "Cannot access super inside a local function" p);
if mode <> MSet && ctx.in_super_call then ctx.in_super_call <- false;
AKExpr (mk (TConst TSuper) t p)
| "null" ->
Expand Down Expand Up @@ -2978,7 +2981,12 @@ and type_expr ctx (e,p) (with_type:with_type) =
if v.[0] = '$' then display_error ctx "Variable names starting with a dollar are not allowed" p;
Some (add_local ctx v ft)
) in
let e , fargs = Typeload.type_function ctx args rt (match ctx.curfun with FunStatic -> FunStatic | _ -> FunMemberLocal) f false p in
let curfun = match ctx.curfun with
| FunStatic -> FunStatic
| FunMemberAbstract -> FunMemberAbstractLocal
| _ -> FunMemberClassLocal
in
let e , fargs = Typeload.type_function ctx args rt curfun f false p in
ctx.type_params <- old;
let f = {
tf_args = fargs;
Expand Down

0 comments on commit e441609

Please sign in to comment.