瀏覽代碼

[display] resolve overloads if we display fields with MCall

closes #7753
Simon Krajewski 5 年之前
父節點
當前提交
e08e68f698
共有 2 個文件被更改,包括 75 次插入0 次删除
  1. 16 0
      src/typing/typerDisplay.ml
  2. 59 0
      tests/display/src/cases/Issue7753.hx

+ 16 - 0
src/typing/typerDisplay.ml

@@ -307,6 +307,22 @@ and display_expr ctx e_ast e dk mode with_type p =
 			let fa = get_constructor_access c params p in
 			fa.fa_field,c
 	in
+	let maybe_expand_overload e e_on host cf = match mode with
+		| MCall el when cf.cf_overloads <> [] ->
+			let fa = FieldAccess.create e_on cf host false p in
+			let fcc = unify_field_call ctx fa [] el p false in
+			FieldAccess.get_field_expr {fa with fa_field = fcc.fc_field} FCall
+		| _ ->
+			e
+	in
+	(* If we display on a TField node that points to an overloaded field, let's try to unify the field call
+	   in order to resolve the correct overload (issue #7753). *)
+	let e = match e.eexpr with
+		| TField(e1,FStatic(c,cf)) -> maybe_expand_overload e e1 (FHStatic c) cf
+		| TField(e1,(FInstance(c,tl,cf) | FClosure(Some(c,tl),cf))) -> maybe_expand_overload e e1 (FHInstance(c,tl)) cf
+		| TField(e1,(FAnon cf | FClosure(None,cf))) -> maybe_expand_overload e e1 FHAnon cf
+		| _ -> e
+	in
 	match ctx.com.display.dms_kind with
 	| DMResolve _ | DMPackage ->
 		die "" __LOC__

+ 59 - 0
tests/display/src/cases/Issue7753.hx

@@ -0,0 +1,59 @@
+package cases;
+
+class Issue7753 extends DisplayTestCase {
+	/**
+		class Main {
+			static function main() {
+				Foo.f{-1-}oo(0);
+				Foo.f{-2-}oo("");
+			}
+		}
+
+		extern class Foo {
+			@:overload(function(s:String):Void {})
+			static function foo(i:Int):Void;
+		}
+	**/
+	function testStatic() {
+		eq("(i : Int) -> Void", type(pos(1)));
+		eq("(s : String) -> Void", type(pos(2)));
+	}
+
+	/**
+		class Main {
+			static function main() {
+				var foo = new Foo();
+				foo.f{-1-}oo(0);
+				foo.f{-2-}oo("");
+			}
+		}
+
+		extern class Foo {
+			function new():Void;
+			@:overload(function(s:String):Void {})
+			function foo(i:Int):Void;
+		}
+	**/
+	function testInstance() {
+		eq("(i : Int) -> Void", type(pos(1)));
+		eq("(s : String) -> Void", type(pos(2)));
+	}
+
+	/**
+		class Main {
+			static function main() {
+				var foo = n{-1-}ew Foo(0);
+				var foo = n{-2-}ew Foo("");
+			}
+		}
+
+		extern class Foo {
+			@:overload(function(s:String):Void {})
+			function new(i:Int):Void;
+		}
+	**/
+	function testConstructor() {
+		eq("(i : Int) -> cases.Foo", type(pos(1)));
+		eq("(s : String) -> cases.Foo", type(pos(2)));
+	}
+}