Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,24 @@ public async Task OutVariables([ValueSource(nameof(roslyn2OrNewerOptions))] Comp
await RunForLibrary(cscOptions: cscOptions);
}

[Test]
public async Task DefaultLiteral([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}

[Test]
public async Task OverloadResolution([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}

[Test]
public async Task TargetTypedDefault([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}

[Test]
public async Task PatternMatching([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
Expand Down
18 changes: 12 additions & 6 deletions ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1638,14 +1638,20 @@ public void UserDefinedImplicitConversion_OperatorDeclaredInBaseClassOfSource()
Assert.That(c.Method.DeclaringType.Name, Is.EqualTo("OperatorInBaseClass"));
}

[Test, Ignore("C# standard 10.2.16 is not implemented: CSharpConversions.ImplicitConversion has a TODO for default literal conversions, and no ResolveResult represents a typeless default literal")]
[Test]
public void DefaultLiteralConversions()
{
// C# standard 10.2.16: an implicit conversion exists from a default_literal to
// any type, producing the default value of the inferred type. Once the semantic
// model gains a typeless default-literal ResolveResult, this test should assert
// that it converts to int, string, int? and type parameters.
Assert.Fail("Default literal conversions are not implemented.");
// C# standard 10.2.16: an implicit conversion exists from a default_literal to any type
var defaultLiteral = new DefaultLiteralResolveResult();
// a default_value_expression is a constant expression (C# standard 12.8.21)
Assert.That(defaultLiteral.IsCompileTimeConstant);
Assert.That(conversions.ImplicitConversion(defaultLiteral, compilation.FindType(KnownTypeCode.Int32)), Is.EqualTo(C.DefaultLiteralConversion));
Assert.That(conversions.ImplicitConversion(defaultLiteral, compilation.FindType(KnownTypeCode.String)), Is.EqualTo(C.DefaultLiteralConversion));
Assert.That(conversions.ImplicitConversion(defaultLiteral, compilation.FindType(typeof(int?))), Is.EqualTo(C.DefaultLiteralConversion));
ITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, "T");
Assert.That(conversions.ImplicitConversion(defaultLiteral, t), Is.EqualTo(C.DefaultLiteralConversion));
// explicit conversions include all implicit conversions, so (T)default is also valid
Assert.That(conversions.ExplicitConversion(defaultLiteral, compilation.FindType(KnownTypeCode.Int32)), Is.EqualTo(C.DefaultLiteralConversion));
}

[Test, Ignore("C# standard 10.2.18 is not implemented: no ResolveResult represents a switch expression; the decompiler converts each arm separately in ILAst")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,82 @@ static void Main()
Issue2444.M2();
Issue2741.B.Test(new Issue2741.C());
ExtensionMethodDemo.Issue2165.Test();
#if CS71
DefaultLiteralTests();
#endif
}

#if CS71
static void DefaultLiteralTests()
{
// The decompiled output may shorten default(T) to a default literal;
// re-compilation must still pick the same overloads and operators.
DefaultOverload(default(DataStruct));
DefaultOverload(default(OtherStruct));
DefaultNullableOverload(default(DataStruct));
Console.WriteLine(default(DataStruct) == new DataStruct());
Console.WriteLine(GenericDefault("x", default));
Console.WriteLine(GenericDefault(42, default));
}

struct DataStruct
{
public int Field;

public static bool operator ==(DataStruct a, DataStruct b)
{
Console.WriteLine("DataStruct operator ==");
return a.Field == b.Field;
}

public static bool operator !=(DataStruct a, DataStruct b)
{
return a.Field != b.Field;
}

public override bool Equals(object obj)
{
return obj is DataStruct other && Field == other.Field;
}

public override int GetHashCode()
{
return Field;
}
}

struct OtherStruct
{
public int Field;
}

static void DefaultOverload(DataStruct data)
{
Console.WriteLine("DefaultOverload(DataStruct)");
}

static void DefaultOverload(OtherStruct data)
{
Console.WriteLine("DefaultOverload(OtherStruct)");
}

static void DefaultNullableOverload(DataStruct data)
{
Console.WriteLine("DefaultNullableOverload(DataStruct)");
}

static void DefaultNullableOverload(DataStruct? data)
{
Console.WriteLine("DefaultNullableOverload(DataStruct?)");
}

static T GenericDefault<T>(T a, T b)
{
Console.WriteLine("GenericDefault: " + typeof(T).Name);
return b;
}
#endif

#region ConstructorTest
static void ConstructorTest()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ internal class Issue2260
{
private void dgvItemList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
string text = default(string);
string s = default(string);
string text = default;
string s = default;
switch (text)
{
case "rowno":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class SpanConversionOperatorMismatch
{
public static implicit operator ReadOnlySpan<char>(object o)
{
return default(ReadOnlySpan<char>);
return default;
}

public static ReadOnlySpan<char> ConvertString(string s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ public class NestedAwaitable
{
public TaskAwaiter GetAwaiter()
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}
}
Expand All @@ -51,7 +55,7 @@ private sealed class AsyncDisposable : IAsyncDisposable
{
public ValueTask DisposeAsync()
{
return default(ValueTask);
return default;
}
}
#endif
Expand Down Expand Up @@ -247,7 +251,11 @@ public static class AwaiterExtensions
{
public static TaskAwaiter GetAwaiter(this IAwaitableMarker marker)
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}

public static TaskAwaiter GetAwaiter(this int millisecondsDelay)
Expand All @@ -257,12 +265,20 @@ public static TaskAwaiter GetAwaiter(this int millisecondsDelay)

public static TaskAwaiter GetAwaiter(this Action action)
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}

public static TaskAwaiter<T[]> GetAwaiter<T>(this IEnumerable<Task<T>> tasks)
{
#if CS71
return default;
#else
return default(TaskAwaiter<T[]>);
#endif
}

#if CS70 && !NET40
Expand Down Expand Up @@ -573,7 +589,11 @@ public struct ByRefReceiver

public TaskAwaiter Self()
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}
#endif
Expand All @@ -582,7 +602,11 @@ public class ClassAwaitable : IAwaitable
{
public TaskAwaiter GetAwaiter()
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}

Expand All @@ -609,7 +633,11 @@ public class ExplicitClassAwaitable : IAwaitable
{
TaskAwaiter IAwaitable.GetAwaiter()
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}

Expand All @@ -618,15 +646,23 @@ public struct ExplicitStructAwaitable : IAwaitable
{
TaskAwaiter IAwaitable.GetAwaiter()
{
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}

public class GenericAwaitable<T>
{
public TaskAwaiter<T> GetAwaiter()
{
#if CS71
return default;
#else
return default(TaskAwaiter<T>);
#endif
}
}

Expand Down Expand Up @@ -664,7 +700,11 @@ public struct StructAwaitable : IAwaitable
public TaskAwaiter GetAwaiter()
{
Counter++;
#if CS71
return default;
#else
return default(TaskAwaiter);
#endif
}
}
}
4 changes: 2 additions & 2 deletions ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncUsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ public static async void TestAsyncUsingClass()

public static async void TestAsyncUsingStruct()
{
await using (AsyncDisposableStruct asyncDisposableStruct = default(AsyncDisposableStruct))
await using (AsyncDisposableStruct asyncDisposableStruct = default)
{
Use(asyncDisposableStruct);
}
}

public static async void TestAsyncUsingNullableStruct()
{
await using (AsyncDisposableStruct? asyncDisposableStruct = new AsyncDisposableStruct?(default(AsyncDisposableStruct)))
await using (AsyncDisposableStruct? asyncDisposableStruct = default(AsyncDisposableStruct))
{
Use(asyncDisposableStruct);
}
Expand Down
Loading
Loading