using System; #if CS120 using System.Collections.Generic; #endif namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { internal class DynamicTests { private class Base { public Base(object baseObj) { } } private class Derived : Base { public Derived(dynamic d) : base((object)d) { } } private struct MyValueType { private readonly dynamic _getOnlyProperty; public dynamic Field; #if CS60 public dynamic GetOnlyProperty => _getOnlyProperty; #else public dynamic GetOnlyProperty { get { return _getOnlyProperty; } } #endif public dynamic Property { get; set; } public void Method(dynamic a) { } } public interface I { } private static dynamic field; private static volatile dynamic volatileField; private static object objectField; public dynamic Property { get; set; } public DynamicTests() { } public DynamicTests(dynamic test) { } public DynamicTests(DynamicTests test) { } private static void CallWithOut(out dynamic d) { d = null; } #if CS70 private static void CallWithIn(in dynamic d) { } #endif #if CS120 private static void CallWithRefReadonly(ref readonly Dictionary d) { } #endif private static void CallWithRef(ref dynamic d) { } private static void RefCallSiteTests() { #if CS70 CallWithOut(out var d); CallWithIn(in d); #else dynamic d; CallWithOut(out d); #endif CallWithRef(ref d); d.SomeCall(); } private static void InvokeConstructor() { DynamicTests dynamicTests = new DynamicTests(); dynamic val = new DynamicTests(); val.Test(new UnauthorizedAccessException()); dynamic val2 = new DynamicTests(val); val2.Get(new DynamicTests((DynamicTests)val)); val2.Call(new DynamicTests((dynamic)dynamicTests)); } private static dynamic InlineAssign(object a, out dynamic b) { return b = ((dynamic)a).Test; } private static dynamic SelfReference(dynamic d) { return d[d, d] = d; } private static dynamic LongArgumentListFunc(dynamic d) { // Func`13 return d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } private static void LongArgumentListAction(dynamic d) { // Action`13 d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); } private static void DynamicThrow() { try { throw (Exception)field; } catch (Exception ex) { Console.WriteLine(ex.ToString()); throw; } } private static void MemberAccess(dynamic a) { a.Test1(); a.GenericTest(); a.Test2(1); a.Test3(a.InnerTest(1, 2, 3, 4, 5)); a.Test4(2, null, a.Index[0]); a.Test5(a, a.Number, a.String); a[0] = 3; a.Index[a.Number] = 5; a.Index[a.Number] += 5; a.Setter = new DynamicTests(); a.Setter2 = 5; } private static void StructMemberAccess(MyValueType valueType) { valueType.Field = 0; valueType.Field += 5; valueType.Field[1] = 5; valueType.Field.CallMe(); DynamicTests.Casts(valueType.GetOnlyProperty); valueType.GetOnlyProperty.CallMe(); valueType.Property = 0; valueType.Property += 5; valueType.Property[1] = 5; valueType.Property.CallMe(5.ToDynamic((object)valueType.Property.Call())); valueType.Method(valueType.GetOnlyProperty + valueType.Field); } private static void RequiredCasts() { ((dynamic)objectField).A = 5; ((dynamic)objectField).B += 5; ((dynamic)objectField).Call(); ((object)field).ToString(); field.Call("Hello World"); field.Call((object)"Hello World"); field.Call((dynamic)"Hello World"); } private void StaticCallWithDynamicArgument(dynamic d) { M3(d + 5); } private static void StaticCallWithDynamicArgumentInStaticContext(dynamic d) { DynamicTests.M3(d + 5); } private static void DynamicCallWithString() { field.Call("Hello World"); } private static void DynamicCallWithNamedArgs() { field.Call(a: "Hello World"); } private static void DynamicCallWithRefOutArg(int a, out int b) { field.Call(ref a, out b); } private static void DynamicCallWithStringCastToObj() { field.Call((object)"Hello World"); } private static void DynamicCallWithStringCastToDynamic() { field.Call((dynamic)"Hello World"); } private static void DynamicCallWithStringCastToDynamic2() { field.Call((dynamic)"Hello World", 5, null); } private static void DynamicCallWithStringCastToDynamic3() { field.Call((dynamic)"Hello World", 5u, null); } private static void Invocation(dynamic a, dynamic b) { a(null, b.Test()); } private static dynamic Test1(dynamic a) { dynamic val = a.IndexedProperty; return val[0]; } private static dynamic Test2(dynamic a) { return a.IndexedProperty[0]; } private static void ArithmeticBinaryOperators(dynamic a, dynamic b) { DynamicTests.MemberAccess(a + b); DynamicTests.MemberAccess(a + 1); DynamicTests.MemberAccess(a + null); DynamicTests.MemberAccess(a - b); DynamicTests.MemberAccess(a - 1); DynamicTests.MemberAccess(a - null); DynamicTests.MemberAccess(a * b); DynamicTests.MemberAccess(a * 1); DynamicTests.MemberAccess(a * null); DynamicTests.MemberAccess(a / b); DynamicTests.MemberAccess(a / 1); DynamicTests.MemberAccess(a / null); DynamicTests.MemberAccess(a % b); DynamicTests.MemberAccess(a % 1); DynamicTests.MemberAccess(a % null); } private static void CheckedArithmeticBinaryOperators(dynamic a, dynamic b) { checked { DynamicTests.MemberAccess(a + b); DynamicTests.MemberAccess(a + 1); DynamicTests.MemberAccess(a + null); DynamicTests.MemberAccess(a - b); DynamicTests.MemberAccess(a - 1); DynamicTests.MemberAccess(a - null); DynamicTests.MemberAccess(a * b); DynamicTests.MemberAccess(a * 1); DynamicTests.MemberAccess(a * null); DynamicTests.MemberAccess(a / b); DynamicTests.MemberAccess(a / 1); DynamicTests.MemberAccess(a / null); DynamicTests.MemberAccess(a % b); DynamicTests.MemberAccess(a % 1); DynamicTests.MemberAccess(a % null); } } private static void UncheckedArithmeticBinaryOperators(dynamic a, dynamic b) { checked { DynamicTests.MemberAccess(a + b); DynamicTests.MemberAccess(a + 1); DynamicTests.MemberAccess(a + null); DynamicTests.MemberAccess(unchecked(a - b)); DynamicTests.MemberAccess(a - 1); DynamicTests.MemberAccess(a - null); DynamicTests.MemberAccess(unchecked(a * b)); DynamicTests.MemberAccess(a * 1); DynamicTests.MemberAccess(a * null); DynamicTests.MemberAccess(a / b); DynamicTests.MemberAccess(a / 1); DynamicTests.MemberAccess(a / null); DynamicTests.MemberAccess(a % b); DynamicTests.MemberAccess(a % 1); DynamicTests.MemberAccess(a % null); } } private static void RelationalOperators(dynamic a, dynamic b) { DynamicTests.MemberAccess(a == b); DynamicTests.MemberAccess(a == 1); DynamicTests.MemberAccess(a == null); DynamicTests.MemberAccess(a != b); DynamicTests.MemberAccess(a != 1); DynamicTests.MemberAccess(a != null); DynamicTests.MemberAccess(a < b); DynamicTests.MemberAccess(a < 1); DynamicTests.MemberAccess(a < null); DynamicTests.MemberAccess(a > b); DynamicTests.MemberAccess(a > 1); DynamicTests.MemberAccess(a > null); DynamicTests.MemberAccess(a >= b); DynamicTests.MemberAccess(a >= 1); DynamicTests.MemberAccess(a >= null); DynamicTests.MemberAccess(a <= b); DynamicTests.MemberAccess(a <= 1); DynamicTests.MemberAccess(a <= null); } private static void Casts(dynamic a) { Console.WriteLine(); MemberAccess((int)a); MemberAccess(checked((int)a)); } private static void M(object o) { } private static void M2(dynamic d) { } private static void M3(int i) { } private static void NotDynamicDispatch(dynamic d) { DynamicTests.M(d); M((object)d); DynamicTests.M2(d); M2((object)d); } private static void CompoundAssignment(dynamic a, dynamic b) { a.Setter2 += 5; a.Setter2 -= 1; a.Setter2 *= 2; a.Setter2 /= 5; a.Setter2 += b; a.Setter2 -= b; a.Setter2 *= b; a.Setter2 /= b; field.Setter += 5; field.Setter -= 5; } private static void InlineCompoundAssignment(dynamic a, dynamic b) { Console.WriteLine(a.Setter2 += 5); Console.WriteLine(a.Setter2 -= 1); Console.WriteLine(a.Setter2 *= 2); Console.WriteLine(a.Setter2 /= 5); Console.WriteLine(a.Setter2 += b); Console.WriteLine(a.Setter2 -= b); Console.WriteLine(a.Setter2 *= b); Console.WriteLine(a.Setter2 /= b); } private static void UnaryOperators(dynamic a) { // TODO : beautify inc/dec on locals and fields //a--; //a++; //--a; //++a; DynamicTests.Casts(-a); DynamicTests.Casts(+a); } private static void Loops(dynamic list) { foreach (dynamic item in list) { DynamicTests.UnaryOperators(item); } } private static void If(dynamic a, dynamic b) { if (a == b) { Console.WriteLine("Equal"); } } private static void If2(dynamic a, dynamic b) { if (a == null || b == null) { Console.WriteLine("One is null"); } } private static void If3(dynamic a, dynamic b) { if (a == null && b == null) { Console.WriteLine("Both are null"); } } private static void If4(dynamic a, dynamic b) { if ((a == null || b == null) && GetDynamic(1) && !(GetDynamic(2) && GetDynamic(3))) { Console.WriteLine("then"); } else { Console.WriteLine("else"); } } private static bool ConstantTarget(dynamic a) { return true.Equals(a); } #if CS110 && NET70 private static nint NewIntPtr(dynamic a) { return new nint(a); } #else private static IntPtr NewIntPtr(dynamic a) { return new IntPtr(a); } #endif private static dynamic GetDynamic(int i) { return null; } private static bool GetBool(int i) { return false; } private static dynamic LogicAnd() { return GetDynamic(1) && GetDynamic(2); } private static dynamic LogicAnd(dynamic a, dynamic b) { return a && b; } private static void LogicAndExtended(int i, dynamic d) { Console.WriteLine(GetDynamic(1) && GetDynamic(2)); Console.WriteLine(GetDynamic(1) && GetBool(2)); Console.WriteLine(GetBool(1) && GetDynamic(2)); Console.WriteLine(i == 1 && d == null); } private static dynamic LogicOr() { return GetDynamic(1) || GetDynamic(2); } private static dynamic LogicOr(dynamic a, dynamic b) { return a || b; } private static void LogicOrExtended(int i, dynamic d) { Console.WriteLine(GetDynamic(1) || GetDynamic(2)); Console.WriteLine(GetDynamic(1) || GetBool(2)); Console.WriteLine(GetBool(1) || GetDynamic(2)); Console.WriteLine(i == 1 || d == null); } private static int ImplicitCast(object o) { return (dynamic)o; } private static int ExplicitCast(object o) { return (int)(dynamic)o; } private static dynamic GetI() { return null; } public I Test() { return GetI(); } public I Test1() { return (I)GetI(); } public I Test2() { return (I)(object)GetI(); } #if CS72 public void RefParams(ref object a, ref dynamic b, ref dynamic c) { } public void RefParams2(in object a, ref dynamic b, out dynamic c) { c = null; } public ref dynamic RefReturn(ref object o) { return ref o; } public ref readonly dynamic RefReadonlyReturn(in object o) { return ref o; } #endif } internal static class Extension { public static dynamic ToDynamic(this int i, dynamic info) { throw null; } } }