浏览代码

[typer] move abstract `this` handling from syntax to typing

closes #9739
Simon Krajewski 5 年之前
父节点
当前提交
da9ec7d5c1

+ 10 - 4
src/typing/typeloadFields.ml

@@ -255,7 +255,6 @@ let transform_abstract_field com this_t a_t a f =
 		{ f with cff_name = "_new",pos f.cff_name; cff_access = (AStatic,null_pos) :: f.cff_access; cff_kind = FFun fu; cff_meta = meta }
 	| FFun fu when not stat ->
 		if Meta.has Meta.From f.cff_meta then error "@:from cast functions must be static" f.cff_pos;
-		let fu = { fu with f_args = (if List.mem_assoc AMacro f.cff_access then fu.f_args else (("this",null_pos),false,[],Some this_t,None) :: fu.f_args) } in
 		{ f with cff_kind = FFun fu; cff_access = (AStatic,null_pos) :: f.cff_access; cff_meta = (Meta.Impl,[],null_pos) :: f.cff_meta }
 	| _ ->
 		f
@@ -1146,6 +1145,13 @@ let create_method (ctx,cctx,fctx) c f fd p =
 			[]
 	in
 	let args = loop fd.f_args in
+	let fargs = TypeloadFunction.convert_fargs fd in
+	let args,fargs = match cctx.abstract with
+		| Some a when Meta.has Meta.Impl f.cff_meta && fst f.cff_name <> "_new" (* TODO: this sucks *) && not fctx.is_macro ->
+			("this",None,a.a_this) :: args,(null_pos,[]) :: fargs
+		| _ ->
+			args,fargs
+	in
 	let t = TFun (fun_args args,ret) in
 	let cf = {
 		(mk_field (fst f.cff_name) ~public:(is_public (ctx,cctx) f.cff_access parent) t f.cff_pos (pos f.cff_name)) with
@@ -1205,7 +1211,7 @@ let create_method (ctx,cctx,fctx) c f fd p =
 					cf.cf_type <- t
 				| _ ->
 					if Meta.has Meta.DisplayOverride cf.cf_meta then DisplayEmitter.check_field_modifiers ctx c cf fctx.override fctx.display_modifier;
-					let e , fargs = TypeloadFunction.type_function ctx args ret fmode fd fctx.is_display_field p in
+					let e , fargs = TypeloadFunction.type_function ctx args fargs ret fmode fd.f_expr fctx.is_display_field p in
 					begin match fctx.field_kind with
 					| FKNormal when not fctx.is_static -> TypeloadCheck.check_overriding ctx c cf
 					| _ -> ()
@@ -1235,7 +1241,7 @@ let create_method (ctx,cctx,fctx) c f fd p =
 	else begin
 		delay ctx PTypeField (fun () ->
 			(* We never enter type_function so we're missing out on the argument processing there. Let's do it here. *)
-			List.iter2 (fun (n,ct,t) ((_,pn),_,m,_,_) ->
+			List.iter2 (fun (n,ct,t) (pn,m) ->
 				(* dirty dodge to avoid flash extern problems until somebody fixes that *)
 				begin if ctx.com.platform = Flash && (has_class_flag c CExtern) then
 					()
@@ -1246,7 +1252,7 @@ let create_method (ctx,cctx,fctx) c f fd p =
 					let v = add_local_with_origin ctx TVOArgument n t pn in
 					DisplayEmitter.display_variable ctx v pn;
 				end
-			) args fd.f_args;
+			) args fargs;
 		);
 		check_field_display ctx fctx c cf;
 		if fd.f_expr <> None then begin

+ 9 - 6
src/typing/typeloadFunction.ml

@@ -99,8 +99,11 @@ let process_function_arg ctx n t c do_display check_name p =
 	if check_name && starts_with n '$' then error "Function argument names starting with a dollar are not allowed" p;
 	type_function_arg_value ctx t c do_display
 
-let type_function ctx args ret fmode f do_display p =
-	let fargs = List.map2 (fun (n,c,t) ((_,pn),_,m,_,_) ->
+let convert_fargs fd =
+	List.map (fun ((_,pn),_,m,_,_) -> (pn,m)) fd.f_args
+
+let type_function ctx args fargs ret fmode e do_display p =
+	let fargs = List.map2 (fun (n,c,t) (pn,m) ->
 		let c = process_function_arg ctx n t c do_display true pn in
 		let v = add_local_with_origin ctx TVOArgument n t pn in
 		v.v_meta <- v.v_meta @ m;
@@ -108,13 +111,13 @@ let type_function ctx args ret fmode f do_display p =
 			DisplayEmitter.display_variable ctx v pn;
 		if n = "this" then v.v_meta <- (Meta.This,[],null_pos) :: v.v_meta;
 		v,c
-	) args f.f_args in
+	) args fargs in
 	ctx.in_function <- true;
 	ctx.curfun <- fmode;
 	ctx.ret <- ret;
 	ctx.opened <- [];
 	ctx.monomorphs.perfunction <- [];
-	let e = match f.f_expr with
+	let e = match e with
 		| None ->
 			if ctx.com.display.dms_error_policy = EPIgnore then
 				(* when we don't care because we're in display mode, just act like
@@ -231,9 +234,9 @@ let type_function ctx args ret fmode f do_display p =
 	if is_position_debug then print_endline ("typing:\n" ^ (Texpr.dump_with_pos "" e));
 	e , fargs
 
-let type_function ctx args ret fmode f do_display p =
+let type_function ctx args fargs ret fmode e do_display p =
 	let save = save_field_state ctx in
-	Std.finally save (type_function ctx args ret fmode f do_display) p
+	Std.finally save (type_function ctx args fargs ret fmode e do_display) p
 
 let add_constructor ctx c force_constructor p =
 	let super() =

+ 2 - 1
src/typing/typer.ml

@@ -2087,7 +2087,8 @@ and type_local_function ctx kind f with_type p =
 		| FunMemberAbstractLocal -> FunMemberAbstractLocal
 		| _ -> FunMemberClassLocal
 	in
-	let e , fargs = TypeloadFunction.type_function ctx args rt curfun f ctx.in_display p in
+	let fargs = TypeloadFunction.convert_fargs f in
+	let e , fargs = TypeloadFunction.type_function ctx args fargs rt curfun f.f_expr ctx.in_display p in
 	ctx.type_params <- old_tp;
 	ctx.in_loop <- old_in_loop;
 	let tf = {

+ 1 - 1
std/haxe/ds/Vector.hx

@@ -345,7 +345,7 @@ abstract Vector<T>(VectorData<T>) {
 
 		If `f` is null, the result is unspecified.
 	**/
-	public inline function sort<T>(f:T->T->Int):Void {
+	public inline function sort(f:T->T->Int):Void {
 		#if (neko || cs || java || eval)
 		throw "not yet supported";
 		#elseif lua

+ 1 - 1
std/hl/_std/haxe/ds/Vector.hx

@@ -72,7 +72,7 @@ abstract Vector<T>(VectorData<T>) {
 		return this.join(sep);
 	}
 
-	public inline function sort<T>(f:T->T->Int):Void {
+	public inline function sort(f:T->T->Int):Void {
 		this.sort(f);
 	}
 

+ 1 - 1
tests/unit/src/unit/issues/Issue2713.hx

@@ -17,7 +17,7 @@ private abstract MyVector<T>(Array<T>) {
 	}
 
 	@:to public function toArray<T>():Array<T> {
-		return this;
+		return cast this;
 	}
 }
 

+ 0 - 30
tests/unit/src/unit/issues/Issue3388.hx

@@ -1,30 +0,0 @@
-package unit.issues;
-
-private abstract A<T>(Array<T>) {
-	public inline function new(a:Array<T>) {
-		this = a;
-	}
-
-	#if java
-	@:impl
-	@:overload extern
-	static inline public function sum(a:Array<Int>) {
-		return "sum of ints";
-	}
-
-	@:overload
-	@:impl
-	extern static inline public function sum(a:Array<String>) {
-		return "sum of strings";
-	}
-	#end
-}
-
-class Issue3388 extends Test {
-	#if java
-	function test() {
-		eq("sum of ints", new A([1]).sum());
-		eq("sum of strings", new A(["1"]).sum());
-	}
-	#end
-}