瀏覽代碼

added @:require implementation
allow -swf-version 10.1 10.2 support

Nicolas Cannasse 14 年之前
父節點
當前提交
41d2f43cb3
共有 9 個文件被更改,包括 81 次插入20 次删除
  1. 2 2
      common.ml
  2. 1 0
      doc/CHANGES.txt
  3. 16 6
      genswf.ml
  4. 1 1
      genswf8.ml
  5. 2 2
      genxml.ml
  6. 18 7
      main.ml
  7. 4 2
      type.ml
  8. 22 0
      typeload.ml
  9. 15 0
      typer.ml

+ 2 - 2
common.ml

@@ -62,7 +62,7 @@ type context = {
 	mutable load_extern_type : (path -> pos -> Ast.package option) list; (* allow finding types which are not in sources *)
 	(* output *)
 	mutable file : string;
-	mutable flash_version : int;
+	mutable flash_version : float;
 	mutable modules : Type.module_def list;
 	mutable types : Type.module_type list;
 	mutable resources : (string,string) Hashtbl.t;
@@ -93,7 +93,7 @@ let create v =
 		file = "";
 		types = [];
 		modules = [];
-		flash_version = 8;
+		flash_version = 8.;
 		resources = Hashtbl.create 0;
 		php_front = None;
 		swf_libs = [];

+ 1 - 0
doc/CHANGES.txt

@@ -27,6 +27,7 @@
 	flash9 : added @:getter and @:setter
 	all : added @:require
 	flash9 : moved vector utils functions from flash.Lib to flash.Vector
+	flash9 : added support for FP 10.1 and 10.2
 
 2010-08-14: 2.06
 	neko : change serializer to be able to handle instances of basic classes from other modules

+ 16 - 6
genswf.ml

@@ -539,10 +539,20 @@ let tag ?(ext=false) d = {
 	tdata = d;
 }
 
+let swf_ver = function
+	| 6. -> 6
+	| 7. -> 7
+	| 8. -> 8
+	| 9. -> 9
+	| 10. | 10.1 -> 10
+	| 10.2 -> 11
+	| 11. -> 12
+	| _ -> assert false
+
 let convert_header com (w,h,fps,bg) =
 	if max w h >= 1639 then failwith "-swf-header : size too large";
 	{
-		h_version = com.flash_version;
+		h_version = swf_ver com.flash_version;
 		h_size = {
 			rect_nbits = if (max w h) >= 820 then 16 else 15;
 			left = 0;
@@ -814,7 +824,7 @@ let build_swf9 com swc =
 
 let merge com file priority (h1,tags1) (h2,tags2) =
   (* prioritize header+bgcolor for first swf *)
-	let header = if priority then { h2 with h_version = max h2.h_version com.flash_version } else h1 in
+	let header = if priority then { h2 with h_version = max h2.h_version (swf_ver com.flash_version) } else h1 in
 	let tags1 = if priority then List.filter (function { tdata = TSetBgColor _ } -> false | _ -> true) tags1 else tags1 in
   (* remove unused tags *)
 	let use_stage = priority && Common.defined com "flash_use_stage" in
@@ -832,7 +842,7 @@ let merge com file priority (h1,tags1) (h2,tags2) =
 		| TActionScript3 (Some (_,"org/papervision3d/render/QuadrantRenderEngine"),_) when not as3_native -> false
 		| TFilesAttributes _ | TEnableDebugger2 _ | TScenes _ -> false
 		| TSetBgColor _ -> priority
-		| TExport el when !nframe = 0 && com.flash_version >= 9 ->
+		| TExport el when !nframe = 0 && com.flash_version >= 9. ->
 			let el = List.filter (fun e ->
 				let path = parse_path e.exp_name in
 				let b = List.exists (fun t -> t_path t = path) com.types in
@@ -844,7 +854,7 @@ let merge com file priority (h1,tags1) (h2,tags2) =
 			classes := !classes @ List.map (fun e -> { f9_cid = Some e.exp_id; f9_classname = e.exp_name }) el;
 			false
 		| TF9Classes el when !nframe = 0 ->
-			if com.flash_version < 9 then failwith "You can't use AS3 SWF with Flash8 target";
+			if com.flash_version < 9. then failwith "You can't use AS3 SWF with Flash8 target";
 			classes := !classes @ List.filter (fun e -> e.f9_cid <> None) el;
 			false
 		| _ -> true
@@ -896,7 +906,7 @@ let merge com file priority (h1,tags1) (h2,tags2) =
 
 let generate com swf_header =
 	let t = Common.timer "generate swf" in
-	let isf9 = com.flash_version >= 9 in
+	let isf9 = com.flash_version >= 9. in
 	let swc = if Common.defined com "swc" then Some (ref "") else None in
 	if swc <> None && not isf9 then failwith "SWC support is only available for Flash9+";
 	let file , codeclip = (try let f , c = ExtString.String.split com.file "@" in f, Some c with _ -> com.file , None) in
@@ -935,7 +945,7 @@ let generate com swf_header =
 	let header, bg = (match swf_header with None -> default_header com | Some h -> convert_header com h) in
 	let bg = tag (TSetBgColor { cr = bg lsr 16; cg = (bg lsr 8) land 0xFF; cb = bg land 0xFF }) in
 	let debug = (if isf9 && Common.defined com "fdb" then [tag (TEnableDebugger2 (0,""))] else []) in
-	let fattr = (if com.flash_version < 8 then [] else
+	let fattr = (if com.flash_version < 8. then [] else
 		[tag (TFilesAttributes {
 			fa_network = Common.defined com "network-sandbox";
 			fa_as3 = isf9;

+ 1 - 1
genswf8.ml

@@ -1494,7 +1494,7 @@ let generate com =
 	let ctx = {
 		com = com;
 		stack = Codegen.stack_init com true;
-		flash6 = com.flash_version = 6;
+		flash6 = com.flash_version = 6.;
 		segs = [];
 		opcodes = DynArray.create();
 		code_pos = 0;

+ 2 - 2
genxml.ml

@@ -82,10 +82,10 @@ let rec gen_type t =
 and gen_field att f =
 	let add_get_set acc name att =
 		match acc with
-		| AccNormal | AccResolve -> att
+		| AccNormal | AccResolve | AccRequire _ -> att
 		| AccNo | AccNever -> (name, "null") :: att
 		| AccCall m -> (name,m) :: att
-		| AccInline -> (name,"inline") :: att
+		| AccInline -> (name,"inline") :: att		
 	in
 	let att = (match f.cf_expr with None -> att | Some e -> ("line",string_of_int (Lexer.get_error_line e.epos)) :: att) in
 	let att = (match f.cf_kind with

+ 18 - 7
main.ml

@@ -283,11 +283,11 @@ try
 		("-swf",Arg.String (set_platform Flash),"<file> : compile code to Flash SWF file");
 		("-swf9",Arg.String (fun file ->
 			set_platform Flash file;
-			if com.flash_version < 9 then com.flash_version <- 9;
+			if com.flash_version < 9. then com.flash_version <- 9.;
 		),"<file> : compile code to Flash9 SWF file");
 		("-as3",Arg.String (fun dir ->
 			set_platform Flash dir;
-			if com.flash_version < 9 then com.flash_version <- 9;
+			if com.flash_version < 9. then com.flash_version <- 9.;
 			gen_as3 := true;
 			Common.define com "as3";
 			Common.define com "no_inline";
@@ -329,7 +329,7 @@ try
 		), ": add debug informations to the compiled code");
 	] in
 	let adv_args_spec = [
-		("-swf-version",Arg.Int (fun v ->
+		("-swf-version",Arg.Float (fun v ->
 			com.flash_version <- v;
 		),"<version> : change the SWF version (6 to 10)");
 		("-swf-header",Arg.String (fun h ->
@@ -517,15 +517,26 @@ try
 			set_platform Cross "";
 			"?"
 		| Flash | Flash9 ->
-			Common.define com ("flash" ^ string_of_int com.flash_version);
-			if com.flash_version >= 9 then begin
-				Common.define com "flash9"; (* always define flash9, even for flash10+ *)
+			if com.flash_version >= 9. then begin
+				let rec loop = function
+					| [] -> ()
+					| v :: _ when v > com.flash_version -> ()
+					| v :: l ->
+						let maj = int_of_float v in
+						let min = int_of_float (mod_float (v *. 10.) 10.) in
+						let def = "flash" ^ string_of_int maj ^ (if min = 0 then "" else "_" ^ string_of_int min) in
+						Common.define com def;
+						loop l
+				in
+				loop [9.;10.;10.1;10.2;11.];
 				com.package_rules <- PMap.add "flash" (Directory "flash9") com.package_rules;
 				com.package_rules <- PMap.add "flash9" Forbidden com.package_rules;
 				com.platform <- Flash9;
 				add_std "flash9";
-			end else
+			end else begin
+				Common.define com ("flash" ^ string_of_int (int_of_float com.flash_version));
 				add_std "flash";
+			end;
 			"swf"
 		| Neko -> add_std "neko"; "n"
 		| Js -> add_std "js"; "js"

+ 4 - 2
type.ml

@@ -36,6 +36,7 @@ and var_access =
 	| AccResolve		(* call resolve("field") when accessed *)
 	| AccCall of string (* perform a method call when accessed *)
 	| AccInline			(* similar to Normal but inline when accessed *)
+	| AccRequire of string (* set when @:require(cond) fails *)
 
 and method_kind =
 	| MethNormal
@@ -124,7 +125,7 @@ and tclass_field = {
 	cf_public : bool;
 	mutable cf_doc : Ast.documentation;
 	mutable cf_meta : metadata;
-	cf_kind : field_kind;
+	mutable cf_kind : field_kind;
 	cf_params : (string * t) list;
 	mutable cf_expr : texpr option;
 }
@@ -322,6 +323,7 @@ let s_access = function
 	| AccResolve -> "resolve"
 	| AccCall m -> m
 	| AccInline	-> "inline"
+	| AccRequire n -> "require " ^ n
 
 let s_kind = function
 	| Var { v_read = AccNormal; v_write = AccNormal } -> "var"
@@ -541,7 +543,7 @@ let unify_access a1 a2 =
 	| _ -> false
 
 let direct_access = function
-	| AccNo | AccNever | AccNormal | AccInline -> true
+	| AccNo | AccNever | AccNormal | AccInline | AccRequire _ -> true
 	| AccResolve | AccCall _ -> false
 
 let unify_kind k1 k2 =

+ 22 - 0
typeload.ml

@@ -849,11 +849,33 @@ let init_class ctx c p herits fields meta =
 			} in
 			f, false, cf, (fun() -> (!check_get)(); (!check_set)())
 	in
+	let rec check_require = function
+		| [] -> None
+		| (":require",conds) :: l ->
+			let rec loop = function
+				| [] -> check_require l
+				| (EConst (Ident i | Type i),_) :: l ->
+					if not (Common.defined ctx.com i) then
+						Some i
+					else
+						loop l
+				| _ -> error "Invalid require identifier" p
+			in
+			loop conds			
+		| _ :: l ->
+			check_require l
+	in
+	let cl_req = check_require meta in
 	let fl = List.map (fun f ->
 		let fd , constr, f , delayed = loop_cf f in
 		let is_static = List.mem AStatic fd.cff_access in
 		if is_static && f.cf_name = "name" && Common.defined ctx.com "js" then error "This identifier cannot be used in Javascript for statics" p;
 		if (is_static || constr) && c.cl_interface && f.cf_name <> "__init__" then error "You can't declare static fields in interfaces" p;
+		let req = check_require fd.cff_meta in
+		let req = (match req with None -> if is_static || constr then cl_req else None | _ -> req) in
+		(match req with
+		| None -> ()
+		| Some r -> f.cf_kind <- Var { v_read = AccRequire r; v_write = AccRequire r });
 		if constr then begin
 			if c.cl_constructor <> None then error "Duplicate constructor" p;
 			c.cl_constructor <- Some f;

+ 15 - 0
typer.ml

@@ -328,6 +328,16 @@ let rec acc_get ctx g p =
 	| AKMacro _ ->
 		assert false
 
+let error_require r p =
+	let r = try
+		if String.sub r 0 5 <> "flash" then raise Exit;
+		let _, v = ExtString.String.replace (String.sub r 5 (String.length r - 5)) "_" "." in
+		"flash version " ^ v ^ " (use --swf-version " ^ v ^ ")"
+	with _ ->
+		"'" ^ r ^ "' to be enabled"
+	in
+	error ("Accessing this field require " ^ r) p
+
 let field_access ctx mode f t e p =
 	let fnormal() = AKExpr (mk (TField (e,f.cf_name)) t p) in
 	let normal() =
@@ -379,6 +389,8 @@ let field_access ctx mode f t e p =
 			AKNo f.cf_name
 		| AccInline ->
 			AKInline (e,f,t)
+		| AccRequire r ->
+			error_require r p
 
 let using_field ctx mode e i p =
 	if mode = MSet then raise Not_found;
@@ -1389,6 +1401,9 @@ and type_expr ctx ?(need_val=true) (e,p) =
 			if PMap.mem name ctx.locals then error ("Local variable " ^ name ^ " is preventing usage of this class here") p;
 			let f = get_constructor c p in
 			if not f.cf_public && not (is_parent c ctx.curclass) && not ctx.untyped then error "Cannot access private constructor" p;
+			(match f.cf_kind with
+			| Var { v_read = AccRequire r } -> error_require r p
+			| _ -> ());
 			let el = (match follow (apply_params c.cl_types params (field_type f)) with
 			| TFun (args,r) ->
 				unify_call_params ctx (Some "new") el args p false