decompose macro methods and realization

This commit is contained in:
Dmitri Granetchi
2014-11-10 19:25:52 +02:00
parent ab5fde94b0
commit 6df0806282
2 changed files with 50 additions and 27 deletions
+38 -16
View File
@@ -7,8 +7,9 @@ import haxe.macro.Context;
using haxe.macro.Tools; using haxe.macro.Tools;
using bindx.MetaUtils; using bindx.MetaUtils;
#end
using Lambda; using Lambda;
#end
@:access(bindx.BindMacros) @:access(bindx.BindMacros)
class Bind { class Bind {
@@ -18,8 +19,7 @@ class Bind {
} }
@:noUsing macro static public function bindTo(field:Expr, target:Expr):Expr { @:noUsing macro static public function bindTo(field:Expr, target:Expr):Expr {
var fieldData = checkField(field); return _bindTo(field, target);
return BindMacros.bindingSignalProvider.getClassFieldBindToExpr(fieldData.e, fieldData.field, target);
} }
@:noUsing macro static public function unbind(field:Expr, ?listener:Expr):Expr { @:noUsing macro static public function unbind(field:Expr, ?listener:Expr):Expr {
@@ -27,19 +27,15 @@ class Bind {
} }
@:noUsing macro static public function notify(field:Expr, ?oldValue:Expr, ?newValue:Expr):Expr { @:noUsing macro static public function notify(field:Expr, ?oldValue:Expr, ?newValue:Expr):Expr {
var fieldData = checkField(field); return _notify(field, oldValue, newValue);
return BindMacros.bindingSignalProvider.getClassFieldChangedExpr(fieldData.e, fieldData.field, oldValue, newValue);
} }
@:noUsing macro static public function disposeBindings(object:ExprOf<IBindable>):Expr { @:noUsing macro static public function disposeBindings(object:ExprOf<IBindable>):Expr {
var type = Context.typeof(object).follow(); return _disposeBindings(object);
if (!isBindable(type.getClass())) {
Context.error('\'${object.toString()}\' must be bindx.IBindable', object.pos);
}
return BindMacros.bindingSignalProvider.getDisposeBindingsExpr(object, type);
} }
#if macro #if macro
static function _bind(field:Expr, listener:Expr, doBind:Bool):Expr { static function _bind(field:Expr, listener:Expr, doBind:Bool):Expr {
var fieldData = checkField(field); var fieldData = checkField(field);
return if (fieldData != null) { return if (fieldData != null) {
@@ -48,6 +44,24 @@ class Bind {
} else macro {}; } else macro {};
} }
static function _bindTo(field:Expr, target:Expr):Expr {
var fieldData = checkField(field);
return BindMacros.bindingSignalProvider.getClassFieldBindToExpr(fieldData.e, fieldData.field, target);
}
static function _notify(field:Expr, ?oldValue:Expr, ?newValue:Expr):Expr {
var fieldData = checkField(field);
return BindMacros.bindingSignalProvider.getClassFieldChangedExpr(fieldData.e, fieldData.field, oldValue, newValue);
}
static function _disposeBindings(object:ExprOf<IBindable>):Expr {
var type = Context.typeof(object).follow();
if (!isBindable(type.getClass())) {
Context.error('\'${object.toString()}\' must be bindx.IBindable', object.pos);
}
return BindMacros.bindingSignalProvider.getDisposeBindingsExpr(object, type);
}
static function checkField(field:Expr):{e:Expr, field:ClassField} { static function checkField(field:Expr):{e:Expr, field:ClassField} {
switch (field.expr) { switch (field.expr) {
case EField(e, field): case EField(e, field):
@@ -79,12 +93,20 @@ class Bind {
return null; return null;
} }
static inline function isBindable(classType:ClassType) { static var IBindableType = macro : bindx.IBindable;
var res = classType.interfaces.exists(function (it) {
var t = it.t.get(); static function isBindable(classType:ClassType) {
return t.module == "bindx.IBindable" && t.name == "IBindable";
}); var t = classType;
return res || classType.superClass == null ? res : isBindable(classType.superClass.t.get()); while (t != null) {
for (it in t.interfaces) {
var t = it.t.get();
if (t.module == "bindx.IBindable" && t.name == "IBindable")
return true;
}
t = t.superClass != null ? t.superClass.t.get() : null;
}
return false;
} }
#end #end
} }
+12 -11
View File
@@ -1,6 +1,7 @@
package ; package ;
import bindx.Bind; import bindx.Bind;
import bindx.Bind.bind in bind;
import haxe.unit.TestCase; import haxe.unit.TestCase;
class BaseTest extends TestCase { class BaseTest extends TestCase {
@@ -13,13 +14,13 @@ class BaseTest extends TestCase {
var b = new Bindable1(); var b = new Bindable1();
b.str = "a"; b.str = "a";
var callNum = 0; var callNum = 0;
Bind.bind(b.str, function (from, to) { bind(b.str, function (from, to) {
assertEquals(from, "a"); assertEquals(from, "a");
assertEquals(to, "b"); assertEquals(to, "b");
callNum ++; callNum ++;
}); });
bindx.Bind.bind(b.str, function (from, to) { bind(b.str, function (from, to) {
assertEquals(from, "a"); assertEquals(from, "a");
assertEquals(to, "b"); assertEquals(to, "b");
callNum ++; callNum ++;
@@ -38,12 +39,12 @@ class BaseTest extends TestCase {
callNum ++; callNum ++;
} }
bindx.Bind.bind(b.str, listener); bind(b.str, listener);
bindx.Bind.bind(b.str, listener); bind(b.str, listener);
b.str = ""; b.str = "";
assertEquals(callNum, 1); assertEquals(callNum, 1);
bindx.Bind.bind(b.str, listener); Bind.bind(b.str, listener);
bindx.Bind.unbind(b.str, listener); bindx.Bind.unbind(b.str, listener);
b.str = "1"; b.str = "1";
assertEquals(callNum, 1); assertEquals(callNum, 1);
@@ -54,12 +55,12 @@ class BaseTest extends TestCase {
b.str = null; b.str = null;
var callNum = 0; var callNum = 0;
bindx.Bind.bind(b.str, function (_, _) callNum++); bind(b.str, function (_, _) callNum++);
bindx.Bind.bind(b.str, function (_, _) callNum++); bind(b.str, function (_, _) callNum++);
b.str = ""; b.str = "";
assertEquals(callNum, 2); assertEquals(callNum, 2);
bindx.Bind.unbind(b.str); Bind.unbind(b.str);
b.str = "1"; b.str = "1";
assertEquals(callNum, 2); assertEquals(callNum, 2);
@@ -84,10 +85,10 @@ class BaseTest extends TestCase {
} }
Bind.bind(b.str, listener); Bind.bind(b.str, listener);
bindx.Bind.notify(b.str, "1", "2"); Bind.notify(b.str, "1", "2");
assertEquals(callNum, 1); assertEquals(callNum, 1);
bindx.Bind.notify(b.str, "1", "2"); Bind.notify(b.str, "1", "2");
assertEquals(callNum, 2); assertEquals(callNum, 2);
} }
@@ -101,7 +102,7 @@ class BaseTest extends TestCase {
assertEquals(callNum, 1); assertEquals(callNum, 1);
assertFalse(Reflect.hasField(b, "noBindChanged")); assertFalse(Reflect.hasField(b, "noBindChanged"));
bindx.Bind.notify(b.bind); Bind.notify(b.bind);
assertEquals(callNum, 2); assertEquals(callNum, 2);
} }
} }