From fbc2a97fbec8825423c125841cf2e032ce51b1d8 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Wed, 25 Aug 2010 16:34:59 +0100 Subject: [PATCH 1/1] Maintain only one place with dynamic explicit conversions --- mcs/mcs/convert.cs | 2 +- mcs/mcs/expression.cs | 8 -- mcs/mcs/statement.cs | 3 + mcs/tests/dtest-003.cs | 54 ++++++++----- mcs/tests/ver-il-dmcs.xml | 161 ++++++++++++++++++++++---------------- 5 files changed, 129 insertions(+), 99 deletions(-) diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs index ce2b8ecb675..5fc3cd8a914 100644 --- a/mcs/mcs/convert.cs +++ b/mcs/mcs/convert.cs @@ -1246,7 +1246,7 @@ namespace Mono.CSharp { case MemberKind.TypeParameter: Arguments args = new Arguments (1); args.Add (new Argument (expr)); - return new DynamicConversion (target_type, 0, args, loc).Resolve (ec); + return new DynamicConversion (target_type, explicit_cast ? CSharpBinderFlags.ConvertExplicit : 0, args, loc).Resolve (ec); } return null; diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 13253f75e22..cbf26e46d6a 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -1535,14 +1535,6 @@ namespace Mono.CSharp { if (type.IsPointer && !ec.IsUnsafe) { UnsafeError (ec, loc); - } else if (expr.Type == InternalType.Dynamic) { - if (type != InternalType.Dynamic) { - Arguments arg = new Arguments (1); - arg.Add (new Argument (expr)); - return new DynamicConversion (type, CSharpBinderFlags.ConvertExplicit, arg, loc).Resolve (ec); - } - - return expr; } var res = Convert.ExplicitConversion (ec, expr, type, loc); diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 1ebe7ea3c32..f66a37b862d 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -5462,6 +5462,9 @@ namespace Mono.CSharp { // Infer implicitly typed local variable from foreach enumerable type var_type = new TypeExpression (current_pe.Type, var_type.Location); } + } else if (is_dynamic) { + // Explicit cast of dynamic collection elements has to be done at runtime + current_pe = EmptyCast.Create (current_pe, InternalType.Dynamic); } var_type = var_type.ResolveAsTypeTerminal (ec, false); diff --git a/mcs/tests/dtest-003.cs b/mcs/tests/dtest-003.cs index 5789eefcced..d729de72067 100644 --- a/mcs/tests/dtest-003.cs +++ b/mcs/tests/dtest-003.cs @@ -25,11 +25,10 @@ class AssertDynamicObject : DynamicMetaObject DynamicMetaObject GetFakeMetaObject (object value) { Type t = value == null ? typeof (object) : value.GetType (); - var v = Expression.Variable (t); - Expression e = Expression.Block (new[] { v }, Expression.Default (t)); + Expression> et = () => value; Expression restr = Expression.Constant (true); - return new DynamicMetaObject (e, BindingRestrictions.GetExpressionRestriction (restr)); + return new DynamicMetaObject (Expression.Convert (et.Body, t), BindingRestrictions.GetExpressionRestriction (restr)); } public override DynamicMetaObject BindBinaryOperation (BinaryOperationBinder binder, DynamicMetaObject arg) @@ -217,8 +216,7 @@ class Tester : DynamicObjectMock if (values.Count != expected.Length) throw new ApplicationException (name + ": Array length does not match " + values.Count + " != " + expected.Length); - for (int i = 0; i < expected.Length; i++) - { + for (int i = 0; i < expected.Length; i++) { Assert (flags.GetValue (expected[i]), flags.GetValue (values[i]), "flags"); } } @@ -300,7 +298,7 @@ class Tester : DynamicObjectMock d = checked (d + 3); } - + void BinaryAddChecked_2 (dynamic d, DynamicObjectMock mock) { mock.BinaryOperation = (binder, arg) => { @@ -317,7 +315,7 @@ class Tester : DynamicObjectMock checked { r = () => d + 3; } - + r (); } @@ -729,10 +727,10 @@ class Tester : DynamicObjectMock mock.ConvertOperation = (binder) => { Assert (binder.Explicit, false, "Explicit"); Assert (binder.Type, typeof (int), "Type"); - return 2; + return 1; }; - object[] o = new object [2]; + object[] o = new object[2]; d = o[d]; } @@ -745,7 +743,7 @@ class Tester : DynamicObjectMock return (byte) 2; }; - object b = checked((byte) d); + object b = checked ((byte) d); } void Convert_4 (dynamic d, DynamicObjectMock mock) @@ -759,6 +757,20 @@ class Tester : DynamicObjectMock var g = new int[d]; } + void Convert_5 (dynamic d, DynamicObjectMock mock) + { + int counter = 0; + mock.ConvertOperation = (binder) => { + Assert (binder.Explicit, false, "Explicit"); + Assert (binder.Type, typeof (System.Collections.IEnumerable), "Type"); + return new object[] { 1 }; + }; + + foreach (int v in d) { +// Console.WriteLine (v); + } + } + void GetIndex_1 (dynamic d, DynamicObjectMock mock) { mock.GetIndexOperation = (binder, args) => { @@ -769,10 +781,10 @@ class Tester : DynamicObjectMock CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }, "ArgumentInfo"); - Assert ((IList)args, new object[] { 0 }, "args"); + Assert ((IList) args, new object[] { 0 }, "args"); }; - var o = d [0]; + var o = d[0]; } void GetIndex_2 (dynamic d, DynamicObjectMock mock) @@ -832,7 +844,7 @@ class Tester : DynamicObjectMock CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) - }, "ArgumentInfo"); + }, "ArgumentInfo"); Assert ((IList) args, new object[] { "foo", null }, "args"); }; @@ -878,9 +890,9 @@ class Tester : DynamicObjectMock Assert ((IList) args, new object[] { typeof (bool), -1 }, "args"); }; - d (typeof (bool), name:-1); + d (typeof (bool), name: -1); } - + void Invoke_5 (dynamic d, DynamicObjectMock mock) { mock.InvokeOperation = (binder, args) => { @@ -894,10 +906,10 @@ class Tester : DynamicObjectMock Assert ((IList) args, new object[] { typeof (bool), -1 }, "args"); }; - Action a = (i) => {}; + Action a = (i) => { }; a (d); } - + void InvokeMember_1 (dynamic d, DynamicObjectMock mock) { mock.InvokeMemberOperation = (binder, args) => { @@ -1090,7 +1102,7 @@ class Tester : DynamicObjectMock AssertArgument (binder, new[] { CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.Constant, null) // CSC bug? - }, "ArgumentInfo"); + }, "ArgumentInfo"); Assert (value, d_const, "value"); }; @@ -1293,7 +1305,7 @@ class Tester : DynamicObjectMock return true; }; - object g = d ? 1 :4; + object g = d ? 1 : 4; } void UnaryIsTrue_2 (dynamic d, DynamicObjectMock mock) @@ -1319,7 +1331,7 @@ class Tester : DynamicObjectMock object x = d || null; } - + #pragma warning restore 168, 169, 219 static bool RunTest (MethodInfo test) @@ -1327,7 +1339,7 @@ class Tester : DynamicObjectMock Console.Write ("Running test {0, -25}", test.Name); try { var d = new DynamicObjectMock (); - test.Invoke (new Tester (), new [] { d, d }); + test.Invoke (new Tester (), new[] { d, d }); if (d.HitCounter < 1) Assert (true, false, "HitCounter"); diff --git a/mcs/tests/ver-il-dmcs.xml b/mcs/tests/ver-il-dmcs.xml index 4343166478e..565354c6c58 100644 --- a/mcs/tests/ver-il-dmcs.xml +++ b/mcs/tests/ver-il-dmcs.xml @@ -83,7 +83,7 @@ - 91 + 120 62 @@ -482,125 +482,154 @@ 50 - + + 7 + + + 7 + + + 34 + + + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + 226 + + + 59 + + 92 - + 111 - + 66 - + 101 - + 73 - + 127 - + 127 - + 1 - + 110 - + 111 - + 110 - + 90 - + 124 - + 139 - + 101 - + 47 - + 47 - + 47 - + 47 - + 47 - + 51 - + 47 - + 51 - + 52 - + 68 - + 52 - + 68 - + 52 - + 67 - + 52 - + 52 - + 68 - + 12 - + 7 - + 7 - + 5 + + 7 - - 7 - - - 34 - - + 91 @@ -608,48 +637,32 @@ 7 - - + + 92 7 - - + + 109 7 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - + + 119 7 - - + + 119 @@ -911,7 +924,7 @@ 16 - 569 + 502 87 @@ -1701,6 +1714,16 @@ + + + + 187 + + + 7 + + + -- 2.25.1