Skip to content

Commit fcab367

Browse files
authored
Method flags now processes finalizer (#169)
1 parent 6d968f8 commit fcab367

File tree

5 files changed

+235
-0
lines changed

5 files changed

+235
-0
lines changed

MetadataProcessor.Shared/Tables/nanoMethodDefinitionTable.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ public static uint GetFlags(MethodDefinition method)
242242
flag |= (method.IsStatic ? MD_StaticConstructor : MD_Constructor);
243243
}
244244

245+
if(method.Name == "Finalize"
246+
&& method.ReturnType.FullName == "System.Void"
247+
&& method.Parameters.Count == 0)
248+
{
249+
flag |= MD_Finalizer;
250+
}
251+
245252
if (method.IsSynchronized)
246253
{
247254
flag |= MD_Synchronized;

MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@
55

66
using Microsoft.VisualStudio.TestTools.UnitTesting;
77
using Mono.Cecil;
8+
using System.Linq;
89

910
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
1011
{
1112
[TestClass]
1213
public class nanoMethodDefinitionTableTests
1314
{
1415
private TypeDefinition _testDelegatesClassTypeDefinition;
16+
private TypeDefinition _destructorTestClassTypeDefinition;
17+
private TypeDefinition _destructorAnotherTestClassTypeDefinition;
18+
private TypeDefinition _destructorAnotherBaseClassTypeDefinition;
1519

1620
[TestInitialize]
1721
public void Setup()
1822
{
1923
var nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext();
2024
_testDelegatesClassTypeDefinition = TestObjectHelper.GetTestNFAppTestingDelegatesTypeDefinition(nanoTablesContext.AssemblyDefinition);
25+
_destructorTestClassTypeDefinition = TestObjectHelper.GetTestNFAppDestructorsTestClassTypeDefinition(nanoTablesContext.AssemblyDefinition);
26+
_destructorAnotherTestClassTypeDefinition = TestObjectHelper.GetTestNFAppDestructorsTestAnotherClassTypeDefinition(nanoTablesContext.AssemblyDefinition);
27+
_destructorAnotherBaseClassTypeDefinition = TestObjectHelper.GetTestNFAppDestructorsTestAnotherClassBaseTypeDefinition(nanoTablesContext.AssemblyDefinition);
2128
}
2229

2330
#region delegate method flags
@@ -75,5 +82,45 @@ public void TestDelegateEndInvokeMethodReturnsDelegateEndInvokeFlag()
7582
}
7683

7784
#endregion
85+
86+
#region finalizer method flags
87+
88+
[DataRow("DestructorsTestClass")]
89+
[DataRow("DestructorsTestAnotherClass")]
90+
[DataRow("DestructorsTestAnotherClassBase")]
91+
[TestMethod]
92+
public void TestFinalizerMethodReturnsFinalizerFlag(string className)
93+
{
94+
// Arrange
95+
MethodDefinition methodDefinition = null;
96+
97+
if (className == "DestructorsTestClass")
98+
{
99+
methodDefinition = _destructorTestClassTypeDefinition.Methods.First(m => m.Name == "Finalize");
100+
}
101+
else if (className == "DestructorsTestAnotherClass")
102+
{
103+
methodDefinition = _destructorAnotherTestClassTypeDefinition.Methods.First(m => m.Name == "Finalize");
104+
}
105+
else if (className == "DestructorsTestAnotherClassBase")
106+
{
107+
methodDefinition = _destructorAnotherBaseClassTypeDefinition.Methods.First(m => m.Name == "Finalize");
108+
}
109+
else
110+
{
111+
Assert.Fail("Invalid class name.");
112+
}
113+
114+
Assert.IsNotNull(methodDefinition, "Finalizer method not found.");
115+
116+
// Act
117+
uint flags = nanoMethodDefinitionTable.GetFlags(methodDefinition);
118+
119+
// Assert
120+
const uint expectedFlag = 0x00004000; // MD_Finalizer
121+
Assert.IsTrue((flags & expectedFlag) == expectedFlag, "Expected flag not set for Finalizer method.");
122+
}
123+
124+
#endregion
78125
}
79126
}

MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<Compile Include="OneClassOverAll.cs" />
3333
<Compile Include="Program.cs" />
3434
<Compile Include="Properties\AssemblyInfo.cs" />
35+
<Compile Include="TestingDestructors.cs" />
3536
<Compile Include="TestingDelegates.cs" />
3637
</ItemGroup>
3738
<ItemGroup>
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
8+
namespace TestNFApp
9+
{
10+
public class TestingDestructors
11+
{
12+
public TestingDestructors()
13+
{
14+
Console.WriteLine("Test Destructors class 3");
15+
16+
if (DestructorsTestClass.TestMethod())
17+
{
18+
Console.WriteLine("Test Destructors class 3 passed!");
19+
}
20+
else
21+
{
22+
Console.WriteLine("Test Destructors class 3 failed!");
23+
}
24+
25+
Console.WriteLine("Test Destructors class 4");
26+
if (DestructorsTestAnotherClass.TestMethod())
27+
{
28+
Console.WriteLine("Test Destructors class 4 passed!");
29+
}
30+
else
31+
{
32+
Console.WriteLine("Test Destructors class 4 failed!");
33+
}
34+
35+
Console.WriteLine("Test destructors completed!");
36+
}
37+
}
38+
39+
public class DestructorsTestClass
40+
{
41+
static int intI = 1;
42+
43+
~DestructorsTestClass()
44+
{
45+
// Calling Destructor for Test Class 3
46+
intI = 2;
47+
48+
Console.WriteLine("Calling Destructor for Test Class 3");
49+
}
50+
51+
public static bool TestMethod()
52+
{
53+
DestructorsTestClass mc = new DestructorsTestClass();
54+
mc = null;
55+
56+
// should be calling GC
57+
// nanoFramework.Runtime.Native.GC.Run(true);
58+
59+
int sleepTime = 5000;
60+
int slept = 0;
61+
62+
while (intI != 2 && slept < sleepTime)
63+
{
64+
System.Threading.Thread.Sleep(10);
65+
slept += 10;
66+
}
67+
68+
// Thread has slept for
69+
Console.WriteLine($"Thread has slept for {slept}");
70+
71+
if (intI == 2)
72+
{
73+
return true;
74+
}
75+
else
76+
{
77+
return false;
78+
}
79+
}
80+
}
81+
82+
public class DestructorsTestAnotherClassBase
83+
{
84+
public static int intI = 2;
85+
86+
~DestructorsTestAnotherClassBase()
87+
{
88+
intI = intI * 2;
89+
90+
Console.WriteLine("Calling Destructor for Test Class 4 Base");
91+
}
92+
}
93+
94+
public class DestructorsTestAnotherClass : DestructorsTestAnotherClassBase
95+
{
96+
~DestructorsTestAnotherClass()
97+
{
98+
intI = intI + 2;
99+
100+
Console.WriteLine("Calling Destructor for Test Class 4");
101+
}
102+
103+
public static bool TestMethod()
104+
{
105+
DestructorsTestAnotherClass mc = new DestructorsTestAnotherClass();
106+
107+
mc = null;
108+
109+
// should be calling GC
110+
// nanoFramework.Runtime.Native.GC.Run(true);
111+
112+
int sleepTime = 5000;
113+
int slept = 0;
114+
115+
while (intI != 8 && slept < sleepTime)
116+
{
117+
System.Threading.Thread.Sleep(10);
118+
slept += 10;
119+
}
120+
121+
Console.WriteLine($"Thread has slept for {slept}");
122+
123+
if (intI == 8)
124+
{
125+
return true;
126+
}
127+
else
128+
{
129+
return false;
130+
}
131+
}
132+
}
133+
}

MetadataProcessor.Tests/TestObjectHelper.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,46 @@ internal static TypeDefinition GetTestNFAppTestingDelegatesTypeDefinition(Assemb
385385
return ret;
386386
}
387387

388+
internal static TypeDefinition GetTestNFAppTestingDestructorsTypeDefinition(AssemblyDefinition assemblyDefinition)
389+
{
390+
TypeDefinition ret = null;
391+
392+
var module = assemblyDefinition.Modules[0];
393+
ret = module.Types.First(i => i.FullName == "TestNFApp.TestingDestructors");
394+
395+
return ret;
396+
}
397+
398+
internal static TypeDefinition GetTestNFAppDestructorsTestClassTypeDefinition(AssemblyDefinition assemblyDefinition)
399+
{
400+
TypeDefinition ret = null;
401+
402+
var module = assemblyDefinition.Modules[0];
403+
ret = module.Types.First(i => i.FullName == "TestNFApp.DestructorsTestClass");
404+
405+
return ret;
406+
}
407+
408+
internal static TypeDefinition GetTestNFAppDestructorsTestAnotherClassBaseTypeDefinition(AssemblyDefinition assemblyDefinition)
409+
{
410+
TypeDefinition ret = null;
411+
412+
var module = assemblyDefinition.Modules[0];
413+
ret = module.Types.First(i => i.FullName == "TestNFApp.DestructorsTestAnotherClassBase");
414+
415+
return ret;
416+
}
417+
418+
internal static TypeDefinition GetTestNFAppDestructorsTestAnotherClassTypeDefinition(AssemblyDefinition assemblyDefinition)
419+
{
420+
TypeDefinition ret = null;
421+
422+
var module = assemblyDefinition.Modules[0];
423+
ret = module.Types.First(i => i.FullName == "TestNFApp.DestructorsTestAnotherClass");
424+
425+
return ret;
426+
}
427+
388428
internal static MethodDefinition GetMethodDefinition(
389429
TypeDefinition typeDefinition,
390430
string delegateName,
@@ -393,5 +433,12 @@ internal static MethodDefinition GetMethodDefinition(
393433
var delegateType = typeDefinition.NestedTypes.First(nt => nt.Name == delegateName);
394434
return delegateType.Methods.First(m => m.Name == methodName);
395435
}
436+
437+
internal static MethodDefinition GetMethodDefinition(
438+
TypeDefinition typeDefinition,
439+
string methodName)
440+
{
441+
return typeDefinition.Methods.First(m => m.Name == methodName);
442+
}
396443
}
397444
}

0 commit comments

Comments
 (0)