Skip to content

Commit

Permalink
Add support for C# 7 tuple types:
Browse files Browse the repository at this point in the history
 * Use tuple literals instead of calling 'new ValueTuple<..>' constructor
 * Where available, use element names for field access
 * Make CallBuilder aware of tuple-name/dynamic type erasure, to avoid introducing casts when the types differ only in the tuple element names.
 * Make CallBuilder provide a ResolveResult with the correct C# return type for the resulting expression.
   Previously we were using the type-erased return type from the IL.
 * Fix a bug that caused us to introduce returning casts when accessing an indexer.
  • Loading branch information
dgrunwald committed May 13, 2018
1 parent 395bc18 commit 4695012
Show file tree
Hide file tree
Showing 28 changed files with 1,159 additions and 349 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<Compile Include="TestCases\Pretty\Issue1080.cs" />
<Compile Include="TestCases\Pretty\QualifierTests.cs" />
<Compile Include="TestCases\Pretty\RefLocalsAndReturns.cs" />
<Compile Include="TestCases\Pretty\TupleTypes.cs" />
<Compile Include="TestCases\Pretty\TupleTests.cs" />
<Compile Include="TestCases\Pretty\WellKnownConstants.cs" />
<Compile Include="TypeSystem\TypeSystemHelper.cs" />
<Compile Include="TypeSystem\TypeSystemLoaderTests.cs" />
Expand Down
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ public void QualifierTests([ValueSource("defaultOptions")] CSharpCompilerOptions
}

[Test]
public void TupleTypes([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions)
public void TupleTests([ValueSource("roslynOnlyOptions")] CSharpCompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public class TupleTypes
public class TupleTests
{
public ValueTuple VT0;
public ValueTuple<int> VT1;
Expand All @@ -44,5 +46,34 @@ public class TupleTypes
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 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 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);
}
}
}
344 changes: 344 additions & 0 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.opt.roslyn.il

Large diffs are not rendered by default.

359 changes: 359 additions & 0 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.roslyn.il

Large diffs are not rendered by default.

This file was deleted.

92 changes: 0 additions & 92 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTypes.roslyn.il

This file was deleted.

10 changes: 10 additions & 0 deletions ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,16 @@ static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttr
HasNullableSpecifier = true
};
}
if (CecilLoader.IsValueTuple(gType, out int tupleCardinality) && tupleCardinality > 1 && tupleCardinality < TupleType.RestPosition) {
var tupleType = new TupleAstType();
foreach (var typeArgument in gType.GenericArguments) {
typeIndex++;
tupleType.Elements.Add(new TupleTypeElement {
Type = ConvertType(typeArgument, typeAttributes, ref typeIndex, options)
});
}
return tupleType;
}
AstType baseType = ConvertType(gType.ElementType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions);
List<AstType> typeArguments = new List<AstType>();
foreach (var typeArgument in gType.GenericArguments) {
Expand Down
Loading

0 comments on commit 4695012

Please sign in to comment.