Skip to content

Commit

Permalink
Merge pull request #252 from adrianoc/vnext
Browse files Browse the repository at this point in the history
August 2023 updates
  • Loading branch information
adrianoc authored Aug 18, 2023
2 parents 214eb89 + f5dfb34 commit 6e47175
Show file tree
Hide file tree
Showing 34 changed files with 1,043 additions and 316 deletions.
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion Cecilifier.Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>11</LangVersion>
<AssemblyVersion>2.4.1</AssemblyVersion>
<AssemblyVersion>2.5.0</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion Cecilifier.CommonPackages.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"><Version>4.6.0-1.final</Version></PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"><Version>4.7.0-2.final</Version></PackageReference>
<PackageReference Include="Mono.Cecil"><Version>0.11.5</Version></PackageReference>
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions Cecilifier.Core.Tests/Cecilifier.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Cecilifier.Core\Cecilifier.Core.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,30 @@ IL_0006: add
IL_0007: stloc V_0
IL_000b: ldloc V_0
IL_000f: ldc.i4 0
IL_0014: beq.s IL_0036
IL_0014: beq.s IL_0031
IL_0016: ldloc V_0
IL_001a: ldc.i4 1
IL_001f: beq.s IL_0036
IL_001f: beq.s IL_0031
IL_0021: ldloc V_0
IL_0025: ldc.i4 2
IL_002a: beq.s IL_004f
IL_002c: br IL_0057
IL_0031: br IL_0064
IL_0036: nop
IL_0037: ldarg.1
IL_0038: ldc.i4 2
IL_003d: add
IL_003e: call System.Void System.Console::WriteLine(System.Int32)
IL_0043: ldc.i4 2
IL_0048: starg.s 1
IL_004a: br IL_0064
IL_004f: nop
IL_0050: ldc.i4 1
IL_0055: neg
IL_0056: ret
IL_0057: nop
IL_0058: ldc.i4 3
IL_005d: starg.s 1
IL_005f: br IL_0064
IL_0064: nop
IL_0065: ldarg.1
IL_0066: ret
IL_002a: beq.s IL_004a
IL_002c: br IL_0052
IL_0031: nop
IL_0032: ldarg.1
IL_0033: ldc.i4 2
IL_0038: add
IL_0039: call System.Void System.Console::WriteLine(System.Int32)
IL_003e: ldc.i4 2
IL_0043: starg.s 1
IL_0045: br IL_005f
IL_004a: nop
IL_004b: ldc.i4 1
IL_0050: neg
IL_0051: ret
IL_0052: nop
IL_0053: ldc.i4 3
IL_0058: starg.s 1
IL_005a: br IL_005f
IL_005f: nop
IL_0060: ldarg.1
IL_0061: ret
30 changes: 30 additions & 0 deletions Cecilifier.Core.Tests/Tests/Unit/ArrayTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,34 @@ public void InitializationOptimized(string code)
\s+\4.Emit\(OpCodes.Ldtoken, \3\);
"""));
}

[TestCase("Property", "Call, m_get_2", TestName = "Property")]
[TestCase("Method()", "Call, m_method_8", TestName = "Method")]
[TestCase("Field", "Ldfld, fld_field_7", TestName = "Field")]
public void MemberAccessOnElementAccessOnValueTypeArray_LoadsElementAddress(string member, string expectedILMemberRef)
{
var result = RunCecilifier($$"""int M(S[] sa) => sa[0].{{member}}; struct S { public int Property { get; set; } public int Field; public int Method() => 1; }""");
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match($"""
(il_M_\d+\.Emit\(OpCodes\.)Ldarg_1\);
\s+\1Ldc_I4, 0\);
\s+\1Ldelema, st_S_0\);
\s+\1{expectedILMemberRef}\);
\s+\1Ret\);
"""));
}

[TestCase("Property", "Callvirt, m_get_2", TestName = "Property")]
[TestCase("Method()", "Callvirt, m_method_8", TestName = "Method")]
[TestCase("Field", "Ldfld, fld_field_7", TestName = "Field")]
public void MemberAccessOnElementAccessOnReferenceTypeArray_LoadsElementByReference(string member, string expectedILMemberRef)
{
var result = RunCecilifier($$"""int M(S[] sa) => sa[0].{{member}}; class S { public int Property { get; set; } public int Field; public int Method() => 1; }""");
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match($"""
(il_M_\d+\.Emit\(OpCodes\.)Ldarg_1\);
\s+\1Ldc_I4, 0\);
\s+\1Ldelem_Ref\);
\s+\1{expectedILMemberRef}\);
\s+\1Ret\);
"""));
}
}
28 changes: 28 additions & 0 deletions Cecilifier.Core.Tests/Tests/Unit/CastTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NUnit.Framework;

namespace Cecilifier.Core.Tests.Tests.Unit;

[TestFixture]
public class CastTests : CecilifierUnitTestBase
{
[Test]
public void Unbox()
{
var result = RunCecilifier("int UnboxIt(object o) => (int) o;");
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match("""
(il_unboxIt_\d+\.Emit\(OpCodes\.)Ldarg_1\);
\s+\1Unbox_Any, assembly.MainModule.TypeSystem.Int32\);
"""));
}

[TestCase("i", TestName = "Implicit boxing")]
[TestCase("(object) i", TestName = "Explicit boxing")]
public void Box(string expression)
{
var result = RunCecilifier($"object BoxIt(int i) => {expression};");
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match("""
(il_boxIt_\d+\.Emit\(OpCodes\.)Ldarg_1\);
\s+\1Box, assembly.MainModule.TypeSystem.Int32\);
"""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void SimpleStoreToOutStructParameter(string toStore)
Assert.That(result.GeneratedCode.ReadToEnd(), Contains.Substring(
@"il_M_3.Emit(OpCodes.Ldarg_1);
il_M_3.Emit(OpCodes.Ldarg_2);
il_M_3.Emit(OpCodes.Stobj);"));
il_M_3.Emit(OpCodes.Stobj, st_myStruct_0);"));
}

[Test]
Expand Down Expand Up @@ -62,18 +62,9 @@ public void ArrayElementAssignment(string arrayVariable)
result.GeneratedCode.ReadToEnd(), Does.Match(
@"il_M_4.Emit\(OpCodes.(?:Ldarg_1|Ldfld, fld_f_2)\);
il_M_4.Emit\(OpCodes.Ldc_I4, 1\);
il_M_4.Emit\(OpCodes.Ldelema\);
il_M_4.Emit\(OpCodes.Ldelema, st_myStruct_0\);
il_M_4.Emit\(OpCodes.Initobj, st_myStruct_0\);"));
}

[Test]
public void TestParameterlessStructInstantiation()
{
var result = RunCecilifier("struct Foo { static Foo Create() => new Foo(); public Foo() { } }");
var cecilifiedCode = result.GeneratedCode.ReadToEnd();

Assert.That(cecilifiedCode, Does.Match(@"il_create_2\.Emit\(OpCodes.Newobj, ctor_foo_3\);"));
}

[TestCaseSource(nameof(InvocationOnObjectCreationExpressionTestScenarios))]
public void InvocationOnObjectCreationExpression(string invocationStatement, string expectedILSnippet)
Expand Down Expand Up @@ -112,6 +103,42 @@ public Test(int i) {}
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match(expectedGeneratedSnippet));
}


[TestCase("var x = new S(); struct S {}",
"""
il_topLevelMain_4.Emit\(OpCodes.Ldloca_S, l_x_7\);
\s+il_topLevelMain_4.Emit\(OpCodes.Initobj, st_S_0\);
""",
TestName = "Implicit parameterless ctor")]

[TestCase("var x = new S(); struct S { public S() {} }",
"""
(il_topLevelMain_\d+.Emit\(OpCodes\.)Newobj, ctor_S_1\);
\s+\1Stloc, l_x_9\);
""",
TestName = "Explicit parameterless ctor")]

[TestCase("var x = new S(42, true); struct S { public S(int i, bool b) {} }",
"""
(il_topLevelMain_\d+.Emit\(OpCodes\.)Ldc_I4, 42\);
(\s+\1)Ldc_I4, 1\);
\2Newobj, ctor_S_1\);
""",
TestName = "Ctor with parameters")]

[TestCase("var x = new S(42, true); struct S { public S(int i, bool b) {} }",
"""
(il_topLevelMain_\d+.Emit\(OpCodes\.)Ldc_I4, 42\);
(\s+\1)Ldc_I4, 1\);
\2Newobj, ctor_S_1\);
""",
TestName = "Ctor with parameters")]
public void Instantiation_EmitsCorrectOpcode(string code, string expected)
{
var result = RunCecilifier(code);
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match(expected));
}

static TestCaseData[] InvocationExpressionAsParametersTestScenarios()
{
return new[]
Expand Down
2 changes: 1 addition & 1 deletion Cecilifier.Core.Tests/Tests/Unit/FieldsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void TestExternalFields()

[TestCase(
"class Foo { int Value; void M() => Value = 42; }",
"Append(ldarg_0_4);", // Load this
"Emit(OpCodes.Ldarg_0);", // Load this
"Emit(OpCodes.Ldc_I4, 42);", // Load 42
"Emit(OpCodes.Stfld, fld_value_1);", // Store in Value
TestName = "Implicit This")]
Expand Down
11 changes: 5 additions & 6 deletions Cecilifier.Core.Tests/Tests/Unit/GenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,10 @@ public void GenericParameter_IsUsed_InsteadOfTypeOf_Issue240()
"fieldIDisp = value",
"""
//fieldIDisp = value;
\s+var ldarg_0_\d+ = (il_test_\d+\.)Create\(OpCodes.Ldarg_0\);
\s+\1Append\(ldarg_0_\d+\);
(\s+\1Emit\(OpCodes\.)Ldarg_1\);
\2Box, gp_T_\d+\);
\2Stfld, fld_fieldIDisp_\d+\);
(\s+il_test_\d+\.Emit\(OpCodes\.)Ldarg_0\);
\1Ldarg_1\);
\1Box, gp_T_\d+\);
\1Stfld, fld_fieldIDisp_\d+\);
""")]

[TestCase(
Expand Down Expand Up @@ -320,7 +319,7 @@ public void GenericParameter_IsUsed_InsteadOfTypeOf_Issue240()
\1Ldstr, "Ola Mundo"\);
\1Call, \2\);
\1Stloc, l_o_\d+\);
""")]
""")]

[TestCase(
"""Foo f = new Foo(); object o; o = f.M<T>(value)""",
Expand Down
21 changes: 10 additions & 11 deletions Cecilifier.Core.Tests/Tests/Unit/Miscellaneous.Statements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,35 +113,34 @@ void M()
\s+//case 1: \(condition\)
\s+il_M_7.Emit\(OpCodes.Ldloc, l_switchCondition_13\);
\s+il_M_7.Emit\(OpCodes.Ldc_I4, 1\);
\s+il_M_7.Emit\(OpCodes.Beq_S, nop_15\);
\s+il_M_7.Emit\(OpCodes.Beq_S, lbl_caseCode_0_15\);
\s+//case 2: \(condition\)
\s+il_M_7.Emit\(OpCodes.Ldloc, l_switchCondition_13\);
\s+il_M_7.Emit\(OpCodes.Ldc_I4, 2\);
\s+il_M_7.Emit\(OpCodes.Beq_S, nop_16\);
\s+il_M_7.Emit\(OpCodes.Beq_S, lbl_caseCode_1_16\);
\s+il_M_7.Emit\(OpCodes.Br, lbl_caseCode_2_17\);
\s+il_M_7.Emit\(OpCodes.Br, nop_17\);
\s+il_M_7.Emit\(OpCodes.Br, nop_14\);
\s+//case 1: \(code\)
\s+il_M_7.Append\(nop_15\);
\s+il_M_7.Append\(lbl_caseCode_0_15\);
\s+il_M_7.Emit\(OpCodes.Ldstr, "C1"\);
\s+il_M_7.Emit\(OpCodes.Call, .+System.Console.+WriteLine.+\);
\s+il_M_7.Emit\(OpCodes.Br, nop_14\);
\s+il_M_7.Emit\(OpCodes.Br, lbl_endOfSwitch_14\);
\s+//case 2: \(code\)
\s+il_M_7.Append\(nop_16\);
\s+il_M_7.Append\(lbl_caseCode_1_16\);
\s+il_M_7.Emit\(OpCodes.Ldstr, "C2"\);
\s+il_M_7.Emit\(OpCodes.Call, .+System.Console.+WriteLine.+\);
\s+il_M_7.Emit\(OpCodes.Br, nop_14\);
\s+il_M_7.Emit\(OpCodes.Br, lbl_endOfSwitch_14\);
\s+//default: \(code\)
\s+il_M_7.Append\(nop_17\);
\s+il_M_7.Append\(lbl_caseCode_2_17\);
\s+il_M_7.Emit\(OpCodes.Ldstr, "CD"\);
\s+il_M_7.Emit\(OpCodes.Call, .+System.Console.+WriteLine.+\);
\s+il_M_7.Emit\(OpCodes.Br, nop_14\);
\s+il_M_7.Emit\(OpCodes.Br, lbl_endOfSwitch_14\);
\s+//End of switch
\s+il_M_7.Append\(nop_14\);
\s+il_M_7.Append\(lbl_endOfSwitch_14\);
"""));
}

Expand Down
11 changes: 5 additions & 6 deletions Cecilifier.Core.Tests/Tests/Unit/Miscellaneous.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,11 @@ public void TestCallerArgumentExpressionAttribute_InvalidParameterName(string de
[TestCase(
"C c = new() { Value = 42 }; class C { public int Value; }",
"""
(il_topLevelMain_\d+).Emit\(OpCodes.Newobj, ctor_C_\d+\);
\s+var (dup_\d+) = \1.Create\(OpCodes.Dup\);
\s+\1.Append\(\2\);
\s+\1.Emit\(OpCodes.Ldc_I4, 42\);
\s+\1.Emit\(OpCodes.Stfld, fld_value_\d+\);
\s+\1.Emit\(OpCodes.Stloc, l_c_\d+\);
(il_topLevelMain_\d+.Emit\(OpCodes\.)Newobj, ctor_C_\d+\);
\s+\1Dup\);
\s+\1Ldc_I4, 42\);
\s+\1Stfld, fld_value_\d+\);
\s+\1Stloc, l_c_\d+\);
""",
TestName = "Object Initializer")]
public void TestImplicitObjectCreation(string code, params string[] expectations)
Expand Down
Loading

0 comments on commit 6e47175

Please sign in to comment.