Explorar o código

handle calls to abstract member from within abstract by passing "this" (fixed issue #1722)

Simon Krajewski %!s(int64=12) %!d(string=hai) anos
pai
achega
04cd7100f4
Modificáronse 3 ficheiros con 18 adicións e 1 borrados
  1. 9 0
      tests/unit/MyAbstract.hx
  2. 5 0
      tests/unit/TestBasetypes.hx
  3. 4 1
      typer.ml

+ 9 - 0
tests/unit/MyAbstract.hx

@@ -275,4 +275,13 @@ abstract MyAbstractCounter(Int) {
 	}
 	
 	inline public function getValue():Int return this + 1;
+}
+
+abstract MyAbstractThatCallsAMember(Int) to Int {
+	public function new(i) {
+		this = i;
+		bar();
+	}
+
+	inline function bar() this++;
 }

+ 5 - 0
tests/unit/TestBasetypes.hx

@@ -477,4 +477,9 @@ class TestBasetypes extends Test {
 		as.value = "foo";
 		eq(as.value, "foo");
 	}
+	
+	function testAbstractMemberCall() {
+		var as = new MyAbstract.MyAbstractThatCallsAMember(2);
+		eq(3, as);
+	}
 }

+ 4 - 1
typer.ml

@@ -788,6 +788,9 @@ let field_access ctx mode f fmode t e p =
 	| Method m ->
 		if mode = MSet && m <> MethDynamic && not ctx.untyped then error "Cannot rebind this method : please use 'dynamic' before method declaration" p;
 		(match m, mode with
+		| _ when (match e.eexpr with TTypeExpr(TClassDecl ({cl_kind = KAbstractImpl a} as c)) -> c == ctx.curclass && ctx.curfun = FunMemberAbstract && Meta.has Meta.Impl f.cf_meta | _ -> false) ->
+			let e = mk (TField(e,fmode)) t p in
+			AKUsing(e,ctx.curclass,f,get_this ctx p)
 		| MethInline, _ -> AKInline (e,f,fmode,t)
 		| MethMacro, MGet -> display_error ctx "Macro functions must be called immediately" p; normal()
 		| MethMacro, MCall -> AKMacro (e,f)
@@ -3170,7 +3173,7 @@ and build_call ctx acc el (with_type:with_type) p =
 			(match acc with
 			| AKMacro _ ->
 				build_call ctx acc (Interp.make_ast eparam :: el) with_type p
-			| AKExpr _ | AKField _ | AKInline _ ->
+			| AKExpr _ | AKField _ | AKInline _ | AKUsing _ ->
 				let params, tfunc = (match follow et.etype with
 					| TFun ( _ :: args,r) -> unify_call_params ctx (Some (TInst(cl,[]),ef)) el args r p (ef.cf_kind = Method MethInline)
 					| _ -> assert false