Browse Source

respect `@:genericBuild` in `type_module_type` (closes #4653)

Simon Krajewski 9 years ago
parent
commit
3f0069928c
4 changed files with 50 additions and 0 deletions
  1. 20 0
      tests/unit/src/unit/issues/Issue4653.hx
  2. 7 0
      tests/unit/src/unit/issues/misc/Issue4653Macro.hx
  3. 13 0
      type.ml
  4. 10 0
      typer.ml

+ 20 - 0
tests/unit/src/unit/issues/Issue4653.hx

@@ -0,0 +1,20 @@
+package unit.issues;
+
+@:genericBuild(unit.issues.misc.Issue4653Macro.getType())
+private class C<T> { }
+
+@:genericBuild(unit.issues.misc.Issue4666Macro.getType())
+private class C2<T> { }
+
+class Issue4653 extends Test {
+	function test() {
+		var s = C;
+		eq("A", s.fromCharCode(65));
+
+		var s2 = cast("foo", C<Dynamic>);
+		eq("FOO", s2.toUpperCase());
+
+		var d = C2;
+		// no idea how to test this properly
+	}
+}

+ 7 - 0
tests/unit/src/unit/issues/misc/Issue4653Macro.hx

@@ -0,0 +1,7 @@
+package unit.issues.misc;
+
+class Issue4653Macro {
+	static public function getType() {
+		return macro : String;
+	}
+}

+ 13 - 0
type.ml

@@ -674,6 +674,19 @@ let type_of_module_type = function
 	| TTypeDecl t -> TType (t,List.map snd t.t_params)
 	| TAbstractDecl a -> TAbstract (a,List.map snd a.a_params)
 
+let rec module_type_of_type = function
+	| TInst(c,_) -> TClassDecl c
+	| TEnum(en,_) -> TEnumDecl en
+	| TType(t,_) -> TTypeDecl t
+	| TAbstract(a,_) -> TAbstractDecl a
+	| TLazy f -> module_type_of_type (!f())
+	| TMono r ->
+		(match !r with
+		| Some t -> module_type_of_type t
+		| _ -> raise Exit)
+	| _ ->
+		raise Exit
+
 let tconst_to_const = function
 	| TInt i -> Int (Int32.to_string i)
 	| TFloat s -> Float s

+ 10 - 0
typer.ml

@@ -837,6 +837,16 @@ let fast_enum_field e ef p =
 
 let rec type_module_type ctx t tparams p =
 	match t with
+	| TClassDecl {cl_kind = KGenericBuild _} ->
+		let _,_,f = Codegen.build_instance ctx t p in
+		let t = f (match tparams with None -> [] | Some tl -> tl) in
+		let mt = try
+			module_type_of_type t
+		with Exit ->
+			if follow t == t_dynamic then Typeload.load_type_def ctx p { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None }
+			else error "Invalid module type" p
+		in
+		type_module_type ctx mt None p
 	| TClassDecl c ->
 		let t_tmp = {
 			t_path = [],"Class<" ^ (s_type_path c.cl_path) ^ ">" ;