warn unbindable expr items
This commit is contained in:
+15
-12
@@ -38,20 +38,23 @@ class Bind {
|
|||||||
#if macro
|
#if macro
|
||||||
|
|
||||||
public static function internalBind(field:Expr, listener:Expr, doBind:Bool):Expr {
|
public static function internalBind(field:Expr, listener:Expr, doBind:Bool):Expr {
|
||||||
var fieldData = checkField(field);
|
var fieldData = warnCheckField(field);
|
||||||
return if (fieldData != null) {
|
return if (fieldData != null) {
|
||||||
if (doBind) BindMacros.bindingSignalProvider.getClassFieldBindExpr(fieldData.e, fieldData.field, listener);
|
if (doBind) BindMacros.bindingSignalProvider.getClassFieldBindExpr(fieldData.e, fieldData.field, listener);
|
||||||
else BindMacros.bindingSignalProvider.getClassFieldUnbindExpr(fieldData.e, fieldData.field, listener);
|
else BindMacros.bindingSignalProvider.getClassFieldUnbindExpr(fieldData.e, fieldData.field, listener);
|
||||||
} else macro {};
|
} else {
|
||||||
|
Context.fatalError('can\'t bind field ${field.expr}', field.pos);
|
||||||
|
macro {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function internalBindTo(field:Expr, target:Expr):Expr {
|
public static function internalBindTo(field:Expr, target:Expr):Expr {
|
||||||
var fieldData = checkField(field);
|
var fieldData = warnCheckField(field);
|
||||||
return BindMacros.bindingSignalProvider.getClassFieldBindToExpr(fieldData.e, fieldData.field, target);
|
return BindMacros.bindingSignalProvider.getClassFieldBindToExpr(fieldData.e, fieldData.field, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function internalNotify(field:Expr, ?oldValue:Expr, ?newValue:Expr):Expr {
|
public static function internalNotify(field:Expr, ?oldValue:Expr, ?newValue:Expr):Expr {
|
||||||
var fieldData = checkField(field);
|
var fieldData = warnCheckField(field);
|
||||||
return BindMacros.bindingSignalProvider.getClassFieldChangedExpr(fieldData.e, fieldData.field, oldValue, newValue);
|
return BindMacros.bindingSignalProvider.getClassFieldChangedExpr(fieldData.e, fieldData.field, oldValue, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,19 +66,20 @@ class Bind {
|
|||||||
return BindMacros.bindingSignalProvider.getUnbindAllExpr(object, type);
|
return BindMacros.bindingSignalProvider.getUnbindAllExpr(object, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function checkField(field:Expr):{e:Expr, field:ClassField} {
|
static function warnCheckField(field:Expr):{e:Expr, field:ClassField} {
|
||||||
var res = null;
|
var res = null;
|
||||||
try {
|
try {
|
||||||
res = tryCheckField(field);
|
res = checkField(field);
|
||||||
if (res.error != null)
|
if (res.error != null) throw res.error;
|
||||||
res.error.contextError();
|
} catch (e:FatalError) {
|
||||||
|
e.contextFatal();
|
||||||
} catch (e:bindx.Error) {
|
} catch (e:bindx.Error) {
|
||||||
e.contextError();
|
e.contextError();
|
||||||
};
|
};
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tryCheckField(field:Expr):{e:Expr, field:ClassField, error:bindx.Error} {
|
public static function checkField(field:Expr):{e:Expr, field:ClassField, error:bindx.Error} {
|
||||||
var error:bindx.Error;
|
var error:bindx.Error;
|
||||||
switch (field.expr) {
|
switch (field.expr) {
|
||||||
case EField(e, field):
|
case EField(e, field):
|
||||||
@@ -101,12 +105,11 @@ class Bind {
|
|||||||
return {e:e, field:field, error:error};
|
return {e:e, field:field, error:error};
|
||||||
|
|
||||||
case EConst(CIdent(_)):
|
case EConst(CIdent(_)):
|
||||||
return {e:field, field:null, error:new bindx.Error('can\'t bind \'${field.toString()}\'. Please use \'this.${field.toString()}\'', field.pos)};
|
return {e:field, field:null, error:new bindx.Error('Can\'t bind \'${field.toString()}\'. Please use \'this.${field.toString()}\'', field.pos)};
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
return {e:field, field:null, error:new bindx.Error('can\'t bind field \'${field.toString()}\'', field.pos)};
|
|
||||||
}
|
}
|
||||||
return null;
|
return {e:field, field:null, error:new bindx.Error('Can\'t bind field \'${field.toString()}\'', field.pos)};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isBindable(classType:ClassType):Bool {
|
public static function isBindable(classType:ClassType):Bool {
|
||||||
|
|||||||
+22
-18
@@ -40,7 +40,8 @@ class BindExt {
|
|||||||
|
|
||||||
public static function internalBindChain(expr:Expr, listener:Expr):Expr {
|
public static function internalBindChain(expr:Expr, listener:Expr):Expr {
|
||||||
var zeroListener = listenerName(0, "");
|
var zeroListener = listenerName(0, "");
|
||||||
var chain = prepareChain(expr, macro $i{ zeroListener });
|
var chain = null;
|
||||||
|
try { chain = warnPrepareChain(expr, macro $i{ zeroListener }); } catch (e:bindx.Error) e.contextError();
|
||||||
|
|
||||||
var res = macro (function ($zeroListener):Void->Void
|
var res = macro (function ($zeroListener):Void->Void
|
||||||
$b { chain.bind.concat(chain.init).concat([macro return function ():Void $b { chain.unbind }]) }
|
$b { chain.bind.concat(chain.init).concat([macro return function ():Void $b { chain.unbind }]) }
|
||||||
@@ -85,11 +86,14 @@ class BindExt {
|
|||||||
var zeroListener = listenerName(0, pre);
|
var zeroListener = listenerName(0, pre);
|
||||||
chain.init.push(macro var $zeroListener = ${ecall ? methodListenerNameExpr : fieldListenerNameExpr});
|
chain.init.push(macro var $zeroListener = ${ecall ? methodListenerNameExpr : fieldListenerNameExpr});
|
||||||
|
|
||||||
var c = prepareChain(start, macro $i{zeroListener}, pre);
|
var c = null;
|
||||||
|
try { c = warnPrepareChain(start, macro $i{zeroListener}, pre); } catch (e:bindx.Error) { e.contextWarning(); }
|
||||||
|
if (c != null) {
|
||||||
chain.init = chain.init.concat(c.init);
|
chain.init = chain.init.concat(c.init);
|
||||||
chain.bind = chain.bind.concat(c.bind);
|
chain.bind = chain.bind.concat(c.bind);
|
||||||
chain.unbind = chain.unbind.concat(c.unbind);
|
chain.unbind = chain.unbind.concat(c.unbind);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
e.iter(findChain);
|
e.iter(findChain);
|
||||||
}
|
}
|
||||||
findChain(expr);
|
findChain(expr);
|
||||||
@@ -119,23 +123,16 @@ class BindExt {
|
|||||||
var prevField = {e:first.e, field:first.field, error:null};
|
var prevField = {e:first.e, field:first.field, error:null};
|
||||||
var fields:Array<FieldExpr> = [ { field:first.field, bindable:true, e:first.e } ];
|
var fields:Array<FieldExpr> = [ { field:first.field, bindable:true, e:first.e } ];
|
||||||
|
|
||||||
inline function tryCheck(e:Expr) {
|
|
||||||
var field = null;
|
|
||||||
try { field = Bind.tryCheckField(e); } catch (e:FatalError) e.contextFatal();
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var field = tryCheck(prevField.e);
|
var field = Bind.checkField(prevField.e);
|
||||||
if (field.field != null) {
|
if (field.field != null) {
|
||||||
fields.push( { field:field.field, bindable:field.error == null, e:field.e } );
|
fields.push( { field:field.field, bindable:field.error == null, e:field.e } );
|
||||||
} else if (field.error != null) {
|
} else if (field.error != null) {
|
||||||
var end = true;
|
var end = true;
|
||||||
switch (prevField.e.expr) {
|
switch (prevField.e.expr) {
|
||||||
case ECall(e, params):
|
case ECall(e, params):
|
||||||
field = tryCheck(e);
|
field = Bind.checkField(e);
|
||||||
if (field.error != null) field.error.contextError();
|
if (field.field == null) throw new FatalError('error parse fields ${e.toString()}', e.pos);
|
||||||
if (field.field == null) Context.fatalError('error parse fields ${e.toString()}', e.pos);
|
|
||||||
fields.push( { e:field.e, field:field.field, params:params, bindable:field.error == null } );
|
fields.push( { e:field.e, field:field.field, params:params, bindable:field.error == null } );
|
||||||
end = false;
|
end = false;
|
||||||
case _:
|
case _:
|
||||||
@@ -148,11 +145,13 @@ class BindExt {
|
|||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function prepareChain(expr:Expr, listener:Expr, prefix = ""):Chain {
|
static function warnPrepareChain(expr:Expr, listener:Expr, prefix = ""):Chain {
|
||||||
var fields = checkFields(expr);
|
var fields = checkFields(expr);
|
||||||
|
|
||||||
if (fields.length == 0)
|
if (fields.length == 0) {
|
||||||
Context.fatalError("can't bind empty expression", expr.pos);
|
throw new FatalError("can't bind empty expression: " + expr.toString(), expr.pos);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var i = fields.length;
|
var i = fields.length;
|
||||||
var first = null;
|
var first = null;
|
||||||
@@ -161,15 +160,20 @@ class BindExt {
|
|||||||
if (first != null) f.bindable = false;
|
if (first != null) f.bindable = false;
|
||||||
else if (!f.bindable && first == null) first = f;
|
else if (!f.bindable && first == null) first = f;
|
||||||
}
|
}
|
||||||
|
var bindableNum = fields.fold(function (it, n) return n += it.bindable ? 1 : 0, 0);
|
||||||
|
if (bindableNum == 0) {
|
||||||
|
throw new bindx.Error('expr is not bindable "${expr.toString()}".', expr.pos);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (first != null)
|
if (first != null)
|
||||||
Context.warning('expr in not full bindable. Can bind only "${first.e.toString()}"', expr.pos);
|
Context.warning('expr is not full bindable. Can bind only "${first.e.toString()}"', expr.pos);
|
||||||
|
|
||||||
return prepareBindChain(fields, macro listener, expr.pos, prefix);
|
return prepareChain(fields, macro listener, expr.pos, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static function listenerName(idx:Int, prefix) return '${prefix}listener$idx';
|
inline static function listenerName(idx:Int, prefix) return '${prefix}listener$idx';
|
||||||
|
|
||||||
public static function prepareBindChain(fields:Array<FieldExpr>, listener:Expr, pos:Position, prefix = ""):Chain {
|
static function prepareChain(fields:Array<FieldExpr>, listener:Expr, pos:Position, prefix = ""):Chain {
|
||||||
var res:Chain = { init:[], bind:[], unbind:[] };
|
var res:Chain = { init:[], bind:[], unbind:[] };
|
||||||
|
|
||||||
var prevListenerName = listenerName(0, prefix);
|
var prevListenerName = listenerName(0, prefix);
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ class ExprBindTest extends BuddySuite {
|
|||||||
var b = new BaseTest.Bindable1();
|
var b = new BaseTest.Bindable1();
|
||||||
a.str = "a1";
|
a.str = "a1";
|
||||||
b.str = "b1";
|
b.str = "b1";
|
||||||
inline function val() return a.str + b.str;
|
inline function val() return a.str + b.str + "ab".charAt(0);
|
||||||
|
|
||||||
BindExt.expr(a.str + b.str, function (from, to:String) {
|
BindExt.expr(a.str + b.str + "ab".charAt(0), function (from, to:String) {
|
||||||
//trace(from);
|
//trace(from);
|
||||||
to.should.be(val());
|
to.should.be(val());
|
||||||
callNum ++;
|
callNum ++;
|
||||||
@@ -37,6 +37,10 @@ class ExprBindTest extends BuddySuite {
|
|||||||
a.str = "a2";
|
a.str = "a2";
|
||||||
|
|
||||||
callNum.should.be(2);
|
callNum.should.be(2);
|
||||||
|
|
||||||
|
b.str = "b2";
|
||||||
|
|
||||||
|
callNum.should.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user