Преглед изворни кода

[js] reserve flattened paths for variable renaming (closes #6409)

Simon Krajewski пре 8 година
родитељ
комит
3ead2175a1

+ 8 - 0
src/compiler/path.ml

@@ -120,6 +120,14 @@ let rec remove_trailing_slash p =
 		| '\\' | '/' -> remove_trailing_slash (String.sub p 0 (l - 1))
 		| _ -> p
 
+let flat_path (p,s) =
+	(* Replace _ with _$ in paths to prevent name collisions. *)
+	let escape str = String.concat "_$" (ExtString.String.nsplit str "_") in
+
+	match p with
+	| [] -> escape s
+	| _ -> String.concat "_" (List.map escape p) ^ "_" ^ (escape s)
+
 open Globals
 
 let find_directories target recursive paths =

+ 1 - 9
src/generators/genjs.ml

@@ -74,15 +74,7 @@ let get_exposed ctx path meta =
 
 let dot_path = s_type_path
 
-let flat_path (p,s) =
-	(* Replace _ with _$ in paths to prevent name collisions. *)
-	let escape str = String.concat "_$" (ExtString.String.nsplit str "_") in
-
-	match p with
-	| [] -> escape s
-	| _ -> String.concat "_" (List.map escape p) ^ "_" ^ (escape s)
-
-let s_path ctx = if ctx.js_flatten then flat_path else dot_path
+let s_path ctx = if ctx.js_flatten then Path.flat_path else dot_path
 
 let kwds =
 	let h = Hashtbl.create 0 in

+ 2 - 2
src/macro/macroContext.ml

@@ -411,7 +411,7 @@ and flush_macro_context mint ctx =
 		mint
 	end else mint in
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
-	let expr_filters = [Filters.VarLazifier.apply mctx.com;AbstractCast.handle_abstract_casts mctx; CapturedVars.captured_vars mctx.com; Filters.rename_local_vars mctx] in
+	let expr_filters = [Filters.VarLazifier.apply mctx.com;AbstractCast.handle_abstract_casts mctx; CapturedVars.captured_vars mctx.com;] in
 
 	(*
 		some filters here might cause side effects that would break compilation server.
@@ -427,7 +427,7 @@ and flush_macro_context mint ctx =
 			()
 	in
 	let type_filters = [
-		Filters.add_field_inits mctx;
+		Filters.add_field_inits (StringMap.empty) mctx;
 		minimal_restore;
 		Filters.apply_native_paths mctx
 	] in

+ 13 - 7
src/optimization/filters.ml

@@ -215,12 +215,12 @@ let check_local_vars_init e =
 (* -------------------------------------------------------------------------- *)
 (* RENAME LOCAL VARS *)
 
-let rename_local_vars ctx e =
+let rename_local_vars ctx reserved e =
 	let vars = ref [] in
 	let declare v =
 		vars := v :: !vars
 	in
-	let reserved = ref StringMap.empty in
+	let reserved = ref reserved in
 	let reserve name =
 		reserved := StringMap.add name true !reserved
 	in
@@ -572,7 +572,7 @@ let add_rtti ctx t =
 		()
 
 (* Adds member field initializations as assignments to the constructor *)
-let add_field_inits ctx t =
+let add_field_inits reserved ctx t =
 	let is_as3 = Common.defined ctx.com Define.As3 && not ctx.in_macro in
 	let apply c =
 		let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_params)) c.cl_pos in
@@ -648,7 +648,7 @@ let add_field_inits ctx t =
 			(match cf.cf_expr with
 			| Some e ->
 				(* This seems a bit expensive, but hopefully constructor expressions aren't that massive. *)
-				let e = rename_local_vars ctx e in
+				let e = rename_local_vars ctx reserved e in
 				let e = Optimizer.sanitize ctx.com e in
 				cf.cf_expr <- Some e
 			| _ ->
@@ -908,12 +908,18 @@ let run com tctx main =
 	List.iter (fun f -> List.iter f new_types) filters;
 	t();
 	if com.platform <> Cross then Analyzer.Run.run_on_types tctx new_types;
-
+	let reserved = match com.platform with
+		| Js ->
+			let h = ref StringMap.empty in
+			List.iter (fun mt -> h := StringMap.add (Path.flat_path (t_infos mt).mt_path) true !h) com.types;
+			!h
+		| _ -> StringMap.empty
+	in
 	let filters = [
 		Optimizer.sanitize com;
 		if com.config.pf_add_final_return then add_final_return else (fun e -> e);
 		if com.platform = Js then wrap_js_exceptions com else (fun e -> e);
-		rename_local_vars tctx;
+		rename_local_vars tctx reserved;
 		mark_switch_break_loops;
 	] in
 	let t = filter_timer detail_times ["expr 2"] in
@@ -955,7 +961,7 @@ let run com tctx main =
 		check_private_path;
 		apply_native_paths;
 		add_rtti;
-		(match com.platform with | Java | Cs -> (fun _ _ -> ()) | _ -> add_field_inits);
+		(match com.platform with | Java | Cs -> (fun _ _ -> ()) | _ -> add_field_inits reserved);
 		(match com.platform with Hl -> (fun _ _ -> ()) | _ -> add_meta_field);
 		check_void_field;
 		(match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ _ -> ()) );

+ 6 - 6
std/js/_std/Std.hx

@@ -69,12 +69,12 @@ import js.Boot;
 			__feature__("js.Boot.getClass",__js__('Date').prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Date"] = __js__('Date'),__js__('Date')));
 			__feature__("js.Boot.isClass",__js__('Date').__name__ = ["Date"]);
 		});
-		__feature__("Int.*",var Int = {});
-		__feature__("Dynamic.*",var Dynamic = {});
-		__feature__("Float.*",var Float = __js__("Number"));
-		__feature__("Bool.*",var Bool = __js__("Boolean"));
-		__feature__("Class.*",var Class = {});
-		__feature__("Enum.*",var Enum = {});
+		__feature__("Int.*",__js__('var Int = { };'));
+		__feature__("Dynamic.*",__js__('var Dynamic = { };'));
+		__feature__("Float.*",__js__('var Float = Number'));
+		__feature__("Bool.*",__js__('var Bool = Boolean'));
+		__feature__("Class.*",__js__('var Class = { };'));
+		__feature__("Enum.*",__js__('var Enum = { };'));
 
 #if (js_es < 5)
 		__feature__("Array.map",

+ 19 - 0
tests/optimization/src/issues/Issue6409.hx

@@ -0,0 +1,19 @@
+package issues;
+
+enum E {
+    Flags( v : String );
+}
+
+class Issue6409 {
+	@:js('
+		var issues_E1 = null;
+		var f = issues_E.Flags("");
+		console.log(f);
+	')
+	@:analyzer(ignore)
+    static function test() {
+        var issues_E = null;
+        var f : E = Flags("");
+        trace(f);
+    }
+}