Преглед на файлове

allow `@:using` with Class and Enum (#11553)

closes #10106
Simon Krajewski преди 1 година
родител
ревизия
e1bc23d04c
променени са 4 файла, в които са добавени 123 реда и са изтрити 5 реда
  1. 24 5
      src/context/display/displayFields.ml
  2. 7 0
      src/core/tFunctions.ml
  3. 57 0
      tests/display/src/cases/Issue10106.hx
  4. 35 0
      tests/unit/src/unit/issues/Issue10106.hx

+ 24 - 5
src/context/display/displayFields.ml

@@ -99,12 +99,31 @@ let collect_static_extensions ctx items e p =
 	| _ ->
 		let items = loop items ctx.m.module_using in
 		let items = loop items ctx.g.global_using in
-		let items = try
-			let mt = module_type_of_type e.etype in
-			loop items (t_infos mt).mt_using
-		with Exit ->
-			items
+		let rec loop_module_using items t = match follow_without_type t with
+			| TInst(c,_) ->
+				loop items c.cl_using
+			| TEnum(en,_) ->
+				loop items en.e_using
+			| TType(td,tl) ->
+				let items = loop items td.t_using in
+				loop_module_using items (apply_typedef td tl)
+			| TAbstract(a,_) ->
+				loop items a.a_using
+			| TAnon an ->
+				begin match !(an.a_status) with
+					| Statics c ->
+						loop items c.cl_using
+					| EnumStatics en ->
+						loop items en.e_using
+					| AbstractStatics a ->
+						loop items a.a_using
+					| _ ->
+						items
+				end
+			| _ ->
+				items
 		in
+		let items = loop_module_using items e.etype in
 		items
 
 let collect ctx e_ast e dk with_type p =

+ 7 - 0
src/core/tFunctions.ml

@@ -663,6 +663,13 @@ let rec module_type_of_type = function
 		(match r.tm_type with
 		| Some t -> module_type_of_type t
 		| _ -> raise Exit)
+	| TAnon an ->
+		begin match !(an.a_status) with
+			| Statics c -> TClassDecl c
+			| EnumStatics en -> TEnumDecl en
+			| AbstractStatics a -> TAbstractDecl a
+			| _ -> raise Exit
+		end
 	| _ ->
 		raise Exit
 

+ 57 - 0
tests/display/src/cases/Issue10106.hx

@@ -0,0 +1,57 @@
+package cases;
+
+class Issue10106 extends DisplayTestCase {
+	/**
+		class CExtension {
+			public static function toS(c: C): String {
+				return 'c';
+			}
+			public static function fromS(cls: Class<C>, s: String):C {
+				return new C();
+			}
+		}
+
+		@:using(cases.Issue10106.CExtension)
+		class C {
+			public function new(){}
+		}
+
+
+		class Main {
+			static public function main() {
+				C.{-1-}
+			}
+		}
+	**/
+	function testClass() {
+		eq(true, hasField(fields(pos(1)), "fromS", "(s : String) -> cases.C"));
+	}
+
+	/**
+		class EnExtension {
+			public static function toS(e:En):String {
+				return '${e}';
+			}
+
+			public static function fromS(en:Enum<En>, s:String):En {
+				return A;
+			}
+		}
+
+		@:using(cases.Issue10106.EnExtension)
+		enum En {
+			A;
+			B;
+		}
+
+
+		class Main {
+			static public function main() {
+				En.{-1-}
+			}
+		}
+	**/
+	function testEnum() {
+		eq(true, hasField(fields(pos(1)), "fromS", "(s : String) -> cases.En"));
+	}
+}

+ 35 - 0
tests/unit/src/unit/issues/Issue10106.hx

@@ -0,0 +1,35 @@
+package unit.issues;
+
+private class CExtension {
+	public static function fromS(cls:Class<C>, s:String) {
+		return new C(s);
+	}
+}
+
+@:using(unit.issues.Issue10106.CExtension)
+private class C {
+	public final s:String;
+
+	public function new(s:String) {
+		this.s = s;
+	}
+}
+
+private class EnExtension {
+	public static function fromS(en:Enum<En>, st:String):En {
+		return A;
+	}
+}
+
+@:using(unit.issues.Issue10106.EnExtension)
+private enum En {
+	A;
+	B;
+}
+
+class Issue10106 extends Test {
+	function test() {
+		eq(A, En.fromS("A"));
+		eq("foo", C.fromS("foo").s);
+	}
+}