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.
293 lines
9.9 KiB
293 lines
9.9 KiB
// Copyright (c) 2020 Daniel Grunwald |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this |
|
// software and associated documentation files (the "Software"), to deal in the Software |
|
// without restriction, including without limitation the rights to use, copy, modify, merge, |
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons |
|
// to whom the Software is furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included in all copies or |
|
// substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
// DEALINGS IN THE SOFTWARE. |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
|
|
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty |
|
{ |
|
internal class CustomList |
|
{ |
|
public int Count => 0; |
|
public int this[int index] => 0; |
|
|
|
public CustomList Slice(int start, int length) |
|
{ |
|
return this; |
|
} |
|
} |
|
|
|
internal class CustomList2 |
|
{ |
|
public int Count => 0; |
|
public int this[int index] => 0; |
|
public int this[Index index] => 0; |
|
public CustomList2 this[Range range] => this; |
|
|
|
public CustomList2 Slice(int start, int length) |
|
{ |
|
return this; |
|
} |
|
} |
|
|
|
internal class IndexRangeTest |
|
{ |
|
public static int[] GetArray() |
|
{ |
|
throw null; |
|
} |
|
public static List<int> GetList() |
|
{ |
|
throw null; |
|
} |
|
public static Span<int> GetSpan() |
|
{ |
|
throw null; |
|
} |
|
public static string GetString() |
|
{ |
|
throw null; |
|
} |
|
public static Index GetIndex(int i = 0) |
|
{ |
|
return i; |
|
} |
|
public static Range GetRange(int i = 0) |
|
{ |
|
return i..^i; |
|
} |
|
public static int GetInt(int i = 0) |
|
{ |
|
return i; |
|
} |
|
public static Range[] SeveralRanges() |
|
{ |
|
// Some of these are semantically identical, but we can still distinguish them in the IL code: |
|
return new Range[14] { |
|
.., |
|
0.., |
|
^0.., |
|
GetInt(1).., |
|
^GetInt(2).., |
|
..0, |
|
..^0, |
|
..GetInt(3), |
|
..^GetInt(4), |
|
0..^0, |
|
^0..0, |
|
0..0, |
|
GetInt(5)..GetInt(6), |
|
0..(GetInt(7) + GetInt(8)) |
|
}; |
|
} |
|
|
|
public static void UseIndex() |
|
{ |
|
Console.WriteLine(GetArray()[GetIndex()]); |
|
Console.WriteLine(GetList()[GetIndex()]); |
|
Console.WriteLine(GetSpan()[GetIndex()]); |
|
Console.WriteLine(GetString()[GetIndex()]); |
|
Console.WriteLine(GetString()?[GetIndex()]); |
|
Console.WriteLine(new CustomList()[GetIndex()]); |
|
Console.WriteLine(new CustomList2()[GetIndex()]); |
|
} |
|
|
|
public static void UseIndexFromEnd() |
|
{ |
|
Console.WriteLine(GetArray()[^GetInt()]); |
|
Console.WriteLine(GetList()[^GetInt()]); |
|
Console.WriteLine(GetSpan()[^GetInt()]); |
|
Console.WriteLine(GetString()[^GetInt()]); |
|
Console.WriteLine(GetString()?[^GetInt()]); |
|
Console.WriteLine(new CustomList()[^GetInt()]); |
|
Console.WriteLine(new CustomList2()[^GetInt()]); |
|
} |
|
|
|
public static void UseIndexForWrite() |
|
{ |
|
GetArray()[GetIndex()] = GetInt(); |
|
GetList()[GetIndex()] = GetInt(); |
|
GetSpan()[GetIndex()] = GetInt(); |
|
} |
|
|
|
private static void UseRef(ref int i) |
|
{ |
|
} |
|
|
|
public static void UseIndexForRef() |
|
{ |
|
UseRef(ref GetArray()[GetIndex()]); |
|
UseRef(ref GetArray()[^GetInt()]); |
|
UseRef(ref GetSpan()[GetIndex()]); |
|
UseRef(ref GetSpan()[^GetInt()]); |
|
} |
|
|
|
public static void UseRange() |
|
{ |
|
Console.WriteLine(GetArray()[GetRange()]); |
|
//Console.WriteLine(GetList()[GetRange()]); // fails to compile |
|
Console.WriteLine(GetSpan()[GetRange()].ToString()); |
|
Console.WriteLine(GetString()[GetRange()]); |
|
Console.WriteLine(GetString()?[GetRange()]); |
|
Console.WriteLine(new CustomList()[GetRange()]); |
|
Console.WriteLine(new CustomList2()[GetRange()]); |
|
} |
|
public static void UseNewRangeFromIndex() |
|
{ |
|
Console.WriteLine(GetArray()[GetIndex(1)..GetIndex(2)]); |
|
//Console.WriteLine(GetList()[GetIndex(1)..GetIndex(2)]); // fails to compile |
|
Console.WriteLine(GetSpan()[GetIndex(1)..GetIndex(2)].ToString()); |
|
Console.WriteLine(GetString()[GetIndex(1)..GetIndex(2)]); |
|
Console.WriteLine(GetString()?[GetIndex(1)..GetIndex(2)]); |
|
Console.WriteLine(new CustomList()[GetIndex(1)..GetIndex(2)]); |
|
Console.WriteLine(new CustomList2()[GetIndex(1)..GetIndex(2)]); |
|
} |
|
public static void UseNewRangeFromIntegers_BothFromStart() |
|
{ |
|
Console.WriteLine(GetArray()[GetInt(1)..GetInt(2)]); |
|
//Console.WriteLine(GetList()[GetInt()..GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[GetInt(1)..GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(GetString()?[GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(new CustomList()[GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[GetInt(1)..GetInt(2)]); |
|
} |
|
public static void UseNewRangeFromIntegers_BothFromEnd() |
|
{ |
|
Console.WriteLine(GetArray()[^GetInt(1)..^GetInt(2)]); |
|
//Console.WriteLine(GetList()[^GetInt()..^GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[^GetInt(1)..^GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[^GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(GetString()?[^GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(new CustomList()[^GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[^GetInt(1)..^GetInt(2)]); |
|
} |
|
public static void UseNewRangeFromIntegers_FromStartAndEnd() |
|
{ |
|
Console.WriteLine(GetArray()[GetInt(1)..^GetInt(2)]); |
|
//Console.WriteLine(GetList()[GetInt()..^GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[GetInt(1)..^GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(GetString()?[GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(new CustomList()[GetInt(1)..^GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[GetInt(1)..^GetInt(2)]); |
|
} |
|
public static void UseNewRangeFromIntegers_FromEndAndStart() |
|
{ |
|
Console.WriteLine(GetArray()[^GetInt(1)..GetInt(2)]); |
|
//Console.WriteLine(GetList()[^GetInt()..GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[^GetInt(1)..GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[^GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(GetString()?[^GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(new CustomList()[^GetInt(1)..GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[^GetInt(1)..GetInt(2)]); |
|
} |
|
|
|
public static void UseNewRangeFromIntegers_OnlyEndPoint() |
|
{ |
|
Console.WriteLine(GetArray()[..GetInt(2)]); |
|
//Console.WriteLine(GetList()[..GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[..GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[..GetInt(2)]); |
|
Console.WriteLine(GetString()?[..GetInt(2)]); |
|
Console.WriteLine(new CustomList()[..GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[..GetInt(2)]); |
|
} |
|
|
|
public static void UseNewRangeFromIntegers_OnlyEndPoint_FromEnd() |
|
{ |
|
Console.WriteLine(GetArray()[..^GetInt(2)]); |
|
//Console.WriteLine(GetList()[..^GetInt()]); // fails to compile |
|
Console.WriteLine(GetSpan()[..^GetInt(2)].ToString()); |
|
Console.WriteLine(GetString()[..^GetInt(2)]); |
|
Console.WriteLine(GetString()?[..^GetInt(2)]); |
|
Console.WriteLine(new CustomList()[..^GetInt(2)]); |
|
Console.WriteLine(new CustomList2()[..^GetInt(2)]); |
|
} |
|
|
|
public static void UseNewRangeFromIntegers_OnlyStartPoint() |
|
{ |
|
Console.WriteLine(GetArray()[GetInt(1)..]); |
|
//Console.WriteLine(GetList()[GetInt()..]); // fails to compile |
|
Console.WriteLine(GetSpan()[GetInt(1)..].ToString()); |
|
Console.WriteLine(GetString()[GetInt(1)..]); |
|
Console.WriteLine(GetString()?[GetInt(1)..]); |
|
Console.WriteLine(new CustomList()[GetInt(1)..]); |
|
Console.WriteLine(new CustomList2()[GetInt(1)..]); |
|
} |
|
|
|
public static void UseNewRangeFromIntegers_OnlyStartPoint_FromEnd() |
|
{ |
|
Console.WriteLine(GetArray()[^GetInt(1)..]); |
|
//Console.WriteLine(GetList()[^GetInt()..]); // fails to compile |
|
Console.WriteLine(GetSpan()[^GetInt(1)..].ToString()); |
|
Console.WriteLine(GetString()[^GetInt(1)..]); |
|
Console.WriteLine(GetString()?[^GetInt(1)..]); |
|
Console.WriteLine(new CustomList()[^GetInt(1)..]); |
|
Console.WriteLine(new CustomList2()[^GetInt(1)..]); |
|
} |
|
|
|
public static void UseConstantRange() |
|
{ |
|
// Fortunately the C# compiler doesn't optimize |
|
// "str.Length - 2 - 1" here, so the normal pattern applies. |
|
Console.WriteLine(GetString()[1..2]); |
|
Console.WriteLine(GetString()[1..^1]); |
|
Console.WriteLine(GetString()[^2..^1]); |
|
|
|
Console.WriteLine(GetString()[..1]); |
|
Console.WriteLine(GetString()[..^1]); |
|
Console.WriteLine(GetString()[1..]); |
|
Console.WriteLine(GetString()[^1..]); |
|
} |
|
|
|
public static void UseWholeRange() |
|
{ |
|
Console.WriteLine(GetArray()[..]); |
|
//Console.WriteLine(GetList()[..]); // fails to compile |
|
Console.WriteLine(GetSpan()[..].ToString()); |
|
Console.WriteLine(GetString()[..]); |
|
Console.WriteLine(new CustomList()[..]); |
|
Console.WriteLine(new CustomList2()[..]); |
|
} |
|
|
|
public static void UseIndexForIntIndexerWhenIndexIndexerIsAvailable() |
|
{ |
|
// Same code as the compiler emits for CustomList, |
|
// but here we can't translate it back to `customList[GetIndex()]` |
|
// because that would call a different overload. |
|
CustomList2 customList = new CustomList2(); |
|
int count = customList.Count; |
|
int offset = GetIndex().GetOffset(count); |
|
Console.WriteLine(customList[offset]); |
|
} |
|
|
|
public static void UseSliceWhenRangeIndexerIsAvailable() |
|
{ |
|
// Same code as the compiler emits for CustomList, |
|
// but here we can't translate it back to `customList[GetIndex()]` |
|
// because that would call a different overload. |
|
CustomList2 customList = new CustomList2(); |
|
int count = customList.Count; |
|
Range range = GetRange(); |
|
int offset = range.Start.GetOffset(count); |
|
int length = range.End.GetOffset(count) - offset; |
|
Console.WriteLine(customList.Slice(offset, length)); |
|
} |
|
} |
|
}
|
|
|