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
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
Original file line number Diff line number Diff line change
Expand Up @@ -5024,7 +5024,11 @@ public static void CustomClassPreDecTest(CustomClass p, CustomClass c, CustomStr
}
public static void CustomStructAddTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p += default(CustomStruct);
num += default(CustomStruct);
Use(ref num);
Expand All @@ -5051,7 +5055,11 @@ public static void CustomStructAddTest(CustomStruct p, CustomClass c, CustomStru

public static void CustomStructSubtractTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p -= default(CustomStruct);
num -= default(CustomStruct);
Use(ref num);
Expand All @@ -5078,7 +5086,11 @@ public static void CustomStructSubtractTest(CustomStruct p, CustomClass c, Custo

public static void CustomStructMultiplyTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p *= default(CustomStruct);
num *= default(CustomStruct);
Use(ref num);
Expand All @@ -5105,7 +5117,11 @@ public static void CustomStructMultiplyTest(CustomStruct p, CustomClass c, Custo

public static void CustomStructDivideTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p /= default(CustomStruct);
num /= default(CustomStruct);
Use(ref num);
Expand All @@ -5132,7 +5148,11 @@ public static void CustomStructDivideTest(CustomStruct p, CustomClass c, CustomS

public static void CustomStructModulusTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p %= default(CustomStruct);
num %= default(CustomStruct);
Use(ref num);
Expand All @@ -5159,7 +5179,11 @@ public static void CustomStructModulusTest(CustomStruct p, CustomClass c, Custom

public static void CustomStructLeftShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p <<= 5;
num <<= 5;
Use(ref num);
Expand All @@ -5186,7 +5210,11 @@ public static void CustomStructLeftShiftTest(CustomStruct p, CustomClass c, Cust

public static void CustomStructRightShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p >>= 5;
num >>= 5;
Use(ref num);
Expand Down Expand Up @@ -5239,7 +5267,11 @@ public static void CustomStructUnsignedRightShiftTest(CustomStruct p, CustomClas

public static void CustomStructBitAndTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p &= default(CustomStruct);
num &= default(CustomStruct);
Use(ref num);
Expand All @@ -5266,7 +5298,11 @@ public static void CustomStructBitAndTest(CustomStruct p, CustomClass c, CustomS

public static void CustomStructBitOrTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p |= default(CustomStruct);
num |= default(CustomStruct);
Use(ref num);
Expand All @@ -5293,7 +5329,11 @@ public static void CustomStructBitOrTest(CustomStruct p, CustomClass c, CustomSt

public static void CustomStructBitXorTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
p ^= default(CustomStruct);
num ^= default(CustomStruct);
Use(ref num);
Expand All @@ -5320,7 +5360,11 @@ public static void CustomStructBitXorTest(CustomStruct p, CustomClass c, CustomS

public static void CustomStructPostIncTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
X(p++);
X(num++);
Use(ref num);
Expand All @@ -5347,7 +5391,11 @@ public static void CustomStructPostIncTest(CustomStruct p, CustomClass c, Custom

public static void CustomStructPreIncTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
X(++p);
X(++num);
Use(ref num);
Expand All @@ -5373,7 +5421,11 @@ public static void CustomStructPreIncTest(CustomStruct p, CustomClass c, CustomS
}
public static void CustomStructPostDecTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
X(p--);
X(num--);
Use(ref num);
Expand All @@ -5400,7 +5452,11 @@ public static void CustomStructPostDecTest(CustomStruct p, CustomClass c, Custom

public static void CustomStructPreDecTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
#if CS71
CustomStruct num = default;
#else
CustomStruct num = default(CustomStruct);
#endif
X(--p);
X(--num);
Use(ref num);
Expand Down
Loading
Loading