Browse Source

check enum flatness during type loading

Simon Krajewski 12 years ago
parent
commit
d03b64bdf7
4 changed files with 8 additions and 3 deletions
  1. 1 0
      ast.ml
  2. 1 0
      common.ml
  3. 2 2
      type.ml
  4. 4 1
      typeload.ml

+ 1 - 0
ast.ml

@@ -60,6 +60,7 @@ module Meta = struct
 		| FakeEnum
 		| File
 		| Final
+		| FlatEnum
 		| Font
 		| From
 		| FunctionCode

+ 1 - 0
common.ml

@@ -319,6 +319,7 @@ module MetaInfo = struct
 		| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
 		| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
 		| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
+		| FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; Internal])
 		| Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
 		| From -> ":from",("Specifies that the field of the abstract is a cast operation from the type identified in the function",[UsedOn TAbstractField])
 		| FunctionCode -> ":functionCode",("",[Platform Cpp])

+ 2 - 2
type.ml

@@ -1155,8 +1155,8 @@ let rec unify a b =
 		| _ -> error [cannot_unify a b])
 	| TEnum _, TAbstract ({ a_path = [],"EnumValue" },[]) ->
 		()
-	| TEnum(en,_), TAbstract ({ a_path = ["haxe"],"FlatEnum" },[]) ->
-		PMap.iter (fun _ ef -> match follow ef.ef_type with TFun _ -> error [cannot_unify a b] | _ -> ()) en.e_constrs	
+	| TEnum(en,_), TAbstract ({ a_path = ["haxe"],"FlatEnum" },[]) when Meta.has Meta.FlatEnum en.e_meta ->
+		()
 	| TFun _, TAbstract ({ a_path = ["haxe"],"Function" },[]) ->
 		()		
 	| TDynamic t , _ ->

+ 4 - 1
typeload.ml

@@ -2171,6 +2171,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
 		let et = TEnum (e,List.map snd e.e_types) in
 		let names = ref [] in
 		let index = ref 0 in
+		let is_flat = ref true in
 		List.iter (fun c ->
 			let p = c.ec_pos in
 			let params = ref [] in
@@ -2191,6 +2192,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
 			let t = (match c.ec_args with
 				| [] -> rt
 				| l ->
+					is_flat := false;
 					let pnames = ref PMap.empty in
 					TFun (List.map (fun (s,opt,t) ->
 						(match t with CTPath({tpackage=[];tname="Void"}) -> error "Arguments of type Void are not allowed in enum constructors" c.ec_pos | _ -> ());
@@ -2213,7 +2215,8 @@ let rec init_module_type ctx context_init do_init (decl,p) =
 			names := c.ec_name :: !names;
 		) (!constructs);
 		e.e_names <- List.rev !names;
-		e.e_extern <- e.e_extern
+		e.e_extern <- e.e_extern;
+		if !is_flat then e.e_meta <- (Meta.FlatEnum,[],e.e_pos) :: e.e_meta;
 	| ETypedef d ->
 		let t = (match get_type d.d_name with TTypeDecl t -> t | _ -> assert false) in
 		let ctx = { ctx with type_params = t.t_types } in