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.
209 lines
6.0 KiB
209 lines
6.0 KiB
// Copyright (c) 2018 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; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
|
|
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty |
|
{ |
|
public class TupleTests |
|
{ |
|
private abstract class OverloadResolution |
|
{ |
|
public abstract void M1((long, long) a); |
|
public abstract void M1(object a); |
|
|
|
public void UseM1((int, int) a) |
|
{ |
|
// M1(a); TODO: tuple conversion transform |
|
// Cast is required to avoid the overload usable via tuple conversion: |
|
M1((object)a); |
|
} |
|
} |
|
|
|
public struct GenericStruct<T> |
|
{ |
|
public T Field; |
|
public T Property { get; set; } |
|
} |
|
|
|
public ValueTuple VT0; |
|
public ValueTuple<int> VT1; |
|
public ValueTuple<int, int, int, int, int, int, int, ValueTuple> VT7EmptyRest; |
|
|
|
public (int, uint) Unnamed2; |
|
public (int, int, int) Unnamed3; |
|
public (int, int, int, int) Unnamed4; |
|
public (int, int, int, int, int) Unnamed5; |
|
public (int, int, int, int, int, int) Unnamed6; |
|
public (int, int, int, int, int, int, int) Unnamed7; |
|
public (int, int, int, int, int, int, int, int) Unnamed8; |
|
|
|
public (int a, uint b) Named2; |
|
public (int a, uint b)[] Named2Array; |
|
public (int a, int b, int c, int d, int e, int f, int g, int h) Named8; |
|
|
|
public (int, int a, int, int b, int) PartiallyNamed; |
|
|
|
public ((int a, int b) x, (int, int) y, (int c, int d) z) Nested1; |
|
public ((object a, dynamic b), dynamic, (dynamic c, object d)) Nested2; |
|
public (ValueTuple a, (int x1, int x2), ValueTuple<int> b, (int y1, int y2), (int, int) c) Nested3; |
|
public (int a, int b, int c, int d, int e, int f, int g, int h, (int i, int j)) Nested4; |
|
|
|
public Dictionary<(int a, string b), (string c, int d)> TupleDict; |
|
public List<(int, string)> List; |
|
public bool HasItems => List.Any(((int, string) a) => a.Item1 > 0); |
|
|
|
public int VT1Member => VT1.Item1; |
|
public int AccessUnnamed8 => Unnamed8.Item8; |
|
public int AccessNamed8 => Named8.h; |
|
public int AccessPartiallyNamed => PartiallyNamed.a + PartiallyNamed.Item3; |
|
|
|
public ValueTuple<int> NewTuple1 => new ValueTuple<int>(1); |
|
public (int a, int b) NewTuple2 => (1, 2); |
|
public object BoxedTuple10 => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); |
|
|
|
public (uint, int) SwapUnnamed => (Unnamed2.Item2, Unnamed2.Item1); |
|
public (uint, int) SwapNamed2 => (Named2.b, Named2.a); |
|
|
|
public int TupleHash => (1, 2, 3).GetHashCode(); |
|
public int TupleHash2 => Named2.GetHashCode(); |
|
|
|
public (int, int) AccessRest => (1, 2, 3, 4, 5, 6, 7, 8, 9).Rest; |
|
|
|
public (string, object, Action) TargetTyping => (null, 1, delegate { |
|
#pragma warning disable format |
|
}); |
|
#pragma warning restore format |
|
|
|
public object NotTargetTyping => ((string)null, (object)1, (Action)delegate { |
|
#pragma warning disable format |
|
}); |
|
#pragma warning restore format |
|
|
|
public void UnnamedTupleOut(out (int, string, Action, dynamic) tuple) |
|
{ |
|
tuple = (42, "Hello", Console.WriteLine, null); |
|
} |
|
|
|
public void UnnamedTupleIn(in (int, string, Action, dynamic) tuple) |
|
{ |
|
|
|
} |
|
|
|
public void UnnamedTupleRef(ref (int, string, Action, dynamic) tuple) |
|
{ |
|
|
|
} |
|
|
|
public void NamedTupleOut(out (int A, string B, Action C, dynamic D) tuple) |
|
{ |
|
tuple = (42, "Hello", Console.WriteLine, null); |
|
} |
|
|
|
public void NamedTupleIn(in (int A, string B, Action C, dynamic D) tuple) |
|
{ |
|
|
|
} |
|
|
|
public void NamedTupleRef(ref (int A, string B, Action C, dynamic D) tuple) |
|
{ |
|
|
|
} |
|
|
|
public void UseDict() |
|
{ |
|
if (TupleDict.Count > 10) |
|
{ |
|
TupleDict.Clear(); |
|
} |
|
// TODO: it would be nice if we could infer the name 'c' for the local |
|
string item = TupleDict[(1, "abc")].c; |
|
Console.WriteLine(item); |
|
Console.WriteLine(item); |
|
Console.WriteLine(TupleDict.Values.ToList().First().d); |
|
} |
|
|
|
public void Issue1174() |
|
{ |
|
Console.WriteLine((1, 2, 3).GetHashCode()); |
|
} |
|
|
|
public void LocalVariables((int, int) a) |
|
{ |
|
(int, int) tuple = (a.Item1 + a.Item2, a.Item1 * a.Item2); |
|
Console.WriteLine(tuple.ToString()); |
|
Console.WriteLine(tuple.GetType().FullName); |
|
} |
|
|
|
public void Foreach(IEnumerable<(int, string)> input) |
|
{ |
|
foreach (var item in input) |
|
{ |
|
Console.WriteLine($"{item.Item1}: {item.Item2}"); |
|
} |
|
} |
|
|
|
public void ForeachNamedElements(IEnumerable<(int Index, string Data)> input) |
|
{ |
|
foreach (var item in input) |
|
{ |
|
Console.WriteLine($"{item.Index}: {item.Data}"); |
|
} |
|
} |
|
|
|
public void NonGenericForeach(IEnumerable input) |
|
{ |
|
foreach ((string, int) item in input) |
|
{ |
|
Console.WriteLine($"{item.Item1}: {item.Item2}"); |
|
} |
|
} |
|
|
|
public void CallForeach() |
|
{ |
|
Foreach(new List<(int, string)> { |
|
(1, "a"), |
|
(2, "b") |
|
}); |
|
} |
|
|
|
public void DynamicTuple((dynamic A, dynamic B) a) |
|
{ |
|
a.A.DynamicCall(); |
|
a.B.Dynamic = 42; |
|
} |
|
|
|
public void GenericStructWithElementNames(GenericStruct<(int A, int B)> s) |
|
{ |
|
Console.WriteLine(s.Field.A + s.Property.B); |
|
} |
|
|
|
public void RefCallSites(out (int, string, Action, dynamic) tuple) |
|
{ |
|
UnnamedTupleOut(out tuple); |
|
UnnamedTupleIn(in tuple); |
|
UnnamedTupleRef(ref tuple); |
|
NamedTupleOut(out tuple); |
|
NamedTupleIn(in tuple); |
|
NamedTupleRef(ref tuple); |
|
} |
|
} |
|
}
|
|
|