Browse Source

Fix #3383: more aggressively transform object initializers on structs

pull/3404/head
Siegfried Pammer 3 months ago
parent
commit
202c5e22e3
  1. 16
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/InitializerTests.cs
  2. 61
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs
  3. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

16
ICSharpCode.Decompiler.Tests/TestCases/Correctness/InitializerTests.cs

@ -318,14 +318,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -318,14 +318,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
};
}
public static void NotAStructInitializer_DefaultConstructor()
{
InitializerTests.StructData data = new InitializerTests.StructData();
data.Field = 1;
data.Property = 2;
InitializerTests.X(InitializerTests.Y(), data);
}
public static void StructInitializer_DefaultConstructor()
{
InitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData {
@ -334,14 +326,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -334,14 +326,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
});
}
public static void NotAStructInitializer_ExplicitConstructor()
{
InitializerTests.StructData data = new InitializerTests.StructData(0);
data.Field = 1;
data.Property = 2;
InitializerTests.X(InitializerTests.Y(), data);
}
public static void StructInitializer_ExplicitConstructor()
{
InitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData(0) {

61
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs

@ -247,6 +247,51 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests @@ -247,6 +247,51 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests
}
}
private class StructInitPropertiesTest
{
private class TypeA
{
public int A { get; set; }
public int B { get; set; }
}
private struct TypeB
{
public int A { get; set; }
public int B { get; set; }
}
private struct TypeC
{
public int A { get; init; }
public int B { get; init; }
}
private static TypeA TestA()
{
return new TypeA {
A = 1,
B = 2
};
}
private static TypeB TestB()
{
return new TypeB {
A = 1,
B = 2
};
}
private static TypeC TestC()
{
return new TypeC {
A = 1,
B = 2
};
}
}
#endif
#endregion
@ -928,14 +973,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests @@ -928,14 +973,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests
});
}
public static void NotAStructInitializer_DefaultConstructor()
{
StructData structData = default(StructData);
structData.Field = 1;
structData.Property = 2;
X(Y(), structData);
}
public static void StructInitializer_DefaultConstructor()
{
X(Y(), new StructData {
@ -956,14 +993,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests @@ -956,14 +993,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests
};
}
public static void NotAStructInitializer_ExplicitConstructor()
{
StructData structData = new StructData(0);
structData.Field = 1;
structData.Property = 2;
X(Y(), structData);
}
public static void StructInitializer_ExplicitConstructor()
{
X(Y(), new StructData(0) {

8
ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

@ -73,14 +73,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -73,14 +73,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
instType = newObjInst.Method.DeclaringType;
break;
case DefaultValue defaultVal:
if (defaultVal.ILStackWasEmpty && v.Kind == VariableKind.Local && !currentMethod.IsConstructor)
{
// on statement level (no other expressions on IL stack),
// prefer to keep local variables (but not stack slots),
// unless we are in a constructor (where inlining object initializers might be
// critical for the base ctor call)
return;
}
instType = defaultVal.Type;
break;
case Call c when c.Method.FullNameIs("System.Activator", "CreateInstance") && c.Method.TypeArguments.Count == 1:

Loading…
Cancel
Save