Ver Fonte

change in optional structure fields

Nicolas Cannasse há 13 anos atrás
pai
commit
04348b7701
3 ficheiros alterados com 28 adições e 18 exclusões
  1. 7 6
      parser.ml
  2. 2 2
      type.ml
  3. 19 10
      typeload.ml

+ 7 - 6
parser.ml

@@ -339,10 +339,10 @@ and parse_complex_type_inner = parser
 	| [< '(POpen,_); t = parse_complex_type; '(PClose,_) >] -> CTParent t
 	| [< '(BrOpen,p1); s >] ->
 		(match s with parser
-		| [< name, p = any_ident >] -> CTAnonymous (parse_type_anonymous_resume name p s)
+		| [< l = parse_type_anonymous false >] -> CTAnonymous l
 		| [< '(Binop OpGt,_); t = parse_type_path; '(Comma,_); s >] ->
 			(match s with parser
-			| [< name, p = any_ident; l = parse_type_anonymous_resume name p >] -> CTExtend (t,l)
+			| [< l = parse_type_anonymous false >] -> CTExtend (t,l)
 			| [< l, _ = parse_class_fields true p1 >] -> CTExtend (t,l)
 			| [< >] -> serror())
 		| [< l, _ = parse_class_fields true p1 >] -> CTAnonymous l
@@ -406,15 +406,16 @@ and parse_complex_type_next t = parser
 			CTFunction ([t] , t2))
 	| [< >] -> t
 
-and parse_type_anonymous_resume name p1 = parser
-	| [< '(DblDot,_); t = parse_complex_type; s >] ->
+and parse_type_anonymous opt = parser
+	| [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s
+	| [< name, p1 = any_ident; '(DblDot,_); t = parse_complex_type; s >] ->
 		let next p2 acc =
 			{
 				cff_name = name;
 				cff_meta = [];
 				cff_access = [];
 				cff_doc = None;
-				cff_kind = FVar (Some t,None);
+				cff_kind = FVar (Some (if opt then CTOptional t else t),None);
 				cff_pos = punion p1 p2;
 			} :: acc
 		in
@@ -423,7 +424,7 @@ and parse_type_anonymous_resume name p1 = parser
 		| [< '(Comma,p2) >] ->
 			(match s with parser
 			| [< '(BrClose,_) >] -> next p2 []
-			| [< name, p = any_ident; s >] -> next p2 (parse_type_anonymous_resume name p s)
+			| [< l = parse_type_anonymous false >] -> next p2 l
 			| [< >] -> serror());
 		| [< >] -> serror()
 

+ 2 - 2
type.ml

@@ -311,7 +311,7 @@ let rec s_type ctx t =
 			(if b then "?" else "") ^ (if s = "" then "" else s ^ " : ") ^ s_fun ctx t true
 		) l) ^ " -> " ^ s_fun ctx t false
 	| TAnon a ->
-		let fl = PMap.fold (fun f acc -> (" " ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in
+	let fl = PMap.fold (fun f acc -> ((if List.exists (function ":optional",_,_ -> true | _ -> false) f.cf_meta then " ?" else " ") ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in
 		"{" ^ (if not (is_closed a) then "+" else "") ^  String.concat "," fl ^ " }"
 	| TDynamic t2 ->
 		"Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
@@ -834,7 +834,7 @@ let rec unify a b =
 					| Opened ->
 						if not (link (ref None) a f2.cf_type) then error [];
 						a1.a_fields <- PMap.add n f2 a1.a_fields
-					| Const when is_null f2.cf_type ->
+					| Const when has_meta ":optional" f2.cf_meta ->
 						()
 					| _ ->
 						error [has_no_field a n];

+ 19 - 10
typeload.ml

@@ -179,7 +179,7 @@ and load_complex_type ctx p t =
 	match t with
 	| CTParent t -> load_complex_type ctx p t
 	| CTPath t -> load_instance ctx t p false
-	| CTOptional _ -> error "Optional type not allowed outside function arguments" p
+	| CTOptional _ -> error "Optional type not allowed here" p
 	| CTExtend (t,l) ->
 		(match load_complex_type ctx p (CTAnonymous l) with
 		| TAnon a ->
@@ -233,15 +233,24 @@ and load_complex_type ctx p t =
 				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
 				| AStatic | AOverride | AInline | ADynamic -> error ("Invalid access " ^ Ast.s_access a) p
 			) f.cff_access;
-			let t , access = (match f.cff_kind with
+			let t , access, meta = (match f.cff_kind with
 				| FVar (t, e) ->
 					no_expr e;
-					topt t, Var { v_read = AccNormal; v_write = AccNormal }
-				| FFun f ->
-					if f.f_params <> [] then error "Type parameters are not allowed in structures" p;
-					no_expr f.f_expr;
-					let args = List.map (fun (name,o,t,e) -> no_expr e; name, o, topt t) f.f_args in
-					TFun (args,topt f.f_type), Method (if !dyn then MethDynamic else MethNormal)
+					let t, meta = (match t with
+						| Some (CTOptional t) -> 
+							let t = (match t with
+							| CTPath { tpackage = []; tname = "Null"; tparams = [_] } -> t
+							| _ -> CTPath { tpackage = []; tname = "Null"; tparams = [TPType t]; tsub = None }
+							) in
+							Some t, (":optional",[],f.cff_pos) :: f.cff_meta
+						| _ -> t, f.cff_meta
+					) in
+					topt t, Var { v_read = AccNormal; v_write = AccNormal }, meta
+				| FFun ff ->
+					if ff.f_params <> [] then error "Type parameters are not allowed in structures" p;
+					no_expr ff.f_expr;
+					let args = List.map (fun (name,o,t,e) -> no_expr e; name, o, topt t) ff.f_args in
+					TFun (args,topt ff.f_type), Method (if !dyn then MethDynamic else MethNormal), f.cff_meta
 				| FProp (i1,i2,t,e) ->
 					no_expr e;
 					let access m get =
@@ -252,7 +261,7 @@ and load_complex_type ctx p t =
 						| "dynamic" -> AccCall ((if get then "get_"  else "set_") ^ n)
 						| _ -> AccCall m
 					in
-					load_complex_type ctx p t, Var { v_read = access i1 true; v_write = access i2 false }
+					load_complex_type ctx p t, Var { v_read = access i1 true; v_write = access i2 false }, f.cff_meta
 			) in
 			PMap.add n {
 				cf_name = n;
@@ -263,7 +272,7 @@ and load_complex_type ctx p t =
 				cf_params = [];
 				cf_expr = None;
 				cf_doc = f.cff_doc;
-				cf_meta = f.cff_meta;
+				cf_meta = meta;
 			} acc
 		in
 		mk_anon (List.fold_left loop PMap.empty l)