浏览代码

[as3] resolve dynamic access on "map" and "filter" at runtime so we can deal with arrays (closes #2889)

Simon Krajewski 11 年之前
父节点
当前提交
2e253867ce
共有 4 个文件被更改,包括 66 次插入19 次删除
  1. 6 0
      genas3.ml
  2. 15 0
      std/flash/Boot.hx
  3. 45 0
      tests/unit/issues/Issue2889.hx
  4. 0 19
      tests/unit/issues/Issue2889.hx.disabled

+ 6 - 0
genas3.ml

@@ -505,6 +505,12 @@ let rec gen_call ctx e el r =
 				print ctx ")";
 				print ctx ")";
 			| _ -> assert false)
 			| _ -> assert false)
 		| _ -> assert false)
 		| _ -> assert false)
+	| TField(e1, (FAnon {cf_name = s} | FDynamic s)),[ef] when s = "map" || s = "filter" ->
+		spr ctx (s_path ctx true (["flash";],"Boot") e.epos);
+		gen_field_access ctx t_dynamic (s ^ "Dynamic");
+		spr ctx "(";
+		concat ctx "," (gen_value ctx) [e1;ef];
+		spr ctx ")"
 	| TField (ee,f), args when is_var_field f ->
 	| TField (ee,f), args when is_var_field f ->
 		spr ctx "(";
 		spr ctx "(";
 		gen_value ctx e;
 		gen_value ctx e;

+ 15 - 0
std/flash/Boot.hx

@@ -209,6 +209,21 @@ class Boot extends flash.display.MovieClip {
 		return s;
 		return s;
 	}
 	}
 
 
+	static public function mapDynamic(d:Dynamic, f:Dynamic) {
+		if (Std.is(d, Array)) {
+			return untyped d["mapHX"](f);
+		} else {
+			return d.map(f);
+		}
+	}
+
+	static public function filterDynamic(d:Dynamic, f:Dynamic) {
+		if (Std.is(d, Array)) {
+			return untyped d["filterHX"](f);
+		} else {
+			return d.map(f);
+		}
+	}
 
 
 	static function __init__() untyped {
 	static function __init__() untyped {
 		var aproto = Array.prototype;
 		var aproto = Array.prototype;

+ 45 - 0
tests/unit/issues/Issue2889.hx

@@ -0,0 +1,45 @@
+package unit.issues;
+
+class Issue2889 extends Test {
+	public function test()
+	{
+		function mapMappable <A,B>(m:Mappable<A>, f:A->B):Mappable<B> {
+			return m.map(f);
+		}
+		var r = mapMappable([1], function (y) return y+1);
+		var r:Array<Int> = cast r;
+		eq(r.length,1);
+		eq(2,r[0]);
+	}
+
+	function testDynamic() {
+		var a:Dynamic = [1, 2];
+		var b:Dynamic = a.map(function(x) return x * 2);
+		eq(2, b.length);
+		eq(2, b[0]);
+		eq(4, b[1]);
+		var c:Dynamic = a.filter(function(x) return x % 2 == 0);
+		eq(1, c.length);
+		eq(2, c[0]);
+	}
+
+	function testFilterStructure() {
+		var a:{ function filter(f:Int->Bool):Array<Int>; } = [1, 2];
+		var b = a.filter(function(x) return x % 2 == 0);
+		eq(1, b.length);
+		eq(2, b[0]);
+	}
+
+	function testMapStructure() {
+		var a:{ function map(f:Int->Int):Array<Int>; } = [1, 2];
+		var b = a.map(function(x) return x * 2);
+		eq(2, b.length);
+		eq(2, b[0]);
+		eq(4, b[1]);
+	}
+}
+
+private typedef Mappable<Y> = {
+	public function map <X>(f:Y->X):Array<X>;
+}
+

+ 0 - 19
tests/unit/issues/Issue2889.hx.disabled

@@ -1,19 +0,0 @@
-package unit.issues;
-
-class Issue2889 extends Test {
-	public function test()
-	{
-		function mapMappable <A,B>(m:Mappable<A>, f:A->B):Mappable<B> {
-			return m.map(f);
-		}
-		var r = mapMappable([1], function (y) return y+1);
-		var r:Array<Int> = cast r;
-		eq(r.length,1);
-		eq(2,r[0]);
-	}
-}
-
-private typedef Mappable<Y> = {
-	public function map <X>(f:Y->X):Array<X>;
-}
-