Browse Source

[display] iterate overloads when resolving static extensions

closes #10004
closes #10120
Simon Krajewski 4 years ago
parent
commit
852c3f88c0
2 changed files with 86 additions and 35 deletions
  1. 37 35
      src/context/display/displayFields.ml
  2. 49 0
      tests/display/src/cases/Issue10004.hx

+ 37 - 35
src/context/display/displayFields.ml

@@ -46,48 +46,50 @@ let collect_static_extensions ctx items e p =
 		| _ ->
 			t
 	in
+	let rec dup t = Type.map dup t in
+	let handle_field c f acc =
+		let f = { f with cf_type = opt_type f.cf_type } in
+		let monos = List.map (fun _ -> spawn_monomorph ctx p) f.cf_params in
+		let map = apply_params f.cf_params monos in
+		match follow (map f.cf_type) with
+		| TFun((_,_,TType({t_path=["haxe";"macro"], "ExprOf"}, [t])) :: args, ret)
+		| TFun((_,_,t) :: args, ret) ->
+			begin try
+				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
+				List.iter2 (fun m (name,t) -> match follow t with
+					| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
+						List.iter (fun tc -> unify_raise ctx m (map tc) e.epos) constr
+					| _ -> ()
+				) monos f.cf_params;
+				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
+					acc
+				else begin
+					let f = prepare_using_field f in
+					let f = { f with cf_params = []; cf_flags = set_flag f.cf_flags (int_of_class_field_flag CfPublic); cf_type = TFun(args,ret) } in
+					let decl = match c.cl_kind with
+						| KAbstractImpl a -> TAbstractDecl a
+						| _ -> TClassDecl c
+					in
+					let origin = StaticExtension(decl) in
+					let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta f.cf_meta) f.cf_type in
+					let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) (f.cf_type,ct) in
+					PMap.add f.cf_name item acc
+				end
+			with Error (Unify _,_) | Unify_error _ ->
+				acc
+			end
+		| _ ->
+			acc
+		in
 	let rec loop acc = function
 		| [] ->
 			acc
 		| (c,_) :: l ->
-			let rec dup t = Type.map dup t in
 			let acc = List.fold_left (fun acc f ->
 				if Meta.has Meta.NoUsing f.cf_meta || Meta.has Meta.NoCompletion f.cf_meta || has_class_field_flag f CfImpl || PMap.mem f.cf_name acc then
 					acc
-				else begin
-					let f = { f with cf_type = opt_type f.cf_type } in
-					let monos = List.map (fun _ -> spawn_monomorph ctx p) f.cf_params in
-					let map = apply_params f.cf_params monos in
-					match follow (map f.cf_type) with
-					| TFun((_,_,TType({t_path=["haxe";"macro"], "ExprOf"}, [t])) :: args, ret)
-					| TFun((_,_,t) :: args, ret) ->
-						begin try
-							let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
-							List.iter2 (fun m (name,t) -> match follow t with
-								| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
-									List.iter (fun tc -> unify_raise ctx m (map tc) e.epos) constr
-								| _ -> ()
-							) monos f.cf_params;
-							if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
-								acc
-							else begin
-								let f = prepare_using_field f in
-								let f = { f with cf_params = []; cf_flags = set_flag f.cf_flags (int_of_class_field_flag CfPublic); cf_type = TFun(args,ret) } in
-								let decl = match c.cl_kind with
-									| KAbstractImpl a -> TAbstractDecl a
-									| _ -> TClassDecl c
-								in
-								let origin = StaticExtension(decl) in
-								let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta f.cf_meta) f.cf_type in
-								let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) (f.cf_type,ct) in
-								PMap.add f.cf_name item acc
-							end
-						with Error (Unify _,_) | Unify_error _ ->
-							acc
-						end
-					| _ ->
-						acc
-				end
+				else
+					List.fold_left (fun acc f -> handle_field c f acc) acc (f :: f.cf_overloads)
 			) acc c.cl_ordered_statics in
 			loop acc l
 	in

+ 49 - 0
tests/display/src/cases/Issue10004.hx

@@ -0,0 +1,49 @@
+package cases;
+
+class Issue10004 extends DisplayTestCase {
+	/**
+		using Issue10004.Foo;
+
+		class Main {
+			static function main() {
+				0.{-1-}
+			}
+		}
+
+		class Foo {
+			public static overload extern inline function foo():Void {}
+
+			public static overload extern inline function foo(i:Int):Void {}
+		}
+	**/
+	function testGama() {
+		var fields = fields(pos(1));
+		eq(true, hasField(fields, "foo", "() -> Void"));
+	}
+
+	/**
+		using Issue10004.Tools;
+
+		class Tools {
+			public static extern inline overload function getOrZero<K>(map:Map<K,Int>, key:K):Int {
+				var value = map.get(key);
+				return if (value != null) value else 0;
+			}
+
+			public static extern inline overload function getOrZero<K>(map:Map<K,Float>, key:K):Float {
+				var value = map.get(key);
+				return if (value != null) value else 0.0;
+			}
+
+		}
+
+		function main() {
+			var m = ["a" => 1.1, "b" => 2.3];
+			m.{-1-}
+		}
+	**/
+	function testNotGama() {
+		var fields = fields(pos(1));
+		eq(true, hasField(fields, "getOrZero", "(key : String) -> Float"));
+	}
+}