Browse Source

Add --js-modern.

This will prevent most uses of the global namespace, use JS strict mode (soon)
and potentially other new JS compiler features in the future.

This is a compiler flag due to non-backwards compatibility, but perhaps
--js-modern can become the default in haXe 3.0.
Bruno Garcia 13 years ago
parent
commit
d9217d0667
6 changed files with 67 additions and 38 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 27 5
      genjs.ml
  3. 3 0
      main.ml
  4. 3 1
      std/haxe/Timer.hx
  5. 24 23
      std/js/Lib.hx
  6. 9 9
      std/js/_std/Std.hx

+ 1 - 0
doc/CHANGES.txt

@@ -31,6 +31,7 @@
 	js : make difference between values and statements expressions in JSGenApi
 	js : make difference between values and statements expressions in JSGenApi
 	js : added source mapping with -debug (replace previous stack emulation)
 	js : added source mapping with -debug (replace previous stack emulation)
 	flash : added @:file("a.dat") class File extends flash.utils.ByteArray
 	flash : added @:file("a.dat") class File extends flash.utils.ByteArray
+	js : added --js-modern for wrapping output in a closure
 
 
 2011-09-25: 2.08
 2011-09-25: 2.08
 	js : added js.JQuery
 	js : added js.JQuery

+ 27 - 5
genjs.ml

@@ -42,6 +42,7 @@ type ctx = {
 	packages : (string list,unit) Hashtbl.t;
 	packages : (string list,unit) Hashtbl.t;
 	stack : Codegen.stack_context;
 	stack : Codegen.stack_context;
 	smap : sourcemap;
 	smap : sourcemap;
+	js_modern : bool;
 	mutable current : tclass;
 	mutable current : tclass;
 	mutable statics : (tclass * string * texpr) list;
 	mutable statics : (tclass * string * texpr) list;
 	mutable inits : texpr list;
 	mutable inits : texpr list;
@@ -778,10 +779,17 @@ let generate_package_create ctx (p,_) =
 			Hashtbl.add ctx.packages (p :: acc) ();
 			Hashtbl.add ctx.packages (p :: acc) ();
 			(match acc with
 			(match acc with
 			| [] ->
 			| [] ->
-				print ctx "var %s = %s || {}" p p;
+				if ctx.js_modern then
+					print ctx "var %s = {}" p
+				else
+					print ctx "var %s = %s || {}" p p
 			| _ ->
 			| _ ->
 				let p = String.concat "." (List.rev acc) ^ (field p) in
 				let p = String.concat "." (List.rev acc) ^ (field p) in
-		        print ctx "if(!%s) %s = {}" p p);
+				if ctx.js_modern then
+					print ctx "%s = {}" p
+				else
+					print ctx "if(!%s) %s = {}" p p
+			);
 			newline ctx;
 			newline ctx;
 			loop (p :: acc) l
 			loop (p :: acc) l
 	in
 	in
@@ -835,11 +843,18 @@ let generate_class ctx c =
 	| _ -> ());
 	| _ -> ());
 	let p = s_path ctx c.cl_path in
 	let p = s_path ctx c.cl_path in
 	generate_package_create ctx c.cl_path;
 	generate_package_create ctx c.cl_path;
-	print ctx "%s = $hxClasses[\"%s\"] = " p p;
+	if ctx.js_modern then
+		print ctx "%s = " p
+	else
+		print ctx "%s = $hxClasses[\"%s\"] = " p p;
 	(match c.cl_constructor with
 	(match c.cl_constructor with
 	| Some { cf_expr = Some e } -> gen_expr ctx e
 	| Some { cf_expr = Some e } -> gen_expr ctx e
 	| _ -> print ctx "function() { }");
 	| _ -> print ctx "function() { }");
 	newline ctx;
 	newline ctx;
+	if ctx.js_modern then begin
+		print ctx "$hxClasses[\"%s\"] = %s" p p;
+		newline ctx;
+	end;
 	print ctx "%s.__name__ = [%s]" p (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" (Ast.s_escape s)) (fst c.cl_path @ [snd c.cl_path])));
 	print ctx "%s.__name__ = [%s]" p (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" (Ast.s_escape s)) (fst c.cl_path @ [snd c.cl_path])));
 	newline ctx;
 	newline ctx;
 	(match c.cl_implements with
 	(match c.cl_implements with
@@ -953,6 +968,7 @@ let alloc_ctx com =
 			sources_hash = Hashtbl.create 0;
 			sources_hash = Hashtbl.create 0;
 			mappings = Buffer.create 16;
 			mappings = Buffer.create 16;
 		};
 		};
+		js_modern = Common.defined com "js_modern";
 		statics = [];
 		statics = [];
 		inits = [];
 		inits = [];
 		current = null_class;
 		current = null_class;
@@ -981,12 +997,17 @@ let generate com =
 	| Some g -> g()
 	| Some g -> g()
 	| None ->
 	| None ->
 	let ctx = alloc_ctx com in
 	let ctx = alloc_ctx com in
-	print ctx "var $_, $hxClasses = $hxClasses || {}, $estr = function() { return js.Boot.__string_rec(this,''); }
+	if ctx.js_modern then begin
+		print ctx "(function () {";
+		newline ctx;
+	end;
+	let hxClasses = if ctx.js_modern then "{}" else "$hxClasses || {}" in
+	print ctx "var $_, $hxClasses = %s, $estr = function() { return js.Boot.__string_rec(this,''); }
 function $extend(from, fields) {
 function $extend(from, fields) {
 	function inherit() {}; inherit.prototype = from; var proto = new inherit();
 	function inherit() {}; inherit.prototype = from; var proto = new inherit();
 	for (var name in fields) proto[name] = fields[name];
 	for (var name in fields) proto[name] = fields[name];
 	return proto;
 	return proto;
-}";
+}" hxClasses;
 	newline ctx;
 	newline ctx;
 	List.iter (generate_type ctx) com.types;
 	List.iter (generate_type ctx) com.types;
 	print ctx "js.Boot.__res = {}";
 	print ctx "js.Boot.__res = {}";
@@ -1007,6 +1028,7 @@ function $extend(from, fields) {
 	(match com.main with
 	(match com.main with
 	| None -> ()
 	| None -> ()
 	| Some e -> gen_expr ctx e);
 	| Some e -> gen_expr ctx e);
+	if ctx.js_modern then print ctx "})()";
 	if com.debug then write_mappings ctx;
 	if com.debug then write_mappings ctx;
 	let ch = open_out_bin com.file in
 	let ch = open_out_bin com.file in
 	output_string ch (Buffer.contents ctx.buf);
 	output_string ch (Buffer.contents ctx.buf);

+ 3 - 0
main.ml

@@ -746,6 +746,9 @@ try
 			com.foptimize <- false;
 			com.foptimize <- false;
 			Common.define com "no_opt";
 			Common.define com "no_opt";
 		), ": disable code optimizations");
 		), ": disable code optimizations");
+		("--js-modern", Arg.Unit (fun() ->
+			Common.define com "js_modern";
+		), ": wrap JS output in a closure, strict mode, and other upcoming features");
 		("--php-front",Arg.String (fun f ->
 		("--php-front",Arg.String (fun f ->
 			if com.php_front <> None then raise (Arg.Bad "Multiple --php-front");
 			if com.php_front <> None then raise (Arg.Bad "Multiple --php-front");
 			com.php_front <- Some f;
 			com.php_front <- Some f;

+ 3 - 1
std/haxe/Timer.hx

@@ -113,7 +113,9 @@ class Timer {
 
 
 	#if js
 	#if js
 	static function __init__() untyped {
 	static function __init__() untyped {
-		if( __js__('typeof')(haxe_timers) == 'undefined' ) haxe_timers = [];
+		if( __js__('typeof')(haxe_timers) == 'undefined' ) {
+			var haxe_timers = [];
+		}
 	}
 	}
 	#end
 	#end
 	
 	

+ 24 - 23
std/js/Lib.hx

@@ -49,31 +49,32 @@ class Lib {
 	static function __init__() untyped {
 	static function __init__() untyped {
 		if( __js__("typeof document") != "undefined" )
 		if( __js__("typeof document") != "undefined" )
 			document = __js__("document");
 			document = __js__("document");
-		if( __js__("typeof window") != "undefined" )
+		if( __js__("typeof window") != "undefined" ) {
 			window = __js__("window");
 			window = __js__("window");
-		#if debug
-__js__('onerror = function(msg,url,line) {
-		var stack = $s.copy();
-		var f = js.Lib.onerror;
-		$s.splice(0,$s.length);
-		if( f == null ) {
-			var i = stack.length;
-			var s = "";
-			while( --i >= 0 )
-				s += "Called from "+stack[i]+"\\n";
-			alert(msg+"\\n\\n"+s);
-			return false;
+			#if debug
+	__js__('window.onerror = function(msg,url,line) {
+			var stack = $s.copy();
+			var f = js.Lib.onerror;
+			$s.splice(0,$s.length);
+			if( f == null ) {
+				var i = stack.length;
+				var s = "";
+				while( --i >= 0 )
+					s += "Called from "+stack[i]+"\\n";
+				alert(msg+"\\n\\n"+s);
+				return false;
+			}
+			return f(msg,stack);
+		}');
+			#else
+	__js__('window.onerror = function(msg,url,line) {
+			var f = js.Lib.onerror;
+			if( f == null )
+				return false;
+			return f(msg,[url+":"+line]);
+		}');
+			#end
 		}
 		}
-		return f(msg,stack);
-	}');
-		#else
-__js__('onerror = function(msg,url,line) {
-		var f = js.Lib.onerror;
-		if( f == null )
-			return false;
-		return f(msg,[url+":"+line]);
-	}');
-		#end
 	}
 	}
 
 
 }
 }

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

@@ -60,19 +60,19 @@
 	}
 	}
 
 
 	static function __init__() : Void untyped {
 	static function __init__() : Void untyped {
-		String.prototype.__class__ = $hxClasses['String'] = String;
+		String.prototype.__class__ = $hxClasses["String"] = String;
 		String.__name__ = ["String"];
 		String.__name__ = ["String"];
-		Array.prototype.__class__ = $hxClasses['Array'] = Array;
+		Array.prototype.__class__ = $hxClasses["Array"] = Array;
 		Array.__name__ = ["Array"];
 		Array.__name__ = ["Array"];
-		Int = $hxClasses['Int'] = { __name__ : ["Int"] };
-		Dynamic = $hxClasses['Dynamic'] = { __name__ : ["Dynamic"] };
-		Float = $hxClasses['Float'] = __js__("Number");
+		var Int = $hxClasses["Int"] = { __name__ : ["Int"] };
+		var Dynamic = $hxClasses["Dynamic"] = { __name__ : ["Dynamic"] };
+		var Float = $hxClasses["Float"] = __js__("Number");
 		Float.__name__ = ["Float"];
 		Float.__name__ = ["Float"];
-		Bool = $hxClasses['Bool'] = __js__("Boolean");
+		var Bool = $hxClasses["Bool"] = __js__("Boolean");
 		Bool.__ename__ = ["Bool"];
 		Bool.__ename__ = ["Bool"];
-		Class = $hxClasses['Class'] = { __name__ : ["Class"] };
-		Enum = {};
-		Void = $hxClasses['Void'] = { __ename__ : ["Void"] };
+		var Class = $hxClasses["Class"] = { __name__ : ["Class"] };
+		var Enum = {};
+		var Void = $hxClasses["Void"] = { __ename__ : ["Void"] };
 	}
 	}
 
 
 }
 }