mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
564 lines
11 KiB
564 lines
11 KiB
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<object, dynamic> 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<int, int>(); |
|
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; |
|
} |
|
} |
|
}
|
|
|