Nicolas Cannasse 17 years ago
parent
commit
a1ca05ebce
4 changed files with 36 additions and 31 deletions
  1. 2 2
      genas3.ml
  2. 1 1
      genxml.ml
  3. 3 3
      type.ml
  4. 30 25
      typer.ml

+ 2 - 2
genas3.ml

@@ -743,7 +743,7 @@ let generate_field ctx static f =
 	let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in
 	let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in
 	let p = ctx.curclass.cl_pos in
 	let p = ctx.curclass.cl_pos in
 	match f.cf_expr with
 	match f.cf_expr with
-	| Some { eexpr = TFunction fd } when f.cf_set = F9MethodAccess ->
+	| Some { eexpr = TFunction fd } when f.cf_set = MethodCantAccess ->
 		print ctx "%s " rights;
 		print ctx "%s " rights;
 		let rec loop c =
 		let rec loop c =
 			match c.cl_super with
 			match c.cl_super with
@@ -831,7 +831,7 @@ let generate_class ctx c =
 		let f = { f with
 		let f = { f with
 			cf_name = snd c.cl_path;
 			cf_name = snd c.cl_path;
 			cf_public = true;
 			cf_public = true;
-			cf_set = F9MethodAccess;
+			cf_set = MethodCantAccess;
 		} in
 		} in
 		ctx.constructor_block <- true;
 		ctx.constructor_block <- true;
 		generate_field ctx false f;
 		generate_field ctx false f;

+ 1 - 1
genxml.ml

@@ -87,7 +87,7 @@ let gen_field att f =
 		| NormalAccess | ResolveAccess -> att
 		| NormalAccess | ResolveAccess -> att
 		| NoAccess | NeverAccess -> (name, "null") :: att
 		| NoAccess | NeverAccess -> (name, "null") :: att
 		| MethodAccess m -> (name, if m = name ^ "_" ^ f.cf_name then "dynamic" else m) :: att
 		| MethodAccess m -> (name, if m = name ^ "_" ^ f.cf_name then "dynamic" else m) :: att
-		| F9MethodAccess -> att
+		| MethodCantAccess -> att
 		| InlineAccess -> assert false
 		| InlineAccess -> assert false
 	in
 	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_expr with None -> att | Some e -> ("line",string_of_int (Lexer.get_error_line e.epos)) :: att) in

+ 3 - 3
type.ml

@@ -25,7 +25,7 @@ type field_access =
 	| NoAccess
 	| NoAccess
 	| ResolveAccess
 	| ResolveAccess
 	| MethodAccess of string
 	| MethodAccess of string
-	| F9MethodAccess
+	| MethodCantAccess
 	| NeverAccess
 	| NeverAccess
 	| InlineAccess
 	| InlineAccess
 
 
@@ -464,8 +464,8 @@ let has_extra_field t n = Has_extra_field (t,n)
 let error l = raise (Unify_error l)
 let error l = raise (Unify_error l)
 
 
 let unify_access a1 a2 =
 let unify_access a1 a2 =
-	a1 = a2 || (a1 = NormalAccess && (a2 = NoAccess || a2 = F9MethodAccess))
-	|| (a1 = F9MethodAccess && a2 = NoAccess)
+	a1 = a2 || (a1 = NormalAccess && (a2 = NoAccess || a2 = MethodCantAccess))
+	|| (a1 = MethodCantAccess && a2 = NoAccess)
 
 
 let eq_stack = ref []
 let eq_stack = ref []
 
 

+ 30 - 25
typer.ml

@@ -35,7 +35,8 @@ type context = {
 	constructs : (module_path , access list * type_param list * func) Hashtbl.t;
 	constructs : (module_path , access list * type_param list * func) Hashtbl.t;
 	warn : string -> pos -> unit;
 	warn : string -> pos -> unit;
 	error : error_msg -> pos -> unit;
 	error : error_msg -> pos -> unit;
-	flash9 : bool;
+	fdynamic : bool;
+	fnullable : bool;
 	doinline : bool;
 	doinline : bool;
 	mutable std : module_def;
 	mutable std : module_def;
 	mutable untyped : bool;
 	mutable untyped : bool;
@@ -84,7 +85,7 @@ let access_str = function
 	| NoAccess -> "null"
 	| NoAccess -> "null"
 	| NeverAccess -> "never"
 	| NeverAccess -> "never"
 	| MethodAccess m -> m
 	| MethodAccess m -> m
-	| F9MethodAccess -> "f9dynamic"
+	| MethodCantAccess -> "f9dynamic"
 	| ResolveAccess -> "resolve"
 	| ResolveAccess -> "resolve"
 	| InlineAccess -> "inline"
 	| InlineAccess -> "inline"
 
 
@@ -138,12 +139,14 @@ let context err warn =
 		mtypes = [];
 		mtypes = [];
 		mimports = [];
 		mimports = [];
 	} in
 	} in
+	let f9 = Plugin.defined "flash9" in
 	let ctx = {
 	let ctx = {
 		modules = Hashtbl.create 0;
 		modules = Hashtbl.create 0;
 		types = Hashtbl.create 0;
 		types = Hashtbl.create 0;
 		constructs = Hashtbl.create 0;
 		constructs = Hashtbl.create 0;
 		delays = ref [];
 		delays = ref [];
-		flash9 = Plugin.defined "flash9";
+		fdynamic = f9 || Plugin.defined "php";
+		fnullable = f9;
 		doinline = not (Plugin.defined "no_inline");
 		doinline = not (Plugin.defined "no_inline");
 		in_constructor = false;
 		in_constructor = false;
 		in_static = false;
 		in_static = false;
@@ -260,13 +263,13 @@ let field_access ctx get f t e p =
 			| _ -> if ctx.untyped then normal else AccNo f.cf_name)
 			| _ -> if ctx.untyped then normal else AccNo f.cf_name)
 		| _ ->
 		| _ ->
 			if ctx.untyped then normal else AccNo f.cf_name)
 			if ctx.untyped then normal else AccNo f.cf_name)
-	| F9MethodAccess when not ctx.untyped ->
-		error "Cannot redefine method with Flash9 : please use 'f9dynamic' before method declaration" p
-	| NormalAccess | F9MethodAccess ->
+	| MethodCantAccess when not ctx.untyped ->
+		error "Cannot rebind this method : please use 'f9dynamic' before method declaration" p
+	| NormalAccess | MethodCantAccess ->
 		AccExpr (mk (TField (e,f.cf_name)) t p)
 		AccExpr (mk (TField (e,f.cf_name)) t p)
 	| MethodAccess m ->
 	| MethodAccess m ->
 		if m = ctx.curmethod && (match e.eexpr with TConst TThis -> true | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then
 		if m = ctx.curmethod && (match e.eexpr with TConst TThis -> true | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then
-			let prefix = if ctx.flash9 && Plugin.defined "as3gen" then "$" else "" in
+			let prefix = if Plugin.defined "as3gen" then "$" else "" in
 			AccExpr (mk (TField (e,prefix ^ f.cf_name)) t p)
 			AccExpr (mk (TField (e,prefix ^ f.cf_name)) t p)
 		else if get then
 		else if get then
 			AccExpr (mk (TCall (mk (TField (e,m)) (mk_mono()) p,[])) t p)
 			AccExpr (mk (TCall (mk (TField (e,m)) (mk_mono()) p,[])) t p)
@@ -413,7 +416,7 @@ and load_type ctx p t =
 				| AFFun (tl,t) ->
 				| AFFun (tl,t) ->
 					let t = load_type ctx p t in
 					let t = load_type ctx p t in
 					let args = List.map (fun (name,o,t) -> name , o, load_type ctx p t) tl in
 					let args = List.map (fun (name,o,t) -> name , o, load_type ctx p t) tl in
-					TFun (args,t), NormalAccess, (if ctx.flash9 then F9MethodAccess else NormalAccess)
+					TFun (args,t), NormalAccess, (if ctx.fdynamic then MethodCantAccess else NormalAccess)
 				| AFProp (t,i1,i2) ->
 				| AFProp (t,i1,i2) ->
 					let access m get =
 					let access m get =
 						match m with
 						match m with
@@ -609,7 +612,7 @@ let extend_remoting ctx c t p async prot =
 				if not f.cf_public then
 				if not f.cf_public then
 					acc
 					acc
 				else match follow f.cf_type with
 				else match follow f.cf_type with
-				| TFun (args,ret) when f.cf_get = NormalAccess && (f.cf_set = NormalAccess || f.cf_set = F9MethodAccess) && f.cf_params = [] ->
+				| TFun (args,ret) when f.cf_get = NormalAccess && (f.cf_set = NormalAccess || f.cf_set = MethodCantAccess) && f.cf_params = [] ->
 					make_field f.cf_name args ret :: acc
 					make_field f.cf_name args ret :: acc
 				| _ -> acc
 				| _ -> acc
 			) c.cl_fields []
 			) c.cl_fields []
@@ -838,7 +841,7 @@ let rec nullable_basic = function
 		None
 		None
 
 
 let make_nullable ctx t =
 let make_nullable ctx t =
-	if not ctx.flash9 then
+	if not ctx.fnullable then
 		t
 		t
 	else match follow t with
 	else match follow t with
 	| TMono _
 	| TMono _
@@ -859,10 +862,10 @@ let make_nullable ctx t =
 			assert false)
 			assert false)
 	| _ -> t
 	| _ -> t
 
 
-let load_type_opt ?(param=false) ctx p t =
+let load_type_opt ?(opt=false) ctx p t =
 	match t with
 	match t with
 	| None ->
 	| None ->
-		if param && ctx.flash9 then
+		if ctx.fnullable && opt then
 			let show = hide_types ctx in
 			let show = hide_types ctx in
 			let t = load_normal_type ctx { tpackage = []; tname = "Null"; tparams = [] } null_pos true in
 			let t = load_normal_type ctx { tpackage = []; tname = "Null"; tparams = [] } null_pos true in
 			show();
 			show();
@@ -871,7 +874,7 @@ let load_type_opt ?(param=false) ctx p t =
 			mk_mono()
 			mk_mono()
 	| Some t ->
 	| Some t ->
 		let t = load_type ctx p t in
 		let t = load_type ctx p t in
-		if param then make_nullable ctx t else t
+		if opt then make_nullable ctx t else t
 
 
 let type_expr_with_type ctx e t =
 let type_expr_with_type ctx e t =
 	match e with
 	match e with
@@ -1217,7 +1220,7 @@ let type_field ctx e i p get =
 		in
 		in
 		(try
 		(try
 			let t , f = class_field c i in
 			let t , f = class_field c i in
-			if ctx.flash9 && e.eexpr = TConst TSuper && f.cf_set = NormalAccess then error "Cannot access superclass variable for calling : needs to be a proper method" p;
+			if ctx.fdynamic && e.eexpr = TConst TSuper && f.cf_set = NormalAccess then error "Cannot access superclass variable for calling : needs to be a proper method" p;
 			if not f.cf_public && not (is_parent c ctx.curclass) && not ctx.untyped then display_error ctx ("Cannot access to private field " ^ i) p;
 			if not f.cf_public && not (is_parent c ctx.curclass) && not ctx.untyped then display_error ctx ("Cannot access to private field " ^ i) p;
 			field_access ctx get f (apply_params c.cl_types params t) e p
 			field_access ctx get f (apply_params c.cl_types params t) e p
 		with Not_found -> try
 		with Not_found -> try
@@ -1876,11 +1879,11 @@ and type_expr ctx ?(need_val=true) (e,p) =
 				| TConst TNull, _ -> make_nullable ctx e2.etype
 				| TConst TNull, _ -> make_nullable ctx e2.etype
 				| _  ->
 				| _  ->
 					unify_raise ctx e1.etype e2.etype p;
 					unify_raise ctx e1.etype e2.etype p;
-					if ctx.flash9 && nullable_basic e1.etype <> None then make_nullable ctx e2.etype else e2.etype)
+					if ctx.fnullable && nullable_basic e1.etype <> None then make_nullable ctx e2.etype else e2.etype)
 			with
 			with
 				Error (Unify _,_) ->
 				Error (Unify _,_) ->
 					unify ctx e2.etype e1.etype p;
 					unify ctx e2.etype e1.etype p;
-					if ctx.flash9 && nullable_basic e2.etype <> None then make_nullable ctx e1.etype else e1.etype
+					if ctx.fnullable && nullable_basic e2.etype <> None then make_nullable ctx e1.etype else e1.etype
 			) in
 			) in
 			mk (TIf (e,e1,Some e2)) t p)
 			mk (TIf (e,e1,Some e2)) t p)
 	| EWhile (cond,e,NormalWhile) ->
 	| EWhile (cond,e,NormalWhile) ->
@@ -1971,7 +1974,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 		type_unop ctx op flag e p
 		type_unop ctx op flag e p
 	| EFunction f ->
 	| EFunction f ->
 		let rt = load_type_opt ctx p f.f_type in
 		let rt = load_type_opt ctx p f.f_type in
-		let args = List.map (fun (s,opt,t) -> s , opt, load_type_opt ~param:opt ctx p t) f.f_args in
+		let args = List.map (fun (s,opt,t) -> s , opt, load_type_opt ~opt ctx p t) f.f_args in
 		(match ctx.param_type with
 		(match ctx.param_type with
 		| None -> ()
 		| None -> ()
 		| Some t ->
 		| Some t ->
@@ -2564,13 +2567,13 @@ let init_class ctx c p herits fields =
 	let is_public access =
 	let is_public access =
 		if c.cl_extern || c.cl_interface || extends_public then not (List.mem APrivate access) else List.mem APublic access
 		if c.cl_extern || c.cl_interface || extends_public then not (List.mem APrivate access) else List.mem APublic access
 	in
 	in
-	let type_opt ?param ctx p t =
+	let type_opt ?opt ctx p t =
 		match t with
 		match t with
 		| None when c.cl_extern || c.cl_interface ->
 		| None when c.cl_extern || c.cl_interface ->
 			display_error ctx "Type required for extern classes and interfaces" p;
 			display_error ctx "Type required for extern classes and interfaces" p;
 			t_dynamic
 			t_dynamic
 		| _ ->
 		| _ ->
-			load_type_opt ?param ctx p t
+			load_type_opt ?opt ctx p t
 	in
 	in
 	let rec has_field f = function
 	let rec has_field f = function
 		| None -> false
 		| None -> false
@@ -2636,7 +2639,7 @@ let init_class ctx c p herits fields =
 				type_params = if stat then params  else params @ ctx.type_params;
 				type_params = if stat then params  else params @ ctx.type_params;
 			} in
 			} in
 			let ret = type_opt ctx p f.f_type in
 			let ret = type_opt ctx p f.f_type in
-			let args = List.map (fun (name,opt,t) -> name , opt, type_opt ~param:opt ctx p t) f.f_args in
+			let args = List.map (fun (name,opt,t) -> name , opt, type_opt ~opt ctx p t) f.f_args in
 			let t = TFun (args,ret) in
 			let t = TFun (args,ret) in
 			let constr = (name = "new") in
 			let constr = (name = "new") in
 			if constr && c.cl_interface then error "An interface cannot have a constructor" p;
 			if constr && c.cl_interface then error "An interface cannot have a constructor" p;
@@ -2650,7 +2653,7 @@ let init_class ctx c p herits fields =
 				cf_doc = doc;
 				cf_doc = doc;
 				cf_type = t;
 				cf_type = t;
 				cf_get = if inline then InlineAccess else NormalAccess;
 				cf_get = if inline then InlineAccess else NormalAccess;
-				cf_set = (if ctx.flash9 && not (List.mem AF9Dynamic access) then F9MethodAccess else if inline then NeverAccess else NormalAccess);
+				cf_set = (if ctx.fdynamic && not (List.mem AF9Dynamic access) then MethodCantAccess else if inline then NeverAccess else NormalAccess);
 				cf_expr = None;
 				cf_expr = None;
 				cf_public = is_public access;
 				cf_public = is_public access;
 				cf_params = params;
 				cf_params = params;
@@ -2699,7 +2702,8 @@ let init_class ctx c p herits fields =
 			) in
 			) in
 			let set = (match set with
 			let set = (match set with
 				| "null" ->
 				| "null" ->
-					if ctx.flash9 && c.cl_extern && (match c.cl_path with "flash" :: _  , _ -> true | _ -> false) then
+					(* standard flash library read-only variables can't be accessed for writing, even in subclasses *)
+					if c.cl_extern && (match c.cl_path with "flash" :: _  , _ -> true | _ -> false) && Plugin.defined "flash9" then
 						NeverAccess
 						NeverAccess
 					else
 					else
 						NoAccess
 						NoAccess
@@ -2856,7 +2860,8 @@ let type_module ctx m tdecls loadp =
 		std = ctx.std;
 		std = ctx.std;
 		ret = ctx.ret;
 		ret = ctx.ret;
 		isproxy = ctx.isproxy;
 		isproxy = ctx.isproxy;
-		flash9 = ctx.flash9;
+		fdynamic = ctx.fdynamic;
+		fnullable = ctx.fnullable;
 		doinline = ctx.doinline;
 		doinline = ctx.doinline;
 		current = m;
 		current = m;
 		locals = PMap.empty;
 		locals = PMap.empty;
@@ -2930,7 +2935,7 @@ let type_module ctx m tdecls loadp =
 				if c = "name" && Plugin.defined "js" then error "This identifier cannot be used in Javascript" p;
 				if c = "name" && Plugin.defined "js" then error "This identifier cannot be used in Javascript" p;
 				let t = (match t with
 				let t = (match t with
 					| [] -> et
 					| [] -> et
-					| l -> TFun (List.map (fun (s,opt,t) -> s, opt, load_type_opt ~param:opt ctx p (Some t)) l, et)
+					| l -> TFun (List.map (fun (s,opt,t) -> s, opt, load_type_opt ~opt ctx p (Some t)) l, et)
 				) in
 				) in
 				if PMap.mem c e.e_constrs then error ("Duplicate constructor " ^ c) p;
 				if PMap.mem c e.e_constrs then error ("Duplicate constructor " ^ c) p;
 				e.e_constrs <- PMap.add c {
 				e.e_constrs <- PMap.add c {
@@ -3040,7 +3045,7 @@ let load ctx m p =
 				| [] , name -> name
 				| [] , name -> name
 				| x :: l , name ->
 				| x :: l , name ->
 					if List.mem x (!forbidden_packages) then error ("You can't access the " ^ x ^ " package with current compilation flags") p;
 					if List.mem x (!forbidden_packages) then error ("You can't access the " ^ x ^ " package with current compilation flags") p;
-					let x = (match x with "flash" when ctx.flash9 -> "flash9" | _ -> x) in
+					let x = (match x with "flash" when Plugin.defined "flash9" -> "flash9" | _ -> x) in
 					String.concat "/" (x :: l) ^ "/" ^ name
 					String.concat "/" (x :: l) ^ "/" ^ name
 			) ^ ".hx" in
 			) ^ ".hx" in
 			let file = (try Plugin.find_file file with Not_found -> raise (Error (Module_not_found m,p))) in
 			let file = (try Plugin.find_file file with Not_found -> raise (Error (Module_not_found m,p))) in