Browse Source

[jvm] generate private types as inner classes

Simon Krajewski 5 years ago
parent
commit
fab1478ede

+ 1 - 1
src/core/tType.ml

@@ -189,7 +189,7 @@ and tclass_kind =
 and metadata = Ast.metadata
 and metadata = Ast.metadata
 
 
 and tinfos = {
 and tinfos = {
-	mt_path : path;
+	mutable mt_path : path;
 	mt_module : module_def;
 	mt_module : module_def;
 	mt_pos : pos;
 	mt_pos : pos;
 	mt_name_pos : pos;
 	mt_name_pos : pos;

+ 27 - 6
src/generators/genjvm.ml

@@ -215,6 +215,10 @@ module AnnotationHandler = struct
 		List.iter (fun (m,el,_) -> match m,el with
 		List.iter (fun (m,el,_) -> match m,el with
 			| Meta.Meta,[e] ->
 			| Meta.Meta,[e] ->
 				let path,annotation = parse_expr e in
 				let path,annotation = parse_expr e in
+				let path = match path with
+					| [],name -> ["haxe";"root"],name
+					| _ -> path
+				in
 				builder#add_annotation path annotation;
 				builder#add_annotation path annotation;
 			| _ ->
 			| _ ->
 				()
 				()
@@ -1415,7 +1419,7 @@ class texpr_to_jvm gctx (jc : JvmClass.builder) (jm : JvmMethod.builder) (return
 			let tl,tr = self#call_arguments cf.cf_type el in
 			let tl,tr = self#call_arguments cf.cf_type el in
 			jm#invokestatic c.cl_path (String.sub cf.cf_name 1 (String.length cf.cf_name - 1)) (method_sig tl tr);
 			jm#invokestatic c.cl_path (String.sub cf.cf_name 1 (String.length cf.cf_name - 1)) (method_sig tl tr);
 			tr
 			tr
-		| TField(_,FStatic({cl_path = (["haxe";"_Int64"],"Int64_Impl_")},{cf_name = "make"})) ->
+		| TField(_,FStatic({cl_path = (["haxe"],"Int64$Int64_Impl_")},{cf_name = "make"})) ->
 			begin match el with
 			begin match el with
 			| [{eexpr = TConst (TInt i1)};{eexpr = TConst (TInt i2)}] ->
 			| [{eexpr = TConst (TInt i1)};{eexpr = TConst (TInt i2)}] ->
 				let high = Int64.of_int32 i1 in
 				let high = Int64.of_int32 i1 in
@@ -2752,12 +2756,32 @@ module Preprocessor = struct
 	let make_root path =
 	let make_root path =
 		["haxe";"root"],snd path
 		["haxe";"root"],snd path
 
 
+	let check_path mt =
+		if mt.mt_private then begin
+			let m = mt.mt_module in
+			mt.mt_path <- (fst m.m_path,Printf.sprintf "%s$%s" (snd m.m_path) (snd mt.mt_path))
+		end else if fst mt.mt_path = [] then
+			mt.mt_path <- make_root mt.mt_path
+
 	let preprocess gctx =
 	let preprocess gctx =
+		let rec has_runtime_meta = function
+			| (Meta.Custom s,_,_) :: _ when String.length s > 0 && s.[0] <> ':' ->
+				true
+			| _ :: l ->
+				has_runtime_meta l
+			| [] ->
+				false
+		in
 		(* go through com.modules so we can also pick up private typedefs *)
 		(* go through com.modules so we can also pick up private typedefs *)
 		List.iter (fun m ->
 		List.iter (fun m ->
-			List.iter (fun mt -> match mt with
+			List.iter (fun mt ->
+				match mt with
+				| TClassDecl ({cl_interface=true} as c) when has_runtime_meta c.cl_meta ->
+					() (* TODO: run-time interface metadata is a problem (issue #2042) *)
+				| TClassDecl _ | TEnumDecl _ ->
+					check_path (t_infos mt);
 				| TTypeDecl td ->
 				| TTypeDecl td ->
-					if fst td.t_path = [] then td.t_path <- make_root td.t_path;
+					check_path (t_infos mt);
 					gctx.anon_identification#identify_typedef td
 					gctx.anon_identification#identify_typedef td
 				| _ ->
 				| _ ->
 					()
 					()
@@ -2767,10 +2791,7 @@ module Preprocessor = struct
 		List.iter (fun mt ->
 		List.iter (fun mt ->
 			match mt with
 			match mt with
 			| TClassDecl c ->
 			| TClassDecl c ->
-				if fst c.cl_path = [] then c.cl_path <- make_root c.cl_path;
 				if debug_path c.cl_path && not c.cl_interface then gctx.preprocessor#preprocess_class c
 				if debug_path c.cl_path && not c.cl_interface then gctx.preprocessor#preprocess_class c
-			| TEnumDecl en ->
-				if fst en.e_path = [] then en.e_path <- make_root en.e_path;
 			| _ -> ()
 			| _ -> ()
 		) gctx.com.types;
 		) gctx.com.types;
 		(* find typedef-interface implementations *)
 		(* find typedef-interface implementations *)

+ 1 - 1
src/generators/jvm/jvmConstantPool.ml

@@ -87,7 +87,7 @@ class constant_pool = object(self)
 	method add_path path =
 	method add_path path =
 		let s = self#s_type_path path in
 		let s = self#s_type_path path in
 		let offset = self#add_type s in
 		let offset = self#add_type s in
-		if String.contains (snd path) '$' then begin
+		if String.contains (snd path) '$' && not (ExtString.String.starts_with s "[") then begin
 			let name1,name2 = ExtString.String.split (snd path) "$" in
 			let name1,name2 = ExtString.String.split (snd path) "$" in
 			Hashtbl.replace inner_classes ((fst path,name1),name2) offset;
 			Hashtbl.replace inner_classes ((fst path,name1),name2) offset;
 		end;
 		end;

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

@@ -3,7 +3,7 @@ package unit.issues;
 class Issue6838 extends unit.Test {
 class Issue6838 extends unit.Test {
 	function test() {
 	function test() {
 		var o = new Object();
 		var o = new Object();
-		eq('unit.issues._Issue6838.Object', Type.getClassName(Type.getClass(o)));
+		eq(#if jvm "unit.issues.Issue6838$Object" #else 'unit.issues._Issue6838.Object' #end, Type.getClassName(Type.getClass(o)));
 	}
 	}
 }
 }