瀏覽代碼

small fixes for as3
Enum<T>

Nicolas Cannasse 16 年之前
父節點
當前提交
2e83a0c37a
共有 14 個文件被更改,包括 58 次插入27 次删除
  1. 6 0
      doc/CHANGES.txt
  2. 19 9
      genas3.ml
  3. 1 1
      std/Enum.hx
  4. 15 6
      std/Type.hx
  5. 1 1
      std/haxe/Unserializer.hx
  6. 1 1
      tests/unit/MyClass.hx
  7. 1 1
      tests/unit/MySubClass.hx
  8. 3 2
      tests/unit/Test.hx
  9. 3 0
      tests/unit/TestMisc.hx
  10. 2 0
      tests/unit/TestResource.hx
  11. 1 1
      tests/unit/unit.hxml
  12. 2 2
      tests/unit/unit.hxp
  13. 2 2
      type.ml
  14. 1 1
      typer.ml

+ 6 - 0
doc/CHANGES.txt

@@ -18,6 +18,12 @@ TODO :
 	flash9 : fixed switch on Null<Int> verify error
 	flash9 : fixes related to UInt type + error when using Int/UInt comparison
 	as3 : improved Vector support, inline flash.Lib.as
+	as3 : bugfix with skip_constructor
+	as3 : added Enum.__constructs__ (allow Type.getEnumConstructs)
+	as3 : make all constructor parameters optional (allow Type.createEmptyInstance)
+	as3 : bugfix with property access inside setter (stack overflow)
+	all : Enum is now Enum<T>
+	all : added Type.createEnumIndex
 
 2009-03-22: 2.03
 	optimized Type.enumEq : use index instead of tag comparison for neko/flash9/php

+ 19 - 9
genas3.ml

@@ -181,6 +181,13 @@ let parent e =
 	| TParenthesis _ -> e
 	| _ -> mk (TParenthesis e) e.etype e.epos
 
+let default_value tstr =
+	match tstr with
+	| "int" | "uint" -> "0"
+	| "Number" -> "NaN"
+	| "Boolean" -> "false"
+	| _ -> "null"
+
 let rec type_str ctx t p =
 	match t with
 	| TEnum _ | TInst _ when List.memq t ctx.local_types ->
@@ -277,9 +284,11 @@ let gen_function_header ctx name f params p =
 	print ctx "function%s(" (match name with None -> "" | Some n -> " " ^ n);
 	concat ctx "," (fun (arg,c,t) ->
 		let arg = define_local ctx arg in
-		print ctx "%s : %s" arg (type_str ctx t p);
+		let tstr = type_str ctx t p in
+		print ctx "%s : %s" arg tstr;
 		match c with
-		| None -> ()
+		| None ->
+			if ctx.constructor_block then print ctx " = %s" (default_value tstr);
 		| Some c ->
 			spr ctx " = ";
 			gen_constant ctx p c
@@ -495,9 +504,12 @@ and gen_expr ctx e =
 		let b = save_locals ctx in
 		print ctx "{";
 		let bend = open_block ctx in
-		let cb = (if not ctx.constructor_block || not (Codegen.constructor_side_effects e) then
+		let cb = (if not ctx.constructor_block then
 			(fun () -> ())
-		else begin
+		else if not (Codegen.constructor_side_effects e) then begin
+			ctx.constructor_block <- false;
+			(fun () -> ())
+		end else begin
 			ctx.constructor_block <- false;
 			print ctx " if( !%s.skip_constructor ) {" (s_path ctx true (["flash"],"Boot") e.epos);
             (fun() -> print ctx "}")
@@ -832,11 +844,7 @@ let generate_field ctx static f =
 				concat ctx "," (fun (arg,o,t) ->
 					let tstr = type_str ctx t p in
 					print ctx "%s : %s" arg tstr;
-					if o then print ctx " = %s" (match tstr with
-						| "int" | "uint" -> "0"
-						| "Number" -> "NaN"
-						| "Boolean" -> "false"
-						| _ -> "null");					
+					if o then print ctx " = %s" (default_value tstr);
 				) args;
 				print ctx ") : %s " (type_str ctx r p);
 			| _ -> ()
@@ -974,6 +982,8 @@ let generate_enum ctx e =
 		| _ ->
 			print ctx "public static var %s : %s = new %s(\"%s\",%d)" c.ef_name ename ename c.ef_name c.ef_index;
 	) e.e_constrs;
+	newline ctx;
+	print ctx "public static var __constructs__ : Array = [%s];" (String.concat "," (List.map (fun s -> "\"" ^ Ast.s_escape s ^ "\"") e.e_names));
 	cl();
 	newline ctx;
 	print ctx "}";

+ 1 - 1
std/Enum.hx

@@ -3,5 +3,5 @@
 	An abstract type that represents an Enum.
 	See [Type] for the haXe Reflection API.
 **/
-extern class Enum {
+extern class Enum<T> {
 }

+ 15 - 6
std/Type.hx

@@ -10,7 +10,7 @@ enum ValueType {
 	TObject;
 	TFunction;
 	TClass( c : Class<Dynamic> );
-	TEnum( e : Enum );
+	TEnum( e : Enum<Dynamic> );
 	TUnknown;
 }
 
@@ -76,7 +76,7 @@ class Type {
 	/**
 		Returns the enum of a value or [null] if this value is not an Enum instance.
 	**/
-	public static function getEnum( o : Dynamic ) : Enum untyped {
+	public static function getEnum( o : Dynamic ) : Enum<Dynamic> untyped {
 		#if flash9
 			var cname = __global__["flash.utils.getQualifiedClassName"](o);
 			if( cname == "null" || cname.substr(0,8) == "builtin." )
@@ -164,7 +164,7 @@ class Type {
 	/**
 		Returns the complete name of an enum.
 	**/
-	public static function getEnumName( e : Enum ) : String {
+	public static function getEnumName( e : Enum<Dynamic> ) : String {
 		#if flash9
 			return getClassName(cast e);
 		#elseif php
@@ -236,7 +236,7 @@ class Type {
 		Evaluates an enum from a name. The enum must have been compiled
 		to be accessible.
 	**/
-	public static function resolveEnum( name : String ) : Enum untyped {
+	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
 		#if php
 			var e = untyped __call__("_hx_qtype", name);
 			if(untyped __php__("$e instanceof _hx_enum"))
@@ -394,7 +394,7 @@ class Type {
 	/**
 		Create an instance of an enum by using a constructor name and parameters.
 	**/
-	public static function createEnum( e : Enum, constr : String, ?params : Array<Dynamic> ) : Dynamic {
+	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T {
 		#if cpp
 		if (untyped e.mConstructEnum != null)
 			return untyped e.mConstructEnum(constr,params);
@@ -412,6 +412,15 @@ class Type {
 		#end
 	}
 
+	/**
+		Create an instance of an enum by using a constructor index and parameters.
+	**/
+	public static function createEnumIndex<T>( e : Enum<T>, index : Int, ?params : Array<Dynamic> ) : T {
+		var c = Type.getEnumConstructs(e)[index];
+		if( c == null ) throw index+" is not a valid enum constructor index";
+		return createEnum(e,c,params);
+	}
+
 	#if flash9
 	static function describe( t : Dynamic, fact : Bool ) untyped {
 		var fields = new Array();
@@ -523,7 +532,7 @@ class Type {
 	/**
 		Returns all the available constructor names for an enum.
 	**/
-	public static function getEnumConstructs( e : Enum ) : Array<String> untyped {
+	public static function getEnumConstructs( e : Enum<Dynamic> ) : Array<String> untyped {
 		#if php
 			if(__php__("$e->__tname__ == 'Bool'")) return ['true', 'false'];
 			if(__php__("$e->__tname__ == 'Void'")) return [];

+ 1 - 1
std/haxe/Unserializer.hx

@@ -26,7 +26,7 @@ package haxe;
 
 typedef TypeResolver = {
 	function resolveClass( name : String ) : Class<Dynamic>;
-	function resolveEnum( name : String ) : Enum;
+	function resolveEnum( name : String ) : Enum<Dynamic>;
 }
 
 class Unserializer {

+ 1 - 1
tests/unit/MyClass.hx

@@ -2,7 +2,7 @@ package unit;
 
 class MyClass {
 
-	var val : Int;
+	#if as3 public #end var val : Int;
 
 	public var ref : MyClass;
 	public var intValue : Int;

+ 1 - 1
tests/unit/MySubClass.hx

@@ -6,6 +6,6 @@ class MySubClass extends MyClass {
 		return val * 2;
 	}
 
-	static var XXX = 3;
+	#if as3 public #end static var XXX = 3;
 
 }

+ 3 - 2
tests/unit/Test.hx

@@ -1,6 +1,6 @@
 package unit;
 
-class Test #if swf_mark implements mt.Protect #end {
+class Test #if swf_mark implements mt.Protect #end #if as3 implements haxe.Public #end {
 
 	public function new() {
 	}
@@ -197,7 +197,8 @@ class Test #if swf_mark implements mt.Protect #end {
 			}
 			asyncWaits.remove(null);
 			checkDone();
-		} catch( e : Dynamic ) {
+		}
+		catch( e : #if as3 Test #else Dynamic #end ) {
 			asyncWaits.remove(null);
 			var msg = "???";
 			var stack = haxe.Stack.toString(haxe.Stack.exceptionStack());

+ 3 - 0
tests/unit/TestMisc.hx

@@ -92,9 +92,12 @@ class TestMisc extends Test {
 		eq( arr[x++].v++, 3 );
 		eq( x, 1 );
 		eq( arr[0].v, 4 );
+
+		#if !as3
 		x = 0;
 		eq( arr[x++].v += 3, 7 );
 		eq( arr[0].v, 7 );
+		#end
 	}
 
 	function testInitOrder() {

+ 2 - 0
tests/unit/TestResource.hx

@@ -4,6 +4,7 @@ class TestResource extends Test {
 
 	static var STR = "Héllo World !";
 
+	#if !as3
 	function testResources() {
 		var names = haxe.Resource.listNames();
 		eq( names.length, 2 );
@@ -30,6 +31,7 @@ class TestResource extends Test {
 		for( i in 0...lasts.length )
 			eq( b.get(b.length - lasts.length + i), lasts[i] );
 	}
+	#end
 
 	#if neko
 	static function main() {

+ 1 - 1
tests/unit/unit.hxml

@@ -19,7 +19,7 @@
 #-as3 as3
 #-cp ..
 #-main unit.Test
-#-cmd mxmlc -output unit9_as3.swf as3/__main__.as
+#-cmd mxmlc -default-size 800 600 -debug -output unit9_as3.swf as3/__main__.as
 
 --next
 # JS

+ 2 - 2
tests/unit/unit.hxp

@@ -2,7 +2,7 @@
   <output name="Flash" mode="swf" out="unit8.swf" class="unit.Test" lib="" cmd="http://dev.unit-tests/unit.html" main="True" debug="True">-cp ..
 -resource res1.txt
 -resource res2.bin</output>
-  <output name="Flash9" mode="swf9" out="unit9.swf" class="unit.Test" lib="" cmd="" main="True" debug="True">-cp ..
+  <output name="Flash9" mode="swf9" out="unit9.swf" class="unit.Test" lib="" cmd="unit9_as3.swf" main="True" debug="True">-cp ..
 -resource res1.txt
 -resource res2.bin
 
@@ -10,7 +10,7 @@
 #-as3 as3
 #-cp ..
 #-main unit.Test
-#-cmd mxmlc -output unit9_as3.swf as3/__main__.as</output>
+#-cmd mxmlc -default-size 800 600 -debug -output unit9_as3.swf as3/__main__.as</output>
   <output name="JS" mode="js" out="unit.js" class="unit.Test" lib="" cmd="" main="False" debug="False">-cp ..
 -resource res1.txt
 -resource res2.bin</output>

+ 2 - 2
type.ml

@@ -731,9 +731,9 @@ let rec unify a b =
 		(match !(an.a_status) with
 		| Statics cl -> unify (TInst (cl,List.map snd cl.cl_types)) pt
 		| _ -> error [cannot_unify a b])
-	| TAnon an, TInst ({ cl_path = [],"Enum" },[]) ->
+	| TAnon an, TInst ({ cl_path = [],"Enum" },[pt]) ->
 		(match !(an.a_status) with
-		| EnumStatics _ -> ()
+		| EnumStatics e -> unify (TEnum (e,List.map snd e.e_types)) pt
 		| _ -> error [cannot_unify a b])
 	| TDynamic t , _ ->
 		if t == a then

+ 1 - 1
typer.ml

@@ -286,7 +286,7 @@ let field_access ctx get f t e p =
 		AccExpr (mk (TField (e,f.cf_name)) t p)
 	| MethodAccess m ->
 		if m = ctx.curmethod && (match e.eexpr with TConst TThis -> true | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then
-			let prefix = if Common.defined ctx.com "as3gen" then "$" else "" in
+			let prefix = if Common.defined ctx.com "as3" then "$" else "" in
 			AccExpr (mk (TField (e,prefix ^ f.cf_name)) t p)
 		else if get then
 			AccExpr (mk (TCall (mk (TField (e,m)) (tfun [] t) p,[])) t p)