Skip to content

Commit

Permalink
Fix for Issue #11 dynamic properties - comparing/assignment of dynami…
Browse files Browse the repository at this point in the history
…c properties
  • Loading branch information
RupertAvery committed May 5, 2014
1 parent 8acb0b9 commit 642804e
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 15 deletions.
16 changes: 8 additions & 8 deletions Parser/ExpressionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static Expression GetPropertyIndex(Expression le, IEnumerable<Expression>
{
type = le.Type;
instance = le;
isDynamic = type.IsDynamic();
isDynamic = type.IsDynamicOrObject();
}

if (isDynamic)
Expand Down Expand Up @@ -88,9 +88,9 @@ public static Expression GetPropertyIndex(Expression le, IEnumerable<Expression>
public static Expression Assign(Expression le, Expression re)
{
var type = le.Type;
var isDynamic = type.IsDynamic();
var isDynamic = type.IsDynamicOrObject();

if (isDynamic)
if (type.IsDynamic())
{
var dle = (DynamicExpression)le;
var membername = ((GetMemberBinder)dle.Binder).Name;
Expand Down Expand Up @@ -243,7 +243,7 @@ public static Expression GetProperty(Expression le, string membername)
{
type = le.Type;
instance = le;
isDynamic = type.IsDynamic();
isDynamic = type.IsDynamicOrObject();
}

if (isDynamic)
Expand Down Expand Up @@ -314,7 +314,7 @@ public static Expression GetMethod(Expression le, TypeOrGeneric member, List<Exp
{
type = le.Type;
instance = le;
isDynamic = type.IsDynamic();
isDynamic = type.IsDynamicOrObject();
}

if (isDynamic)
Expand Down Expand Up @@ -719,7 +719,7 @@ public static Expression UnaryOperator(Expression le, ExpressionType expressionT
{
// perform implicit conversion on known types

if (le.Type.IsDynamic())
if (le.Type.IsDynamicOrObject())
{
return DynamicUnaryOperator(le, expressionType);
}
Expand All @@ -733,7 +733,7 @@ public static Expression BinaryOperator(Expression le, Expression re, Expression
{
// perform implicit conversion on known types

if (le.Type.IsDynamic() && re.Type.IsDynamic())
if (le.Type.IsDynamicOrObject() || re.Type.IsDynamicOrObject())
{
if (expressionType == ExpressionType.OrElse)
{
Expand Down Expand Up @@ -1041,7 +1041,7 @@ public static Expression ForEach(LabelTarget exitLabel, LabelTarget continueLabe
variables.Add(parameter);

var current = GetProperty(enumParam, "Current");

if (current.Type == typeof(object) && parameter.Type != typeof(object))
{
current = Expression.Convert(current, parameter.Type);
Expand Down
16 changes: 16 additions & 0 deletions Parser/TypeConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ internal static int CanConvert(Type from, Type to)
return -1;
}

// 6.1.7 Boxing Conversions
// A boxing conversion permits a value-type to be implicitly converted to a reference type. A boxing conversion exists from any non-nullable-value-type to object and dynamic, to System.ValueType and to any interface-type implemented by the non-nullable-value-type. Furthermore an enum-type can be converted to the type System.Enum.
// A boxing conversion exists from a nullable-type to a reference type, if and only if a boxing conversion exists from the underlying non-nullable-value-type to the reference type.
// A value type has a boxing conversion to an interface type I if it has a boxing conversion to an interface type I0 and I0 has an identity conversion to I.

public static Expression BoxingConversion(Expression dest, Expression src)
{
if (src.Type.IsValueType && dest.Type.IsDynamicOrObject())
{
src = Expression.Convert(src, dest.Type);
}
return src;
}

public static Expression ImplicitConversion(Expression dest, Expression src)
{
Expand All @@ -115,10 +128,13 @@ public static Expression ImplicitConversion(Expression dest, Expression src)
{
src = ImplicitNumericConversion(src, dest.Type);
}
src = BoxingConversion(dest, src);
}
return src;
}

// 6.1.2 Implicit numeric conversions

public static Expression ImplicitNumericConversion(Expression src, Type target)
{
List<Type> allowed;
Expand Down
12 changes: 11 additions & 1 deletion Parser/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ namespace ExpressionEvaluator.Parser
{
internal static class TypeExtensions
{
public static bool IsDynamic(this Type type)
public static bool IsDynamicOrObject(this Type type)
{
return type.GetInterfaces().Contains(typeof(IDynamicMetaObjectProvider)) ||
type == typeof(Object);
}

public static bool IsDynamic(this Type type)
{
return type.GetInterfaces().Contains(typeof (IDynamicMetaObjectProvider));
}

public static bool IsObject(this Type type)
{
return type == typeof(Object);
}
}
}
5 changes: 0 additions & 5 deletions TestProject1/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -745,30 +745,25 @@ public void DynamicValue()
registry.RegisterSymbol("obj", obj);
registry.RegisterDefaultTypes();

// okay
var cc = new CompiledExpression() { StringToParse = "obj.Value == 'aa'", TypeRegistry = registry };
var ret = cc.Eval();
Assert.AreEqual(true, ret);

// okay
obj.Value = 10;
cc = new CompiledExpression() { StringToParse = "obj.Value == 10", TypeRegistry = registry };
ret = cc.Eval();
Assert.AreEqual(true, ret);

// fails
obj.Value = 10.0;
cc = new CompiledExpression() { StringToParse = "obj.Value == 10", TypeRegistry = registry };
ret = cc.Eval();
Assert.AreEqual(true, ret);

// fails
obj.Value = 10.0;
cc = new CompiledExpression() { StringToParse = "obj.Value = 5", TypeRegistry = registry };
ret = cc.Eval();
Assert.AreEqual(5, obj.Value);

// fails
obj.Value = 10;
cc = new CompiledExpression() { StringToParse = "obj.Value == 10.0", TypeRegistry = registry };
ret = cc.Eval();
Expand Down
9 changes: 8 additions & 1 deletion Tests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,18 @@ public float AMT(float value)
}
}


public class objHolder2
{
public dynamic Value;
}
class Program
{
static void Main(string[] args)
{
var obj2 = new objHolder2();
obj2.Value = 5;


var exp = "@ATADJ( @MAX( @SUBTR(@PR( 987043 ) , @AMT( 913000 ) ) , @MULT( @PR( 987043 ) , 0.20f ) ) , 60f ) ";
var util = new Utility();
var reg = new TypeRegistry();
Expand Down

0 comments on commit 642804e

Please sign in to comment.