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.
343 lines
7.0 KiB
343 lines
7.0 KiB
using System; |
|
|
|
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty |
|
{ |
|
internal static class Ext |
|
{ |
|
public static void ExtOnRef(this ref RefLocalsAndReturns.NormalStruct s) |
|
{ |
|
} |
|
public static void ExtOnIn(this in RefLocalsAndReturns.NormalStruct s) |
|
{ |
|
} |
|
public static void ExtOnRef(this ref RefLocalsAndReturns.ReadOnlyStruct s) |
|
{ |
|
} |
|
public static void ExtOnIn(this in RefLocalsAndReturns.ReadOnlyStruct s) |
|
{ |
|
} |
|
public static void ExtOnRef(this ref RefLocalsAndReturns.ReadOnlyRefStruct s) |
|
{ |
|
} |
|
public static void ExtOnIn(this in RefLocalsAndReturns.ReadOnlyRefStruct s) |
|
{ |
|
} |
|
} |
|
|
|
internal class RefLocalsAndReturns |
|
{ |
|
public struct Issue1630 |
|
{ |
|
private object data; |
|
|
|
private int next; |
|
|
|
public static void Test() |
|
{ |
|
Issue1630[] array = new Issue1630[1]; |
|
int num = 0; |
|
while (num >= 0) |
|
{ |
|
ref Issue1630 reference = ref array[num]; |
|
Console.WriteLine(reference.data); |
|
num = reference.next; |
|
} |
|
} |
|
} |
|
|
|
|
|
public delegate ref T RefFunc<T>(); |
|
public delegate ref readonly T ReadOnlyRefFunc<T>(); |
|
public delegate ref TReturn RefFunc<T1, TReturn>(T1 param1); |
|
|
|
public ref struct RefStruct |
|
{ |
|
private int dummy; |
|
} |
|
|
|
public readonly ref struct ReadOnlyRefStruct |
|
{ |
|
private readonly int dummy; |
|
} |
|
|
|
public struct NormalStruct |
|
{ |
|
private readonly int dummy; |
|
private int[] arr; |
|
|
|
public int Property { |
|
get { |
|
return 1; |
|
} |
|
set { |
|
} |
|
} |
|
|
|
#if CS80 |
|
public readonly int ReadOnlyProperty { |
|
get { |
|
return 1; |
|
} |
|
set { |
|
} |
|
} |
|
|
|
public int PropertyWithReadOnlyGetter { |
|
readonly get { |
|
return 1; |
|
} |
|
set { |
|
} |
|
} |
|
|
|
public int PropertyWithReadOnlySetter { |
|
get { |
|
return 1; |
|
} |
|
readonly set { |
|
} |
|
} |
|
|
|
public readonly int ReadOnlyPropertyWithOnlyGetter { |
|
get { |
|
Console.WriteLine("No inlining"); |
|
return 1; |
|
} |
|
} |
|
|
|
public ref int RefProperty => ref arr[0]; |
|
public ref readonly int RefReadonlyProperty => ref arr[0]; |
|
public readonly ref int ReadonlyRefProperty => ref arr[0]; |
|
public readonly ref readonly int ReadonlyRefReadonlyProperty => ref arr[0]; |
|
#endif |
|
|
|
public ref readonly int this[in int index] => ref arr[index]; |
|
|
|
public event EventHandler NormalEvent; |
|
|
|
#if CS80 |
|
public readonly event EventHandler ReadOnlyEvent { |
|
add { |
|
} |
|
remove { |
|
} |
|
} |
|
#endif |
|
public void Method() |
|
{ |
|
} |
|
|
|
#if CS80 |
|
public readonly void ReadOnlyMethod() |
|
{ |
|
} |
|
#endif |
|
} |
|
|
|
public readonly struct ReadOnlyStruct |
|
{ |
|
private readonly int Field; |
|
|
|
public void Method() |
|
{ |
|
ref readonly int field = ref Field; |
|
Console.WriteLine("No inlining"); |
|
Console.WriteLine(field.GetHashCode()); |
|
} |
|
|
|
public void RefReadonlyCallVirt(RefLocalsAndReturns provider) |
|
{ |
|
ref readonly NormalStruct readonlyRefInstance = ref provider.GetReadonlyRefInstance<NormalStruct>(); |
|
Console.WriteLine("No inlining"); |
|
readonlyRefInstance.Method(); |
|
} |
|
} |
|
|
|
private static int[] numbers = new int[10] { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 }; |
|
private static string[] strings = new string[2] { "Hello", "World" }; |
|
|
|
private static string NullString = ""; |
|
|
|
private static int DefaultInt = 0; |
|
|
|
public static ref T GetRef<T>() |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public static ref readonly T GetReadonlyRef<T>() |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public ref readonly T GetReadonlyRefInstance<T>() |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
|
|
public void CallOnRefReturn() |
|
{ |
|
// Both direct calls: |
|
GetRef<NormalStruct>().Method(); |
|
GetRef<ReadOnlyStruct>().Method(); |
|
|
|
// call on a copy, not the original ref: |
|
NormalStruct normalStruct = GetRef<NormalStruct>(); |
|
normalStruct.Method(); |
|
|
|
ReadOnlyStruct readOnlyStruct = GetRef<ReadOnlyStruct>(); |
|
readOnlyStruct.Method(); |
|
} |
|
|
|
public void CallOnReadOnlyRefReturn() |
|
{ |
|
// uses implicit temporary: |
|
GetReadonlyRef<NormalStruct>().Method(); |
|
// direct call: |
|
GetReadonlyRef<ReadOnlyStruct>().Method(); |
|
// call on a copy, not the original ref: |
|
ReadOnlyStruct readonlyRef = GetReadonlyRef<ReadOnlyStruct>(); |
|
readonlyRef.Method(); |
|
} |
|
|
|
public void CallOnInParam(in NormalStruct ns, in ReadOnlyStruct rs) |
|
{ |
|
// uses implicit temporary: |
|
ns.Method(); |
|
// direct call: |
|
rs.Method(); |
|
// call on a copy, not the original ref: |
|
ReadOnlyStruct readOnlyStruct = rs; |
|
readOnlyStruct.Method(); |
|
} |
|
|
|
public void M(in DateTime a = default(DateTime)) |
|
{ |
|
} |
|
|
|
public void M2<T>(in T a = default(T)) |
|
{ |
|
} |
|
|
|
public void M3<T>(in T? a = null) where T : struct |
|
{ |
|
} |
|
|
|
public static TReturn Invoker<T1, TReturn>(RefFunc<T1, TReturn> action, T1 value) |
|
{ |
|
return action(value); |
|
} |
|
|
|
public static ref int FindNumber(int target) |
|
{ |
|
for (int i = 0; i < numbers.Length; i++) |
|
{ |
|
if (numbers[i] >= target) |
|
{ |
|
return ref numbers[i]; |
|
} |
|
} |
|
return ref numbers[0]; |
|
} |
|
|
|
public static ref int LastNumber() |
|
{ |
|
return ref numbers[numbers.Length - 1]; |
|
} |
|
|
|
public static ref int ElementAtOrDefault(int index) |
|
{ |
|
if (index >= 0 && index < numbers.Length) |
|
{ |
|
return ref numbers[index]; |
|
} |
|
return ref DefaultInt; |
|
} |
|
|
|
public static ref int LastOrDefault() |
|
{ |
|
if (numbers.Length != 0) |
|
{ |
|
return ref numbers[numbers.Length - 1]; |
|
} |
|
return ref DefaultInt; |
|
} |
|
|
|
public static void DoubleNumber(ref int num) |
|
{ |
|
Console.WriteLine("old: " + num); |
|
num *= 2; |
|
Console.WriteLine("new: " + num); |
|
} |
|
|
|
public static ref string GetOrSetString(int index) |
|
{ |
|
if (index < 0 || index >= strings.Length) |
|
{ |
|
return ref NullString; |
|
} |
|
|
|
return ref strings[index]; |
|
} |
|
|
|
public void CallSiteTests(NormalStruct s, ReadOnlyStruct r, ReadOnlyRefStruct rr) |
|
{ |
|
s.ExtOnIn(); |
|
s.ExtOnRef(); |
|
r.ExtOnIn(); |
|
r.ExtOnRef(); |
|
rr.ExtOnIn(); |
|
rr.ExtOnRef(); |
|
CallOnInParam(in s, in r); |
|
} |
|
|
|
public void RefReassignment(ref NormalStruct s) |
|
{ |
|
ref NormalStruct reference = ref GetRef<NormalStruct>(); |
|
RefReassignment(ref reference); |
|
if (s.GetHashCode() == 0) |
|
{ |
|
reference = ref GetRef<NormalStruct>(); |
|
} |
|
RefReassignment(ref reference.GetHashCode() == 4 ? ref reference : ref s); |
|
} |
|
|
|
public static void Main(string[] args) |
|
{ |
|
DoubleNumber(ref args.Length == 1 ? ref numbers[0] : ref DefaultInt); |
|
DoubleNumber(ref FindNumber(32)); |
|
Console.WriteLine(string.Join(", ", numbers)); |
|
DoubleNumber(ref LastNumber()); |
|
Console.WriteLine(string.Join(", ", numbers)); |
|
Console.WriteLine(GetOrSetString(0)); |
|
GetOrSetString(0) = "Goodbye"; |
|
Console.WriteLine(string.Join(" ", strings)); |
|
GetOrSetString(5) = "Here I mutated the null value!?"; |
|
Console.WriteLine(GetOrSetString(-5)); |
|
|
|
Console.WriteLine(Invoker((int x) => ref numbers[x], 0)); |
|
Console.WriteLine(LastOrDefault()); |
|
LastOrDefault() = 10000; |
|
Console.WriteLine(ElementAtOrDefault(-5)); |
|
} |
|
|
|
#if CS120 |
|
public ref readonly int M(in int x) |
|
{ |
|
return ref x; |
|
} |
|
|
|
public ref readonly int M2(ref readonly int x) |
|
{ |
|
return ref x; |
|
} |
|
|
|
public void Test() |
|
{ |
|
int x = 32; |
|
M(in x); |
|
M2(in x); |
|
} |
|
#endif |
|
} |
|
}
|
|
|