Skip to content

Commit 20ed3fd

Browse files
committed
Fix getting scope for type references
- Code to figure out scope has been improved so it doesn't rely solely on DeclaringType. Now performs a true check if the type is defined in the same assembly or not. - WriteItem now can handle nested types, by writting the full type name (this has to be processed accordingly in type resolution in nanoCLR). - Update class in test app to declare a local with an enum from amother assembly and an enum from another assembly declared as a nested type.
1 parent 0f2f1b7 commit 20ed3fd

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

MetadataProcessor.Shared/Tables/nanoTypeReferenceTable.cs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
// See LICENSE file in the project root for full license information.
55
//
66

7-
using Mono.Cecil;
7+
using System;
88
using System.Collections.Generic;
99
using System.Diagnostics;
10+
using Mono.Cecil;
1011

1112
namespace nanoFramework.Tools.MetadataProcessor
1213
{
@@ -69,7 +70,11 @@ protected override void WriteSingleItem(
6970
{
7071
var writerStartPosition = writer.BaseStream.Position;
7172

72-
WriteStringReference(writer, item.Name);
73+
74+
// Get the full name for nested types
75+
string fullName = nanoTypeReferenceTable.GetFullName(item);
76+
77+
WriteStringReference(writer, fullName);
7378
WriteStringReference(writer, item.Namespace);
7479

7580
writer.WriteUInt16(GetScope(item)); // scope - TBL_AssemblyRef | TBL_TypeRef // 0x8000
@@ -90,17 +95,45 @@ protected override void AllocateSingleItemStrings(
9095
internal ushort GetScope(
9196
TypeReference typeReference)
9297
{
93-
// TODO need to review this to use TypeRefOrAssemblyRef
94-
if (typeReference.DeclaringType == null)
98+
// Check if the type is defined in the same assembly
99+
if (typeReference.Scope is ModuleDefinition moduleDefinition
100+
&& moduleDefinition.Assembly == _context.AssemblyDefinition)
101+
{
102+
// The type is defined in the same assembly
103+
if (_context.TypeReferencesTable.TryGetTypeReferenceId(
104+
typeReference.DeclaringType,
105+
out ushort referenceId))
106+
{
107+
return (ushort)(0x8000 | referenceId);
108+
}
109+
else
110+
{
111+
// unknown scope
112+
throw new InvalidOperationException($"Unknown scope for type reference '{typeReference.FullName}'");
113+
}
114+
}
115+
else if (typeReference.Scope is AssemblyNameReference assemblyNameReference)
95116
{
96-
return _context.AssemblyReferenceTable.GetReferenceId(typeReference.Scope as AssemblyNameReference);
117+
// The type is defined in a referenced assembly
118+
return _context.AssemblyReferenceTable.GetReferenceId(assemblyNameReference);
97119
}
98120
else
99121
{
100-
ushort referenceId;
101-
_context.TypeReferencesTable.TryGetTypeReferenceId(typeReference.DeclaringType, out referenceId);
102-
return (ushort)(0x8000 | referenceId);
122+
// unknown scope
123+
throw new InvalidOperationException($"Unknown scope for type reference '{typeReference.FullName}'");
103124
}
125+
126+
}
127+
128+
private static string GetFullName(TypeReference typeReference)
129+
{
130+
if (typeReference.DeclaringType == null)
131+
{
132+
return typeReference.Name;
133+
}
134+
135+
// return the full name of the declaring type
136+
return typeReference.FullName;
104137
}
105138
}
106139
}

MetadataProcessor.Tests/TestNFApp/TestEnumInAnotherAssembly.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,23 @@ public class TestEnumInAnotherAssembly
1010
public void CallTestEnumInAnotherAssembly()
1111
{
1212
// This test checks if MDP can minimize the assembly using an enum that is defined in another assembly
13-
// and the class calling it is in a different assembly BUT in the same namespace.
14-
var ioException = new IOException(
13+
// as a nested type
14+
IOException.IOExceptionErrorCode dummyEnum = IOException.IOExceptionErrorCode.DirectoryNotFound;
15+
16+
_ = new IOException(
1517
string.Empty,
16-
(int)IOException.IOExceptionErrorCode.DirectoryNotFound);
18+
(int)dummyEnum);
19+
20+
// This test checks if MDP can minimize the assembly using an enum that is defined in another assembly
21+
Base64FormattingOptions formattingOptions = Base64FormattingOptions.InsertLineBreaks;
22+
23+
byte[] testBytes = new byte[] {0x01, 0x03, 0x05, 0x07, 0x09 };
24+
25+
_ = Convert.ToBase64String(
26+
testBytes,
27+
0,
28+
testBytes.Length,
29+
formattingOptions);
1730
}
1831
}
19-
2032
}

0 commit comments

Comments
 (0)