diff --git a/.runsettings b/.runsettings
new file mode 100644
index 00000000..fe2e508b
--- /dev/null
+++ b/.runsettings
@@ -0,0 +1,9 @@
+
+
+
+
+ 120000
+ net472
+ x64
+
+
\ No newline at end of file
diff --git a/MetadataProcessor.Console/Program.cs b/MetadataProcessor.Console/Program.cs
index 87d7c29a..3d4e121e 100644
--- a/MetadataProcessor.Console/Program.cs
+++ b/MetadataProcessor.Console/Program.cs
@@ -1,18 +1,14 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Mono.Cecil;
-using nanoFramework.Tools.MetadataProcessor.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
-using System.Reflection;
using System.Xml;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core;
namespace nanoFramework.Tools.MetadataProcessor.Console
{
@@ -93,10 +89,7 @@ public void Compile(
_assemblyBuilder.Write(GetBinaryWriter(writer));
}
- using (var writer = XmlWriter.Create(Path.ChangeExtension(fileName, "pdbx")))
- {
- _assemblyBuilder.Write(writer);
- }
+ _assemblyBuilder.Write(Path.ChangeExtension(fileName, "pdbx"));
if (DumpMetadata)
{
@@ -188,7 +181,7 @@ public void GenerateDependency(string fileName)
public static void Main(string[] args)
{
- FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
+ FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
bool isCoreLibrary = false;
diff --git a/MetadataProcessor.Console/Properties/AssemblyInfo.cs b/MetadataProcessor.Console/Properties/AssemblyInfo.cs
index 90979639..f363be35 100644
--- a/MetadataProcessor.Console/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Console/Properties/AssemblyInfo.cs
@@ -1,10 +1,12 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
-[assembly: AssemblyTitle ("nanoFramework.MetadataProcessor.Console")]
+[assembly: AssemblyTitle("nanoFramework.MetadataProcessor.Console")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("nanoFramework project contributors")]
diff --git a/MetadataProcessor.Core/MetadataProcessor.Core.csproj b/MetadataProcessor.Core/MetadataProcessor.Core.csproj
index 01d934d4..c93da7b0 100644
--- a/MetadataProcessor.Core/MetadataProcessor.Core.csproj
+++ b/MetadataProcessor.Core/MetadataProcessor.Core.csproj
@@ -59,6 +59,16 @@
+
+ 8.0.0
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ 8.0.0
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
8.0.0
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -75,6 +85,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ 8.0.5
+
diff --git a/MetadataProcessor.Core/Properties/AssemblyInfo.cs b/MetadataProcessor.Core/Properties/AssemblyInfo.cs
index 7a7628c6..e447b7b5 100644
--- a/MetadataProcessor.Core/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Core/Properties/AssemblyInfo.cs
@@ -1,13 +1,16 @@
-using System.Reflection;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
-[assembly: AssemblyTitle ("nanoFramework.MetadataProcessor.Core")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("nanoFramework project contributors")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("Copyright (c) 2019 The nanoFramework project contributors")]
+[assembly: AssemblyTitle("nanoFramework.MetadataProcessor.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("nanoFramework project contributors")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Copyright (c) 2019 The nanoFramework project contributors")]
-[assembly: InternalsVisibleTo("nanoFramework.Tools.MetadataProcessor.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010035b49090a010c2970b2f8df8f66ad47a09583d654c0f2375980cf4afcfb48141ec9fd27d464b93a3216545588a5119d779c0ec66eed7c715567c2315cb908f70403b3bb59018b34096ad29c1c91f8d3c83ad407052ead9112e694660dec0ce7a361bff67781cf041e19d78afd128603dd188eb238186ac5aa6caf418891d5bb2")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("nanoFramework.Tools.MetadataProcessor.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001001120aa3e809b3da4f65e1b1f65c0a3a1bf6335c39860ca41acb3c48de278c6b63c5df38239ec1f2e32d58cb897c8c174a5f8e78a9c0b6087d3aef373d7d0f3d9be67700fc2a5a38de1fb71b5b6f6046d841ff35abee2e0b0840a6291a312be184eb311baff5fef0ff6895b9a5f2253aed32fb06b819134f6bb9d531488a87ea2")]
\ No newline at end of file
diff --git a/MetadataProcessor.Core/key.snk b/MetadataProcessor.Core/key.snk
index bf5ef8f7..67c9bb0a 100644
Binary files a/MetadataProcessor.Core/key.snk and b/MetadataProcessor.Core/key.snk differ
diff --git a/MetadataProcessor.Core/packages.lock.json b/MetadataProcessor.Core/packages.lock.json
index 6753ecc4..1081cf76 100644
--- a/MetadataProcessor.Core/packages.lock.json
+++ b/MetadataProcessor.Core/packages.lock.json
@@ -2,6 +2,18 @@
"version": 1,
"dependencies": {
".NETFramework,Version=v4.7.2": {
+ "Microsoft.Build.Tasks.Git": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
+ },
+ "Microsoft.SourceLink.Common": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
+ },
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -30,15 +42,76 @@
"resolved": "3.7.115",
"contentHash": "EpXamaAdRfG/BMxGgvZlTM0npRnkmXUjAj8OdNKd17t4oN+2nvjdv/KnFmzOOMDqvlwB49UCwtOHJrAQTfUBtQ=="
},
- "Microsoft.Build.Tasks.Git": {
+ "System.Text.Json": {
+ "type": "Direct",
+ "requested": "[8.0.5, )",
+ "resolved": "8.0.5",
+ "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "8.0.0",
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+ "System.Text.Encodings.Web": "8.0.0",
+ "System.Threading.Tasks.Extensions": "4.5.4",
+ "System.ValueTuple": "4.5.0"
+ }
+ },
+ "Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "8.0.0",
- "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
+ "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
},
- "Microsoft.SourceLink.Common": {
+ "System.Buffers": {
+ "type": "Transitive",
+ "resolved": "4.5.1",
+ "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
+ },
+ "System.Memory": {
+ "type": "Transitive",
+ "resolved": "4.5.5",
+ "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ },
+ "System.Numerics.Vectors": {
+ "type": "Transitive",
+ "resolved": "4.5.0",
+ "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
+ },
+ "System.Runtime.CompilerServices.Unsafe": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
+ },
+ "System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
- "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
+ "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+ }
+ },
+ "System.Threading.Tasks.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.5.4",
+ "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ },
+ "System.ValueTuple": {
+ "type": "Transitive",
+ "resolved": "4.5.0",
+ "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ=="
}
},
".NETFramework,Version=v4.7.2/win": {},
diff --git a/MetadataProcessor.MsBuildTask/MetaDataProcessorTask.cs b/MetadataProcessor.MsBuildTask/MetaDataProcessorTask.cs
index 2109dc6e..a458b085 100644
--- a/MetadataProcessor.MsBuildTask/MetaDataProcessorTask.cs
+++ b/MetadataProcessor.MsBuildTask/MetaDataProcessorTask.cs
@@ -1,20 +1,17 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// Portions Copyright (c) Microsoft Corporation. All rights reserved.
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-using System.ComponentModel;
using System;
+using System.Collections.Generic;
+using System.ComponentModel;
using System.IO;
using System.Linq;
-using System.Collections.Generic;
-using nanoFramework.Tools.Utilities;
using System.Xml;
-using nanoFramework.Tools.MetadataProcessor.Core;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core;
+using nanoFramework.Tools.Utilities;
namespace nanoFramework.Tools.MetadataProcessor.MsBuildTask
{
@@ -126,7 +123,7 @@ public override bool Execute()
// developer note: to debug this task set an environment variable like this:
// set NFBUILD_TASKS_DEBUG=1
// this will cause the execution to pause bellow so a debugger can be attached
- DebuggerHelper.WaitForDebuggerIfEnabled(TasksConstants.BuildTaskDebugVar);
+ DebuggerHelper.WaitForDebuggerIfEnabled(TasksConstants.BuildTaskDebugVar, Log);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
try
@@ -298,6 +295,26 @@ private void ExecuteParse(
private void ExecuteCompile(
string fileName)
{
+ FileStream logOutputStream = null;
+ StreamWriter logWriter = null;
+ string logFile = "";
+
+ try
+ {
+ if (Verbose)
+ {
+ logFile = Path.ChangeExtension(fileName, "log.txt");
+
+ logOutputStream = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.Write);
+ logWriter = new StreamWriter(logOutputStream);
+ Console.SetOut(logWriter);
+ }
+ }
+ catch
+ {
+ Log.LogError($"Unable to create log file '{logFile}'.");
+ }
+
try
{
// compile assembly (1st pass)
@@ -319,6 +336,12 @@ private void ExecuteCompile(
{
Log.LogError($"Unable to compile output assembly file '{fileName}' - check parse command results");
+ if (Verbose)
+ {
+ logWriter?.Close();
+ logOutputStream?.Close();
+ }
+
throw;
}
@@ -342,10 +365,7 @@ private void ExecuteCompile(
}
// output PDBX
- using (var writer = XmlWriter.Create(Path.ChangeExtension(fileName, "pdbx")))
- {
- _assemblyBuilder.Write(writer);
- }
+ _assemblyBuilder.Write(Path.ChangeExtension(fileName, "pdbx"));
// output assembly metadata
if (DumpMetadata)
@@ -375,6 +395,14 @@ private void ExecuteCompile(
Log.LogError($"Exception minimizing assembly");
throw;
}
+ finally
+ {
+ if (Verbose)
+ {
+ logWriter?.Close();
+ logOutputStream?.Close();
+ }
+ }
}
private void AddClassToExclude(
diff --git a/MetadataProcessor.MsBuildTask/MetadataProcessor.MsBuildTask.csproj b/MetadataProcessor.MsBuildTask/MetadataProcessor.MsBuildTask.csproj
index ea5599c8..3ad7a915 100644
--- a/MetadataProcessor.MsBuildTask/MetadataProcessor.MsBuildTask.csproj
+++ b/MetadataProcessor.MsBuildTask/MetadataProcessor.MsBuildTask.csproj
@@ -15,6 +15,8 @@
git
nf-logo.png
LICENSE.md
+ true
+ true
@@ -61,7 +63,8 @@
-
+
+
diff --git a/MetadataProcessor.MsBuildTask/TasksConstants.cs b/MetadataProcessor.MsBuildTask/TasksConstants.cs
index 3dc34158..85094792 100644
--- a/MetadataProcessor.MsBuildTask/TasksConstants.cs
+++ b/MetadataProcessor.MsBuildTask/TasksConstants.cs
@@ -1,13 +1,10 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// Portions Copyright (c) Microsoft Corporation. All rights reserved.
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools
{
internal class TasksConstants
{
- public const string BuildTaskDebugVar = "NFBUILD_TASKS_DEBUG";
+ public const string BuildTaskDebugVar = "NF_MDP_MSBUILD_TASK_DEBUG";
}
}
diff --git a/MetadataProcessor.MsBuildTask/Utilities/DebuggerHelper.cs b/MetadataProcessor.MsBuildTask/Utilities/DebuggerHelper.cs
index 8e58c240..72217024 100644
--- a/MetadataProcessor.MsBuildTask/Utilities/DebuggerHelper.cs
+++ b/MetadataProcessor.MsBuildTask/Utilities/DebuggerHelper.cs
@@ -1,18 +1,17 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// Portions Copyright (c) Microsoft Corporation. All rights reserved.
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.Threading;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
namespace nanoFramework.Tools.Utilities
{
internal static class DebuggerHelper
{
- public static void WaitForDebuggerIfEnabled(string varName, int timeoutSeconds = 30)
+ public static void WaitForDebuggerIfEnabled(string varName, TaskLoggingHelper logger, int timeoutSeconds = 30)
{
// this wait should be only available on debug build
// to prevent unwanted wait on VS in machines where the variable is present
@@ -21,20 +20,19 @@ public static void WaitForDebuggerIfEnabled(string varName, int timeoutSeconds =
var isToEnablePauseForDebug = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User);
- if (!string.IsNullOrEmpty(isToEnablePauseForDebug)
+ if (!string.IsNullOrEmpty(isToEnablePauseForDebug)
&& isToEnablePauseForDebug.Equals("1", StringComparison.Ordinal))
{
- // output helper messsage to console, hopefully to be read by a human
- Console.WriteLine($".NET nanoFramework Metadata Processor msbuild task debugging is enabled. Waiting {timeoutSeconds} seconds for debugger to attach...");
-
var currentProcessId = Process.GetCurrentProcess().Id;
var currentProcessName = Process.GetProcessById(currentProcessId).ProcessName;
- Console.WriteLine(
- string.Format("Process Id: {0}, Name: {1}", currentProcessId, currentProcessName)
- );
+
+ // output helper message to console, hopefully to be read by a human
+ Console.WriteLine($".NET nanoFramework Metadata Processor msbuild task debugging is enabled. Waiting {timeoutSeconds} seconds for debugger to attach on Process Id: {currentProcessId} Name: {currentProcessName}...");
+
+ logger.LogMessage(MessageImportance.Normal, $"Debugging of .NET nanoFramework Metadata Processor msbuild task is enabled. Waiting {timeoutSeconds} seconds for debugger attachment on Process Id: {currentProcessId} Name: {currentProcessName}...");
// wait N seconds for debugger to attach
- while (!Debugger.IsAttached
+ while (!Debugger.IsAttached
&& timeoutToWaitForDebugToAttach.TotalSeconds > 0)
{
Thread.Sleep(1000);
diff --git a/MetadataProcessor.Shared/DumpGenerator/AssemblyRef.cs b/MetadataProcessor.Shared/DumpGenerator/AssemblyRef.cs
index a0f8da81..6a0c801d 100644
--- a/MetadataProcessor.Shared/DumpGenerator/AssemblyRef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/AssemblyRef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/AttFixedArgs.cs b/MetadataProcessor.Shared/DumpGenerator/AttFixedArgs.cs
index d3e2fd65..d819fa6e 100644
--- a/MetadataProcessor.Shared/DumpGenerator/AttFixedArgs.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/AttFixedArgs.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/AttributeCustom.cs b/MetadataProcessor.Shared/DumpGenerator/AttributeCustom.cs
index 8113a0ee..a70e7470 100644
--- a/MetadataProcessor.Shared/DumpGenerator/AttributeCustom.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/AttributeCustom.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -15,6 +13,6 @@ public class AttributeCustom
public string TypeToken;
- public List FixedArgs = new List();
+ public List FixedArgs = new List();
}
}
diff --git a/MetadataProcessor.Shared/DumpGenerator/DumpAllTable.cs b/MetadataProcessor.Shared/DumpGenerator/DumpAllTable.cs
index 2557ac52..0969a994 100644
--- a/MetadataProcessor.Shared/DumpGenerator/DumpAllTable.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/DumpAllTable.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -12,9 +10,12 @@ public class DumpAllTable
public List AssemblyReferences = new List();
public List TypeReferences = new List();
public List TypeDefinitions = new List();
+ public List TypeSpecifications = new List();
public List MethodDefinitions = new List();
public List InterfaceDefinitions = new List();
public List Attributes = new List();
+ public List StringHeap = new List();
public List UserStrings = new List();
+ public List GenericParams = new List();
}
}
diff --git a/MetadataProcessor.Shared/DumpGenerator/DumpTemplates.cs b/MetadataProcessor.Shared/DumpGenerator/DumpTemplates.cs
index cbbc4401..b8c72e3f 100644
--- a/MetadataProcessor.Shared/DumpGenerator/DumpTemplates.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/DumpTemplates.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -9,30 +7,58 @@ internal partial class DumpTemplates
{
internal const string DumpAllTemplate =
@"{{#each AssemblyReferences}}
-AssemblyRefProps [{{ReferenceId}}]: Flags: {{Flags}} '{{Name}}'{{#newline}}
+AssemblyRef {{ReferenceId}}{{#newline}}
+-------------------------------------------------------{{#newline}}
+'{{Name}}'{{#newline}}
+ Flags: {{Flags}}{{#newline}}
+{{#newline}}
{{/each}}
-{{#if AssemblyReferences}}{{#newline}}{{/if}}
{{#each TypeReferences}}
-TypeRefProps [{{ReferenceId}}]: Scope: {{Scope}} '{{Name}}'{{#newline}}
+TypeRef {{ReferenceId}}{{#newline}}
+-------------------------------------------------------{{#newline}}
+Scope: {{Scope}}{{#newline}}
+ '{{Name}}'{{#newline}}
{{#each MemberReferences}}
- MemberRefProps [{{ReferenceId}}]: '{{Name}}' [{{Signature}}]{{#newline}}
+ MemberRef {{ReferenceId}}{{#newline}}
+ -------------------------------------------------------{{#newline}}
+ '{{Name}}'{{#newline}}
+ [{{Signature}}]{{#newline}}
{{/each}}
+{{#newline}}
{{/each}}
-{{#if TypeReferences}}{{#newline}}{{/if}}
{{#each TypeDefinitions}}
-TypeDefProps [{{ReferenceId}}]: Flags: {{Flags}} Extends: {{ExtendsType}} Enclosed: {{EnclosedType}} '{{Name}}'{{#newline}}
+TypeDef {{ReferenceId}}{{#newline}}
+-------------------------------------------------------{{#newline}}
+ '{{Name}}'{{#newline}}
+ Flags: {{Flags}}{{#newline}}
+ Extends: {{ExtendsType}}{{#newline}}
+ Enclosed: {{EnclosedType}}{{#newline}}
+{{#if GenericParameters}}
+ Generic Parameters{{#newline}}
{{#each GenericParameters}}
- GenericParam [{{GenericParamToken}}]: Position: ({{Position}}) '{{Name}}' Owner: {{Owner}} [{{Signature}}]{{#newline}}
+ ({{Position}}) GenericParamToken {{GenericParamToken}} '{{Name}}' Owner: {{Owner}} [{{Signature}}]{{#newline}}
{{/each}}
+{{/if}}
{{#each FieldDefinitions}}
- FieldDefProps [{{ReferenceId}}]: Attr: {{Attributes}} Flags: {{Flags}} '{{Name}}' [{{Signature}}]{{#newline}}
+ FieldDef {{ReferenceId}}{{#newline}}
+ -------------------------------------------------------{{#newline}}
+ Attr: {{Attributes}}{{#newline}}
+ Flags: {{Flags}}{{#newline}}
+ '{{Name}}'{{#newline}}
+ [{{Signature}}]{{#newline}}
{{/each}}
{{#each MethodDefinitions}}
- MethodDefProps [{{ReferenceId}}]: Flags: {{Flags}} Impl: {{Implementation}} RVA: {{RVA}} '{{Name}}' [{{Signature}}]{{#newline}}
+ MethodDef {{ReferenceId}}{{#newline}}
+ -------------------------------------------------------{{#newline}}
+ '{{Name}}'{{#newline}}
+ Flags: {{Flags}}{{#newline}}
+ Impl: {{Implementation}}{{#newline}}
+ RVA: {{RVA}}{{#newline}}
+ [{{Signature}}]{{#newline}}
{{#if Locals}}
Locals {{Locals}}{{#newline}}
{{/if}}
@@ -43,28 +69,64 @@ internal partial class DumpTemplates
IL count: {{ILCodeInstructionsCount}}{{#newline}}
{{/if}}
{{#each ILCode}}
- {{IL}}{{#newline}}
+ {{IL}}{{#newline}}
{{/each}}
{{/each}}
{{#each InterfaceDefinitions}}
- InterfaceImplProps [{{ReferenceId}}]: Itf: {{Interface}}{{#newline}}
+ InterfaceImpl {{ReferenceId}} Itf: {{Interface}}{{#newline}}
+ -------------------------------------------------------{{#newline}}
{{/each}}
+{{#newline}}
{{/each}}
-{{#if TypeDefinitions}}{{#newline}}{{/if}}
+
+{{#each TypeSpecifications}}
+TypeSpec {{ReferenceId}}{{#newline}}
+-------------------------------------------------------{{#newline}}
+ '{{Name}}'{{#newline}}
+{{#each MemberReferences}}
+ MemberRef {{ReferenceId}}{{#newline}}
+ -------------------------------------------------------{{#newline}}
+ '{{Name}}'{{#newline}}
+ {{Signature}}{{#newline}}
+
+{{#if Arguments}}
+ Argument: {{Arguments}}{{#newline}}
+{{/else}}
+ No arguments
+{{/if}}
+{{/each}}
+{{#newline}}
+{{/each}}
+
+Generic Parameters{{#newline}}
+-------------------------------------------------------{{#newline}}
+{{#each GenericParams}}
+{{Position}} {{Name}} {{Owner}}{{#newline}}
+{{/each}}
+{{#newline}}
{{#each Attributes}}
Attribute: {{Name}}::[{{ReferenceId}} {{TypeToken}}]{{#newline}}
+-------------------------------------------------------{{#newline}}
{{#if FixedArgs}}Fixed Arguments:{{#newline}}{{#else}}{{#newline}}{{/if}}
{{#each FixedArgs}}
{{Options}} {{Numeric}}{{Text}}{{#newline}}
+{{/each}}
{{#newline}}
{{/each}}
+
+String Heap{{#newline}}
+-------------------------------------------------------{{#newline}}
+{{#each StringHeap}}
+{{ReferenceId}}: {{Content}}{{#newline}}
{{/each}}
-{{#if Attributes}}{{#newline}}{{/if}}
+{{#newline}}
+User Strings{{#newline}}
+-------------------------------------------------------{{#newline}}
{{#each UserStrings}}
-UserString [{{ReferenceId}}]: '{{Content}}'{{#newline}}
+{{ReferenceId}} : ({{Length}}) ""{{Content}}""{{#newline}}
{{/each}}
";
}
diff --git a/MetadataProcessor.Shared/DumpGenerator/ExceptionHandler.cs b/MetadataProcessor.Shared/DumpGenerator/ExceptionHandler.cs
index 1b798ef8..979a98c2 100644
--- a/MetadataProcessor.Shared/DumpGenerator/ExceptionHandler.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/ExceptionHandler.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/FieldDef.cs b/MetadataProcessor.Shared/DumpGenerator/FieldDef.cs
index dd14c1c9..0998e769 100644
--- a/MetadataProcessor.Shared/DumpGenerator/FieldDef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/FieldDef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/GenericParam.cs b/MetadataProcessor.Shared/DumpGenerator/GenericParam.cs
index 010876ce..d8a5a3e4 100644
--- a/MetadataProcessor.Shared/DumpGenerator/GenericParam.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/GenericParam.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/HeapString.cs b/MetadataProcessor.Shared/DumpGenerator/HeapString.cs
new file mode 100644
index 00000000..76c0a916
--- /dev/null
+++ b/MetadataProcessor.Shared/DumpGenerator/HeapString.cs
@@ -0,0 +1,12 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace nanoFramework.Tools.MetadataProcessor.Core
+{
+ public class HeapString
+ {
+ public string ReferenceId;
+
+ public string Content;
+ }
+}
diff --git a/MetadataProcessor.Shared/DumpGenerator/ILCode.cs b/MetadataProcessor.Shared/DumpGenerator/ILCode.cs
index a2b958b8..200bea4e 100644
--- a/MetadataProcessor.Shared/DumpGenerator/ILCode.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/ILCode.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/InterfaceDef.cs b/MetadataProcessor.Shared/DumpGenerator/InterfaceDef.cs
index e2594158..720352bf 100644
--- a/MetadataProcessor.Shared/DumpGenerator/InterfaceDef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/InterfaceDef.cs
@@ -1,9 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
-
-using System.Collections.Generic;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/LocalDef.cs b/MetadataProcessor.Shared/DumpGenerator/LocalDef.cs
index 23059d26..be9509ca 100644
--- a/MetadataProcessor.Shared/DumpGenerator/LocalDef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/LocalDef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/DumpGenerator/MemberRef.cs b/MetadataProcessor.Shared/DumpGenerator/MemberRef.cs
index b3837a71..a03eaf92 100644
--- a/MetadataProcessor.Shared/DumpGenerator/MemberRef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/MemberRef.cs
@@ -1,7 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
namespace nanoFramework.Tools.MetadataProcessor.Core
{
@@ -12,5 +12,7 @@ public class MemberRef
public string Name;
public string Signature;
+
+ public List Arguments;
}
}
diff --git a/MetadataProcessor.Shared/DumpGenerator/MethodDef.cs b/MetadataProcessor.Shared/DumpGenerator/MethodDef.cs
index 8426a9ff..9cc1c426 100644
--- a/MetadataProcessor.Shared/DumpGenerator/MethodDef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/MethodDef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/DumpGenerator/TypeDef.cs b/MetadataProcessor.Shared/DumpGenerator/TypeDef.cs
index 51b42990..f4e8a42e 100644
--- a/MetadataProcessor.Shared/DumpGenerator/TypeDef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/TypeDef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/DumpGenerator/TypeRef.cs b/MetadataProcessor.Shared/DumpGenerator/TypeRef.cs
index 1112fa4b..cede04b3 100644
--- a/MetadataProcessor.Shared/DumpGenerator/TypeRef.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/TypeRef.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/DumpGenerator/TypeSpec.cs b/MetadataProcessor.Shared/DumpGenerator/TypeSpec.cs
new file mode 100644
index 00000000..aee64d51
--- /dev/null
+++ b/MetadataProcessor.Shared/DumpGenerator/TypeSpec.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core
+{
+ public class TypeSpec
+ {
+ public string ReferenceId;
+
+ public string Name;
+
+ public List MemberReferences = new List();
+ }
+}
diff --git a/MetadataProcessor.Shared/DumpGenerator/UserString.cs b/MetadataProcessor.Shared/DumpGenerator/UserString.cs
index 68f132d6..f2edc668 100644
--- a/MetadataProcessor.Shared/DumpGenerator/UserString.cs
+++ b/MetadataProcessor.Shared/DumpGenerator/UserString.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor.Core
{
@@ -9,6 +7,8 @@ public class UserString
{
public string ReferenceId;
+ public string Length;
+
public string Content;
}
}
diff --git a/MetadataProcessor.Shared/Endianness/nanoBinaryWriter.cs b/MetadataProcessor.Shared/Endianness/nanoBinaryWriter.cs
index 2fb2fe27..f22cfb74 100644
--- a/MetadataProcessor.Shared/Endianness/nanoBinaryWriter.cs
+++ b/MetadataProcessor.Shared/Endianness/nanoBinaryWriter.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System;
using System.IO;
@@ -311,12 +310,12 @@ public void WriteInt64(long value)
///
/// Write metadata token in packed format (variable length).
///
- /// Metadata tocken in .NET Mico Framework format.
+ /// Metadata token in .NET nanoFramework format.
public void WriteMetadataToken(uint value)
{
if (value <= 0x7F)
{
- WriteByte((byte) value);
+ WriteByte((byte)value);
}
else if (value <= 0x3FFF)
{
diff --git a/MetadataProcessor.Shared/Extensions/ByteArrayExtensions.cs b/MetadataProcessor.Shared/Extensions/ByteArrayExtensions.cs
index 68788fae..e68f9457 100644
--- a/MetadataProcessor.Shared/Extensions/ByteArrayExtensions.cs
+++ b/MetadataProcessor.Shared/Extensions/ByteArrayExtensions.cs
@@ -1,11 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Mono.Cecil;
using System.Text;
-using System.Linq;
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
{
@@ -15,7 +11,7 @@ public static string BufferToHexString(this byte[] buffer)
{
StringBuilder output = new StringBuilder();
- foreach(byte b in buffer)
+ foreach (byte b in buffer)
{
output.Append(b.ToString("X2"));
}
diff --git a/MetadataProcessor.Shared/Extensions/ClrTableExtensions.cs b/MetadataProcessor.Shared/Extensions/ClrTableExtensions.cs
new file mode 100644
index 00000000..99a54a38
--- /dev/null
+++ b/MetadataProcessor.Shared/Extensions/ClrTableExtensions.cs
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
+{
+ internal static class ClrTableExtensions
+ {
+ public static uint ToNanoTokenType(this NanoClrTable value)
+ {
+ return ((uint)value << 24);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Extensions/IGenericParameterProviderExtensions.cs b/MetadataProcessor.Shared/Extensions/IGenericParameterProviderExtensions.cs
new file mode 100644
index 00000000..3f326ce7
--- /dev/null
+++ b/MetadataProcessor.Shared/Extensions/IGenericParameterProviderExtensions.cs
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
+{
+ internal static class IGenericParameterProviderExtensions
+ {
+ public static ushort ToEncodedNanoTypeOrMethodDefToken(this IGenericParameterProvider value)
+ {
+ // implements .NET nanoFramework encoding for MethodToken
+ // encodes Method to be decoded with CLR_UncompressTypeOrMethodDefToken
+ // CLR tables are
+ // 0: TBL_TypeDef
+ // 1: TBL_MethodDef
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoTypeOrMethodDefTokenTables);
+ }
+
+ public static NanoClrTable ToNanoCLRTable(this IGenericParameterProvider value)
+ {
+ if (value is TypeDefinition)
+ {
+ return NanoClrTable.TBL_TypeDef;
+ }
+ else if (value is MethodDefinition)
+ {
+ return NanoClrTable.TBL_MethodDef;
+ }
+ else
+ {
+ throw new ArgumentException("Unknown conversion to CLR Table.");
+ }
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Extensions/MemberReferenceExtensions.cs b/MetadataProcessor.Shared/Extensions/MemberReferenceExtensions.cs
new file mode 100644
index 00000000..3754d86c
--- /dev/null
+++ b/MetadataProcessor.Shared/Extensions/MemberReferenceExtensions.cs
@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
+{
+ internal static class MemberReferenceExtensions
+ {
+ public static ushort ToEncodedNanoMethodToken(this MemberReference value)
+ {
+ // implements .NET nanoFramework encoding for MethodToken
+ // encodes Method to be decoded with CLR_UncompressMethodToken
+ // CLR tables are
+ // 0: TBL_MethodDef
+ // 1: TBL_MethodRef
+ // 3: TBL_TypeSpec
+ // 4: TBL_MethodSpec
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoMemberRefTokenTables);
+ }
+
+ public static NanoClrTable ToNanoCLRTable(this MemberReference value)
+ {
+ // this one has to be before the others because generic parameters are also "other" types
+ if (value is MethodDefinition)
+ {
+ return NanoClrTable.TBL_MethodDef;
+ }
+ else if (value is MethodSpecification)
+ {
+ return NanoClrTable.TBL_MethodSpec;
+ }
+ else if (value.Resolve() is MethodReference)
+ {
+ if (value.DeclaringType.Scope.MetadataScopeType == MetadataScopeType.AssemblyNameReference)
+ {
+ // method ref is external
+ return NanoClrTable.TBL_MethodRef;
+ }
+ else
+ {
+ // method ref is internal
+ return NanoClrTable.TBL_MethodDef;
+ }
+ }
+ else if (value.DeclaringType is TypeSpecification)
+ {
+ return NanoClrTable.TBL_TypeSpec;
+ }
+ else
+ {
+ throw new ArgumentException("Unknown conversion to CLR Table.");
+ }
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Extensions/MethodDefinitionExtensions.cs b/MetadataProcessor.Shared/Extensions/MethodDefinitionExtensions.cs
index 4f6afbee..fff7fbc7 100644
--- a/MetadataProcessor.Shared/Extensions/MethodDefinitionExtensions.cs
+++ b/MetadataProcessor.Shared/Extensions/MethodDefinitionExtensions.cs
@@ -1,11 +1,9 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Mono.Cecil;
using System.Linq;
using System.Text;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
{
@@ -13,7 +11,7 @@ internal static class MethodDefinitionExtensions
{
public static string FullName(this MethodDefinition value)
{
- if(value.GenericParameters.Count == 0)
+ if (value.GenericParameters.Count == 0)
{
return value.Name;
}
@@ -22,7 +20,7 @@ public static string FullName(this MethodDefinition value)
StringBuilder name = new StringBuilder(value.Name);
name.Append("<");
- foreach(var p in value.GenericParameters)
+ foreach (var p in value.GenericParameters)
{
name.Append(p.Name);
if (!p.Equals(value.GenericParameters.Last()))
@@ -36,5 +34,25 @@ public static string FullName(this MethodDefinition value)
return name.ToString();
}
}
+
+ ///
+ /// Fixed full name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedFullName(this MethodDefinition value)
+ {
+ return nanoHelpers.FixTypeNames(value.FullName);
+ }
+
+ ///
+ /// Fixed name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedName(this MethodDefinition value)
+ {
+ return nanoHelpers.FixTypeNames(value.Name);
+ }
}
}
diff --git a/MetadataProcessor.Shared/Extensions/MethodReferenceExtensions.cs b/MetadataProcessor.Shared/Extensions/MethodReferenceExtensions.cs
new file mode 100644
index 00000000..2edd0672
--- /dev/null
+++ b/MetadataProcessor.Shared/Extensions/MethodReferenceExtensions.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
+{
+ internal static class MethodReferenceExtensions
+ {
+ public static ushort ToEncodedNanoMethodToken(this MethodReference value)
+ {
+ // implements .NET nanoFramework encoding for MethodToken
+ // encodes Method to be decoded with CLR_UncompressMethodToken
+ // CLR tables are
+ // 0: TBL_MethodDef
+ // 1: TBL_MethodRef
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoMemberRefTokenTables);
+ }
+
+ private static NanoClrTable ToNanoCLRTable(this MethodReference value)
+ {
+ return nanoTokenHelpers.ConvertToNanoCLRTable(value);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Extensions/MethodSpecificationExtensions.cs b/MetadataProcessor.Shared/Extensions/MethodSpecificationExtensions.cs
new file mode 100644
index 00000000..90b0a58b
--- /dev/null
+++ b/MetadataProcessor.Shared/Extensions/MethodSpecificationExtensions.cs
@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
+{
+ internal static class MethodSpecificationExtensions
+ {
+ public static ushort ToEncodedNanoMethodToken(this MethodSpecification value)
+ {
+ // implements .NET nanoFramework encoding for MethodToken
+ // encodes Method to be decoded with CLR_UncompressMethodToken
+ // CLR tables are
+ // 0: TBL_MethodDef
+ // 1: TBL_MethodRef
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoMethodDefOrRefTokenTables);
+ }
+
+ public static NanoClrTable ToNanoCLRTable(this MethodSpecification value)
+ {
+ // this one has to be before the others because generic parameters are also "other" types
+ if (value.Resolve() is MethodDefinition)
+ {
+ return NanoClrTable.TBL_MethodDef;
+ }
+ else if (value.Resolve() is MethodReference ||
+ value.Resolve() is MethodSpecification)
+ {
+ if (value.DeclaringType.Scope.MetadataScopeType == MetadataScopeType.AssemblyNameReference)
+ {
+ // method ref is external
+ return NanoClrTable.TBL_MethodRef;
+ }
+ else
+ {
+ // method ref is internal
+ return NanoClrTable.TBL_MethodDef;
+ }
+ }
+ else
+ {
+ throw new ArgumentException("Unknown conversion to CLR Table.");
+ }
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Extensions/ParameterDefintionExtensions.cs b/MetadataProcessor.Shared/Extensions/ParameterDefintionExtensions.cs
index 930ec1ca..6baf44bf 100644
--- a/MetadataProcessor.Shared/Extensions/ParameterDefintionExtensions.cs
+++ b/MetadataProcessor.Shared/Extensions/ParameterDefintionExtensions.cs
@@ -1,11 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using Mono.Cecil;
-using System.Text;
-using System.Linq;
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
{
@@ -13,7 +9,7 @@ internal static class ParameterDefintionExtensions
{
public static string TypeToString(this ParameterDefinition parameter)
{
- if(parameter.ParameterType is ByReferenceType byReference)
+ if (parameter.ParameterType is ByReferenceType byReference)
{
// pointer to native type
return " *" + byReference.TypeSignatureAsString();
diff --git a/MetadataProcessor.Shared/Extensions/TypeDefinitionExtensions.cs b/MetadataProcessor.Shared/Extensions/TypeDefinitionExtensions.cs
index 5d3294b7..cbbd1a83 100644
--- a/MetadataProcessor.Shared/Extensions/TypeDefinitionExtensions.cs
+++ b/MetadataProcessor.Shared/Extensions/TypeDefinitionExtensions.cs
@@ -1,10 +1,8 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Mono.Cecil;
using System;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
{
@@ -14,7 +12,7 @@ public static bool IncludeInStub(this TypeDefinition value)
{
var typeDefFlags = nanoTypeDefinitionTable.GetFlags(value);
- if ( typeDefFlags.HasFlag(nanoTypeDefinitionFlags.TD_Delegate) ||
+ if (typeDefFlags.HasFlag(nanoTypeDefinitionFlags.TD_Delegate) ||
typeDefFlags.HasFlag(nanoTypeDefinitionFlags.TD_MulticastDelegate))
{
return false;
@@ -23,9 +21,9 @@ public static bool IncludeInStub(this TypeDefinition value)
typeDefFlags = typeDefFlags & nanoTypeDefinitionFlags.TD_Semantics;
// Only generate a stub for classes and value types.
- if (typeDefFlags == nanoTypeDefinitionFlags.TD_Semantics_Class ||
- typeDefFlags == nanoTypeDefinitionFlags.TD_Semantics_ValueType )
- {
+ if (typeDefFlags == nanoTypeDefinitionFlags.TD_Semantics_Class ||
+ typeDefFlags == nanoTypeDefinitionFlags.TD_Semantics_ValueType)
+ {
return true;
}
@@ -42,7 +40,7 @@ public static bool IsToExclude(this TypeDefinition value)
public static EnumDeclaration ToEnumDeclaration(this TypeDefinition source)
{
// sanity check (to prevent missuse)
- if(!source.IsEnum)
+ if (!source.IsEnum)
{
throw new ArgumentException("Can clone only TypeDefinition that are Enums.");
}
@@ -52,21 +50,21 @@ public static EnumDeclaration ToEnumDeclaration(this TypeDefinition source)
// if there is a namespace remove it (as there can't be two enums with the same name)
- if(!string.IsNullOrEmpty(source.Namespace))
+ if (!string.IsNullOrEmpty(source.Namespace))
{
enumName = source.FullName.Replace(source.Namespace, "");
-
+
// remove trailing dot
enumName = enumName.Replace(".", "");
}
else
{
- if(
+ if (
source.DeclaringType != null &&
!string.IsNullOrEmpty(source.DeclaringType.Namespace))
{
enumName = source.FullName.Replace(source.DeclaringType.Namespace, "");
-
+
// remove trailing dot
enumName = enumName.Replace(".", "");
@@ -130,9 +128,9 @@ public static EnumDeclaration ToEnumDeclaration(this TypeDefinition source)
// enum items are named with the enum name followed by the enum item and respective value
// pattern: nnnn_yyyyy
var emunItem = new EnumItem()
- {
- Name = $"{enumName}_{f.Name}",
- };
+ {
+ Name = $"{enumName}_{f.Name}",
+ };
emunItem.Value = f.Constant.ToString();
@@ -142,5 +140,25 @@ public static EnumDeclaration ToEnumDeclaration(this TypeDefinition source)
return myEnum;
}
+
+ ///
+ /// Fixed full name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedFullName(this TypeDefinition value)
+ {
+ return nanoHelpers.FixTypeNames(value.FullName);
+ }
+
+ ///
+ /// Fixed name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedName(this TypeDefinition value)
+ {
+ return nanoHelpers.FixTypeNames(value.Name);
+ }
}
}
diff --git a/MetadataProcessor.Shared/Extensions/TypeReferenceExtensions.cs b/MetadataProcessor.Shared/Extensions/TypeReferenceExtensions.cs
index 4149880c..9120350f 100644
--- a/MetadataProcessor.Shared/Extensions/TypeReferenceExtensions.cs
+++ b/MetadataProcessor.Shared/Extensions/TypeReferenceExtensions.cs
@@ -38,38 +38,38 @@ public static string TypeSignatureAsString(this TypeReference type)
return "U";
}
- nanoCLR_DataType dataType;
+ NanoCLRDataType dataType;
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
{
switch (dataType)
{
- case nanoCLR_DataType.DATATYPE_VOID:
- case nanoCLR_DataType.DATATYPE_BOOLEAN:
- case nanoCLR_DataType.DATATYPE_CHAR:
- case nanoCLR_DataType.DATATYPE_I1:
- case nanoCLR_DataType.DATATYPE_U1:
- case nanoCLR_DataType.DATATYPE_I2:
- case nanoCLR_DataType.DATATYPE_U2:
- case nanoCLR_DataType.DATATYPE_I4:
- case nanoCLR_DataType.DATATYPE_U4:
- case nanoCLR_DataType.DATATYPE_I8:
- case nanoCLR_DataType.DATATYPE_U8:
- case nanoCLR_DataType.DATATYPE_R4:
- case nanoCLR_DataType.DATATYPE_BYREF:
- case nanoCLR_DataType.DATATYPE_OBJECT:
- case nanoCLR_DataType.DATATYPE_WEAKCLASS:
+ case NanoCLRDataType.DATATYPE_VOID:
+ case NanoCLRDataType.DATATYPE_BOOLEAN:
+ case NanoCLRDataType.DATATYPE_CHAR:
+ case NanoCLRDataType.DATATYPE_I1:
+ case NanoCLRDataType.DATATYPE_U1:
+ case NanoCLRDataType.DATATYPE_I2:
+ case NanoCLRDataType.DATATYPE_U2:
+ case NanoCLRDataType.DATATYPE_I4:
+ case NanoCLRDataType.DATATYPE_U4:
+ case NanoCLRDataType.DATATYPE_I8:
+ case NanoCLRDataType.DATATYPE_U8:
+ case NanoCLRDataType.DATATYPE_R4:
+ case NanoCLRDataType.DATATYPE_BYREF:
+ case NanoCLRDataType.DATATYPE_OBJECT:
+ case NanoCLRDataType.DATATYPE_WEAKCLASS:
return dataType.ToString().Replace("DATATYPE_", "");
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE:
return "STRING";
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
return "R8";
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_MARSHAL:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_MARSHAL:
return "TIMESPAN";
- case nanoCLR_DataType.DATATYPE_REFLECTION:
+ case NanoCLRDataType.DATATYPE_REFLECTION:
return type.FullName.Replace(".", "");
}
}
@@ -113,10 +113,23 @@ public static string TypeSignatureAsString(this TypeReference type)
return byrefSig.ToString();
}
- if (type.IsGenericParameter ||
- type.IsGenericInstance)
+ if (type.IsGenericParameter)
{
- return $"!!{type.Name}";
+ StringBuilder genericParamTypeSig = new StringBuilder();
+
+ if ((type as GenericParameter).Owner is TypeDefinition)
+ {
+ genericParamTypeSig.Append("!");
+ }
+ if ((type as GenericParameter).Owner is MethodDefinition)
+ {
+ genericParamTypeSig.Append("!!");
+ }
+
+ genericParamTypeSig.Append($"{type.Name}");
+
+
+ return genericParamTypeSig.ToString();
}
return "";
@@ -124,44 +137,44 @@ public static string TypeSignatureAsString(this TypeReference type)
public static string ToNativeTypeAsString(this TypeReference type)
{
- nanoCLR_DataType dataType;
+ NanoCLRDataType dataType;
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
{
switch (dataType)
{
- case nanoCLR_DataType.DATATYPE_VOID:
+ case NanoCLRDataType.DATATYPE_VOID:
return "void";
- case nanoCLR_DataType.DATATYPE_BOOLEAN:
+ case NanoCLRDataType.DATATYPE_BOOLEAN:
return "bool";
- case nanoCLR_DataType.DATATYPE_CHAR:
+ case NanoCLRDataType.DATATYPE_CHAR:
return "char";
- case nanoCLR_DataType.DATATYPE_I1:
+ case NanoCLRDataType.DATATYPE_I1:
return "int8_t";
- case nanoCLR_DataType.DATATYPE_U1:
+ case NanoCLRDataType.DATATYPE_U1:
return "uint8_t";
- case nanoCLR_DataType.DATATYPE_I2:
+ case NanoCLRDataType.DATATYPE_I2:
return "int16_t";
- case nanoCLR_DataType.DATATYPE_U2:
+ case NanoCLRDataType.DATATYPE_U2:
return "uint16_t";
- case nanoCLR_DataType.DATATYPE_I4:
+ case NanoCLRDataType.DATATYPE_I4:
return "signed int";
- case nanoCLR_DataType.DATATYPE_U4:
+ case NanoCLRDataType.DATATYPE_U4:
return "unsigned int";
- case nanoCLR_DataType.DATATYPE_I8:
+ case NanoCLRDataType.DATATYPE_I8:
return "int64_t";
- case nanoCLR_DataType.DATATYPE_U8:
+ case NanoCLRDataType.DATATYPE_U8:
return "uint64_t";
- case nanoCLR_DataType.DATATYPE_R4:
+ case NanoCLRDataType.DATATYPE_R4:
return "float";
- case nanoCLR_DataType.DATATYPE_BYREF:
+ case NanoCLRDataType.DATATYPE_BYREF:
return "";
// system.String
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE:
return "const char*";
// System.Double
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
return "double";
default:
@@ -196,44 +209,44 @@ public static string ToNativeTypeAsString(this TypeReference type)
public static string ToCLRTypeAsString(this TypeReference type)
{
- nanoCLR_DataType dataType;
+ NanoCLRDataType dataType;
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(type.FullName, out dataType))
{
switch (dataType)
{
- case nanoCLR_DataType.DATATYPE_VOID:
+ case NanoCLRDataType.DATATYPE_VOID:
return "void";
- case nanoCLR_DataType.DATATYPE_BOOLEAN:
+ case NanoCLRDataType.DATATYPE_BOOLEAN:
return "bool";
- case nanoCLR_DataType.DATATYPE_CHAR:
+ case NanoCLRDataType.DATATYPE_CHAR:
return "CHAR";
- case nanoCLR_DataType.DATATYPE_I1:
+ case NanoCLRDataType.DATATYPE_I1:
return "INT8";
- case nanoCLR_DataType.DATATYPE_U1:
+ case NanoCLRDataType.DATATYPE_U1:
return "UINT8";
- case nanoCLR_DataType.DATATYPE_I2:
+ case NanoCLRDataType.DATATYPE_I2:
return "INT16";
- case nanoCLR_DataType.DATATYPE_U2:
+ case NanoCLRDataType.DATATYPE_U2:
return "UINT16";
- case nanoCLR_DataType.DATATYPE_I4:
+ case NanoCLRDataType.DATATYPE_I4:
return "INT32";
- case nanoCLR_DataType.DATATYPE_U4:
+ case NanoCLRDataType.DATATYPE_U4:
return "UINT32";
- case nanoCLR_DataType.DATATYPE_I8:
+ case NanoCLRDataType.DATATYPE_I8:
return "INT64";
- case nanoCLR_DataType.DATATYPE_U8:
+ case NanoCLRDataType.DATATYPE_U8:
return "UINT64";
- case nanoCLR_DataType.DATATYPE_R4:
+ case NanoCLRDataType.DATATYPE_R4:
return "float";
- case nanoCLR_DataType.DATATYPE_BYREF:
+ case NanoCLRDataType.DATATYPE_BYREF:
return "NONE";
// system.String
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE:
return "LPCSTR";
// System.Double
- case nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
+ case NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE:
return "double";
default:
@@ -270,36 +283,36 @@ public static string ToCLRTypeAsString(this TypeReference type)
public static nanoSerializationType ToSerializationType(this TypeReference value)
{
- nanoCLR_DataType dataType;
+ NanoCLRDataType dataType;
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(value.FullName, out dataType))
{
switch (dataType)
{
- case nanoCLR_DataType.DATATYPE_BOOLEAN:
+ case NanoCLRDataType.DATATYPE_BOOLEAN:
return nanoSerializationType.ELEMENT_TYPE_BOOLEAN;
- case nanoCLR_DataType.DATATYPE_I1:
+ case NanoCLRDataType.DATATYPE_I1:
return nanoSerializationType.ELEMENT_TYPE_I1;
- case nanoCLR_DataType.DATATYPE_U1:
+ case NanoCLRDataType.DATATYPE_U1:
return nanoSerializationType.ELEMENT_TYPE_U1;
- case nanoCLR_DataType.DATATYPE_I2:
+ case NanoCLRDataType.DATATYPE_I2:
return nanoSerializationType.ELEMENT_TYPE_I2;
- case nanoCLR_DataType.DATATYPE_U2:
+ case NanoCLRDataType.DATATYPE_U2:
return nanoSerializationType.ELEMENT_TYPE_U2;
- case nanoCLR_DataType.DATATYPE_I4:
+ case NanoCLRDataType.DATATYPE_I4:
return nanoSerializationType.ELEMENT_TYPE_I4;
- case nanoCLR_DataType.DATATYPE_U4:
+ case NanoCLRDataType.DATATYPE_U4:
return nanoSerializationType.ELEMENT_TYPE_U4;
- case nanoCLR_DataType.DATATYPE_I8:
+ case NanoCLRDataType.DATATYPE_I8:
return nanoSerializationType.ELEMENT_TYPE_I8;
- case nanoCLR_DataType.DATATYPE_U8:
+ case NanoCLRDataType.DATATYPE_U8:
return nanoSerializationType.ELEMENT_TYPE_U8;
- case nanoCLR_DataType.DATATYPE_R4:
+ case NanoCLRDataType.DATATYPE_R4:
return nanoSerializationType.ELEMENT_TYPE_R4;
- case nanoCLR_DataType.DATATYPE_R8:
+ case NanoCLRDataType.DATATYPE_R8:
return nanoSerializationType.ELEMENT_TYPE_R8;
- case nanoCLR_DataType.DATATYPE_CHAR:
+ case NanoCLRDataType.DATATYPE_CHAR:
return nanoSerializationType.ELEMENT_TYPE_CHAR;
- case nanoCLR_DataType.DATATYPE_STRING:
+ case NanoCLRDataType.DATATYPE_STRING:
return nanoSerializationType.ELEMENT_TYPE_STRING;
default:
return 0;
@@ -309,5 +322,64 @@ public static nanoSerializationType ToSerializationType(this TypeReference value
return 0;
}
+ public static ushort ToEncodedNanoTypeToken(this TypeReference value)
+ {
+ // implements .NET nanoFramework encoding for TypeToken
+ // encodes TypeReference to be decoded with CLR_UncompressTypeToken
+ // CLR tables are
+ // 0: TBL_TypeDef
+ // 1: TBL_TypeRef
+ // 2: TBL_TypeSpec
+ // 3: TBL_GenericParam
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoTypeTokenTables);
+ }
+
+ public static ushort ToEncodedNanoTypeDefOrRefToken(this TypeReference value)
+ {
+ // implements .NET nanoFramework encoding for TypeToken
+ // CLR tables are
+ // 0: TBL_TypeDef
+ // 1: TBL_TypeRef
+
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.NanoTypeDefOrRefTokenTables);
+ }
+
+ ////////////////////////////////////////////
+
+ ///
+ /// Encodes a TypeReference or TypeSpecification to CLR_TypeRefOrSpec.
+ ///
+ ///
+ ///
+ public static ushort ToCLR_TypeRefOrSpec(this TypeReference value)
+ {
+ return nanoTokenHelpers.EncodeTableIndex(value.ToNanoCLRTable(), nanoTokenHelpers.CLR_TypeRefOrSpecTables);
+ }
+
+ private static NanoClrTable ToNanoCLRTable(this TypeReference value)
+ {
+ return nanoTokenHelpers.ConvertToNanoCLRTable(value);
+ }
+
+ ///
+ /// Fixed full name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedFullName(this TypeReference value)
+ {
+ return nanoHelpers.FixTypeNames(value.FullName);
+ }
+
+ ///
+ /// Fixed name with simplified type names.
+ ///
+ ///
+ ///
+ public static string FixedName(this TypeReference value)
+ {
+ return nanoHelpers.FixTypeNames(value.Name);
+ }
}
}
diff --git a/MetadataProcessor.Shared/InanoTable.cs b/MetadataProcessor.Shared/InanoTable.cs
index 1677b619..1c3e4933 100644
--- a/MetadataProcessor.Shared/InanoTable.cs
+++ b/MetadataProcessor.Shared/InanoTable.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -18,4 +17,4 @@ public interface InanoTable
void Write(
nanoBinaryWriter writer);
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/MetadataProcessor.Shared.projitems b/MetadataProcessor.Shared/MetadataProcessor.Shared.projitems
index 24e869f3..95fe65aa 100644
--- a/MetadataProcessor.Shared/MetadataProcessor.Shared.projitems
+++ b/MetadataProcessor.Shared/MetadataProcessor.Shared.projitems
@@ -17,6 +17,7 @@
+
@@ -24,10 +25,16 @@
+
+
+
+
+
+
@@ -38,6 +45,9 @@
+
+
+
@@ -47,12 +57,15 @@
+
+
+
@@ -63,16 +76,19 @@
+
+
-
+
+
\ No newline at end of file
diff --git a/MetadataProcessor.Shared/Mono.Cecil/CodeWriter.cs b/MetadataProcessor.Shared/Mono.Cecil/CodeWriter.cs
index 5fb16d18..36a46bde 100644
--- a/MetadataProcessor.Shared/Mono.Cecil/CodeWriter.cs
+++ b/MetadataProcessor.Shared/Mono.Cecil/CodeWriter.cs
@@ -1,14 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
-using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.Linq;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -51,11 +50,11 @@ internal sealed class CodeWriter
/// Assembly tables context - contains all tables used for building target assembly.
///
public CodeWriter(
- MethodDefinition method,
+ MethodDefinition method,
nanoBinaryWriter writer,
nanoStringTable stringTable,
nanoTablesContext context)
- {
+ {
_stringTable = stringTable;
_body = method.Body;
@@ -109,13 +108,13 @@ public static IEnumerable> PreProcessMethod(
switch (instruction.OpCode.OperandType)
{
case OperandType.InlineSwitch:
- var targets = (Instruction[]) instruction.Operand;
+ var targets = (Instruction[])instruction.Operand;
offset -= 3; // One bye used instead of Int32
- offset -= 2 * targets.Length; // each target use Int16 instead of Int32
+ offset -= 2 * targets.Length; // each target use Int16 instead of Int32
offsetChanged = true;
break;
case OperandType.InlineString:
- stringTable.GetOrCreateStringId((string) instruction.Operand, true);
+ stringTable.GetOrCreateStringId((string)instruction.Operand, true);
offset -= 2;
offsetChanged = true;
break;
@@ -138,8 +137,8 @@ public static IEnumerable> PreProcessMethod(
/// Method body in Mono.Cecil format.
/// Maximal evaluated stack size for passed method body.
public static byte CalculateStackSize(
- MethodBody methodBody)
- {
+ MethodBody methodBody)
+ {
if (methodBody == null)
{
return 0;
@@ -149,16 +148,16 @@ public static byte CalculateStackSize(
var size = 0;
var maxSize = 0;
- foreach (var instruction in methodBody.Instructions)
- {
+ foreach (var instruction in methodBody.Instructions)
+ {
int correctedStackSize;
- if (offsets.TryGetValue(instruction.Offset, out correctedStackSize))
- {
- size = correctedStackSize;
- }
+ if (offsets.TryGetValue(instruction.Offset, out correctedStackSize))
+ {
+ size = correctedStackSize;
+ }
- switch (instruction.OpCode.Code)
- {
+ switch (instruction.OpCode.Code)
+ {
case Code.Throw:
case Code.Endfinally:
case Code.Endfilter:
@@ -169,30 +168,30 @@ public static byte CalculateStackSize(
continue;
case Code.Newobj:
- {
- var method = (MethodReference)instruction.Operand;
- size -= method.Parameters.Count;
- }
- break;
+ {
+ var method = (MethodReference)instruction.Operand;
+ size -= method.Parameters.Count;
+ }
+ break;
case Code.Callvirt:
case Code.Call:
- {
- var method = (MethodReference)instruction.Operand;
- if (method.HasThis)
- {
- --size;
- }
- size -= method.Parameters.Count;
- if (method.ReturnType.FullName != "System.Void")
- {
- ++size;
- }
+ {
+ var method = (MethodReference)instruction.Operand;
+ if (method.HasThis)
+ {
+ --size;
}
- break;
- }
+ size -= method.Parameters.Count;
+ if (method.ReturnType.FullName != "System.Void")
+ {
+ ++size;
+ }
+ }
+ break;
+ }
- size = CorrectStackDepthByPushes(instruction, size);
+ size = CorrectStackDepthByPushes(instruction, size);
size = CorrectStackDepthByPops(instruction, size);
if (instruction.OpCode.OperandType == OperandType.ShortInlineBrTarget ||
@@ -204,11 +203,11 @@ public static byte CalculateStackSize(
offsets[target.Offset] = Math.Max(stackSize, size);
}
- maxSize = Math.Max(maxSize, size);
- }
+ maxSize = Math.Max(maxSize, size);
+ }
- return (byte)maxSize;
- }
+ return (byte)maxSize;
+ }
private static int CorrectStackDepthByPushes(
Instruction instruction,
@@ -278,7 +277,7 @@ private void WriteExceptionsTable()
{
case ExceptionHandlerType.Catch:
_writer.WriteUInt16(0x0000);
- _writer.WriteUInt16(GetTypeReferenceId(handler.CatchType, 0x8000));
+ _writer.WriteUInt16(_context.GetTypeReferenceId(handler.CatchType));
break;
case ExceptionHandlerType.Fault:
_writer.WriteUInt16(0x0001);
@@ -310,216 +309,153 @@ private void WriteExceptionsTable()
_writer.WriteByte((byte)_body.ExceptionHandlers.Count);
}
- private void WriteOpCode (
+ private void WriteOpCode(
OpCode opcode)
- {
- if (opcode.Size == 1)
+ {
+ if (opcode.Size == 1)
{
- _writer.WriteByte(opcode.Op2);
- }
+ _writer.WriteByte(opcode.Op2);
+ }
else
{
_writer.WriteByte(opcode.Op1);
_writer.WriteByte(opcode.Op2);
}
- }
+ }
- private void WriteOperand (
+ private void WriteOperand(
Instruction instruction)
- {
+ {
var opcode = instruction.OpCode;
- var operandType = opcode.OperandType;
+ var operandType = opcode.OperandType;
- if (operandType == OperandType.InlineNone)
- {
+ if (operandType == OperandType.InlineNone)
+ {
return;
- }
+ }
- var operand = instruction.Operand;
- if (operand == null)
- {
+ var operand = instruction.Operand;
+ if (operand == null)
+ {
throw new ArgumentException();
- }
+ }
- switch (operandType)
- {
- case OperandType.InlineSwitch:
- {
- var targets = (Instruction[]) operand;
+ switch (operandType)
+ {
+ case OperandType.InlineSwitch:
+ {
+ var targets = (Instruction[])operand;
_writer.WriteByte((byte)targets.Length);
- var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1;
- foreach (var item in targets)
- {
- _writer.WriteInt16((short)(GetTargetOffset(item) - diff));
- }
- break;
- }
- case OperandType.ShortInlineBrTarget:
- {
- var target = (Instruction) operand;
- _writer.WriteSByte((sbyte)
+ var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1;
+ foreach (var item in targets)
+ {
+ _writer.WriteInt16((short)(GetTargetOffset(item) - diff));
+ }
+ break;
+ }
+ case OperandType.ShortInlineBrTarget:
+ {
+ var target = (Instruction)operand;
+ _writer.WriteSByte((sbyte)
(GetTargetOffset(target) - (instruction.Offset + opcode.Size + 1)));
- break;
- }
- case OperandType.InlineBrTarget:
- {
- var target = (Instruction) operand;
+ break;
+ }
+ case OperandType.InlineBrTarget:
+ {
+ var target = (Instruction)operand;
_writer.WriteInt16((short)
(GetTargetOffset(target) - (instruction.Offset + opcode.Size + 2)));
- break;
- }
- case OperandType.ShortInlineVar:
+ break;
+ }
+ case OperandType.ShortInlineVar:
_writer.WriteByte((byte)GetVariableIndex((VariableDefinition)operand));
- break;
- case OperandType.ShortInlineArg:
+ break;
+ case OperandType.ShortInlineArg:
_writer.WriteByte((byte)GetParameterIndex((ParameterDefinition)operand));
- break;
- case OperandType.InlineVar:
+ break;
+ case OperandType.InlineVar:
_writer.WriteInt16((short)GetVariableIndex((VariableDefinition)operand));
- break;
- case OperandType.InlineArg:
+ break;
+ case OperandType.InlineArg:
_writer.WriteInt16((short)GetParameterIndex((ParameterDefinition)operand));
- break;
- case OperandType.InlineSig:
- // TODO: implement this properly after finding when such code is generated
- //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
- break;
- case OperandType.ShortInlineI:
- if (opcode == OpCodes.Ldc_I4_S)
- {
+ break;
+ case OperandType.InlineSig:
+ // TODO: implement this properly after finding when such code is generated
+ //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
+ break;
+ case OperandType.ShortInlineI:
+ if (opcode == OpCodes.Ldc_I4_S)
+ {
_writer.WriteSByte((sbyte)operand);
- }
- else
- {
+ }
+ else
+ {
_writer.WriteByte((byte)operand);
}
- break;
- case OperandType.InlineI:
+ break;
+ case OperandType.InlineI:
_writer.WriteInt32((int)operand);
- break;
- case OperandType.InlineI8:
+ break;
+ case OperandType.InlineI8:
_writer.WriteInt64((long)operand);
- break;
- case OperandType.ShortInlineR:
+ break;
+ case OperandType.ShortInlineR:
_writer.WriteSingle((float)operand);
- break;
- case OperandType.InlineR:
+ break;
+ case OperandType.InlineR:
_writer.WriteDouble((double)operand);
- break;
- case OperandType.InlineString:
- var stringReferenceId = _stringTable.GetOrCreateStringId((string) operand, true);
+ break;
+ case OperandType.InlineString:
+ var stringReferenceId = _stringTable.GetOrCreateStringId((string)operand, true);
_writer.WriteUInt16(stringReferenceId);
- break;
+ break;
case OperandType.InlineMethod:
- _writer.WriteUInt16(_context.GetMethodReferenceId((MethodReference)operand));
+ _writer.WriteUInt16(_context.GetMethodReferenceId((MemberReference)operand));
break;
case OperandType.InlineType:
- _writer.WriteUInt16(GetTypeReferenceId((TypeReference)operand));
+ _writer.WriteUInt16(_context.GetTypeReferenceId((TypeReference)operand));
break;
- case OperandType.InlineField:
- _writer.WriteUInt16(GetFieldReferenceId((FieldReference)operand));
+ case OperandType.InlineField:
+ _writer.WriteUInt16(_context.GetFieldReferenceId((FieldReference)operand));
break;
case OperandType.InlineTok:
- _writer.WriteUInt32(GetMetadataToken((IMetadataTokenProvider)operand));
+ _writer.WriteUInt32(_context.GetMetadataToken((IMetadataTokenProvider)operand));
break;
default:
- throw new ArgumentException();
- }
- }
-
- private uint GetMetadataToken(
- IMetadataTokenProvider token)
- {
- ushort referenceId;
- switch (token.MetadataToken.TokenType)
- {
- case TokenType.TypeRef:
- _context.TypeReferencesTable.TryGetTypeReferenceId((TypeReference)token, out referenceId);
- return (uint)0x01000000 | referenceId;
- case TokenType.TypeDef:
- _context.TypeDefinitionTable.TryGetTypeReferenceId((TypeDefinition)token, out referenceId);
- return (uint)0x04000000 | referenceId;
- case TokenType.TypeSpec:
- _context.TypeSpecificationsTable.TryGetTypeReferenceId((TypeReference) token, out referenceId);
- return (uint)0x08000000 | referenceId;
- case TokenType.Field:
- _context.FieldsTable.TryGetFieldReferenceId((FieldDefinition) token, false, out referenceId);
- return (uint)0x05000000 | referenceId;
+ throw new ArgumentException();
}
- return 0U;
}
- private ushort GetFieldReferenceId(
- FieldReference fieldReference)
+ private int GetTargetOffset(
+ Instruction instruction)
{
- ushort referenceId;
- if (_context.FieldReferencesTable.TryGetFieldReferenceId(fieldReference, out referenceId))
+ if (instruction == null)
{
- referenceId |= 0x8000; // External field reference
+ var last = _body.Instructions[_body.Instructions.Count - 1];
+ return last.Offset + last.GetSize();
}
- else
- {
- _context.FieldsTable.TryGetFieldReferenceId(fieldReference.Resolve(), false, out referenceId);
- }
- return referenceId;
+
+ return instruction.Offset;
}
- private ushort GetTypeReferenceId(
- TypeReference typeReference,
- ushort typeReferenceMask = 0x4000)
+ private static int GetVariableIndex(
+ VariableDefinition variable)
{
- ushort referenceId;
+ return variable.Index;
+ }
- if(typeReference is TypeSpecification)
+ private int GetParameterIndex(
+ ParameterDefinition parameter)
+ {
+ if (_body.Method.HasThis)
{
- referenceId = _context.TypeSpecificationsTable.GetOrCreateTypeSpecificationId(typeReference);
+ if (parameter == _body.ThisParameter)
+ return 0;
- return (ushort)(0x8000 | referenceId);
- }
- else if (_context.TypeReferencesTable.TryGetTypeReferenceId(typeReference, out referenceId))
- {
- referenceId |= typeReferenceMask; // External type reference
+ return parameter.Index + 1;
}
- else
- {
- if (!_context.TypeDefinitionTable.TryGetTypeReferenceId(typeReference.Resolve(), out referenceId))
- {
- return 0x8000;
- }
- }
- return referenceId;
+ return parameter.Index;
}
-
- private int GetTargetOffset (
- Instruction instruction)
- {
- if (instruction == null)
- {
- var last = _body.Instructions[_body.Instructions.Count - 1];
- return last.Offset + last.GetSize ();
- }
-
- return instruction.Offset;
- }
-
- private static int GetVariableIndex (
- VariableDefinition variable)
- {
- return variable.Index;
- }
-
- private int GetParameterIndex (
- ParameterDefinition parameter)
- {
- if (_body.Method.HasThis) {
- if (parameter == _body.ThisParameter)
- return 0;
-
- return parameter.Index + 1;
- }
-
- return parameter.Index;
- }
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/Pdbx/Pdbx.cs b/MetadataProcessor.Shared/Pdbx/Pdbx.cs
new file mode 100644
index 00000000..d1264e12
--- /dev/null
+++ b/MetadataProcessor.Shared/Pdbx/Pdbx.cs
@@ -0,0 +1,121 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /// Any changes in these classes need to be replicated on the same class at the Visual Studio extension //
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ public partial class Pdbx
+ {
+ public Assembly Assembly { get; set; }
+ }
+
+ public partial class Assembly
+ {
+ public Token Token { get; set; }
+
+ public string FileName { get; set; }
+
+ [JsonConverter(typeof(VersionConverter))]
+ public Version Version { get; set; }
+
+ public List Classes { get; set; }
+
+ public List GenericParams { get; set; }
+
+ public List TypeSpecs { get; set; }
+ }
+
+ public partial class Class
+ {
+ public Token Token { get; set; }
+
+ public string Name { get; set; }
+ public bool IsEnum { get; set; } = false;
+ public int NumGenericParams { get; set; } = 0;
+ public bool IsGenericInstance { get; set; } = false;
+
+ public List Methods { get; set; }
+ public List Fields { get; set; }
+ }
+
+ public partial class Field
+ {
+ public string Name { get; set; }
+ public Token Token { get; set; }
+ }
+
+ public partial class Method
+ {
+ public Token Token { get; set; }
+
+ public string Name { get; set; }
+ public int NumParams { get; set; } = 0;
+ public int NumLocals { get; set; } = 0;
+ public int NumGenericParams { get; set; } = 0;
+ public bool IsGenericInstance { get; set; } = false;
+ public bool HasByteCode { get; set; } = false;
+ public List ILMap { get; set; }
+ }
+
+ public partial class IL
+ {
+ public Token Token { get; set; }
+ }
+
+ public partial class GenericParam
+ {
+ public Token Token { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ public partial class TypeSpec
+ {
+ public Token Token { get; set; }
+
+ public string Name { get; set; }
+ public bool IsGenericInstance { get; set; } = false;
+
+ public List Members { get; set; }
+ }
+
+ public partial class Member
+ {
+ public Token Token { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ public partial class Token
+ {
+ public string CLR { get; set; }
+ public string NanoCLR { get; set; }
+ }
+
+ #region Converters
+
+ public class VersionConverter : JsonConverter
+ {
+ public override Version Read(
+ ref Utf8JsonReader reader,
+ Type typeToConvert,
+ JsonSerializerOptions options) =>
+ Version.Parse(reader.GetString());
+
+ public override void Write(
+ Utf8JsonWriter writer,
+ Version value,
+ JsonSerializerOptions options) =>
+ writer.WriteStringValue(value.ToString(4));
+ }
+
+ #endregion
+}
diff --git a/MetadataProcessor.Shared/Pdbx/PdbxFileHelpers.cs b/MetadataProcessor.Shared/Pdbx/PdbxFileHelpers.cs
new file mode 100644
index 00000000..8cba49ff
--- /dev/null
+++ b/MetadataProcessor.Shared/Pdbx/PdbxFileHelpers.cs
@@ -0,0 +1,276 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ public partial class Pdbx
+ {
+ public Pdbx(nanoTablesContext context) => Assembly = new Assembly(context);
+ }
+
+ public partial class Assembly
+ {
+ private nanoTablesContext _context;
+
+ public Assembly(nanoTablesContext context)
+ {
+ _context = context;
+
+ Token = new Token(_context.AssemblyDefinition.MetadataToken);
+
+ FileName = _context.AssemblyDefinition.MainModule.Name;
+
+ Version = _context.AssemblyDefinition.Name.Version;
+
+ Classes = WriteClasses(_context);
+
+ GenericParams = WriteGenericParams(_context);
+
+ TypeSpecs = WriteTypeSpecs(_context);
+ }
+
+ private List WriteClasses(nanoTablesContext context)
+ {
+ var classes = new List();
+
+ context.TypeDefinitionTable.ForEachItems((nanoToken, item) => WriteClassInfo(classes, context, item, nanoToken));
+
+ return classes;
+ }
+
+ private void WriteClassInfo(List classes, nanoTablesContext context, TypeDefinition item, uint nanoToken)
+ {
+ classes.Add(new Class(context, item, nanoToken));
+ }
+
+ private List WriteGenericParams(nanoTablesContext context)
+ {
+ var genericParams = new List();
+
+ context.GenericParamsTable.ForEachItems((nanoToken, item) => WriteGenericParamInfo(genericParams, context, item, nanoToken));
+
+ return genericParams;
+ }
+
+ private void WriteGenericParamInfo(List genericParams, nanoTablesContext context, GenericParameter item, uint nanoToken)
+ {
+ genericParams.Add(new GenericParam(context, item, nanoToken));
+ }
+
+ private List WriteTypeSpecs(nanoTablesContext context)
+ {
+ var typeSpecs = new List();
+
+ context.TypeSpecificationsTable.ForEachItems((nanoToken, item) => WriteTypeSpecInfo(typeSpecs, context, item));
+
+ return typeSpecs;
+ }
+
+ private void WriteTypeSpecInfo(List typeSpecs, nanoTablesContext context, TypeReference item)
+ {
+ typeSpecs.Add(new TypeSpec(context, item));
+ }
+ }
+
+ public partial class Class
+ {
+ public Class(nanoTablesContext context, TypeDefinition item, uint nanoToken)
+ {
+ Token = new Token(item.MetadataToken, NanoClrTable.TBL_TypeDef.ToNanoTokenType() | nanoToken);
+
+ Name = item.FullName;
+ IsEnum = item.IsEnum;
+ NumGenericParams = item.GenericParameters.Count;
+ IsGenericInstance = item.IsGenericInstance;
+
+ Methods = new List();
+
+ foreach (var method in item.Methods)
+ {
+ Methods.Add(new Method(context, method));
+ }
+
+ Fields = new List();
+
+ foreach (var field in item.Fields)
+ {
+ Fields.Add(new Field(context, field));
+ }
+ }
+ }
+
+ public partial class Method
+ {
+ public Method(nanoTablesContext context, MethodDefinition method)
+ {
+ context.MethodDefinitionTable.TryGetMethodReferenceId(method, out ushort methodToken);
+
+ Token = new Token(method.MetadataToken, NanoClrTable.TBL_MethodDef.ToNanoTokenType() | methodToken);
+
+ Name = method.Name;
+ NumParams = method.Parameters.Count;
+ NumLocals = method.HasBody ? method.Body.Variables.Count : 0;
+ NumGenericParams = method.GenericParameters.Count;
+ IsGenericInstance = method.IsGenericInstance;
+ HasByteCode = method.HasBody;
+
+ ILMap = new List();
+
+ // sanity check vars
+ uint prevItem1 = 0;
+ uint prevItem2 = 0;
+
+ foreach (var offset in context.TypeDefinitionTable.GetByteCodeOffsets(method.MetadataToken.ToUInt32()))
+ {
+ if (prevItem1 > 0)
+ {
+ // 1st pass, load prevs with current values
+ Debug.Assert(prevItem1 < offset.Item1);
+ Debug.Assert(prevItem2 < offset.Item2);
+ }
+
+ ILMap.Add(new IL(offset.Item1, offset.Item2));
+
+ prevItem1 = offset.Item1;
+ prevItem2 = offset.Item2;
+ }
+ }
+ }
+
+ public partial class Field
+ {
+ public Field(nanoTablesContext context, FieldDefinition field)
+ {
+ context.FieldsTable.TryGetFieldReferenceId(field, false, out ushort fieldToken);
+
+ Token = new Token(field.MetadataToken, NanoClrTable.TBL_FieldDef.ToNanoTokenType() | fieldToken);
+
+ Name = field.Name;
+ }
+ }
+
+ public partial class IL
+ {
+ public IL(uint clrToken, uint nanoToken)
+ {
+ Token = new Token(clrToken, nanoToken);
+ }
+ }
+
+ public partial class GenericParam
+ {
+ public GenericParam(nanoTablesContext context, GenericParameter item, uint nanoToken)
+ {
+ Token = new Token(item.MetadataToken, NanoClrTable.TBL_GenericParam.ToNanoTokenType() | nanoToken);
+
+ Name = item.FullName;
+ }
+ }
+
+ public partial class TypeSpec
+ {
+ public TypeSpec(nanoTablesContext context, TypeReference item)
+ {
+ context.TypeSpecificationsTable.TryGetTypeReferenceId(item, out ushort nanoToken);
+
+ // assume that real token index is the same as ours
+ // need to add one because ours is 0 indexed
+ var clrToken = new MetadataToken(TokenType.TypeSpec, nanoToken + 1);
+
+ Token = new Token(clrToken, NanoClrTable.TBL_TypeSpec.ToNanoTokenType() | nanoToken);
+
+ if (item.IsGenericInstance)
+ {
+ Name = item.FixedFullName();
+ }
+ else if (item.IsGenericParameter)
+ {
+ var genericParam = item as GenericParameter;
+
+ StringBuilder typeSpecName = new StringBuilder();
+
+ if (genericParam.Owner is TypeDefinition)
+ {
+ typeSpecName.Append("!");
+ }
+ if (genericParam.Owner is MethodDefinition)
+ {
+ typeSpecName.Append("!!");
+ }
+
+ typeSpecName.Append(genericParam.Owner.GenericParameters.IndexOf(genericParam));
+
+ Name = typeSpecName.ToString();
+ }
+
+ IsGenericInstance = item.IsGenericInstance;
+
+ Members = new List();
+
+ if (item.IsGenericInstance)
+ {
+ foreach (var mr in context.MethodReferencesTable.Items)
+ {
+ if (context.TypeSpecificationsTable.TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId) &&
+ referenceId == nanoToken)
+ {
+ if (context.MethodReferencesTable.TryGetMethodReferenceId(mr, out referenceId))
+ {
+ Members.Add(new Member(mr, NanoClrTable.TBL_MethodRef.ToNanoTokenType() | nanoToken));
+ }
+ }
+ }
+
+ foreach (var ms in context.MethodSpecificationTable.Items)
+ {
+ if (context.TypeSpecificationsTable.TryGetTypeReferenceId(ms.DeclaringType, out ushort referenceId) &&
+ referenceId == nanoToken)
+ {
+ if (context.MethodSpecificationTable.TryGetMethodSpecificationId(ms, out ushort methodSpecId))
+ {
+ Members.Add(new Member(ms, NanoClrTable.TBL_MethodSpec.ToNanoTokenType() | nanoToken));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public partial class Member
+ {
+ public Member(MethodReference mr, uint nanoToken)
+ {
+ Token = new Token(mr.MetadataToken, NanoClrTable.TBL_MethodRef.ToNanoTokenType() | nanoToken);
+
+ Name = mr.Name;
+ }
+ }
+
+ public partial class Token
+ {
+ public Token(MetadataToken metadataToken)
+ {
+ CLR = metadataToken.ToUInt32().ToString("X8", CultureInfo.InvariantCulture);
+ NanoCLR = "00000000";
+ }
+
+ public Token(MetadataToken metadataToken, uint nanoToken)
+ {
+ CLR = metadataToken.ToUInt32().ToString("X8", CultureInfo.InvariantCulture);
+ NanoCLR = nanoToken.ToString("X8", CultureInfo.InvariantCulture);
+ }
+
+ public Token(uint clrToken, uint nanoToken)
+ {
+ CLR = clrToken.ToString("X8", CultureInfo.InvariantCulture);
+ NanoCLR = nanoToken.ToString("X8", CultureInfo.InvariantCulture);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Pdbx/nanoPdbxFileWriter.cs b/MetadataProcessor.Shared/Pdbx/nanoPdbxFileWriter.cs
new file mode 100644
index 00000000..80d71ad2
--- /dev/null
+++ b/MetadataProcessor.Shared/Pdbx/nanoPdbxFileWriter.cs
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ internal sealed class nanoPdbxFileWriter
+ {
+ private readonly nanoTablesContext _context;
+
+ public nanoPdbxFileWriter(
+ nanoTablesContext context)
+ {
+ _context = context;
+ }
+
+ internal void Write(string fileName)
+ {
+ Pdbx pdbxFile = new Pdbx(_context);
+
+ var options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ };
+
+ var pdbxContent = JsonSerializer.SerializeToUtf8Bytes(pdbxFile, options);
+ File.WriteAllBytes(fileName, pdbxContent);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClass.cs b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClass.cs
index 697d33f5..9d1941ac 100644
--- a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClass.cs
+++ b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClass.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassStubs.cs b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassStubs.cs
index 360a942b..aa310287 100644
--- a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassStubs.cs
+++ b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassStubs.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassTable.cs b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassTable.cs
index 4dfce167..41844ce2 100644
--- a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassTable.cs
+++ b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyClassTable.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyLookupTable.cs b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyLookupTable.cs
index 1943a05a..9b7b7eae 100644
--- a/MetadataProcessor.Shared/SkeletonGenerator/AssemblyLookupTable.cs
+++ b/MetadataProcessor.Shared/SkeletonGenerator/AssemblyLookupTable.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/SkeletonGenerator/SkeletonTemplates.cs b/MetadataProcessor.Shared/SkeletonGenerator/SkeletonTemplates.cs
index 9d696257..357b2a49 100644
--- a/MetadataProcessor.Shared/SkeletonGenerator/SkeletonTemplates.cs
+++ b/MetadataProcessor.Shared/SkeletonGenerator/SkeletonTemplates.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace nanoFramework.Tools.MetadataProcessor
{
diff --git a/MetadataProcessor.Shared/Tables/ICustomStringSorter.cs b/MetadataProcessor.Shared/Tables/ICustomStringSorter.cs
index 7d31d351..77c532f1 100644
--- a/MetadataProcessor.Shared/Tables/ICustomStringSorter.cs
+++ b/MetadataProcessor.Shared/Tables/ICustomStringSorter.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System.Collections.Generic;
@@ -21,4 +20,4 @@ public interface ICustomStringSorter
IEnumerable Sort(
ICollection strings);
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoAssemblyReferenceTable.cs b/MetadataProcessor.Shared/Tables/nanoAssemblyReferenceTable.cs
index 60ff1bfd..a9c8e9d5 100644
--- a/MetadataProcessor.Shared/Tables/nanoAssemblyReferenceTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoAssemblyReferenceTable.cs
@@ -1,12 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -17,6 +17,14 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoAssemblyReferenceTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_ASSEMBLYREF = 10;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
@@ -60,10 +68,14 @@ protected override void WriteSingleItem(
return;
}
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(0); // padding
+ var writerStartPosition = writer.BaseStream.Position;
+ WriteStringReference(writer, item.Name);
writer.WriteVersion(item.Version);
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_ASSEMBLYREF);
}
///
@@ -77,7 +89,7 @@ protected override void AllocateSingleItemStrings(
/// Gets assembly reference ID by assembly name reference in Mono.Cecil format.
///
/// Assembly name reference in Mono.Cecil format.
- /// Refernce ID for passed item.
+ /// Reference ID for passed item.
public ushort GetReferenceId(
AssemblyNameReference assemblyNameReference)
{
diff --git a/MetadataProcessor.Shared/Tables/nanoAttributesTable.cs b/MetadataProcessor.Shared/Tables/nanoAttributesTable.cs
index cf3441ef..3d52e493 100644
--- a/MetadataProcessor.Shared/Tables/nanoAttributesTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoAttributesTable.cs
@@ -1,13 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -38,6 +37,8 @@ public sealed class nanoAttributesTable : InanoTable
///
private readonly nanoTablesContext _context;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_Attributes;
+
///
/// Creates new instance of object.
///
@@ -139,4 +140,4 @@ public void RemoveUnusedItems(HashSet set)
.Select(a => new Tuple(a.Item1, a.Item2));
}
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoByteCodeTable.cs b/MetadataProcessor.Shared/Tables/nanoByteCodeTable.cs
index ce49a0c1..bf152851 100644
--- a/MetadataProcessor.Shared/Tables/nanoByteCodeTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoByteCodeTable.cs
@@ -1,13 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -43,6 +42,8 @@ public sealed class nanoByteCodeTable : InanoTable
///
private ushort _lastAvailableRva;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_ByteCode;
+
///
/// Creates new instance of object.
///
diff --git a/MetadataProcessor.Shared/Tables/nanoClrTable.cs b/MetadataProcessor.Shared/Tables/nanoClrTable.cs
new file mode 100644
index 00000000..11006475
--- /dev/null
+++ b/MetadataProcessor.Shared/Tables/nanoClrTable.cs
@@ -0,0 +1,37 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// .NET nanoFramework PE tables index.
+ ///
+ public enum NanoClrTable
+ {
+ //////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // !!! KEEP IN SYNC WITH enum NanoCLRTable (in NanoCLR_TypeSystem VS extension) !!! //
+ // //
+ // !!! KEEP IN SYNC WITH enum NanoCLRTable (in NanoCLR_Types.h in CLR) !!! //
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ TBL_AssemblyRef = 0x00000000,
+ TBL_TypeRef = 0x00000001,
+ TBL_FieldRef = 0x00000002,
+ TBL_MethodRef = 0x00000003,
+ TBL_TypeDef = 0x00000004,
+ TBL_FieldDef = 0x00000005,
+ TBL_MethodDef = 0x00000006,
+ TBL_GenericParam = 0x00000007,
+ TBL_MethodSpec = 0x00000008,
+ TBL_TypeSpec = 0x00000009,
+ TBL_Attributes = 0x0000000A,
+ TBL_Resources = 0x0000000B,
+ TBL_ResourcesData = 0x0000000C,
+ TBL_Strings = 0x0000000D,
+ TBL_Signatures = 0x0000000E,
+ TBL_ByteCode = 0x000000F,
+ TBL_ResourcesFiles = 0x00000010,
+ TBL_EndOfAssembly = 0x000000011
+ }
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoEmptyTable.cs b/MetadataProcessor.Shared/Tables/nanoEmptyTable.cs
index 44b9662c..ba5371a3 100644
--- a/MetadataProcessor.Shared/Tables/nanoEmptyTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoEmptyTable.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
namespace nanoFramework.Tools.MetadataProcessor
{
diff --git a/MetadataProcessor.Shared/Tables/nanoFieldDefinitionTable.cs b/MetadataProcessor.Shared/Tables/nanoFieldDefinitionTable.cs
index ea64ce23..6d7e0f7f 100644
--- a/MetadataProcessor.Shared/Tables/nanoFieldDefinitionTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoFieldDefinitionTable.cs
@@ -1,13 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -18,6 +18,14 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoFieldDefinitionTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_FIELDDEF = 8;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
@@ -71,11 +79,17 @@ protected override void WriteSingleItem(
return;
}
+ var writerStartPosition = writer.BaseStream.Position;
+
WriteStringReference(writer, item.Name);
writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item.InitialValue));
writer.WriteUInt16(GetFlags(item));
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_FIELDDEF);
}
///
diff --git a/MetadataProcessor.Shared/Tables/nanoFieldReferenceTable.cs b/MetadataProcessor.Shared/Tables/nanoFieldReferenceTable.cs
index 36305ffa..b8a7db08 100644
--- a/MetadataProcessor.Shared/Tables/nanoFieldReferenceTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoFieldReferenceTable.cs
@@ -1,12 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -17,6 +18,14 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoFieldReferenceTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_FIELDREF = 6;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
@@ -73,57 +82,35 @@ protected override void WriteSingleItem(
return;
}
- bool experimentalCode = true;
+ var writerStartPosition = writer.BaseStream.Position;
- ushort referenceId;
-
-
- if (experimentalCode)
+ if ((item.DeclaringType is TypeSpecification ||
+ item.DeclaringType is GenericParameter) &&
+ _context.TypeSpecificationsTable.TryGetTypeReferenceId(item.DeclaringType, out ushort referenceId))
{
- ////////////////////////////////////
- // EXPERIMENTAL CODE FOR GENERICS //
- ////////////////////////////////////
-
- if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(referenceId);
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType.Resolve(), out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(referenceId);
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else if (_context.TypeDefinitionTable.TryGetTypeReferenceId(item.DeclaringType.Resolve(), out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16((ushort)(referenceId | 0x8000));
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else
- {
- throw new ArgumentException($"Can't find entry in type reference table for {item.DeclaringType.FullName} for Field {item.FullName}.");
- }
+ // is TypeSpecification
+ }
+ else if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
+ {
+ // is TypeReference
}
else
{
+ throw new ArgumentException($"Can't find a type reference for {item.DeclaringType}.");
+ }
- _context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId);
+ // Name
+ WriteStringReference(writer, item.Name);
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(referenceId);
+ // Owner
+ writer.WriteUInt16((ushort)(item.DeclaringType.ToCLR_TypeRefOrSpec() | referenceId));
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
+ // signature
+ writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_FIELDREF);
}
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoGenericParamTable.cs b/MetadataProcessor.Shared/Tables/nanoGenericParamTable.cs
index d5a16fc6..2eb26470 100644
--- a/MetadataProcessor.Shared/Tables/nanoGenericParamTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoGenericParamTable.cs
@@ -1,11 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -16,11 +17,19 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoGenericParamTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_GENERICPARAM = 10;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
///
- private sealed class MemberReferenceComparer : IEqualityComparer
+ private sealed class GenericParameterComparer : IEqualityComparer
{
///
public bool Equals(GenericParameter x, GenericParameter y)
@@ -45,6 +54,14 @@ public int GetHashCode(GenericParameter obj)
}
}
+ ///
+ /// Maps each unique generic parameter and its type.
+ ///
+ private Dictionary _typeForGenericParam =
+ new Dictionary();
+
+ public NanoClrTable TableIndex => NanoClrTable.TBL_GenericParam;
+
///
/// Creates new instance of object.
///
@@ -55,21 +72,62 @@ public int GetHashCode(GenericParameter obj)
public nanoGenericParamTable(
IEnumerable items,
nanoTablesContext context)
- : base(items, new MemberReferenceComparer(), context)
+ : base(items, new GenericParameterComparer(), context)
{
+ foreach (var gp in items)
+ {
+ var methodWithGenericParam = _context.MethodDefinitionTable.Items.SingleOrDefault(m => m.GenericParameters.Contains(gp));
+
+ if (methodWithGenericParam != null)
+ {
+ // get the first method specification that matches this type AND name
+ var instanceMethod = _context.MethodSpecificationTable.Items.FirstOrDefault(
+ mr => mr.DeclaringType.GetElementType() == methodWithGenericParam.DeclaringType &&
+ mr.Name == methodWithGenericParam.Name) as GenericInstanceMethod;
+
+ Debug.Assert(instanceMethod != null, $"Couldn't find a method specification for type {methodWithGenericParam.DeclaringType} when processing generic parameter {gp}.");
+
+ _typeForGenericParam.Add(gp, instanceMethod.GenericArguments.ElementAt(gp.Position));
+ }
+ else
+ {
+ var typeWithGenericParam = _context.TypeDefinitionTable.Items.SingleOrDefault(t => t.GenericParameters.Contains(gp));
+
+ if (typeWithGenericParam != null)
+ {
+ if (_context.MethodReferencesTable.Items.Any())
+ {
+ var genericInstance = _context.MethodReferencesTable.Items.FirstOrDefault(
+ mr => mr.DeclaringType.GetElementType() == typeWithGenericParam)
+ .DeclaringType as GenericInstanceType;
+ Debug.Assert(genericInstance != null, $"Couldn't find a method reference for type {typeWithGenericParam} when processing generic parameter {gp}.");
+
+ _typeForGenericParam.Add(gp, genericInstance.GenericArguments.ElementAt(gp.Position));
+ }
+ else
+ {
+ _typeForGenericParam.Add(gp, null);
+ }
+ }
+ else
+ {
+ _typeForGenericParam.Add(gp, null);
+ }
+ }
+ }
}
///
- /// Gets method reference ID if possible (if method is external and stored in this table).
+ /// Gets generic parameter ID if possible (if generic parameter is stored in this table).
///
- /// Method reference metadata in Mono.Cecil format.
- /// Method reference ID in .NET nanoFramework format.
- /// Returns true if reference found, otherwise returns false.
+ /// Generic parameter TypeReference in Mono.Cecil format.
+ /// Generic parameter identifier for filling.
+ /// Returns true the parameter was found, otherwise returns false.
public bool TryGetParameterId(
- GenericParameter genericParameter,
+ TypeReference genericParameter,
out ushort referenceId)
{
- return TryGetIdByValue(genericParameter, out referenceId);
+ return TryGetIdByValue(genericParameter as GenericParameter, out referenceId);
}
///
@@ -82,7 +140,49 @@ protected override void WriteSingleItem(
return;
}
- // TODO
+ var writerStartPosition = writer.BaseStream.Position;
+
+ // number
+ writer.WriteUInt16((ushort)item.Position);
+
+ // flags
+ writer.WriteUInt16((ushort)item.Attributes);
+
+ // find owner
+ if (item.Owner is TypeDefinition &&
+ _context.TypeDefinitionTable.TryGetTypeReferenceId(item.Owner as TypeDefinition, out ushort referenceId))
+ {
+ // is TypeDef
+ }
+ else if (_context.MethodDefinitionTable.TryGetMethodReferenceId(item.Owner as MethodDefinition, out referenceId))
+ {
+ // is MethodDef
+ }
+ else
+ {
+ throw new ArgumentException($"Can't find entry in type or method definition tables for generic parameter '{item.FullName}' [0x{item.Owner.MetadataToken.ToInt32():x8}].");
+ }
+
+ // owner
+ writer.WriteUInt16((ushort)(item.Owner.ToEncodedNanoTypeOrMethodDefToken() | referenceId));
+
+ // Signature
+ if (_typeForGenericParam[item] != null)
+ {
+ writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(_typeForGenericParam[item]));
+ }
+ else
+ {
+ // no type for this generic parameter
+ writer.WriteUInt16(0xFFFF);
+ }
+
+ // name
+ WriteStringReference(writer, item.Name);
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_GENERICPARAM);
}
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoMemberReferenceTable.cs b/MetadataProcessor.Shared/Tables/nanoMemberReferenceTable.cs
new file mode 100644
index 00000000..9c15a7c6
--- /dev/null
+++ b/MetadataProcessor.Shared/Tables/nanoMemberReferenceTable.cs
@@ -0,0 +1,156 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Original work from Oleg Rakhmatulin.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// Encapsulates logic for storing methods references list and writing
+ /// this collected list into target assembly in .NET nanoFramework format.
+ ///
+ public sealed class nanoMemberReferencesTable :
+ nanoReferenceTableBase
+ {
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_MEMBERREF = 6;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Helper class for comparing two instances of objects
+ /// using property as unique key for comparison.
+ ///
+ private sealed class MemberReferenceComparer : IEqualityComparer
+ {
+ ///
+ public bool Equals(MemberReference x, MemberReference y)
+ {
+ if (x is null)
+ {
+ throw new ArgumentNullException(nameof(x));
+ }
+
+ if (y is null)
+ {
+ throw new ArgumentNullException(nameof(y));
+ }
+
+ return x.MetadataToken.ToInt32() == y.MetadataToken.ToInt32();
+ }
+
+ ///
+ public int GetHashCode(MemberReference obj)
+ {
+ return obj.MetadataToken.ToInt32().GetHashCode();
+ }
+ }
+
+ ///
+ /// Creates new instance of object.
+ ///
+ /// List of member references in Mono.Cecil format.
+ ///
+ /// Assembly tables context - contains all tables used for building target assembly.
+ ///
+ public nanoMemberReferencesTable(
+ IEnumerable items,
+ nanoTablesContext context)
+ : base(items, new MemberReferenceComparer(), context)
+ {
+ }
+
+ ///
+ /// Gets member reference ID if possible (if method is external and stored in this table).
+ ///
+ /// Member reference metadata in Mono.Cecil format.
+ /// Member reference ID in .NET nanoFramework format.
+ /// Returns true if reference found, otherwise returns false.
+ public bool TryGetMemberReferenceId(
+ MemberReference memberReference,
+ out ushort referenceId)
+ {
+ return TryGetIdByValue(memberReference, out referenceId);
+ }
+
+ ///
+ protected override void WriteSingleItem(
+ nanoBinaryWriter writer,
+ MemberReference item)
+ {
+ if (!_context.MinimizeComplete)
+ {
+ return;
+ }
+
+ var writerStartPosition = writer.BaseStream.Position;
+
+ ushort tag;
+ ushort signature = 0;
+ ushort referenceId = 0;
+
+ if (item is MethodDefinition &&
+ _context.MethodDefinitionTable.TryGetMethodReferenceId(item as MethodDefinition, out referenceId))
+ {
+ // MemberRefParent tag is 3 (MethodDef)
+ tag = 3;
+
+ signature = 0;
+ }
+ else if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
+ {
+ // MemberRefParent tag is 1 (TypeRef)
+ tag = 1;
+
+ // get signature index
+ signature = _context.SignaturesTable.GetOrCreateSignatureId(item.DeclaringType);
+ }
+ else if (_context.TypeSpecificationsTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
+ {
+ // MemberRefParent tag is 4 (TypeSpec)
+ tag = 4;
+
+ // get signature index
+ signature = _context.SignaturesTable.GetOrCreateSignatureId(item.DeclaringType);
+ }
+ else if (_context.TypeDefinitionTable.TryGetTypeReferenceId(item.DeclaringType.Resolve(), out referenceId))
+ {
+ // MemberRefParent tag is 0 (TypeDef)
+ tag = 0;
+
+ // get signature index
+ signature = _context.SignaturesTable.GetOrCreateSignatureId(item.DeclaringType.Resolve());
+ }
+ else
+ {
+ // developer note:
+ // The current implementation is lacking support for: ModuleRef and MethodDef
+
+ throw new ArgumentException($"Can't find entry in type reference table for {item.DeclaringType.FullName} for MethodReference {item.FullName}.");
+ }
+
+ // MethodDefOrRef tag is 3 bits
+ referenceId = (ushort)(referenceId << 3);
+
+ // OR with tag to form coded index
+ referenceId |= tag;
+
+ WriteStringReference(writer, item.Name);
+ writer.WriteUInt16(referenceId);
+
+ writer.WriteUInt16(signature);
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_MEMBERREF);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoMethodDefinitionTable.cs b/MetadataProcessor.Shared/Tables/nanoMethodDefinitionTable.cs
index 2ee60fb0..7972d674 100644
--- a/MetadataProcessor.Shared/Tables/nanoMethodDefinitionTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoMethodDefinitionTable.cs
@@ -1,7 +1,11 @@
-using Mono.Cecil;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -12,7 +16,13 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoMethodDefinitionTable :
nanoReferenceTableBase
{
- private const int sizeOf_CLR_RECORD_METHODDEF = 16;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_METHODDEF = 19;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
///
/// Helper class for comparing two instances of objects
@@ -33,6 +43,8 @@ public int GetHashCode(MethodDefinition that)
}
}
+ public NanoClrTable TableIndex => NanoClrTable.TBL_MethodDef;
+
///
/// Creates new instance of object.
///
@@ -65,16 +77,21 @@ protected override void WriteSingleItem(
nanoBinaryWriter writer,
MethodDefinition item)
{
- var writerStartPosition = writer.BaseStream.Position;
if (!_context.MinimizeComplete)
{
return;
}
+ var writerStartPosition = writer.BaseStream.Position;
+
+ // Name
WriteStringReference(writer, item.Name);
+
+ // RVA
writer.WriteUInt16(_context.ByteCodeTable.GetMethodRva(item));
+ // Flags
writer.WriteUInt32(GetFlags(item));
var parametersCount = (byte)item.Parameters.Count;
@@ -83,7 +100,9 @@ protected override void WriteSingleItem(
++parametersCount; // add implicit 'this' pointer into non-static methods
}
+ // RetVal
_context.SignaturesTable.WriteDataType(item.ReturnType, writer, false, false, false);
+
if (item.ReturnType is TypeSpecification)
{
// developer note
@@ -97,13 +116,18 @@ protected override void WriteSingleItem(
//}
}
+ // ArgumentsCount
writer.WriteByte(parametersCount);
+
+ // LocalsCount
writer.WriteByte((byte)(item.HasBody ? item.Body.Variables.Count : 0));
+
+ // LengthEvalStack
writer.WriteByte(CodeWriter.CalculateStackSize(item.Body));
var methodSignature = _context.SignaturesTable.GetOrCreateSignatureId(item);
- // locals signature
+ // Locals signature
if (item.HasBody)
{
writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item.Body.Variables));
@@ -122,6 +146,21 @@ protected override void WriteSingleItem(
}
}
+ ushort genericParamRefId = 0xFFFF;
+
+ if (item.HasGenericParameters)
+ {
+ // no need to check if it's found
+ _context.GenericParamsTable.TryGetParameterId(item.GenericParameters.FirstOrDefault(), out genericParamRefId);
+ }
+
+ // FirstGenericParam
+ writer.WriteUInt16(genericParamRefId);
+
+ // GenericParamCount
+ writer.WriteByte((byte)item.GenericParameters.Count);
+
+ // Signature
writer.WriteUInt16(methodSignature);
var writerEndPosition = writer.BaseStream.Position;
@@ -158,8 +197,8 @@ public static uint GetFlags(MethodDefinition method)
const uint MD_DelegateBeginInvoke = 0x00040000;
const uint MD_DelegateEndInvoke = 0x00080000;
- const uint MD_ContainsGenericParameter = 0x00100000;
- const uint MD_HasGenericParameter = 0x00200000;
+ const uint MD_IsGenericInstance = 0x00100000;
+ const uint MD_ContainsGenericParameter = 0x00200000;
const uint MD_Synchronized = 0x01000000;
const uint MD_GloballySynchronized = 0x02000000;
@@ -242,7 +281,7 @@ public static uint GetFlags(MethodDefinition method)
flag |= (method.IsStatic ? MD_StaticConstructor : MD_Constructor);
}
- if(method.Name == "Finalize"
+ if (method.Name == "Finalize"
&& method.ReturnType.FullName == "System.Void"
&& method.Parameters.Count == 0)
{
@@ -300,9 +339,9 @@ public static uint GetFlags(MethodDefinition method)
flag |= MD_ContainsGenericParameter;
}
- if (method.HasGenericParameters)
+ if (method.IsGenericInstance)
{
- flag |= MD_HasGenericParameter;
+ flag |= MD_IsGenericInstance;
}
return flag;
diff --git a/MetadataProcessor.Shared/Tables/nanoMethodReferenceTable.cs b/MetadataProcessor.Shared/Tables/nanoMethodReferenceTable.cs
index ff04252e..4a09ddc2 100644
--- a/MetadataProcessor.Shared/Tables/nanoMethodReferenceTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoMethodReferenceTable.cs
@@ -1,12 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -17,6 +18,14 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoMethodReferenceTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_METHODREF = 6;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
@@ -36,6 +45,8 @@ public int GetHashCode(MethodReference that)
}
}
+ public NanoClrTable TableIndex => NanoClrTable.TBL_MethodRef;
+
///
/// Creates new instance of object.
///
@@ -73,56 +84,35 @@ protected override void WriteSingleItem(
return;
}
- bool experimentalCode = true;
-
- ushort referenceId;
-
+ var writerStartPosition = writer.BaseStream.Position;
- if (experimentalCode)
+ if ((item.DeclaringType is TypeSpecification ||
+ item.DeclaringType is GenericParameter) &&
+ _context.TypeSpecificationsTable.TryGetTypeReferenceId(item.DeclaringType, out ushort referenceId))
{
- ////////////////////////////////////
- // EXPERIMENTAL CODE FOR GENERICS //
- ////////////////////////////////////
-
- if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(referenceId);
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType.Resolve(), out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16((ushort)(referenceId | 0x8000));
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else if (_context.TypeDefinitionTable.TryGetTypeReferenceId(item.DeclaringType.Resolve(), out referenceId))
- {
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16((ushort)(referenceId | 0x8000));
-
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
- else
- {
- throw new ArgumentException($"Can't find entry in type reference table for {item.DeclaringType.FullName} for Method {item.FullName}.");
- }
+ // is TypeSpecification
+ }
+ else if (_context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
+ {
+ // is TypeReference
}
else
{
- _context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId);
+ throw new ArgumentException($"Can't find a type reference for {item.DeclaringType}.");
+ }
- WriteStringReference(writer, item.Name);
- writer.WriteUInt16(referenceId);
+ // Name
+ WriteStringReference(writer, item.Name);
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0); // padding
- }
+ // Owner
+ writer.WriteUInt16((ushort)(item.DeclaringType.ToCLR_TypeRefOrSpec() | referenceId));
+
+ // Signature
+ writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_METHODREF);
}
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoMethodSpecificationTable.cs b/MetadataProcessor.Shared/Tables/nanoMethodSpecificationTable.cs
new file mode 100644
index 00000000..81846591
--- /dev/null
+++ b/MetadataProcessor.Shared/Tables/nanoMethodSpecificationTable.cs
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// Encapsulates logic for storing method specifications list and writing
+ /// this collected list into target assembly in .NET nanoFramework format.
+ ///
+ public sealed class nanoMethodSpecificationTable :
+ nanoReferenceTableBase
+ {
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_METHODSPEC = 6;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Helper class for comparing two instances of objects
+ /// using property as unique key for comparison.
+ ///
+ private sealed class MemberReferenceComparer : IEqualityComparer
+ {
+ ///
+ public bool Equals(MethodSpecification x, MethodSpecification y)
+ {
+ if (x is null)
+ {
+ throw new ArgumentNullException(nameof(x));
+ }
+
+ if (y is null)
+ {
+ throw new ArgumentNullException(nameof(y));
+ }
+
+ return x.MetadataToken.ToInt32() == y.MetadataToken.ToInt32();
+ }
+
+ ///
+ public int GetHashCode(MethodSpecification obj)
+ {
+ return obj.MetadataToken.ToInt32().GetHashCode();
+ }
+ }
+
+ public NanoClrTable TableIndex => NanoClrTable.TBL_MethodSpec;
+
+ ///
+ /// Creates new instance of object.
+ ///
+ /// List of member references in Mono.Cecil format.
+ ///
+ /// Assembly tables context - contains all tables used for building target assembly.
+ ///
+ public nanoMethodSpecificationTable(
+ IEnumerable items,
+ nanoTablesContext context)
+ : base(items, new MemberReferenceComparer(), context)
+ {
+ }
+
+ ///
+ /// Gets method specification ID if possible.
+ ///
+ /// Method reference metadata in Mono.Cecil format.
+ /// Method reference ID in .NET nanoFramework format.
+ /// Returns true if reference found, otherwise returns false.
+ public bool TryGetMethodSpecificationId(
+ MethodSpecification genericParameter,
+ out ushort referenceId)
+ {
+ return TryGetIdByValue(genericParameter, out referenceId);
+ }
+
+ ///
+ protected override void WriteSingleItem(
+ nanoBinaryWriter writer,
+ MethodSpecification item)
+ {
+ if (!_context.MinimizeComplete)
+ {
+ return;
+ }
+
+ var writerStartPosition = writer.BaseStream.Position;
+
+ // Method
+ if (_context.MethodDefinitionTable.TryGetMethodReferenceId(item.Resolve(), out ushort referenceId))
+ {
+ // method is method definition
+ }
+ else
+ {
+ Debug.Fail($"Can't find a reference for {item.Resolve()}");
+ }
+
+ writer.WriteUInt16((ushort)(item.ToEncodedNanoMethodToken() | referenceId));
+
+ // Instantiation
+ writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
+
+ // Container
+ if (_context.TypeSpecificationsTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId))
+ {
+ // method is method definition
+ }
+
+ writer.WriteUInt16(referenceId);
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_METHODSPEC);
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoReferenceTableBase.cs b/MetadataProcessor.Shared/Tables/nanoReferenceTableBase.cs
index 205ff278..7607f562 100644
--- a/MetadataProcessor.Shared/Tables/nanoReferenceTableBase.cs
+++ b/MetadataProcessor.Shared/Tables/nanoReferenceTableBase.cs
@@ -1,13 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -172,5 +171,47 @@ public virtual void RemoveUnusedItems(HashSet set)
_items = usedItems;
}
+
+ public virtual void AddItem(T value, int index = -1)
+ {
+ // sanity check
+ if (_idsByItemsDictionary.ContainsKey(value))
+ {
+ // already there
+ return;
+ }
+
+ // need to recreate the items dictionary after adding this new one
+
+ List copyOfItems = new List();
+
+ foreach (var i in _idsByItemsDictionary)
+ {
+ copyOfItems.Add(i.Key);
+ }
+
+ // add new item...
+ if (index > -1)
+ {
+ // index was specified, so make it happen
+ copyOfItems.Insert(index, value);
+ }
+ else
+ {
+ // no index specified, so just add it
+ copyOfItems.Add(value);
+ }
+
+ // rebuild dictionary
+ _idsByItemsDictionary = copyOfItems
+ .Select((reference,
+ position) => new { reference, position })
+ .ToDictionary(item => item.reference,
+ item => (ushort)item.position,
+ _comparer);
+
+ // repopulate items
+ _items = copyOfItems;
+ }
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoResourceDataTable.cs b/MetadataProcessor.Shared/Tables/nanoResourceDataTable.cs
index d80f147e..23a8de5d 100644
--- a/MetadataProcessor.Shared/Tables/nanoResourceDataTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoResourceDataTable.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System.Collections.Generic;
@@ -18,6 +17,7 @@ public sealed class nanoResourceDataTable : InanoTable
/// List of registered resouce data for writing into output stream "as is".
///
private readonly IList _dataByteArrays = new List();
+ public NanoClrTable TableIndex => NanoClrTable.TBL_ResourcesData;
///
/// Gets current offset in resrouces data table (total size of all data blocks).
diff --git a/MetadataProcessor.Shared/Tables/nanoResourceFileTable.cs b/MetadataProcessor.Shared/Tables/nanoResourceFileTable.cs
index 9729e184..1d33504e 100644
--- a/MetadataProcessor.Shared/Tables/nanoResourceFileTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoResourceFileTable.cs
@@ -1,13 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -27,6 +26,8 @@ public sealed class nanoResourceFileTable : InanoTable
///
private readonly IList> _resouces = new List>();
+ public NanoClrTable TableIndex => NanoClrTable.TBL_ResourcesFiles;
+
///
/// Creates new instance of object.
///
@@ -76,4 +77,4 @@ public void Write(
}
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/Tables/nanoResourcesTable.cs b/MetadataProcessor.Shared/Tables/nanoResourcesTable.cs
index bca808ce..ee9d9d41 100644
--- a/MetadataProcessor.Shared/Tables/nanoResourcesTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoResourcesTable.cs
@@ -1,10 +1,8 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -13,6 +11,7 @@
using System.IO;
using System.Linq;
using System.Resources;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -43,6 +42,8 @@ private enum ResourceKind : byte
///
private readonly nanoTablesContext _context;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_Resources;
+
///
/// Creates new instance of object.
///
diff --git a/MetadataProcessor.Shared/Tables/nanoSignaturesTable.cs b/MetadataProcessor.Shared/Tables/nanoSignaturesTable.cs
index b72f4f10..8a4acbb7 100644
--- a/MetadataProcessor.Shared/Tables/nanoSignaturesTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoSignaturesTable.cs
@@ -40,67 +40,67 @@ public int GetHashCode(byte[] that)
}
}
- private static readonly IDictionary s_primitiveTypes =
- new Dictionary(StringComparer.Ordinal);
+ private static readonly IDictionary s_primitiveTypes =
+ new Dictionary(StringComparer.Ordinal);
///
/// Built-in types (see flags in c_CLR_RT_DataTypeLookup at CLR Core code)
///
- private static readonly IDictionary s_builtInTypes =
- new Dictionary(StringComparer.Ordinal);
+ private static readonly IDictionary s_builtInTypes =
+ new Dictionary(StringComparer.Ordinal);
- public static IDictionary PrimitiveTypes => s_primitiveTypes;
+ public static IDictionary PrimitiveTypes => s_primitiveTypes;
static nanoSignaturesTable()
{
- s_primitiveTypes.Add(typeof(void).FullName, nanoCLR_DataType.DATATYPE_VOID);
+ s_primitiveTypes.Add(typeof(void).FullName, NanoCLRDataType.DATATYPE_VOID);
- s_primitiveTypes.Add(typeof(sbyte).FullName, nanoCLR_DataType.DATATYPE_I1);
- s_primitiveTypes.Add(typeof(short).FullName, nanoCLR_DataType.DATATYPE_I2);
- s_primitiveTypes.Add(typeof(int).FullName, nanoCLR_DataType.DATATYPE_I4);
- s_primitiveTypes.Add(typeof(long).FullName, nanoCLR_DataType.DATATYPE_I8);
+ s_primitiveTypes.Add(typeof(sbyte).FullName, NanoCLRDataType.DATATYPE_I1);
+ s_primitiveTypes.Add(typeof(short).FullName, NanoCLRDataType.DATATYPE_I2);
+ s_primitiveTypes.Add(typeof(int).FullName, NanoCLRDataType.DATATYPE_I4);
+ s_primitiveTypes.Add(typeof(long).FullName, NanoCLRDataType.DATATYPE_I8);
- s_primitiveTypes.Add(typeof(byte).FullName, nanoCLR_DataType.DATATYPE_U1);
- s_primitiveTypes.Add(typeof(ushort).FullName, nanoCLR_DataType.DATATYPE_U2);
- s_primitiveTypes.Add(typeof(uint).FullName, nanoCLR_DataType.DATATYPE_U4);
- s_primitiveTypes.Add(typeof(ulong).FullName, nanoCLR_DataType.DATATYPE_U8);
+ s_primitiveTypes.Add(typeof(byte).FullName, NanoCLRDataType.DATATYPE_U1);
+ s_primitiveTypes.Add(typeof(ushort).FullName, NanoCLRDataType.DATATYPE_U2);
+ s_primitiveTypes.Add(typeof(uint).FullName, NanoCLRDataType.DATATYPE_U4);
+ s_primitiveTypes.Add(typeof(ulong).FullName, NanoCLRDataType.DATATYPE_U8);
- s_primitiveTypes.Add(typeof(float).FullName, nanoCLR_DataType.DATATYPE_R4);
- s_primitiveTypes.Add(typeof(double).FullName, nanoCLR_DataType.DATATYPE_R8);
+ s_primitiveTypes.Add(typeof(float).FullName, NanoCLRDataType.DATATYPE_R4);
+ s_primitiveTypes.Add(typeof(double).FullName, NanoCLRDataType.DATATYPE_R8);
- s_primitiveTypes.Add(typeof(char).FullName, nanoCLR_DataType.DATATYPE_CHAR);
- s_primitiveTypes.Add(typeof(string).FullName, nanoCLR_DataType.DATATYPE_STRING);
- s_primitiveTypes.Add(typeof(bool).FullName, nanoCLR_DataType.DATATYPE_BOOLEAN);
+ s_primitiveTypes.Add(typeof(char).FullName, NanoCLRDataType.DATATYPE_CHAR);
+ s_primitiveTypes.Add(typeof(string).FullName, NanoCLRDataType.DATATYPE_STRING);
+ s_primitiveTypes.Add(typeof(bool).FullName, NanoCLRDataType.DATATYPE_BOOLEAN);
- s_primitiveTypes.Add(typeof(object).FullName, nanoCLR_DataType.DATATYPE_OBJECT);
- s_primitiveTypes.Add(typeof(IntPtr).FullName, nanoCLR_DataType.DATATYPE_I4);
- s_primitiveTypes.Add(typeof(UIntPtr).FullName, nanoCLR_DataType.DATATYPE_U4);
+ s_primitiveTypes.Add(typeof(object).FullName, NanoCLRDataType.DATATYPE_OBJECT);
+ s_primitiveTypes.Add(typeof(IntPtr).FullName, NanoCLRDataType.DATATYPE_I4);
+ s_primitiveTypes.Add(typeof(UIntPtr).FullName, NanoCLRDataType.DATATYPE_U4);
- s_primitiveTypes.Add(typeof(WeakReference).FullName, nanoCLR_DataType.DATATYPE_WEAKCLASS);
+ s_primitiveTypes.Add(typeof(WeakReference).FullName, NanoCLRDataType.DATATYPE_WEAKCLASS);
// from c_CLR_RT_DataTypeLookup at CLR Core code
- s_builtInTypes.Add(typeof(bool).FullName, nanoCLR_DataType.DATATYPE_BOOLEAN);
- s_builtInTypes.Add(typeof(char).FullName, nanoCLR_DataType.DATATYPE_CHAR);
- s_builtInTypes.Add(typeof(sbyte).FullName, nanoCLR_DataType.DATATYPE_I1);
- s_builtInTypes.Add(typeof(byte).FullName, nanoCLR_DataType.DATATYPE_U1);
- s_builtInTypes.Add(typeof(short).FullName, nanoCLR_DataType.DATATYPE_I2);
- s_builtInTypes.Add(typeof(ushort).FullName, nanoCLR_DataType.DATATYPE_U2);
- s_builtInTypes.Add(typeof(int).FullName, nanoCLR_DataType.DATATYPE_I4);
- s_builtInTypes.Add(typeof(uint).FullName, nanoCLR_DataType.DATATYPE_U4);
- s_builtInTypes.Add(typeof(long).FullName, nanoCLR_DataType.DATATYPE_I8);
- s_builtInTypes.Add(typeof(ulong).FullName, nanoCLR_DataType.DATATYPE_U8);
- s_builtInTypes.Add(typeof(float).FullName, nanoCLR_DataType.DATATYPE_R4);
- s_builtInTypes.Add(typeof(double).FullName, nanoCLR_DataType.DATATYPE_R8);
-
- s_builtInTypes.Add(typeof(DateTime).FullName, nanoCLR_DataType.DATATYPE_DATETIME);
- s_builtInTypes.Add(typeof(TimeSpan).FullName, nanoCLR_DataType.DATATYPE_TIMESPAN);
- s_builtInTypes.Add(typeof(string).FullName, nanoCLR_DataType.DATATYPE_STRING);
-
- s_builtInTypes.Add("System.RuntimeTypeHandle", nanoCLR_DataType.DATATYPE_REFLECTION);
- s_builtInTypes.Add("System.RuntimeFieldHandle", nanoCLR_DataType.DATATYPE_REFLECTION);
- s_builtInTypes.Add("System.RuntimeMethodHandle", nanoCLR_DataType.DATATYPE_REFLECTION);
-
- s_builtInTypes.Add(typeof(WeakReference).FullName, nanoCLR_DataType.DATATYPE_WEAKCLASS);
+ s_builtInTypes.Add(typeof(bool).FullName, NanoCLRDataType.DATATYPE_BOOLEAN);
+ s_builtInTypes.Add(typeof(char).FullName, NanoCLRDataType.DATATYPE_CHAR);
+ s_builtInTypes.Add(typeof(sbyte).FullName, NanoCLRDataType.DATATYPE_I1);
+ s_builtInTypes.Add(typeof(byte).FullName, NanoCLRDataType.DATATYPE_U1);
+ s_builtInTypes.Add(typeof(short).FullName, NanoCLRDataType.DATATYPE_I2);
+ s_builtInTypes.Add(typeof(ushort).FullName, NanoCLRDataType.DATATYPE_U2);
+ s_builtInTypes.Add(typeof(int).FullName, NanoCLRDataType.DATATYPE_I4);
+ s_builtInTypes.Add(typeof(uint).FullName, NanoCLRDataType.DATATYPE_U4);
+ s_builtInTypes.Add(typeof(long).FullName, NanoCLRDataType.DATATYPE_I8);
+ s_builtInTypes.Add(typeof(ulong).FullName, NanoCLRDataType.DATATYPE_U8);
+ s_builtInTypes.Add(typeof(float).FullName, NanoCLRDataType.DATATYPE_R4);
+ s_builtInTypes.Add(typeof(double).FullName, NanoCLRDataType.DATATYPE_R8);
+
+ s_builtInTypes.Add(typeof(DateTime).FullName, NanoCLRDataType.DATATYPE_DATETIME);
+ s_builtInTypes.Add(typeof(TimeSpan).FullName, NanoCLRDataType.DATATYPE_TIMESPAN);
+ s_builtInTypes.Add(typeof(string).FullName, NanoCLRDataType.DATATYPE_STRING);
+
+ s_builtInTypes.Add("System.RuntimeTypeHandle", NanoCLRDataType.DATATYPE_REFLECTION);
+ s_builtInTypes.Add("System.RuntimeFieldHandle", NanoCLRDataType.DATATYPE_REFLECTION);
+ s_builtInTypes.Add("System.RuntimeMethodHandle", NanoCLRDataType.DATATYPE_REFLECTION);
+
+ s_builtInTypes.Add(typeof(WeakReference).FullName, NanoCLRDataType.DATATYPE_WEAKCLASS);
}
///
@@ -121,6 +121,8 @@ static nanoSignaturesTable()
///
private ushort _lastAvailableId;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_Signatures;
+
///
/// Creates new instance of object.
///
@@ -135,52 +137,75 @@ public nanoSignaturesTable(nanoTablesContext context)
}
///
- /// Gets existing or creates new singature identifier for method definition.
+ /// Gets existing or creates new signature identifier for field definition.
///
- /// Method definition in Mono.Cecil format.
+ /// Field definition in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
- MethodDefinition methodDefinition)
+ FieldDefinition fieldDefinition)
{
- var sig = GetSignature(methodDefinition);
+ var sig = GetSignature(fieldDefinition.FieldType, true);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{methodDefinition.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{fieldDefinition.MetadataToken} ({fieldDefinition.FullName}) {fieldDefinition.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
///
- /// Gets existing or creates new singature identifier for field definition.
+ /// Gets existing or creates new signature identifier for the list of generic parameters.
///
- /// Field definition in Mono.Cecil format.
+ /// List of parameters information in Mono.Cecil format.
+ public ushort GetOrCreateSignatureId(Collection genericParameters)
+ {
+ if (genericParameters == null || genericParameters.Count == 0)
+ {
+ return 0xFFFF; // No generic parameters
+ }
+
+ return GetOrCreateSignatureIdImpl(GetSignature(genericParameters));
+ }
+
+ ///
+ /// Gets existing or creates new signature identifier for field reference.
+ ///
+ /// Field reference in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
- FieldDefinition fieldDefinition)
+ FieldReference fieldReference)
{
- var sig = GetSignature(fieldDefinition.FieldType, true);
+ var sig = GetSignature(fieldReference);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{fieldDefinition.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{fieldReference.MetadataToken} ({fieldReference.FullName}) {fieldReference.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
///
- /// Gets existing or creates new singature identifier for field reference.
+ /// Gets existing or creates new signature identifier for method definition.
///
- /// Field reference in Mono.Cecil format.
+ /// Method definition in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
- FieldReference fieldReference)
+ MethodDefinition methodDefinition)
{
- var sig = GetSignature(fieldReference);
+ var sig = GetSignature(methodDefinition);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{fieldReference.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{methodDefinition.MetadataToken} ({methodDefinition.FullName}) {methodDefinition.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
///
- /// Gets existing or creates new singature identifier for member reference.
+ /// Gets existing or creates new signature identifier for method reference.
///
/// Method reference in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
@@ -189,13 +214,34 @@ public ushort GetOrCreateSignatureId(
var sig = GetSignature(methodReference);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{methodReference.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{methodReference.MetadataToken} ({methodReference.FullName}) {methodReference.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
+
+ return sigId;
+ }
+
+ ///
+ /// Gets existing or creates new signature identifier for method specification.
+ ///
+ /// Method reference in Mono.Cecil format.
+ public ushort GetOrCreateSignatureId(
+ MethodSpecification methodSpecification)
+ {
+ var sig = GetSignature(methodSpecification);
+ var sigId = GetOrCreateSignatureIdImpl(sig);
+
+ if (_verbose)
+ {
+ Console.WriteLine($"{methodSpecification.MetadataToken} ({methodSpecification.FullName}) {methodSpecification.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
///
- /// Gets existing or creates new singature identifier for list of local variables.
+ /// Gets existing or creates new signature identifier for list of local variables.
///
/// List of variables information in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
@@ -210,7 +256,7 @@ public ushort GetOrCreateSignatureId(
}
///
- /// Gets existing or creates new singature identifier for list of class interfaces.
+ /// Gets existing or creates new signature identifier for list of class interfaces.
///
/// List of interfaes information in Mono.Cecil format.
public ushort GetOrCreateSignatureId(
@@ -249,7 +295,10 @@ public ushort GetOrCreateSignatureId(
var sig = GetSignature(interfaceImplementation, false);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{interfaceImplementation.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{interfaceImplementation.MetadataToken} ({interfaceImplementation.InterfaceType.FullName}) {interfaceImplementation.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
@@ -264,7 +313,10 @@ public ushort GetOrCreateSignatureId(
var sig = GetSignature(typeReference, false);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{typeReference.MetadataToken.ToInt32()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{typeReference.MetadataToken} ({typeReference.FullName}) {typeReference.MetadataToken.ToInt32():X8} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
@@ -278,7 +330,10 @@ public ushort GetOrCreateSignatureId(CustomAttribute customAttribute)
var sig = GetSignature(customAttribute);
var sigId = GetOrCreateSignatureIdImpl(sig);
- if (_verbose) Console.WriteLine($"{customAttribute.ToString()} -> {sig.BufferToHexString()} -> {sigId.ToString("X4")}");
+ if (_verbose)
+ {
+ Console.WriteLine($"{customAttribute} -> {sig.BufferToHexString()} -> {sigId:X4}");
+ }
return sigId;
}
@@ -300,13 +355,13 @@ public void WriteDataType(
if (isTypeDefinition &&
typeDefinition.MetadataType == MetadataType.Object)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_CLASS);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_CLASS);
return;
}
if (s_primitiveTypes.TryGetValue(
typeDefinition.FullName,
- out nanoCLR_DataType dataType))
+ out NanoCLRDataType dataType))
{
writer.WriteByte((byte)dataType);
return;
@@ -319,7 +374,7 @@ public void WriteDataType(
if (typeDefinition.MetadataType == MetadataType.Class)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_CLASS);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_CLASS);
if (alsoWriteSubType)
{
WriteSubTypeInfo(typeDefinition, writer);
@@ -340,7 +395,7 @@ public void WriteDataType(
}
}
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_VALUETYPE);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_VALUETYPE);
if (alsoWriteSubType)
{
WriteSubTypeInfo(typeDefinition, writer);
@@ -350,7 +405,20 @@ public void WriteDataType(
if (typeDefinition.MetadataType == MetadataType.Var)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_MVAR);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_VAR);
+
+ if (alsoWriteSubType)
+ {
+ // following ECMA-335 VI.B.4.3 Metadata
+ writer.WriteByte((byte)(typeDefinition as GenericParameter).Position);
+ }
+
+ return;
+ }
+
+ if (typeDefinition.MetadataType == MetadataType.MVar)
+ {
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_MVAR);
if (alsoWriteSubType)
{
@@ -363,15 +431,16 @@ public void WriteDataType(
if (typeDefinition.IsArray)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_SZARRAY);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_SZARRAY);
var array = (ArrayType)typeDefinition;
if (array.ElementType.IsGenericParameter)
{
// ECMA 335 VI.B.4.3 Metadata
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_VAR);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_VAR);
+ // OK to use byte here as we won't support more than 0x7F generic parameters
writer.WriteByte((byte)(array.ElementType as GenericParameter).Position);
}
else if (alsoWriteSubType)
@@ -385,7 +454,7 @@ public void WriteDataType(
if (typeDefinition.IsByReference)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_BYREF);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_BYREF);
if (alsoWriteSubType)
{
@@ -400,12 +469,13 @@ public void WriteDataType(
if (typeDefinition.IsGenericInstance)
{
// following ECMA-335 VI.B.4.3 Metadata
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_GENERICINST);
+ // II.23.2.12 Type
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_GENERICINST);
var genericType = (GenericInstanceType)typeDefinition;
+ WriteDataType(genericType.Resolve(), writer, true, expandEnumType, isTypeDefinition);
- WriteDataType(genericType.ElementType, writer, false, expandEnumType, isTypeDefinition);
-
+ // OK to use byte here as we won't support more than 0x7F arguments
writer.WriteByte((byte)genericType.GenericArguments.Count);
foreach (var a in genericType.GenericArguments)
@@ -429,7 +499,7 @@ public void WriteDataTypeForTypeDef(TypeDefinition typeDefinition, nanoBinaryWri
// start checking with the built-in types
if (s_builtInTypes.TryGetValue(
typeDefinition.FullName,
- out nanoCLR_DataType dataType))
+ out NanoCLRDataType dataType))
{
writer.WriteByte((byte)dataType);
}
@@ -446,16 +516,16 @@ public void WriteDataTypeForTypeDef(TypeDefinition typeDefinition, nanoBinaryWri
}
else
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_I4);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_I4);
}
}
else if (typeDefinition.IsValueType)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_VALUETYPE);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_VALUETYPE);
}
else if (typeDefinition.IsClass || typeDefinition.IsInterface)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_CLASS);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_CLASS);
}
else
{
@@ -530,6 +600,35 @@ internal byte[] GetSignature(
}
}
+ internal byte[] GetSignature(
+ MethodSpecification methodSpecification)
+ {
+ using (var buffer = new MemoryStream())
+ using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
+ {
+ var binaryWriter = nanoBinaryWriter.CreateLittleEndianBinaryWriter(writer);
+
+ var genericInstance = methodSpecification as GenericInstanceMethod;
+
+ // implementation from ECMA-335 II.23.2.15
+
+ // method calling convention
+ // IMAGE_CEE_CS_CALLCONV_GENERICINST: 0x0A
+
+ writer.Write((byte)0x0A);
+
+ // generic arguments count
+ writer.Write((byte)(genericInstance.GenericArguments.Count));
+
+ foreach (var argument in genericInstance.GenericArguments)
+ {
+ WriteTypeInfo(argument.GetElementType(), binaryWriter);
+ }
+
+ return buffer.ToArray();
+ }
+ }
+
private byte[] GetSignature(
IEnumerable variables)
{
@@ -587,6 +686,21 @@ private byte[] GetSignature(
}
}
+ private byte[] GetSignature(Collection genericParameters)
+ {
+ using (var buffer = new MemoryStream())
+ // Only Write(Byte) will be used
+ using (var writer = new BinaryWriter(buffer))
+ {
+ foreach (GenericParameter parameter in genericParameters)
+ {
+ WriteGenericParameterValue(writer, parameter);
+ }
+
+ return buffer.ToArray();
+ }
+ }
+
private byte[] GetSignature(
InterfaceImplementation typeReference,
bool isFieldSignature)
@@ -643,60 +757,60 @@ private void WriteAttributeArgumentValue(
BinaryWriter writer,
CustomAttributeArgument argument)
{
- nanoCLR_DataType dataType;
+ NanoCLRDataType dataType;
if (s_primitiveTypes.TryGetValue(argument.Type.FullName, out dataType))
{
switch (dataType)
{
- case nanoCLR_DataType.DATATYPE_BOOLEAN:
+ case NanoCLRDataType.DATATYPE_BOOLEAN:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_BOOLEAN);
writer.Write((byte)((bool)argument.Value ? 1 : 0));
break;
- case nanoCLR_DataType.DATATYPE_I1:
+ case NanoCLRDataType.DATATYPE_I1:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_I1);
writer.Write((sbyte)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_U1:
+ case NanoCLRDataType.DATATYPE_U1:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_U1);
writer.Write((byte)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_I2:
+ case NanoCLRDataType.DATATYPE_I2:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_I2);
writer.Write((short)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_U2:
+ case NanoCLRDataType.DATATYPE_U2:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_U2);
writer.Write((ushort)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_I4:
+ case NanoCLRDataType.DATATYPE_I4:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_I4);
writer.Write((int)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_U4:
+ case NanoCLRDataType.DATATYPE_U4:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_U4);
writer.Write((uint)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_I8:
+ case NanoCLRDataType.DATATYPE_I8:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_I8);
writer.Write((long)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_U8:
+ case NanoCLRDataType.DATATYPE_U8:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_U8);
writer.Write((ulong)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_R4:
+ case NanoCLRDataType.DATATYPE_R4:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_R4);
writer.Write((float)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_R8:
+ case NanoCLRDataType.DATATYPE_R8:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_R8);
writer.Write((double)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_CHAR:
+ case NanoCLRDataType.DATATYPE_CHAR:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_CHAR);
writer.Write((char)argument.Value);
break;
- case nanoCLR_DataType.DATATYPE_STRING:
+ case NanoCLRDataType.DATATYPE_STRING:
writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_STRING);
writer.Write(_context.StringTable.GetOrCreateStringId((string)argument.Value));
break;
@@ -727,6 +841,22 @@ private void WriteAttributeArgumentValue(
}
}
+ private void WriteGenericParameterValue(BinaryWriter writer, GenericParameter parameter)
+ {
+ if (_context.GenericParamsTable.TryGetParameterId(parameter, out ushort referenceId))
+ {
+ writer.Write((byte)nanoSerializationType.ELEMENT_TYPE_GENERICINST);
+
+ // OK to use byte because we are not supporting more than 0x7F generic parameters
+ writer.Write((byte)referenceId);
+ }
+ else
+ {
+ // TODO
+ Debug.Fail("NEED TO IMPLEMENT THIS");
+ }
+ }
+
private ushort GetOrCreateSignatureIdImpl(
byte[] signature)
{
@@ -766,7 +896,7 @@ private void WriteTypeInfo(
var byReference = typeReference as ByReferenceType;
if (byReference != null)
{
- writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_BYREF);
+ writer.WriteByte((byte)NanoCLRDataType.DATATYPE_BYREF);
WriteDataType(byReference.ElementType, writer, true, false, false);
}
else
@@ -791,26 +921,47 @@ private byte[] GetFullSignaturesArray()
private void WriteSubTypeInfo(TypeReference typeDefinition, nanoBinaryWriter writer)
{
- ushort referenceId;
- if (typeDefinition is TypeSpecification &&
- _context.TypeSpecificationsTable.TryGetTypeReferenceId(typeDefinition, out referenceId))
+ // decoded at target with CLR_TkFromStream
+
+ ushort tag;
+
+ if ((typeDefinition is TypeSpecification ||
+ typeDefinition is GenericParameter) &&
+ _context.TypeSpecificationsTable.TryGetTypeReferenceId(typeDefinition, out ushort referenceId))
{
- writer.WriteMetadataToken(((uint)referenceId << 2) | 0x02);
+ // TypeDefOrRef tag is 2 (TypeSpec)
+ tag = 2;
+
+ // TypeDefOrRef tag is 2 bits
+ referenceId = (ushort)(referenceId << 2);
}
else if (_context.TypeReferencesTable.TryGetTypeReferenceId(typeDefinition, out referenceId))
{
- writer.WriteMetadataToken(((uint)referenceId << 2) | 0x01);
+ // TypeDefOrRef tag is 1 (TypeRef)
+ tag = 1;
+
+ // TypeDefOrRef tag is 2 bits
+ referenceId = (ushort)(referenceId << 2);
}
else if (_context.TypeDefinitionTable.TryGetTypeReferenceId(
typeDefinition.Resolve(),
out referenceId))
{
- writer.WriteMetadataToken((uint)referenceId << 2);
+ // TypeDefOrRef tag is 0 (TypeDef)
+ tag = 0;
+
+ // TypeDefOrRef tag is 2 bits
+ referenceId = (ushort)(referenceId << 2);
}
else
{
throw new ArgumentException($"Can't find entry in type reference table for {typeDefinition.FullName}.");
}
+
+ // OR with tag to form coded index
+ referenceId |= tag;
+
+ writer.WriteMetadataToken(referenceId);
}
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoStringTable.cs b/MetadataProcessor.Shared/Tables/nanoStringTable.cs
index 295a504c..fce091ba 100644
--- a/MetadataProcessor.Shared/Tables/nanoStringTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoStringTable.cs
@@ -1,14 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -55,6 +54,8 @@ public IEnumerable Sort(
///
private readonly nanoTablesContext _context;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_Strings;
+
///
/// Last pre-allocated string identifier.
///
diff --git a/MetadataProcessor.Shared/Tables/nanoTablesContext.cs b/MetadataProcessor.Shared/Tables/nanoTablesContext.cs
index abf1fb20..fdc927b0 100644
--- a/MetadataProcessor.Shared/Tables/nanoTablesContext.cs
+++ b/MetadataProcessor.Shared/Tables/nanoTablesContext.cs
@@ -1,11 +1,11 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
@@ -14,7 +14,6 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoTablesContext
{
internal readonly bool _verbose;
- internal readonly bool _isCoreLibrary;
internal static HashSet IgnoringAttributes { get; } = new HashSet(StringComparer.Ordinal)
{
@@ -80,7 +79,9 @@ public nanoTablesContext(
ClassNamesToExclude = classNamesToExclude;
_verbose = verbose;
- _isCoreLibrary = isCoreLibrary;
+
+ // add default types to exclude
+ SetDefaultTypesToExclude();
// add default types to exclude
SetDefaultTypesToExclude();
@@ -129,9 +130,10 @@ public nanoTablesContext(
item.DeclaringType.GetElementType().IsPrimitive ||
item.ContainsGenericParameter ||
item.DeclaringType.IsGenericInstance))
-
.ToList();
+ MemberReferencesTable = new nanoMemberReferencesTable(memberReferences, this);
+
FieldReferencesTable = new nanoFieldReferenceTable(
memberReferences.OfType(), this);
MethodReferencesTable = new nanoMethodReferenceTable(
@@ -166,8 +168,6 @@ public nanoTablesContext(
GetAttributes(methods, applyAttributesCompression),
this);
- TypeSpecificationsTable = new nanoTypeSpecificationsTable(this);
-
// Resources information
ResourcesTable = new nanoResourcesTable(
@@ -188,16 +188,14 @@ public nanoTablesContext(
ResourceFileTable = new nanoResourceFileTable(this);
+ List methodSpecifications = GetMethodSpecifications(methods);
+
+ MethodSpecificationTable = new nanoMethodSpecificationTable(methodSpecifications, this);
+
// build list of generic parameters belonging to method defs
List methodDefsGenericParameters = new List();
- foreach (var m in methods)
- {
- if (m.HasGenericParameters)
- {
- methodDefsGenericParameters.AddRange(m.GenericParameters);
- }
- }
+ methodDefsGenericParameters.AddRange(methods.Where(m => m.HasGenericParameters).SelectMany(mm => mm.GenericParameters));
var generics = types
.SelectMany(t => t.GenericParameters)
@@ -206,6 +204,8 @@ public nanoTablesContext(
GenericParamsTable = new nanoGenericParamTable(generics, this);
+ TypeSpecificationsTable = new nanoTypeSpecificationsTable(this);
+
// Pre-allocate strings from some tables
AssemblyReferenceTable.AllocateStrings();
TypeReferencesTable.AllocateStrings();
@@ -228,23 +228,240 @@ public nanoTablesContext(
}
///
- /// Gets method reference identifier (external or internal) encoded with appropriate prefix.
+ /// Gets (.NET nanoFramework encoded) method reference identifier (external or internal).
///
- /// Method reference in Mono.Cecil format.
- /// Reference identifier for passed value.
+ /// Method reference in Mono.Cecil format.
+ /// Reference identifier for passed value.
public ushort GetMethodReferenceId(
- MethodReference methodReference)
+ MemberReference memberReference)
{
- ushort referenceId;
- if (MethodReferencesTable.TryGetMethodReferenceId(methodReference, out referenceId))
+ // encodes MethodReference to be decoded with CLR_UncompressMethodToken
+ // CLR tables are:
+ // 0: TBL_MethodDef
+ // 1: TBL_MethodRef
+ // 2: TBL_MemberRef (TODO find if needed)
+
+ ushort referenceId = 0xFFFF;
+ NanoClrTable ownerTable = NanoClrTable.TBL_EndOfAssembly;
+
+ if (memberReference is MethodDefinition)
+ {
+ // check if method is external
+ if (memberReference.DeclaringType.Scope.MetadataScopeType == MetadataScopeType.AssemblyNameReference)
+ {
+ // method reference is external
+ ownerTable = NanoClrTable.TBL_MethodRef;
+ }
+ else
+ {
+ // method reference is internal
+ if (MethodDefinitionTable.TryGetMethodReferenceId(memberReference as MethodDefinition, out referenceId))
+ {
+ // method reference is internal => method definition
+ ownerTable = NanoClrTable.TBL_MethodDef;
+ }
+ else
+ {
+ Debug.Fail($"Can't find method definition for {memberReference}");
+ }
+ }
+ }
+ else if (memberReference is MethodReference &&
+ MethodReferencesTable.TryGetMethodReferenceId(memberReference as MethodReference, out referenceId))
{
- referenceId |= 0x8000; // External method reference
+ // check if method is external
+ if (memberReference.DeclaringType.Scope.MetadataScopeType == MetadataScopeType.AssemblyNameReference)
+ {
+ // method reference is external
+ }
+ else
+ {
+ // method reference belongs to a TypeSpec
+
+ // find MethodDef for this
+ var methodRef = MethodReferencesTable.Items.FirstOrDefault(m => m.DeclaringType.MetadataToken == memberReference.DeclaringType.MetadataToken && m.Name == memberReference.Name);
+
+ if (!MethodReferencesTable.TryGetMethodReferenceId(methodRef, out referenceId))
+ {
+ Debug.Fail($"Can't find MethodRef for {memberReference}");
+ }
+ }
+
+ ownerTable = NanoClrTable.TBL_MethodRef;
+ }
+ else if (memberReference is MethodSpecification &&
+ MethodSpecificationTable.TryGetMethodSpecificationId(memberReference as MethodSpecification, out referenceId))
+ {
+ // member reference is MethodSpecification
+ ownerTable = NanoClrTable.TBL_MethodSpec;
}
else
{
- MethodDefinitionTable.TryGetMethodReferenceId(methodReference.Resolve(), out referenceId);
+ Debug.Fail($"Can't find any reference for {memberReference}");
}
- return referenceId;
+
+ return (ushort)(nanoTokenHelpers.EncodeTableIndex(ownerTable, nanoTokenHelpers.NanoMemberRefTokenTables) | referenceId);
+ }
+
+ ///
+ /// Gets (.NET nanoFramework encoded) field reference identifier (external or internal).
+ ///
+ /// Field reference in Mono.Cecil format.
+ /// Reference identifier for passed value.
+ public ushort GetFieldReferenceId(
+ FieldReference fieldReference)
+ {
+ // encodes FieldReference to be decoded with CLR_UncompressFieldToken
+ // CLR tables are:
+ // 0: TBL_FieldDef
+ // 1: TBL_FieldRef
+
+ ushort referenceId = 0xFFFF;
+ NanoClrTable ownerTable = NanoClrTable.TBL_EndOfAssembly;
+
+ if (fieldReference is FieldDefinition)
+ {
+ // field reference is internal
+ if (FieldsTable.TryGetFieldReferenceId(fieldReference as FieldDefinition, false, out referenceId))
+ {
+ // field reference is internal => field definition
+ ownerTable = NanoClrTable.TBL_FieldDef;
+ }
+ else
+ {
+ Debug.Fail($"Can't find field definition for {fieldReference}");
+ }
+ }
+ else if (FieldReferencesTable.TryGetFieldReferenceId(fieldReference, out referenceId))
+ {
+ // field reference is external
+ ownerTable = NanoClrTable.TBL_FieldRef;
+ }
+ else
+ {
+ Debug.Fail($"Can't find any reference for {fieldReference}");
+ }
+
+ return (ushort)(nanoTokenHelpers.EncodeTableIndex(ownerTable, nanoTokenHelpers.NanoFieldMemberRefTokenTables) | referenceId);
+ }
+
+ ///
+ /// Gets metadata token encoded with appropriate prefix.
+ ///
+ /// Metadata token in Mono.Cecil format.
+ /// The .NET nanoFramework encoded token for passed value.
+ public uint GetMetadataToken(
+ IMetadataTokenProvider token)
+ {
+ switch (token.MetadataToken.TokenType)
+ {
+ case TokenType.TypeRef:
+ TypeReferencesTable.TryGetTypeReferenceId((TypeReference)token, out ushort referenceId);
+ return (uint)0x01000000 | referenceId;
+ case TokenType.TypeDef:
+ TypeDefinitionTable.TryGetTypeReferenceId((TypeDefinition)token, out referenceId);
+ return (uint)0x04000000 | referenceId;
+ case TokenType.TypeSpec:
+ TypeSpecificationsTable.TryGetTypeReferenceId((TypeReference)token, out referenceId);
+ return (uint)0x09000000 | referenceId;
+ case TokenType.Field:
+ FieldsTable.TryGetFieldReferenceId((FieldDefinition)token, false, out referenceId);
+ return (uint)0x05000000 | referenceId;
+ case TokenType.GenericParam:
+ GenericParamsTable.TryGetParameterId((GenericParameter)token, out referenceId);
+ return (uint)0x07000000 | referenceId;
+
+ default:
+ System.Diagnostics.Debug.Fail("Unsupported TokenType");
+ break;
+ }
+ return 0U;
+ }
+
+ ///
+ /// Gets an (.NET nanoFramework encoded) type reference identifier (all kinds).
+ ///
+ /// Type reference in Mono.Cecil format.
+ /// The mask type to add to the encoded type reference Id. TypeRef mask will be added if none is specified.
+ /// Encoded type reference identifier for passed value.
+ public ushort GetTypeReferenceId(
+ TypeReference typeReference)
+ {
+ // encodes TypeReference to be decoded with CLR_UncompressTypeToken
+
+ NanoClrTable ownerTable = NanoClrTable.TBL_EndOfAssembly;
+
+ if (typeReference is TypeSpecification &&
+ TypeSpecificationsTable.TryGetTypeReferenceId(typeReference, out ushort referenceId))
+ {
+ // is TypeSpec
+ ownerTable = NanoClrTable.TBL_TypeSpec;
+ }
+ else if (typeReference is GenericParameter)
+ {
+ // is GenericParameter
+ if (TypeSpecificationsTable.TryGetTypeReferenceId(typeReference, out referenceId))
+ {
+ // found it!
+ ownerTable = NanoClrTable.TBL_TypeSpec;
+ }
+ else
+ {
+ Debug.Fail("Can't find type reference.");
+ throw new ArgumentException($"Can't find type reference for {typeReference}.");
+ }
+ }
+ else if (typeReference is TypeDefinition &&
+ TypeDefinitionTable.TryGetTypeReferenceId(typeReference.Resolve(), out referenceId))
+ {
+ // is TypeDefinition
+ ownerTable = NanoClrTable.TBL_TypeDef;
+ }
+ else if (TypeReferencesTable.TryGetTypeReferenceId(typeReference, out referenceId))
+ {
+ // is External type reference
+ ownerTable = NanoClrTable.TBL_TypeRef;
+ }
+ else
+ {
+ Debug.Fail("Can't find type reference.");
+ throw new ArgumentException($"Can't find type reference for {typeReference}.");
+ }
+
+ return (ushort)(nanoTokenHelpers.EncodeTableIndex(ownerTable, nanoTokenHelpers.NanoTypeTokenTables) | referenceId);
+ }
+
+ private List GetMethodSpecifications(List methods)
+ {
+ List methodSpecs = new List();
+
+ // need to find MethodSpecs in method body
+ foreach (var m in methods.Where(i => i.HasBody))
+ {
+ foreach (var i in m.Body.Instructions)
+ {
+ if (i.Operand is MethodSpecification)
+ {
+ methodSpecs.Add(i.Operand as MethodSpecification);
+ }
+ }
+ }
+
+ return methodSpecs;
+ }
+
+ private List GetGenericParamsConstraints(List generics)
+ {
+ var genericsWithConstraints = generics.Where(g => g.HasConstraints);
+
+ List constraints = new List();
+
+ foreach (var g in genericsWithConstraints)
+ {
+ constraints.AddRange(g.Constraints);
+ }
+
+ return constraints;
}
public AssemblyDefinition AssemblyDefinition { get; private set; }
@@ -259,6 +476,8 @@ public ushort GetMethodReferenceId(
public nanoGenericParamTable GenericParamsTable { get; private set; }
+ public nanoMethodSpecificationTable MethodSpecificationTable { get; private set; }
+
public nanoMethodReferenceTable MethodReferencesTable { get; private set; }
public nanoFieldDefinitionTable FieldsTable { get; private set; }
@@ -267,6 +486,8 @@ public ushort GetMethodReferenceId(
public nanoTypeDefinitionTable TypeDefinitionTable { get; private set; }
+ public nanoMemberReferencesTable MemberReferencesTable { get; private set; }
+
public nanoAttributesTable AttributesTable { get; private set; }
public nanoTypeSpecificationsTable TypeSpecificationsTable { get; private set; }
@@ -461,6 +682,11 @@ internal void ResetSignaturesTable()
SignaturesTable = new nanoSignaturesTable(this);
}
+ internal void ResetTypeSpecificationsTable()
+ {
+ TypeSpecificationsTable = new nanoTypeSpecificationsTable(this);
+ }
+
internal void ResetResourcesTables()
{
ResourcesTable = new nanoResourcesTable(
diff --git a/MetadataProcessor.Shared/Tables/nanoTypeDefinitionTable.cs b/MetadataProcessor.Shared/Tables/nanoTypeDefinitionTable.cs
index f0b7fd8c..bb45a3c6 100644
--- a/MetadataProcessor.Shared/Tables/nanoTypeDefinitionTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoTypeDefinitionTable.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using Mono.Cecil;
@@ -21,6 +22,14 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoTypeDefinitionTable :
nanoReferenceTableBase
{
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_TYPEDEF = 27;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Helper class for comparing two instances of objects
/// using property as unique key for comparison.
@@ -43,14 +52,16 @@ public int GetHashCode(TypeDefinition item)
private IDictionary>> _byteCodeOffsets =
new Dictionary>>();
- public List TypeDefinitions { get; private set; }
+ private List TypeDefinitions;
public List EnumDeclarations { get; }
+ public NanoClrTable TableIndex => NanoClrTable.TBL_TypeDef;
+
///
/// Creates new instance of object.
///
- /// List of types definitins in Mono.Cecil format.
+ /// List of types definitions in Mono.Cecil format.
///
/// Assembly tables context - contains all tables used for building target assembly.
///
@@ -99,13 +110,21 @@ protected override void WriteSingleItem(
nanoBinaryWriter writer,
TypeDefinition item)
{
+ var writerStartPosition = writer.BaseStream.Position;
+
_context.StringTable.GetOrCreateStringId(item.Namespace);
+ // Name
WriteStringReference(writer, item.Name);
+
+ // NameSpace
WriteStringReference(writer, item.Namespace);
- writer.WriteUInt16(GetTypeReferenceOrDefinitionId(item.BaseType));
- writer.WriteUInt16(GetTypeReferenceOrDefinitionId(item.DeclaringType));
+ // Extends
+ writer.WriteUInt16(GetEncodedTypeReferenceOrDefinitionId(item.BaseType));
+
+ // EnclosingType
+ writer.WriteUInt16(GetEncodedTypeReferenceOrDefinitionId(item.DeclaringType));
var fieldsList = item.Fields
.Where(field => !field.HasConstant)
@@ -155,11 +174,50 @@ protected override void WriteSingleItem(
}
}
- // write flags
+ ushort genericParamRefId = 0xFFFF;
+
+ if (item.HasGenericParameters)
+ {
+ // no need to check if it's found
+ _context.GenericParamsTable.TryGetParameterId(item.GenericParameters.FirstOrDefault(), out genericParamRefId);
+ }
+
+ // FirstGenericParam
+ writer.WriteUInt16(genericParamRefId);
+
+ // GenericParamCount
+ writer.WriteByte((byte)item.GenericParameters.Count);
+
+ // Flags
writer.WriteUInt16(
(ushort)GetFlags(
item,
_context.MethodDefinitionTable));
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ // ignore assert when not minimize
+ if (_context.MinimizeComplete)
+ {
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_TYPEDEF);
+ }
+ }
+
+ ///
+ /// Add a "fake" TypeDef as placeholder for an instanced generic type.
+ ///
+ ///
+ public void AddGenericInstanceType(TypeReference typeReference)
+ {
+ // drop namespace as it's already on the full name
+ // OK to use full name as type name to help comparison ahead
+ var genericType = new TypeDefinition(
+ string.Empty,
+ typeReference.FullName,
+ typeReference.Resolve().Attributes);
+
+ // add to items list
+ AddItem(genericType);
}
private void WriteClassFields(
@@ -223,10 +281,16 @@ private void WriteClassFields(
}
}
+ // FirstStaticField
writer.WriteUInt16(firstStaticFieldId);
+
+ // FirstInstanceField
writer.WriteUInt16(firstInstanceFieldId);
+ // StaticFieldsCount
writer.WriteByte((byte)staticFieldsCount);
+
+ // InstanceFieldsCount
writer.WriteByte((byte)instanceFieldsCount);
}
@@ -266,8 +330,10 @@ private void WriteMethodBodies(
firstMethodId = _context.ByteCodeTable.NextMethodId;
}
+ // Interfaces
writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(iInterfaces));
+ // FirstMethod
writer.WriteUInt16(firstMethodId);
// sanity checks
@@ -286,8 +352,11 @@ private void WriteMethodBodies(
throw new InvalidOperationException($"Fatal error processing '{typeName}', static methods count ({staticMethodsCount}) exceeds maximum supported (255).");
}
+ // VirtualMethodCount
writer.WriteByte((byte)virtualMethodsCount);
+ // InstanceMethodCount
writer.WriteByte((byte)instanceMethodsCount);
+ // StaticMethodCount
writer.WriteByte((byte)staticMethodsCount);
}
@@ -302,19 +371,31 @@ private void CreateMethodSignatures(
_context.StringTable.GetOrCreateStringId(method.Name);
}
- private ushort GetTypeReferenceOrDefinitionId(
+ private ushort GetEncodedTypeReferenceOrDefinitionId(
TypeReference typeReference)
{
- ushort referenceId;
- if (_context.TypeReferencesTable.TryGetTypeReferenceId(typeReference, out referenceId))
+ ushort tag;
+
+ if (_context.TypeReferencesTable.TryGetTypeReferenceId(typeReference, out ushort referenceId))
{
- return (ushort)(0x8000 | referenceId);
+ // check "nested inside" case
+ if (referenceId != 0xFFFF)
+ {
+ // is TypeRef
+
+ return (ushort)(typeReference.ToEncodedNanoTypeDefOrRefToken() | referenceId);
+ }
}
- ushort typeId;
- if (TryGetTypeReferenceId(typeReference.Resolve(), out typeId))
+ if (TryGetTypeReferenceId(typeReference?.Resolve(), out ushort typeId))
{
- return typeId;
+ // check "nested inside" case
+ if (referenceId != 0xFFFF)
+ {
+ // is TypeDef
+
+ return (ushort)(typeReference.Resolve().ToEncodedNanoTypeDefOrRefToken() | typeId);
+ }
}
return 0xFFFF;
diff --git a/MetadataProcessor.Shared/Tables/nanoTypeReferenceTable.cs b/MetadataProcessor.Shared/Tables/nanoTypeReferenceTable.cs
index 77e43041..695cd5b8 100644
--- a/MetadataProcessor.Shared/Tables/nanoTypeReferenceTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoTypeReferenceTable.cs
@@ -1,12 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -17,24 +17,15 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoTypeReferenceTable :
nanoReferenceTableBase
{
- ///
- /// Helper class for comparing two instances of objects
- /// using property as unique key for comparison.
- ///
- private sealed class TypeReferenceEqualityComparer : IEqualityComparer
- {
- ///
- public bool Equals(TypeReference lhs, TypeReference rhs)
- {
- return string.Equals(lhs.FullName, rhs.FullName, StringComparison.Ordinal);
- }
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_TYPEREF = 6;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
- ///
- public int GetHashCode(TypeReference item)
- {
- return item.FullName.GetHashCode();
- }
- }
+ public NanoClrTable TableIndex => NanoClrTable.TBL_TypeRef;
///
/// Creates new instance of object.
@@ -46,7 +37,7 @@ public int GetHashCode(TypeReference item)
public nanoTypeReferenceTable(
IEnumerable items,
nanoTablesContext context)
- : base(items, new TypeReferenceEqualityComparer(), context)
+ : base(items, new TypeReferenceEqualityComparer(context), context)
{
}
@@ -77,11 +68,20 @@ protected override void WriteSingleItem(
nanoBinaryWriter writer,
TypeReference item)
{
- WriteStringReference(writer, item.Name);
+ var writerStartPosition = writer.BaseStream.Position;
+
+
+ // Get the full name for nested types
+ string fullName = nanoTypeReferenceTable.GetFullName(item);
+
+ WriteStringReference(writer, fullName);
WriteStringReference(writer, item.Namespace);
writer.WriteUInt16(GetScope(item)); // scope - TBL_AssemblyRef | TBL_TypeRef // 0x8000
- writer.WriteUInt16(0); // padding
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_TYPEREF);
}
///
@@ -95,16 +95,45 @@ protected override void AllocateSingleItemStrings(
internal ushort GetScope(
TypeReference typeReference)
{
- if (typeReference.DeclaringType == null)
+ // Check if the type is defined in the same assembly
+ if (typeReference.Scope is ModuleDefinition moduleDefinition
+ && moduleDefinition.Assembly == _context.AssemblyDefinition)
{
- return _context.AssemblyReferenceTable.GetReferenceId(typeReference.Scope as AssemblyNameReference);
+ // The type is defined in the same assembly
+ if (_context.TypeReferencesTable.TryGetTypeReferenceId(
+ typeReference.DeclaringType,
+ out ushort referenceId))
+ {
+ return (ushort)(0x8000 | referenceId);
+ }
+ else
+ {
+ // unknown scope
+ throw new InvalidOperationException($"Unknown scope for type reference '{typeReference.FullName}'");
+ }
+ }
+ else if (typeReference.Scope is AssemblyNameReference assemblyNameReference)
+ {
+ // The type is defined in a referenced assembly
+ return _context.AssemblyReferenceTable.GetReferenceId(assemblyNameReference);
}
else
{
- ushort referenceId;
- _context.TypeReferencesTable.TryGetTypeReferenceId(typeReference.DeclaringType, out referenceId);
- return (ushort)(0x8000 | referenceId);
+ // unknown scope
+ throw new InvalidOperationException($"Unknown scope for type reference '{typeReference.FullName}'");
}
+
+ }
+
+ private static string GetFullName(TypeReference typeReference)
+ {
+ if (typeReference.DeclaringType == null)
+ {
+ return typeReference.Name;
+ }
+
+ // return the full name of the declaring type
+ return typeReference.FullName;
}
}
}
diff --git a/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs b/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs
index 9cc8357b..ea27c951 100644
--- a/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs
+++ b/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs
@@ -1,13 +1,14 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -17,40 +18,74 @@ namespace nanoFramework.Tools.MetadataProcessor
///
public sealed class nanoTypeSpecificationsTable : InanoTable
{
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // //
+ // when updating this size here need to update matching define in nanoCLR_Types.h in native //
+ private const int sizeOf_CLR_RECORD_TYPESPEC = 2;
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
///
- /// Helper class for comparing two instances of objects
- /// using property as unique key for comparison.
+ /// Helper class for comparing two instances of objects
+ /// using property as unique key for comparison.
///
- private sealed class TypeReferenceComparer : IEqualityComparer
+ private sealed class TypeSpecificationEqualityComparer : IEqualityComparer
{
///
- public bool Equals(TypeReference lhs, TypeReference rhs)
+ public bool Equals(TypeSpecification x, TypeSpecification y)
+ {
+ if (x is null)
+ {
+ throw new ArgumentNullException(nameof(x));
+ }
+
+ if (y is null)
+ {
+ throw new ArgumentNullException(nameof(y));
+ }
+
+ return string.Equals(x.MetadataToken, y.MetadataToken);
+ }
+
+ ///
+ public int GetHashCode(TypeSpecification obj)
+ {
+ if (obj is null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+
+ return obj.MetadataToken.GetHashCode();
+ }
+ }
+
+ private sealed class TypeSpecBySignatureComparer : IEqualityComparer>
+ {
+ public bool Equals(KeyValuePair x, KeyValuePair y)
{
- return string.Equals(lhs.FullName, rhs.FullName, StringComparison.Ordinal);
+ return x.Key == y.Key;
}
///
- public int GetHashCode(TypeReference that)
+ public int GetHashCode(KeyValuePair that)
{
- return that.FullName.GetHashCode();
+ return that.Key;
}
}
///
/// Maps for each unique type specification and related identifier.
///
- private readonly IDictionary _idByTypeSpecifications =
- new Dictionary(new TypeReferenceComparer());
+ private Dictionary _idByTypeSpecifications;
///
/// Assembly tables context - contains all tables used for building target assembly.
///
private readonly nanoTablesContext _context;
- ///
- /// Last available type specifier identificator.
- ///
- private ushort _lastAvailableId;
+ public NanoClrTable TableIndex => NanoClrTable.TBL_TypeSpec;
///
/// Creates new instance of object.
@@ -62,79 +97,128 @@ public nanoTypeSpecificationsTable(
nanoTablesContext context)
{
_context = context;
- }
- ///
- /// Gets existing or creates new type specification reference identifier.
- ///
- /// Type reference value for obtaining identifier.
- /// Existing identifier if specification already in table or new one.
- public ushort GetOrCreateTypeSpecificationId(
- TypeReference typeReference)
- {
- ushort referenceId;
- if (!_idByTypeSpecifications.TryGetValue(typeReference, out referenceId))
- {
- // check for array in TypeSpec because we don't support for multidimensional arrays
- if (typeReference.IsArray &&
- (typeReference as ArrayType).Rank > 1)
- {
- throw new ArgumentException($".NET nanoFramework doesn't have support for multidimensional arrays. Unable to parse {typeReference.FullName}.");
- }
+ _idByTypeSpecifications = new Dictionary(new TypeReferenceEqualityComparer(context));
- _idByTypeSpecifications.Add(typeReference, _lastAvailableId);
+ FillTypeSpecsFromTypes();
- referenceId = _lastAvailableId;
- ++_lastAvailableId;
- }
-
- return referenceId;
+ FillTypeSpecsFromMemberReferences();
}
///
- /// Gets type specification identifier (if it already added into type specifications list).
+ /// Gets type specification identifier.
///
/// Type reference in Mono.Cecil format.
- /// Type reference identifier for filling.
+ /// Type Specification identifier for filling.
/// Returns true if item found, otherwise returns false.
public bool TryGetTypeReferenceId(
TypeReference typeReference,
out ushort referenceId)
{
- if (typeReference == null) // This case is possible for encoding 'nested inside' case
+ if (_idByTypeSpecifications.TryGetValue(typeReference, out referenceId))
{
- referenceId = 0xFFFF;
+ referenceId = (ushort)Array.IndexOf(_idByTypeSpecifications.Values.ToArray(), referenceId);
+
return true;
}
- referenceId = GetOrCreateTypeSpecificationId(typeReference);
-
- return true;
+ return false;
}
public TypeReference TryGetTypeSpecification(MetadataToken token)
{
- foreach (var t in _idByTypeSpecifications)
+ return _idByTypeSpecifications.FirstOrDefault(typeEntry => typeEntry.Key.MetadataToken == token).Key;
+ }
+
+ ///
+ public void Write(
+ nanoBinaryWriter writer)
+ {
+
+ foreach (var item in _idByTypeSpecifications)
{
- if (t.Key.MetadataToken == token)
+ var writerStartPosition = writer.BaseStream.Position;
+
+ writer.WriteUInt16(item.Value);
+
+ var writerEndPosition = writer.BaseStream.Position;
+
+ Debug.Assert((writerEndPosition - writerStartPosition) == sizeOf_CLR_RECORD_TYPESPEC);
+ }
+ }
+
+ public void ForEachItems(Action action)
+ {
+ foreach (var item in _idByTypeSpecifications)
+ {
+ action(item.Value, item.Key);
+ }
+ }
+
+ private void FillTypeSpecsFromMemberReferences()
+ {
+ List typeSpecs = new List();
+
+ foreach (var m in _context.MemberReferencesTable.Items.Where(mr => mr.DeclaringType is TypeSpecification))
+ {
+ if (!typeSpecs.Contains(m.DeclaringType as TypeSpecification, new TypeSpecificationEqualityComparer()))
{
- return t.Key;
+ // check for array in TypeSpec because we don't support for multidimensional arrays
+ if (m.DeclaringType.IsArray &&
+ (m.DeclaringType as ArrayType).Rank > 1)
+ {
+ throw new ArgumentException($".NET nanoFramework doesn't have support for multidimensional arrays. Unable to parse {m.DeclaringType.FullName}.");
+ }
+
+ typeSpecs.Add(m.DeclaringType as TypeSpecification);
+
+ // get index of signature for the TypeSpecification
+ ushort signatureId = _context.SignaturesTable.GetOrCreateSignatureId(m.DeclaringType);
+
+ if (!_idByTypeSpecifications.TryGetValue(m.DeclaringType, out ushort referenceId))
+ {
+ // is not on the list yet, add it
+ _idByTypeSpecifications.Add(m.DeclaringType, signatureId);
+ }
}
}
-
- return null;
}
- ///
- public void Write(
- nanoBinaryWriter writer)
+ private void FillTypeSpecsFromTypes()
{
- foreach (var item in _idByTypeSpecifications
- .OrderBy(item => item.Value)
- .Select(item => item.Key))
+ foreach (TypeDefinition t in _context.TypeDefinitionTable.Items)
{
- writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
- writer.WriteUInt16(0x0000); // padding
+ foreach (MethodDefinition m in t.Methods.Where(method => method.HasBody))
+ {
+ foreach (Instruction instruction in m.Body.Instructions)
+ {
+ if (instruction.Operand is GenericParameter genericParameter)
+ {
+ ushort signatureId = _context.SignaturesTable.GetOrCreateSignatureId(genericParameter);
+
+ if (!_idByTypeSpecifications.ContainsKey(genericParameter))
+ {
+ _idByTypeSpecifications.Add(genericParameter, signatureId);
+ }
+ }
+ else if (instruction.Operand is TypeReference typeReference)
+ {
+ // Optional: Check additional conditions if needed,
+ // for example, if the operand type should be an array.
+ if (instruction.OpCode.OperandType == OperandType.InlineType && !typeReference.IsArray)
+ {
+ continue;
+ }
+
+ ushort signatureId = _context.SignaturesTable.GetOrCreateSignatureId(typeReference);
+
+ if (!_idByTypeSpecifications.ContainsKey(typeReference))
+ {
+ _idByTypeSpecifications.Add(typeReference, signatureId);
+ }
+ }
+ }
+ }
}
}
}
diff --git a/MetadataProcessor.Shared/Utility/CompressTokenHelper.cs b/MetadataProcessor.Shared/Utility/CompressTokenHelper.cs
new file mode 100644
index 00000000..f38e7d73
--- /dev/null
+++ b/MetadataProcessor.Shared/Utility/CompressTokenHelper.cs
@@ -0,0 +1,187 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// Helpers to handle nanoTokens.
+ ///
+ public class nanoTokenHelpers
+ {
+ ///
+ /// Tables to encode NanoTypeToken.
+ ///
+ public readonly static List NanoTypeTokenTables = new List() {
+ //
+ // order matters and has to match CLR_UncompressTypeToken in native nanoCLR_Types.h
+ NanoClrTable.TBL_TypeDef,
+ NanoClrTable.TBL_TypeRef,
+ NanoClrTable.TBL_TypeSpec,
+ NanoClrTable.TBL_GenericParam
+ };
+
+ ///
+ /// Tables to encode NanoTypeDefOrRefToken.
+ ///
+ public readonly static List NanoTypeDefOrRefTokenTables = new List() {
+ NanoClrTable.TBL_TypeDef,
+ NanoClrTable.TBL_TypeRef,
+ };
+
+ ///
+ /// Tables to encode NanoMemberRefToken.
+ ///
+ public readonly static List NanoMemberRefTokenTables = new List() {
+ //
+ // order matters and has to match CLR_UncompressMethodToken in native nanoCLR_Types.h
+ NanoClrTable.TBL_MethodDef,
+ NanoClrTable.TBL_MethodRef,
+ NanoClrTable.TBL_TypeSpec,
+ NanoClrTable.TBL_MethodSpec,
+ };
+
+ ///
+ /// Tables to encode NanoFieldMemberRefToken.
+ ///
+ public readonly static List NanoFieldMemberRefTokenTables = new List() {
+ NanoClrTable.TBL_FieldDef,
+ NanoClrTable.TBL_FieldRef
+ };
+
+ ///
+ /// Tables to encode NanoMethodDefOrRefToken.
+ ///
+ public readonly static List NanoMethodDefOrRefTokenTables = new List() {
+ NanoClrTable.TBL_MethodDef,
+ NanoClrTable.TBL_MethodRef
+ };
+
+ ///
+ /// Tables to encode NanoTypeOrMethodToken.
+ ///
+ public readonly static List NanoTypeOrMethodDefTokenTables = new List() {
+ NanoClrTable.TBL_TypeDef,
+ NanoClrTable.TBL_MethodDef
+ };
+
+ ///
+ /// Tables to encode CLR_TypeRefOrSpec.
+ ///
+ public readonly static List CLR_TypeRefOrSpecTables = new List() {
+ //
+ // order matters and has to match decoder Owner() in native nanoCLR_Types.h
+ NanoClrTable.TBL_TypeRef,
+ NanoClrTable.TBL_TypeSpec
+ };
+
+ ///
+ /// Encode table to be used in a nanoToken.
+ /// The table index in moved to the MSbits.
+ ///
+ /// Table to compress.
+ /// List of tables to be used in encoding.
+ /// The encoded tag to be used in a nanoToken.
+ public static ushort EncodeTableIndex(NanoClrTable table, List tableList)
+ {
+ // sanity checks
+ if (tableList.Count < 1)
+ {
+ Debug.Fail($"List contains only one element. No need to encode.");
+ }
+
+ if (!tableList.Contains(table))
+ {
+ Debug.Fail($"{table} is not listed in the options.");
+ }
+
+ // find out how many bits are required to compress the list
+ var requiredBits = (int)Math.Round(Math.Log(tableList.Count, 2));
+
+ return (ushort)(tableList.IndexOf(table) << (16 - requiredBits));
+ }
+
+ ///
+ /// Decode from nanoToken.
+ ///
+ /// Encoded value containing the table index.
+ /// List of tables to be used in encoding.
+ /// The encoded in the .
+ public static NanoClrTable DecodeTableIndex(ushort value, List tableList)
+ {
+ if (tableList.Count < 1)
+ {
+ Debug.Fail($"List contains only one element. No need to encode.");
+ }
+
+ // find out how many bits are required to compress the list
+ var requiredBits = (int)Math.Round(Math.Log(tableList.Count, 2));
+
+ var index = (value >> 16 - requiredBits);
+
+ return tableList[index];
+ }
+
+ ///
+ /// Decode the reference from nanoToken taking into account the encoded table.
+ ///
+ /// Encoded value.
+ /// List of tables used in encoding.
+ /// The reference encoded in the .
+ public static ushort DecodeReferenceIndex(ushort value, List tableList)
+ {
+ if (tableList.Count < 1)
+ {
+ Debug.Fail($"List contains only one element. No need to encode.");
+ }
+
+ // find out how many bits are required to compress the list
+ var requiredBits = (int)Math.Log(tableList.Count, 2);
+
+ var mask = 0xFFFF;
+
+ while (requiredBits-- > 0)
+ {
+ mask = mask >> 1;
+ }
+
+ return (ushort)(value & mask);
+ }
+
+ ///
+ /// Convert (and derived) in .
+ ///
+ ///
+ ///
+ public static NanoClrTable ConvertToNanoCLRTable(MemberReference value)
+ {
+ switch (value)
+ {
+ case GenericParameter _:
+ return NanoClrTable.TBL_GenericParam;
+
+ case TypeDefinition _:
+ return NanoClrTable.TBL_TypeDef;
+
+ case TypeSpecification _:
+ return NanoClrTable.TBL_TypeSpec;
+
+ case TypeReference _:
+ return NanoClrTable.TBL_TypeRef;
+
+ case FieldReference _:
+ return NanoClrTable.TBL_FieldRef;
+
+ case MethodReference _:
+ return NanoClrTable.TBL_MethodRef;
+
+ default:
+ throw new ArgumentException("Unknown conversion to CLR Table.");
+ }
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Utility/Crc32.cs b/MetadataProcessor.Shared/Utility/Crc32.cs
index 4f30feb0..d5a5f15a 100644
--- a/MetadataProcessor.Shared/Utility/Crc32.cs
+++ b/MetadataProcessor.Shared/Utility/Crc32.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System.Linq;
@@ -63,4 +62,4 @@ public static uint Compute(byte[] buffer, uint crc = 0)
(index, item) => _crcTable[((index >> 24) ^ item) & 0xFF] ^ (index << 8));
}
}
-}
\ No newline at end of file
+}
diff --git a/MetadataProcessor.Shared/Utility/FixTypeNames.cs b/MetadataProcessor.Shared/Utility/FixTypeNames.cs
new file mode 100644
index 00000000..ecfdef58
--- /dev/null
+++ b/MetadataProcessor.Shared/Utility/FixTypeNames.cs
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ public class nanoHelpers
+ {
+ internal static string FixTypeNames(string name)
+ {
+ // This is used to remedy the wrong output from Cecil.Mono
+ // Reported jbevain/cecil#715
+ // OK to remove if implemented
+
+ // following II.23.2.16 Short form signatures
+ string fixedName;
+
+ fixedName = name.Replace("System.String", "string");
+ fixedName = fixedName.Replace("System.Object", "object");
+ fixedName = fixedName.Replace("System.Void", "void");
+ fixedName = fixedName.Replace("System.Boolean", "bool");
+ fixedName = fixedName.Replace("System.Char", "char");
+ fixedName = fixedName.Replace("System.Byte", "int8");
+ fixedName = fixedName.Replace("System.Sbyte", "uint8");
+ fixedName = fixedName.Replace("System.Int16", "int16");
+ fixedName = fixedName.Replace("System.UInt16", "uint16");
+ fixedName = fixedName.Replace("System.Int32", "int32");
+ fixedName = fixedName.Replace("System.UInt32", "uint32");
+ fixedName = fixedName.Replace("System.Int64", "int64");
+ fixedName = fixedName.Replace("System.UInt64", "uint64");
+ fixedName = fixedName.Replace("System.Single", "float32");
+ fixedName = fixedName.Replace("System.Double", "float64");
+
+ return fixedName;
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Utility/LoadHintsAssemblyResolver.cs b/MetadataProcessor.Shared/Utility/LoadHintsAssemblyResolver.cs
index 04b2d021..0426da49 100644
--- a/MetadataProcessor.Shared/Utility/LoadHintsAssemblyResolver.cs
+++ b/MetadataProcessor.Shared/Utility/LoadHintsAssemblyResolver.cs
@@ -1,13 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Reflection;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
diff --git a/MetadataProcessor.Shared/Utility/NativeMethodsCrc.cs b/MetadataProcessor.Shared/Utility/NativeMethodsCrc.cs
index e85df637..c3bec6e9 100644
--- a/MetadataProcessor.Shared/Utility/NativeMethodsCrc.cs
+++ b/MetadataProcessor.Shared/Utility/NativeMethodsCrc.cs
@@ -1,14 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
-using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Text;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -19,7 +18,7 @@ namespace nanoFramework.Tools.MetadataProcessor
///
public sealed class NativeMethodsCrc
{
- private readonly byte[] _null = Encoding.ASCII.GetBytes("NULL");
+ private readonly byte[] _null = Encoding.ASCII.GetBytes("nullptr");
private readonly byte[] _name;
@@ -118,22 +117,22 @@ private static string GetParameterType(
// special processing for arrays
if (parameterType.IsArray)
{
- typeName += nanoCLR_DataType.DATATYPE_SZARRAY + "_" + GetParameterType(parameterType.GetElementType());
+ typeName += NanoCLRDataType.DATATYPE_SZARRAY + "_" + GetParameterType(parameterType.GetElementType());
continueProcessing = false;
}
else if (parameterType.IsByReference)
{
var elementType = ((TypeSpecification)parameterType).ElementType;
- typeName += nanoCLR_DataType.DATATYPE_BYREF + "_";
+ typeName += NanoCLRDataType.DATATYPE_BYREF + "_";
if (elementType.IsArray)
{
- typeName += nanoCLR_DataType.DATATYPE_SZARRAY + "_" + GetParameterType(((TypeSpecification)elementType).ElementType);
+ typeName += NanoCLRDataType.DATATYPE_SZARRAY + "_" + GetParameterType(((TypeSpecification)elementType).ElementType);
}
else
{
- typeName += GetnanoClrTypeName(elementType);
+ typeName += GetNanoCLRTypeName(elementType);
}
continueProcessing = false;
}
@@ -145,7 +144,7 @@ private static string GetParameterType(
if (continueProcessing)
{
- typeName = GetnanoClrTypeName(parameterType);
+ typeName = GetNanoCLRTypeName(parameterType);
}
// clear 'DATATYPE_' prefixes
@@ -153,26 +152,26 @@ private static string GetParameterType(
return typeName.Replace("DATATYPE_", "");
}
- internal static string GetnanoClrTypeName(TypeReference parameterType)
+ internal static string GetNanoCLRTypeName(TypeReference parameterType)
{
// try getting primitive type
- nanoCLR_DataType myType;
+ NanoCLRDataType myType;
if (nanoSignaturesTable.PrimitiveTypes.TryGetValue(parameterType.FullName, out myType))
{
- if (myType == nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE)
+ if (myType == NanoCLRDataType.DATATYPE_LAST_PRIMITIVE)
{
return "DATATYPE_STRING";
}
- else if (myType == nanoCLR_DataType.DATATYPE_LAST_NONPOINTER)
+ else if (myType == NanoCLRDataType.DATATYPE_LAST_NONPOINTER)
{
return "DATATYPE_TIMESPAN";
}
- else if (myType == nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_MARSHAL)
+ else if (myType == NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_MARSHAL)
{
return "DATATYPE_TIMESPAN";
}
- else if (myType == nanoCLR_DataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE)
+ else if (myType == NanoCLRDataType.DATATYPE_LAST_PRIMITIVE_TO_PRESERVE)
{
return "DATATYPE_R8";
}
diff --git a/MetadataProcessor.Shared/Utility/TypeReferenceEqualityComparer.cs b/MetadataProcessor.Shared/Utility/TypeReferenceEqualityComparer.cs
new file mode 100644
index 00000000..f85a6c21
--- /dev/null
+++ b/MetadataProcessor.Shared/Utility/TypeReferenceEqualityComparer.cs
@@ -0,0 +1,97 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// Helper class for comparing two instances of objects
+ /// using property as unique key for comparison.
+ ///
+ public sealed class TypeReferenceEqualityComparer : IEqualityComparer
+ {
+ private readonly nanoTablesContext _context;
+
+ public TypeReferenceEqualityComparer(nanoTablesContext context) => _context = context;
+
+ ///
+ public bool Equals(TypeReference x, TypeReference y)
+ {
+ if (x is null)
+ {
+ throw new ArgumentNullException(nameof(x));
+ }
+
+ if (y is null)
+ {
+ throw new ArgumentNullException(nameof(y));
+ }
+
+ if (x is TypeSpecification &&
+ !(y is TypeSpecification))
+ {
+ return false;
+ }
+ else if (y is TypeSpecification &&
+ !(x is TypeSpecification))
+ {
+ return false;
+ }
+ else if (x is TypeSpecification &&
+ y is TypeSpecification)
+ {
+ // get signatures to perform comparison
+ ushort xSignatureId = _context.SignaturesTable.GetOrCreateSignatureId(x);
+ ushort ySignatureId = _context.SignaturesTable.GetOrCreateSignatureId(y);
+
+ return xSignatureId == ySignatureId;
+ }
+ else if (x is GenericParameter && y is GenericParameter)
+ {
+ // comparison is made with type and position
+ var xGenericParam = x as GenericParameter;
+ var yGenericParam = y as GenericParameter;
+
+ return (xGenericParam.Type == yGenericParam.Type) &&
+ (xGenericParam.Position == yGenericParam.Position);
+ }
+ else
+ {
+ return x.MetadataToken == y.MetadataToken;
+ }
+ }
+
+ ///
+ public int GetHashCode(TypeReference obj)
+ {
+ if (obj is null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+
+ if (obj is TypeSpecification)
+ {
+ ushort xSignatureId = _context.SignaturesTable.GetOrCreateSignatureId(obj);
+
+ // provide an hash code based on the TypeSpec signature
+ return xSignatureId;
+ }
+ else if (obj is GenericParameter)
+ {
+ // provide an hash code based on the generic parameter position and type,
+ // which is what makes it unique when comparing GenericParameter as a TypeReference
+ var genericParam = obj as GenericParameter;
+
+ return genericParam.Position * 10 + (int)genericParam.Type;
+ }
+ else
+ {
+ // provide an hash code from the metadatatoken
+ return obj.MetadataToken.GetHashCode();
+ }
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Utility/nanoBitmapProcessor.cs b/MetadataProcessor.Shared/Utility/nanoBitmapProcessor.cs
index a483504b..8c9ec57d 100644
--- a/MetadataProcessor.Shared/Utility/nanoBitmapProcessor.cs
+++ b/MetadataProcessor.Shared/Utility/nanoBitmapProcessor.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System;
using System.Drawing;
diff --git a/MetadataProcessor.Shared/Utility/nanoCLR_DataType.cs b/MetadataProcessor.Shared/Utility/nanoCLR_DataType.cs
index 1fca7bc2..5b7fea98 100644
--- a/MetadataProcessor.Shared/Utility/nanoCLR_DataType.cs
+++ b/MetadataProcessor.Shared/Utility/nanoCLR_DataType.cs
@@ -1,12 +1,18 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
namespace nanoFramework.Tools.MetadataProcessor
{
- public enum nanoCLR_DataType : byte
+ //////////////////////////////////////////////////////////////////////////////////
+ // //
+ // !!! KEEP IN SYNC WITH enum CLRDataType (in nanoCLR_TypeSystem Debugger) !!! //
+ // //
+ // !!! KEEP IN SYNC WITH enum CLRDataType (in nanoCLRT_Types.h in CLR) !!! //
+ //////////////////////////////////////////////////////////////////////////////////
+
+ public enum NanoCLRDataType : byte
{
// these where defined @ enum CLR_DataType
diff --git a/MetadataProcessor.Shared/Utility/nanoDependencyGeneratorWriter.cs b/MetadataProcessor.Shared/Utility/nanoDependencyGeneratorWriter.cs
index e462c716..23da2086 100644
--- a/MetadataProcessor.Shared/Utility/nanoDependencyGeneratorWriter.cs
+++ b/MetadataProcessor.Shared/Utility/nanoDependencyGeneratorWriter.cs
@@ -1,15 +1,14 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -129,12 +128,12 @@ private void WriteVersionInfo(
private void WriteClassInfo(
XmlWriter writer,
- uint nanoClrItemToken,
+ uint nanoCLRItemToken,
TypeDefinition item)
{
writer.WriteStartElement("Class");
- WriteTokensPair(writer, item.MetadataToken.ToUInt32(), 0x04000000 | nanoClrItemToken);
+ WriteTokensPair(writer, item.MetadataToken.ToUInt32(), 0x04000000 | nanoCLRItemToken);
writer.WriteStartElement("Methods");
foreach (var tuple in GetMethodsTokens(item.Methods))
@@ -204,12 +203,12 @@ private IEnumerable> GetFieldsTokens(
private void WriteTokensPair(
XmlWriter writer,
uint clrToken,
- uint nanoClrToken)
+ uint nanoCLRToken)
{
writer.WriteStartElement("Token");
writer.WriteElementString("CLR", "0x" + clrToken.ToString("X8", CultureInfo.InvariantCulture));
- writer.WriteElementString("nanoCLR", "0x" + nanoClrToken.ToString("X8", CultureInfo.InvariantCulture));
+ writer.WriteElementString("nanoCLR", "0x" + nanoCLRToken.ToString("X8", CultureInfo.InvariantCulture));
writer.WriteEndElement();
}
diff --git a/MetadataProcessor.Shared/Utility/nanoFontProcessor.cs b/MetadataProcessor.Shared/Utility/nanoFontProcessor.cs
index a6666dbe..1a5f4bcc 100644
--- a/MetadataProcessor.Shared/Utility/nanoFontProcessor.cs
+++ b/MetadataProcessor.Shared/Utility/nanoFontProcessor.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System.IO;
diff --git a/MetadataProcessor.Shared/Utility/nanoMetadataToken.cs b/MetadataProcessor.Shared/Utility/nanoMetadataToken.cs
new file mode 100644
index 00000000..0711f23c
--- /dev/null
+++ b/MetadataProcessor.Shared/Utility/nanoMetadataToken.cs
@@ -0,0 +1,84 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using Mono.Cecil;
+
+namespace nanoFramework.Tools.MetadataProcessor
+{
+ ///
+ /// Encoded type for inline type calls.
+ ///
+ public class nanoMetadataToken
+ {
+ private NanoClrTable _clrTable;
+ private ushort _id;
+
+ public nanoMetadataToken()
+ {
+ }
+
+ public nanoMetadataToken(NanoClrTable clrTable, ushort id)
+ {
+ _clrTable = clrTable;
+ _id = id;
+ }
+
+ public nanoMetadataToken(MetadataToken token, ushort id)
+ {
+ _id = id;
+
+ // get token type
+ switch (token.TokenType)
+ {
+ case TokenType.AssemblyRef:
+ _clrTable = NanoClrTable.TBL_AssemblyRef;
+ break;
+
+ case TokenType.TypeRef:
+ _clrTable = NanoClrTable.TBL_TypeRef;
+ break;
+
+ case TokenType.Field:
+ _clrTable = NanoClrTable.TBL_FieldDef;
+ break;
+
+ case TokenType.Method:
+ _clrTable = NanoClrTable.TBL_MethodDef;
+ break;
+
+ case TokenType.TypeDef:
+ _clrTable = NanoClrTable.TBL_TypeDef;
+ break;
+
+ case TokenType.GenericParam:
+ _clrTable = NanoClrTable.TBL_GenericParam;
+ break;
+
+ case TokenType.MethodSpec:
+ _clrTable = NanoClrTable.TBL_MethodDef;
+ break;
+
+ case TokenType.MemberRef:
+ _clrTable = NanoClrTable.TBL_MethodRef;
+ break;
+
+ case TokenType.TypeSpec:
+ _clrTable = NanoClrTable.TBL_TypeSpec;
+ break;
+
+ default:
+ Debug.Fail("Unsupported token conversion");
+ break;
+ }
+ }
+
+ public override string ToString()
+ {
+ // table token
+ var tokenType = (uint)_clrTable << 24;
+
+ return $"{tokenType | _id:X8}";
+ }
+ }
+}
diff --git a/MetadataProcessor.Shared/Utility/nanoPdbxFileWriter.cs b/MetadataProcessor.Shared/Utility/nanoPdbxFileWriter.cs
deleted file mode 100644
index d27f46c9..00000000
--- a/MetadataProcessor.Shared/Utility/nanoPdbxFileWriter.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-
-using Mono.Cecil;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Xml;
-
-namespace nanoFramework.Tools.MetadataProcessor
-{
- internal sealed class nanoPdbxFileWriter
- {
- private readonly nanoTablesContext _context;
-
- public nanoPdbxFileWriter(
- nanoTablesContext context)
- {
- _context = context;
- }
-
- public void Write(
- XmlWriter writer)
- {
- writer.WriteStartElement("PdbxFile");
- writer.WriteStartElement("Assembly");
-
- WriteTokensPair(writer, _context.AssemblyDefinition.MetadataToken.ToUInt32(), 0x00000000);
- writer.WriteElementString("FileName", _context.AssemblyDefinition.MainModule.Name);
- WriteVersionInfo(writer, _context.AssemblyDefinition.Name.Version);
-
- writer.WriteStartElement("Classes");
-
- _context.TypeDefinitionTable.ForEachItems((token, item) => WriteClassInfo(writer, token, item));
-
- writer.WriteEndDocument();
- }
-
- private void WriteVersionInfo(
- XmlWriter writer,
- Version version)
- {
- writer.WriteStartElement("Version");
-
- writer.WriteElementString("Major", version.Major.ToString("D", CultureInfo.InvariantCulture));
- writer.WriteElementString("Minor", version.Minor.ToString("D", CultureInfo.InvariantCulture));
- writer.WriteElementString("Build", version.Build.ToString("D", CultureInfo.InvariantCulture));
- writer.WriteElementString("Revision", version.Revision.ToString("D", CultureInfo.InvariantCulture));
-
- writer.WriteEndElement();
- }
-
- private void WriteClassInfo(
- XmlWriter writer,
- uint nanoClrItemToken,
- TypeDefinition item)
- {
- writer.WriteStartElement("Class");
-
- WriteTokensPair(writer, item.MetadataToken.ToUInt32(), 0x04000000 | nanoClrItemToken);
-
- writer.WriteStartElement("Methods");
- foreach (var tuple in GetMethodsTokens(item.Methods))
- {
- writer.WriteStartElement("Method");
-
- WriteTokensPair(writer, tuple.Item1, tuple.Item2);
-
- if (!tuple.Item3.HasBody)
- {
- writer.WriteElementString("HasByteCode", "false");
- }
- writer.WriteStartElement("ILMap");
-
- // sanity check vars
- uint prevItem1 = 0;
- uint prevItem2 = 0;
-
- foreach (var offset in _context.TypeDefinitionTable.GetByteCodeOffsets(tuple.Item1))
- {
- if (prevItem1 > 0)
- {
- // 1st pass, load prevs with current values
- Debug.Assert(prevItem1 < offset.Item1);
- Debug.Assert(prevItem2 < offset.Item2);
- }
- writer.WriteStartElement("IL");
-
- writer.WriteElementString("CLR", "0x" + offset.Item1.ToString("X8", CultureInfo.InvariantCulture));
- writer.WriteElementString("nanoCLR", "0x" + offset.Item2.ToString("X8", CultureInfo.InvariantCulture));
-
- prevItem1 = offset.Item1;
- prevItem2 = offset.Item2;
-
- writer.WriteEndElement();
- }
- writer.WriteEndElement();
-
- writer.WriteEndElement();
- }
- writer.WriteEndElement();
-
- writer.WriteStartElement("Fields");
- foreach (var pair in GetFieldsTokens(item.Fields))
- {
- writer.WriteStartElement("Field");
-
- WriteTokensPair(writer, pair.Item1, pair.Item2);
-
- writer.WriteEndElement();
- }
- writer.WriteEndElement();
-
- writer.WriteEndElement();
- }
-
- private IEnumerable> GetMethodsTokens(
- IEnumerable methods)
- {
- foreach (var method in methods)
- {
- ushort fieldToken;
- _context.MethodDefinitionTable.TryGetMethodReferenceId(method, out fieldToken);
- yield return new Tuple(
- method.MetadataToken.ToUInt32(), 0x06000000 | (uint)fieldToken, method);
- }
- }
-
- private IEnumerable> GetFieldsTokens(
- IEnumerable fields)
- {
- foreach (var field in fields.Where(item => !item.HasConstant))
- {
- ushort fieldToken;
- _context.FieldsTable.TryGetFieldReferenceId(field, false, out fieldToken);
- yield return new Tuple(
- field.MetadataToken.ToUInt32(), 0x05000000 | (uint)fieldToken);
- }
- }
-
- private void WriteTokensPair(
- XmlWriter writer,
- uint clrToken,
- uint nanoClrToken)
- {
- writer.WriteStartElement("Token");
-
- writer.WriteElementString("CLR", "0x" + clrToken.ToString("X8", CultureInfo.InvariantCulture));
- writer.WriteElementString("nanoCLR", "0x" + nanoClrToken.ToString("X8", CultureInfo.InvariantCulture));
-
- writer.WriteEndElement();
- }
- }
-}
diff --git a/MetadataProcessor.Shared/Utility/nanoSerializationType.cs b/MetadataProcessor.Shared/Utility/nanoSerializationType.cs
index d9227220..4990d1a0 100644
--- a/MetadataProcessor.Shared/Utility/nanoSerializationType.cs
+++ b/MetadataProcessor.Shared/Utility/nanoSerializationType.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
namespace nanoFramework.Tools.MetadataProcessor
{
diff --git a/MetadataProcessor.Shared/Utility/nanoStringsConstants.cs b/MetadataProcessor.Shared/Utility/nanoStringsConstants.cs
index 5290b1b5..fce86339 100644
--- a/MetadataProcessor.Shared/Utility/nanoStringsConstants.cs
+++ b/MetadataProcessor.Shared/Utility/nanoStringsConstants.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System;
using System.Collections.Generic;
diff --git a/MetadataProcessor.Shared/Utility/nanoTypeDefinitionFlags.cs b/MetadataProcessor.Shared/Utility/nanoTypeDefinitionFlags.cs
index f17206b3..5af14251 100644
--- a/MetadataProcessor.Shared/Utility/nanoTypeDefinitionFlags.cs
+++ b/MetadataProcessor.Shared/Utility/nanoTypeDefinitionFlags.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Shared/nanoAssemblyBuilder.cs b/MetadataProcessor.Shared/nanoAssemblyBuilder.cs
index 1396f5fc..ce3e0320 100644
--- a/MetadataProcessor.Shared/nanoAssemblyBuilder.cs
+++ b/MetadataProcessor.Shared/nanoAssemblyBuilder.cs
@@ -1,19 +1,18 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
-using Mono.Cecil;
-using Mono.Collections.Generic;
-using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
-using System.Xml;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using Mono.Collections.Generic;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor
{
@@ -102,7 +101,7 @@ public void Minimize()
var setNew = new HashSet();
var set = new HashSet();
- foreach (var t in _tablesContext.TypeDefinitionTable.TypeDefinitions)
+ foreach (var t in _tablesContext.TypeDefinitionTable.Items)
{
if (!t.IsToExclude())
{
@@ -166,19 +165,22 @@ public void Minimize()
}
// need to reset several tables so they are recreated only with the used items
+ // order matters on several cases because the list recreation populates others
+ _tablesContext.ResetByteCodeTable();
+ _tablesContext.ResetSignaturesTable();
+ _tablesContext.ResetResourcesTables();
_tablesContext.AssemblyReferenceTable.RemoveUnusedItems(set);
_tablesContext.TypeReferencesTable.RemoveUnusedItems(set);
_tablesContext.FieldsTable.RemoveUnusedItems(set);
_tablesContext.GenericParamsTable.RemoveUnusedItems(set);
+ _tablesContext.MethodSpecificationTable.RemoveUnusedItems(set);
_tablesContext.FieldReferencesTable.RemoveUnusedItems(set);
_tablesContext.MethodDefinitionTable.RemoveUnusedItems(set);
_tablesContext.MethodReferencesTable.RemoveUnusedItems(set);
_tablesContext.TypeDefinitionTable.RemoveUnusedItems(set);
_tablesContext.TypeDefinitionTable.ResetByteCodeOffsets();
+ _tablesContext.ResetTypeSpecificationsTable();
_tablesContext.AttributesTable.RemoveUnusedItems(set);
- _tablesContext.ResetByteCodeTable();
- _tablesContext.ResetSignaturesTable();
- _tablesContext.ResetResourcesTables();
_tablesContext.StringTable.RemoveUnusedItems(set);
// renormalise type definitions look-up tables
@@ -340,6 +342,8 @@ private HashSet BuildDependencyList(MetadataToken token)
Collection parameters = null;
+ FieldReference fr = null;
+
// try to find a method reference
var mr = _tablesContext.MethodReferencesTable.Items.FirstOrDefault(i => i.MetadataToken == token);
@@ -350,7 +354,24 @@ private HashSet BuildDependencyList(MetadataToken token)
if (mr.DeclaringType != null)
{
- set.Add(mr.DeclaringType.MetadataToken);
+ if (mr.DeclaringType is TypeSpecification)
+ {
+ // Cecil.Mono has a bug providing TypeSpecs Metadata tokens generic parameters variables, so we need to check against our internal table and build one from it
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId))
+ {
+ set.Add(new MetadataToken(
+ TokenType.TypeSpec,
+ referenceId));
+ }
+ else
+ {
+ Debug.Fail($"Couldn't find a TypeSpec entry for {mr.DeclaringType}");
+ }
+ }
+ else
+ {
+ set.Add(mr.DeclaringType.MetadataToken);
+ }
}
if (mr.MethodReturnType.ReturnType.IsValueType &&
@@ -428,16 +449,32 @@ private HashSet BuildDependencyList(MetadataToken token)
if (mr == null)
{
// try now with field references
- var fr = _tablesContext.FieldReferencesTable.Items.FirstOrDefault(i => i.MetadataToken == token);
+ fr = _tablesContext.FieldReferencesTable.Items.FirstOrDefault(i => i.MetadataToken == token);
if (fr != null)
{
if (fr.DeclaringType != null)
{
- set.Add(fr.DeclaringType.MetadataToken);
+ if (fr.DeclaringType is TypeSpecification)
+ {
+ // Cecil.Mono has a bug providing TypeSpecs Metadata tokens generic parameters variables, so we need to check against our internal table and build one from it
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(fr.DeclaringType, out ushort referenceId))
+ {
+ set.Add(new MetadataToken(
+ TokenType.TypeSpec,
+ referenceId));
+ }
+ else
+ {
+ Debug.Fail($"Couldn't find a TypeSpec entry for {fr.DeclaringType}");
+ }
+ }
+ else
+ {
+ set.Add(fr.DeclaringType.MetadataToken);
+ }
}
-
if (fr.FieldType.MetadataType == MetadataType.Class)
{
set.Add(fr.FieldType.MetadataToken);
@@ -476,6 +513,8 @@ private HashSet BuildDependencyList(MetadataToken token)
}
}
+ Debug.Assert(mr != null || fr != null);
+
break;
case TokenType.TypeSpec:
@@ -486,6 +525,8 @@ private HashSet BuildDependencyList(MetadataToken token)
set.Add(token);
}
+ Debug.Assert(ts != null);
+
break;
case TokenType.TypeDef:
@@ -696,6 +737,24 @@ private HashSet BuildDependencyList(MetadataToken token)
set.Add(parameterType.MetadataToken);
set.Add(parameterType.GetElementType().MetadataToken);
}
+ else if (parameterType is GenericParameter)
+ {
+ set.Add(parameterType.MetadataToken);
+
+ foreach (var gp in parameterType.GenericParameters)
+ {
+ set.Add(gp.MetadataToken);
+ if (parameterType.DeclaringType != null)
+ {
+ set.Add(parameterType.DeclaringType.MetadataToken);
+ }
+ }
+
+ if (parameterType.DeclaringType != null)
+ {
+ set.Add(parameterType.DeclaringType.MetadataToken);
+ }
+ }
else if (!parameterType.IsValueType &&
!parameterType.IsPrimitive &&
parameterType.FullName != "System.Void" &&
@@ -745,8 +804,19 @@ private HashSet BuildDependencyList(MetadataToken token)
}
else if (v.VariableType is GenericInstanceType)
{
- set.Add(v.VariableType.MetadataToken);
- set.Add(v.VariableType.GetElementType().MetadataToken);
+ // Cecil.Mono has a bug providing TypeSpecs Metadata tokens generic parameters variables, so we need to check against our internal table and build one from it
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(v.VariableType, out ushort referenceId))
+ {
+ set.Add(new MetadataToken(
+ TokenType.TypeSpec,
+ referenceId));
+
+ set.Add(v.VariableType.GetElementType().MetadataToken);
+ }
+ else
+ {
+ Debug.Fail($"Couldn't find a TypeSpec entry for {v.VariableType}");
+ }
}
else if (v.VariableType.IsPointer)
{
@@ -760,15 +830,66 @@ private HashSet BuildDependencyList(MetadataToken token)
// op codes
foreach (var i in md.Body.Instructions)
{
- if (i.Operand is MethodReference ||
- i.Operand is FieldReference ||
- i.Operand is TypeDefinition ||
- i.Operand is TypeSpecification ||
- i.Operand is TypeReference ||
+ if (i.Operand is MethodReference)
+ {
+ var methodReferenceType = i.Operand as MethodReference;
+
+ set.Add(methodReferenceType.MetadataToken);
+
+ if (_tablesContext.MethodReferencesTable.TryGetMethodReferenceId(methodReferenceType, out ushort referenceId))
+ {
+ if (methodReferenceType.DeclaringType != null &&
+ methodReferenceType.DeclaringType.IsGenericInstance)
+ {
+ // Cecil.Mono has a bug providing TypeSpecs Metadata tokens generic parameters variables, so we need to check against our internal table and build one from it
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(methodReferenceType.DeclaringType, out referenceId))
+ {
+ set.Add(new MetadataToken(
+ TokenType.TypeSpec,
+ referenceId));
+ }
+ else
+ {
+ Debug.Fail($"Couldn't find a TypeSpec entry for {methodReferenceType.DeclaringType}");
+ }
+ }
+ }
+ }
+ else if (i.Operand is FieldReference ||
+ i.Operand is TypeDefinition ||
+ i.Operand is MethodSpecification ||
+ i.Operand is TypeReference)
+ {
+ set.Add(((IMetadataTokenProvider)i.Operand).MetadataToken);
+ }
+ else if (
+ i.OpCode.OperandType is OperandType.InlineType ||
i.Operand is GenericInstanceType ||
+ i.Operand is GenericInstanceMethod ||
i.Operand is GenericParameter)
{
- set.Add(((IMetadataTokenProvider)i.Operand).MetadataToken);
+ var opType = (TypeReference)i.Operand;
+
+ var opToken = ((IMetadataTokenProvider)i.Operand).MetadataToken;
+
+ if (opToken.TokenType == TokenType.TypeSpec)
+ {
+ // Cecil.Mono has a bug providing TypeSpecs Metadata tokens generic parameters variables, so we need to check against our internal table and build one from it
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(opType, out ushort referenceId))
+ {
+ set.Add(new MetadataToken(
+ TokenType.TypeSpec,
+ referenceId));
+ }
+ else
+ {
+ Debug.Fail($"Couldn't find a TypeSpec entry for {opType}");
+ }
+ }
+ else
+ {
+ set.Add(opToken);
+ }
}
else if (i.Operand is string)
{
@@ -778,7 +899,6 @@ i.Operand is GenericInstanceType ||
set.Add(newToken);
}
-
}
// exceptions
@@ -823,9 +943,31 @@ i.Operand is GenericInstanceType ||
break;
+ case TokenType.MethodSpec:
+ var ms = _tablesContext.MethodSpecificationTable.Items.FirstOrDefault(i => i.MetadataToken == token);
+
+ if (ms != null)
+ {
+ set.Add(token);
+ }
+ break;
+
case TokenType.GenericParam:
+ var gpar = _tablesContext.GenericParamsTable.Items.FirstOrDefault(i => i.MetadataToken == token);
+
+ if (gpar != null)
+ {
+ // need to add their constraints if, any
+ foreach (var c in gpar.Constraints)
+ {
+ set.Add(c.MetadataToken);
+ }
+ }
+ break;
+
case TokenType.AssemblyRef:
case TokenType.String:
+ case TokenType.GenericParamConstraint:
// we are good with these, nothing to do here
break;
@@ -1017,6 +1159,14 @@ private string TokenToString(MetadataToken token)
}
break;
+ case TokenType.MethodSpec:
+ output.Append($"[MethodSpec 0x{token.ToUInt32().ToString("X8")}]");
+ break;
+
+ case TokenType.GenericParamConstraint:
+ output.Append($"[GenericParamConstraint 0x{token.ToUInt32().ToString("X8")}]");
+ break;
+
default:
Debug.Fail($"Unable to process token {token}.");
break;
@@ -1031,16 +1181,28 @@ private string TokenToString(MetadataToken token)
return output.ToString();
}
- public void Write(
- XmlWriter xmlWriter)
+ public void Write(string fileName)
{
var pdbxWriter = new nanoPdbxFileWriter(_tablesContext);
- pdbxWriter.Write(xmlWriter);
+ pdbxWriter.Write(fileName);
}
- private static IEnumerable GetTables(
+ ///
+ /// Count of tables in the assembly
+ ///
+ static public int TablesCount => 0x12;
+
+ internal static IEnumerable GetTables(
nanoTablesContext context)
{
+ //////////////////////////////////////////////////
+ // order matters and must follow CLR_TABLESENUM //
+ //////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////
+ // update count property above whenever changing the tables //
+ //////////////////////////////////////////////////////////////
+
yield return context.AssemblyReferenceTable;
yield return context.TypeReferencesTable;
@@ -1055,10 +1217,14 @@ private static IEnumerable GetTables(
yield return context.MethodDefinitionTable;
- yield return context.AttributesTable;
+ yield return context.GenericParamsTable;
+
+ yield return context.MethodSpecificationTable;
yield return context.TypeSpecificationsTable;
+ yield return context.AttributesTable;
+
yield return context.ResourcesTable;
yield return context.ResourceDataTable;
diff --git a/MetadataProcessor.Shared/nanoAssemblyDefinition.cs b/MetadataProcessor.Shared/nanoAssemblyDefinition.cs
index 6f13654e..89d77559 100644
--- a/MetadataProcessor.Shared/nanoAssemblyDefinition.cs
+++ b/MetadataProcessor.Shared/nanoAssemblyDefinition.cs
@@ -1,8 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
// Original work from Oleg Rakhmatulin.
-// See LICENSE file in the project root for full license information.
-//
using System.IO;
@@ -14,10 +13,19 @@ namespace nanoFramework.Tools.MetadataProcessor
public sealed class nanoAssemblyDefinition
{
///
- /// nanoFramework assembly marker V1.
+ /// .NET nanoFramework assembly marker V1.
///
+ ///
+ /// Not to be used. Kept for historical reasons.
+ ///
+ [System.Obsolete("Not to be used. Kept for historical reasons. Use V2 instead.")]
private const string c_NFAssemblyMarker_v1 = "NFMRK1";
+ ///
+ /// .NET nanoFramework assembly marker V2.
+ ///
+ private const string c_NFAssemblyMarker_v2 = "NFMRK2";
+
///
/// Position of Assembly CRC32 in the PE file.
///
@@ -48,6 +56,11 @@ public sealed class nanoAssemblyDefinition
///
private long _paddingsOffset;
+ ///
+ /// Size of the PE file header
+ ///
+ private long _headerSize;
+
///
/// Creates new instance of object.
///
@@ -71,10 +84,10 @@ public void Write(
nanoBinaryWriter writer,
bool isPreAllocationCall)
{
- // this replicates the original struct CLR_RECORD_ASSEMBLY
+ // this follows the struct CLR_RECORD_ASSEMBLY
// marker
- writer.WriteString(c_NFAssemblyMarker_v1);
+ writer.WriteString(c_NFAssemblyMarker_v2);
// need to set position because marker could be shorter
writer.BaseStream.Seek(c_HeaderCrc32Position, SeekOrigin.Begin);
@@ -85,21 +98,22 @@ public void Write(
// assembly CRC32
writer.WriteUInt32(0);
- // current builds are for little endian targets only
- // keeping this here for now, just for compatibility
+ // flags
writer.WriteUInt32(0);
+ // nativeMethodsChecksum
writer.WriteUInt32(_context.NativeMethodsCrc.CurrentCrc);
- // Native methods offset
- writer.WriteUInt32(0xFFFFFFFF);
-
+ // version
writer.WriteVersion(_context.AssemblyDefinition.Name.Version);
+ // assemblyName
writer.WriteUInt16(isPreAllocationCall
? (ushort)0x0000
: _context.StringTable.GetOrCreateStringId(_context.AssemblyDefinition.Name.Name));
- writer.WriteUInt16(1); // String table version
+
+ // string table version
+ writer.WriteUInt16(1);
//For every table, a number of bytes that were padded to the end of the table
//to align to unsigned long. Each table starts at a unsigned long boundary, and ends
@@ -108,21 +122,29 @@ public void Write(
//compact form to hold this information, but it only costs 16 bytes/assembly.
//Trying to only align some of the tables is just much more hassle than it's worth.
//And, of course, this field also has to be unsigned long-aligned.
+
+ // startOfTables
+ // paddingOfTables
+
if (isPreAllocationCall)
{
_tablesOffset = writer.BaseStream.Position;
- for (var i = 0; i < 16; ++i)
+ for (var i = 0; i < nanoAssemblyBuilder.TablesCount; ++i)
{
writer.WriteUInt32(0);
}
- writer.WriteUInt32(0); // Number of patched methods
-
_paddingsOffset = writer.BaseStream.Position;
- for (var i = 0; i < 16; ++i)
+ for (var i = 0; i < nanoAssemblyBuilder.TablesCount; ++i)
{
writer.WriteByte(0);
}
+
+ // store the header size which is required to compute the CRC32 ahead
+ _headerSize = (writer.BaseStream.Position + 3) & 0xFFFFFFFC;
+
+ // check if we need to write any padding bytes
+ writer.WriteBytes(new byte[_headerSize - writer.BaseStream.Position]);
}
else
{
@@ -134,8 +156,8 @@ public void Write(
var assemblyCrc32 = ComputeCrc32(
writer.BaseStream,
- _paddingsOffset,
- writer.BaseStream.Length - _paddingsOffset);
+ _headerSize,
+ writer.BaseStream.Length - _headerSize);
writer.WriteUInt32(assemblyCrc32);
// set writer position at Header CRC32 position
@@ -144,7 +166,7 @@ public void Write(
var headerCrc32 = ComputeCrc32(
writer.BaseStream,
0,
- _paddingsOffset);
+ _headerSize);
writer.WriteUInt32(headerCrc32);
}
}
diff --git a/MetadataProcessor.Shared/nanoDependencyGenerator.cs b/MetadataProcessor.Shared/nanoDependencyGenerator.cs
index 83a2d2b7..257e49f7 100644
--- a/MetadataProcessor.Shared/nanoDependencyGenerator.cs
+++ b/MetadataProcessor.Shared/nanoDependencyGenerator.cs
@@ -1,10 +1,10 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Original work from Oleg Rakhmatulin.
-using Mono.Cecil;
using System.Xml;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor.Core
{
diff --git a/MetadataProcessor.Shared/nanoDumperGenerator.cs b/MetadataProcessor.Shared/nanoDumperGenerator.cs
index 452c84c3..d321f3a8 100644
--- a/MetadataProcessor.Shared/nanoDumperGenerator.cs
+++ b/MetadataProcessor.Shared/nanoDumperGenerator.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -37,12 +38,13 @@ public void DumpAll()
DumpAssemblyReferences(dumpTable);
//DumpModuleReferences(dumpTable);
DumpTypeReferences(dumpTable);
-
DumpTypeDefinitions(dumpTable);
+ _tablesContext.TypeSpecificationsTable.ForEachItems((index, typeReference) => DumpTypeSpecifications(typeReference, dumpTable));
+ _tablesContext.GenericParamsTable.ForEachItems((index, genericParameter) => DumpGenericParams(genericParameter, dumpTable));
DumpCustomAttributes(dumpTable);
+ DumpStringHeap(dumpTable);
DumpUserStrings(dumpTable);
-
FormatCompiler compiler = new FormatCompiler();
Generator generator = compiler.Compile(DumpTemplates.DumpAllTemplate);
@@ -53,6 +55,33 @@ public void DumpAll()
}
}
+ private void DumpGenericParams(GenericParameter genericParameter, DumpAllTable dumpTable)
+ {
+ _tablesContext.GenericParamsTable.TryGetParameterId(genericParameter, out ushort referenceId);
+
+ var genericParam = new GenericParam()
+ {
+ Position = referenceId.ToString(),
+ Owner = genericParameter.Owner.ToString(),
+ Name = genericParameter.Name
+ };
+
+ if (genericParameter.Owner is TypeDefinition && _tablesContext.TypeDefinitionTable.TryGetTypeReferenceId((TypeDefinition)genericParameter.Owner, out ushort typeRefId))
+ {
+ string realToken = genericParameter.MetadataToken.ToInt32().ToString("X8");
+
+ genericParam.Owner = $"Owner: {genericParameter.Owner} [{new nanoMetadataToken(genericParameter.Owner.MetadataToken, typeRefId)}] /*{realToken}*/";
+ }
+ else if (_tablesContext.MethodDefinitionTable.TryGetMethodReferenceId((MethodDefinition)genericParameter.Owner, out ushort refId))
+ {
+ string realToken = genericParameter.Owner.MetadataToken.ToInt32().ToString("X8");
+
+ genericParam.Owner = $"Owner: {((MethodDefinition)genericParameter.Owner)} [{new nanoMetadataToken(genericParameter.Owner.MetadataToken, refId)}] /*{realToken}*/";
+ }
+
+ dumpTable.GenericParams.Add(genericParam);
+ }
+
private void DumpCustomAttributes(DumpAllTable dumpTable)
{
foreach (var a in _tablesContext.TypeDefinitionTable.Items.Where(td => td.HasCustomAttributes))
@@ -64,8 +93,8 @@ private void DumpCustomAttributes(DumpAllTable dumpTable)
var attribute = new AttributeCustom()
{
Name = a.Module.Assembly.Name.Name,
- ReferenceId = ma.MetadataToken.ToInt32().ToString("x8"),
- TypeToken = ma.CustomAttributes[0].Constructor.MetadataToken.ToInt32().ToString("x8")
+ ReferenceId = ma.MetadataToken.ToInt32().ToString("X8"),
+ TypeToken = ma.CustomAttributes[0].Constructor.MetadataToken.ToInt32().ToString("X8")
};
if (ma.CustomAttributes[0].HasConstructorArguments)
@@ -87,8 +116,8 @@ private void DumpCustomAttributes(DumpAllTable dumpTable)
var attribute = new AttributeCustom()
{
Name = a.Module.Assembly.Name.Name,
- ReferenceId = fa.MetadataToken.ToInt32().ToString("x8"),
- TypeToken = fa.CustomAttributes[0].Constructor.MetadataToken.ToInt32().ToString("x8")
+ ReferenceId = fa.MetadataToken.ToInt32().ToString("X8"),
+ TypeToken = fa.CustomAttributes[0].Constructor.MetadataToken.ToInt32().ToString("X8")
};
if (!nanoTablesContext.IgnoringAttributes.Contains(fa.CustomAttributes[0].AttributeType.FullName)
@@ -182,11 +211,27 @@ private List BuildFixedArgsAttribute(CustomAttributeArgument value
return new List() { newArg };
}
- private void DumpUserStrings(DumpAllTable dumpTable)
+ private void DumpStringHeap(DumpAllTable dumpTable)
{
- // start at 1, because 0 is the empty string entry
- int tokenId = 1;
+ foreach (var s in _tablesContext.StringTable.GetItems().OrderBy(i => i.Value))
+ {
+ // don't output the empty string
+ if (s.Value == 0)
+ {
+ continue;
+ }
+ dumpTable.StringHeap.Add(
+ new HeapString()
+ {
+ ReferenceId = s.Value.ToString("X8"),
+ Content = s.Key
+ });
+ }
+ }
+
+ private void DumpUserStrings(DumpAllTable dumpTable)
+ {
foreach (var s in _tablesContext.StringTable.GetItems().OrderBy(i => i.Value).Where(i => i.Value > _tablesContext.StringTable.LastPreAllocatedId))
{
// don't output the empty string
@@ -195,13 +240,11 @@ private void DumpUserStrings(DumpAllTable dumpTable)
continue;
}
- // fake the metadata token from the ID
- var stringMetadataToken = new MetadataToken(TokenType.String, tokenId++);
-
dumpTable.UserStrings.Add(
new UserString()
{
- ReferenceId = stringMetadataToken.ToInt32().ToString("x8"),
+ ReferenceId = new nanoMetadataToken(NanoClrTable.TBL_Strings, _tablesContext.StringTable.GetOrCreateStringId(s.Key, true)).ToString(),
+ Length = s.Key.Length.ToString("x2"),
Content = s.Key
});
}
@@ -211,10 +254,12 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
{
foreach (TypeDefinition t in _tablesContext.TypeDefinitionTable.Items.OrderBy(tr => tr.MetadataToken.ToInt32()))
{
+ _tablesContext.TypeDefinitionTable.TryGetTypeReferenceId(t, out ushort referenceId);
+
// fill type definition
var typeDef = new TypeDef()
{
- ReferenceId = t.MetadataToken.ToInt32().ToString("x8"),
+ ReferenceId = TypeDefRefIdToString(t, referenceId)
};
if (t.IsNested)
@@ -230,37 +275,47 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
t,
_tablesContext.MethodDefinitionTable);
- typeDef.Flags = typeFlags.ToString("x8");
+ typeDef.Flags = typeFlags.ToString("X8");
if (t.BaseType != null)
{
- typeDef.ExtendsType = t.BaseType.MetadataToken.ToInt32().ToString("x8");
+ _tablesContext.TypeReferencesTable.TryGetTypeReferenceId(t.BaseType, out referenceId);
+
+ typeDef.ExtendsType = TypeDefExtendsTypeToString(t.BaseType, referenceId);
}
else
{
- var token = new MetadataToken(TokenType.TypeRef, 0);
- typeDef.ExtendsType = token.ToInt32().ToString("x8");
+ typeDef.ExtendsType = "(none)";
}
if (t.DeclaringType != null)
{
- typeDef.EnclosedType = t.DeclaringType.MetadataToken.ToInt32().ToString("x8");
+ string realToken = t.DeclaringType.MetadataToken.ToInt32().ToString("X8");
+
+ _tablesContext.TypeReferencesTable.TryGetTypeReferenceId(t.DeclaringType, out referenceId);
+
+ typeDef.EnclosedType = $"{t.DeclaringType.FullName}[{new nanoMetadataToken(t.DeclaringType.MetadataToken, referenceId)}] /*{realToken}*/";
}
else
{
- var token = new MetadataToken(TokenType.TypeDef, 0);
- typeDef.EnclosedType = token.ToInt32().ToString("x8");
+ typeDef.EnclosedType = "(none)";
}
// list generic parameters
foreach (GenericParameter gp in t.GenericParameters)
{
+ string realToken = gp.MetadataToken.ToInt32().ToString("X8");
+ _tablesContext.GenericParamsTable.TryGetParameterId(gp, out referenceId);
+
+ var ownerRealToken = gp.Owner.MetadataToken.ToInt32().ToString("X8");
+ _tablesContext.TypeDefinitionTable.TryGetTypeReferenceId(gp.Owner as TypeDefinition, out ushort ownerReferenceId);
+
var genericParam = new GenericParam()
{
Position = gp.Position.ToString(),
- GenericParamToken = gp.MetadataToken.ToInt32().ToString("x8"),
- Name = gp.FullName,
- Owner = gp.Owner.MetadataToken.ToInt32().ToString("x8"),
+ GenericParamToken = $"[{new nanoMetadataToken(gp.MetadataToken, referenceId)}] /*{realToken}*/",
+ Name = new string('!', gp.Position + 1) + gp.FullName,
+ Owner = $"[{ownerReferenceId:x4}] /*{ownerRealToken}*/",
Signature = gp.DeclaringType.Name
};
@@ -272,12 +327,15 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
{
uint att = (uint)f.Attributes;
+ string realToken = f.MetadataToken.ToInt32().ToString("X8");
+ _tablesContext.FieldsTable.TryGetFieldReferenceId(f, false, out referenceId);
+
var fieldDef = new FieldDef()
{
- ReferenceId = f.MetadataToken.ToInt32().ToString("x8"),
+ ReferenceId = $"[{new nanoMetadataToken(f.MetadataToken, referenceId)}] /*{realToken}*/",
Name = f.Name,
- Flags = att.ToString("x8"),
- Attributes = att.ToString("x8"),
+ Flags = att.ToString("X8"),
+ Attributes = att.ToString("X8"),
Signature = f.FieldType.TypeSignatureAsString()
};
@@ -287,38 +345,57 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
// list type methods
foreach (MethodDefinition m in t.Methods)
{
+ string realToken = m.MetadataToken.ToInt32().ToString("X8");
+ _tablesContext.MethodDefinitionTable.TryGetMethodReferenceId(m, out referenceId);
+
var methodDef = new MethodDef()
{
- ReferenceId = m.MetadataToken.ToInt32().ToString("x8"),
+ ReferenceId = MethodDefIdToString(m, referenceId),
Name = m.FullName(),
- RVA = m.RVA.ToString("x8"),
+ RVA = _tablesContext.ByteCodeTable.GetMethodRva(m).ToString("X8"),
Implementation = "00000000",
Signature = PrintSignatureForMethod(m)
};
- uint methodFlags = nanoMethodDefinitionTable.GetFlags(m);
- methodDef.Flags = methodFlags.ToString("x8");
+ // check for entry point
+ if (m == m.Module.EntryPoint)
+ {
+ methodDef.ReferenceId += " [ENTRYPOINT]";
+ }
+
+ var methodFlags = nanoMethodDefinitionTable.GetFlags(m);
+ methodDef.Flags = methodFlags.ToString("X8");
if (m.HasBody)
{
// locals
if (m.Body.HasVariables)
{
- methodDef.Locals = PrintSignatureForLocalVar(m.Body.Variables);
+ var locaStringBuilder = new StringBuilder();
+
+ // get signature Id for locals
+ var signatureId = _tablesContext.SignaturesTable.GetOrCreateSignatureId(m.Body.Variables);
+ locaStringBuilder.Append($"[{new nanoMetadataToken(NanoClrTable.TBL_Signatures, signatureId)}]");
+
+ // print locals ids
+ locaStringBuilder.Append($": {PrintSignatureForLocalVar(m.Body.Variables)}");
+
+ methodDef.Locals = locaStringBuilder.ToString();
}
// exceptions
foreach (Mono.Cecil.Cil.ExceptionHandler eh in m.Body.ExceptionHandlers)
{
- var h = new ExceptionHandler();
-
- h.Handler = $"{((int)eh.HandlerType).ToString("x2")} " +
- $"{eh.TryStart?.Offset.ToString("x8")}->{eh.TryEnd?.Offset.ToString("x8")} " +
- $"{eh.HandlerStart?.Offset.ToString("x8")}->{eh.HandlerEnd?.Offset.ToString("x8")} ";
+ var h = new ExceptionHandler
+ {
+ Handler = $"{(int)eh.HandlerType:x2} " +
+ $"{eh.TryStart?.Offset.ToString("X8")}->{eh.TryEnd?.Offset.ToString("X8")} " +
+ $"{eh.HandlerStart?.Offset.ToString("X8")}->{eh.HandlerEnd?.Offset.ToString("X8")} "
+ };
if (eh.CatchType != null)
{
- h.Handler += $"{eh.CatchType.MetadataToken.ToInt32().ToString("x8")}";
+ h.Handler += $"{eh.CatchType.MetadataToken.ToInt32():X8}";
}
else
{
@@ -333,68 +410,148 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
// IL code
foreach (Instruction instruction in m.Body.Instructions)
{
+ if (instruction.OpCode.OperandType == OperandType.InlineMethod ||
+ instruction.OpCode.OperandType == OperandType.InlineField ||
+ instruction.OpCode.OperandType == OperandType.InlineTok ||
+ instruction.OpCode.OperandType == OperandType.InlineType)
+ {
+ realToken = ((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32().ToString("X8");
+ }
+
+ string typeName = string.Empty;
+
ILCode ilCode = new ILCode();
- ilCode.IL += instruction.OpCode.Name.PadRight(12);
+ StringBuilder ilDescription = new StringBuilder();
+
+ ilDescription.Append($"IL_{instruction.Offset:x4}: ");
+
+ ilDescription.Append(instruction.OpCode.Name.PadRight(12));
if (instruction.Operand != null)
{
- if (instruction.OpCode.OperandType == OperandType.InlineTok ||
- instruction.OpCode.OperandType == OperandType.InlineSig)
+ if (instruction.OpCode.OperandType == OperandType.InlineMethod)
{
- ilCode.IL += $"[{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
+ typeName = (instruction.Operand as MethodReference).FullName;
+
+ referenceId = _tablesContext.GetMethodReferenceId((MethodReference)instruction.Operand);
+
+ // get CLR table
+ var clrTable = nanoTokenHelpers.DecodeTableIndex(referenceId, nanoTokenHelpers.NanoMemberRefTokenTables);
+
+ // need to clear the encoded type mask
+ referenceId = nanoTokenHelpers.DecodeReferenceIndex(referenceId, nanoTokenHelpers.NanoMemberRefTokenTables);
+
+ ilDescription.Append($"{typeName} [{new nanoMetadataToken(clrTable, referenceId)}] /*{realToken}*/");
}
else if (instruction.OpCode.OperandType == OperandType.InlineField)
{
- // output the field type name
- ilCode.IL += $"{((FieldReference)instruction.Operand).FieldType.FullName}";
+ typeName = (instruction.Operand as FieldReference).FullName;
+
+ referenceId = _tablesContext.GetFieldReferenceId((FieldReference)instruction.Operand);
- // output the token
- ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
+ // get CLR table
+ var clrTable = nanoTokenHelpers.DecodeTableIndex(referenceId, nanoTokenHelpers.NanoFieldMemberRefTokenTables);
+
+ // need to clear the encoded type mask
+ referenceId = nanoTokenHelpers.DecodeReferenceIndex(referenceId, nanoTokenHelpers.NanoFieldMemberRefTokenTables);
+
+ ilDescription.Append($"{typeName} [{new nanoMetadataToken(clrTable, referenceId)}] /*{realToken}*/");
}
- else if (instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineMethod)
+ else if (instruction.OpCode.OperandType == OperandType.InlineTok)
{
- // output the method name
- ilCode.IL += $"{((MethodReference)instruction.Operand).FullName}";
+ var token = _tablesContext.GetMetadataToken((IMetadataTokenProvider)instruction.Operand);
- // output the token
- ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
+ ilDescription.Append($"[{token:X8}] /*{realToken}*/");
}
else if (instruction.OpCode.OperandType == OperandType.InlineType)
{
- // Mono.Cecil.ArrayType
- if (instruction.Operand is ArrayType arrayType)
- {
- // output the type name
- ilCode.IL += $"{arrayType.ElementType.FullName}[]";
- }
- else
+ referenceId = _tablesContext.GetTypeReferenceId((TypeReference)instruction.Operand);
+ var nfToken = new nanoMetadataToken();
+
+ // get CLR table
+ var clrTable = nanoTokenHelpers.DecodeTableIndex(referenceId, nanoTokenHelpers.NanoTypeTokenTables);
+
+ // need to clear the encoded type mask
+ referenceId = nanoTokenHelpers.DecodeReferenceIndex(referenceId, nanoTokenHelpers.NanoTypeTokenTables);
+
+ switch (clrTable)
{
- // output the type name
- ilCode.IL += $"{((TypeReference)instruction.Operand).FullName}";
+ case NanoClrTable.TBL_GenericParam:
+ typeName = (instruction.Operand as GenericParameter).TypeSignatureAsString();
+ nfToken = new nanoMetadataToken(NanoClrTable.TBL_GenericParam, referenceId);
+ break;
+
+ case NanoClrTable.TBL_TypeSpec:
+ if (instruction.Operand is TypeSpecification)
+ {
+ typeName = (instruction.Operand as TypeSpecification).FullName;
+ }
+ else if (instruction.Operand is GenericParameter)
+ {
+ typeName = (instruction.Operand as GenericParameter).FullName;
+
+ if ((instruction.Operand as GenericParameter).Owner is TypeDefinition)
+ {
+ ilDescription.Append("!");
+ }
+ if ((instruction.Operand as GenericParameter).Owner is MethodDefinition)
+ {
+ ilDescription.Append("!!");
+ }
+ }
+ else
+ {
+ Debug.Fail($"Can't find table for operand type {instruction.Operand}.");
+ }
+
+ // need to fake a MetadataToken and add one because ours is 0 indexed
+ realToken = new MetadataToken(TokenType.TypeSpec, referenceId + 1).ToUInt32().ToString("X8");
+
+ nfToken = new nanoMetadataToken(NanoClrTable.TBL_TypeSpec, referenceId);
+
+ break;
+
+ case NanoClrTable.TBL_TypeRef:
+ typeName = (instruction.Operand as TypeReference).FullName;
+ nfToken = new nanoMetadataToken(NanoClrTable.TBL_TypeRef, referenceId);
+ break;
+
+ case NanoClrTable.TBL_TypeDef:
+ typeName = (instruction.Operand as TypeDefinition).FullName;
+ nfToken = new nanoMetadataToken(NanoClrTable.TBL_TypeDef, referenceId);
+ break;
+
+ default:
+ Debug.Fail($"Can't find table for operand type {instruction.Operand}.");
+ break;
}
- // output the token
- ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
+ ilDescription.Append($"{typeName}[{nfToken}] /*{realToken}*/");
}
else if (instruction.OpCode.OperandType == OperandType.InlineString)
{
// strings need a different processing
// get string ID from table
- ushort stringReferenceId = _tablesContext.StringTable.GetOrCreateStringId((string)instruction.Operand, true);
-
- // fake the metadata token from the ID
- MetadataToken stringMetadataToken = new MetadataToken(TokenType.String, stringReferenceId);
+ referenceId = _tablesContext.StringTable.GetOrCreateStringId((string)instruction.Operand, true);
- // output the string
- ilCode.IL += $"\"{(string)instruction.Operand}\"";
-
- // ouput the metadata token
- ilCode.IL += $" [{stringMetadataToken.ToInt32():x8}]";
+ ilDescription.Append($"\"{instruction.Operand}\" [{new nanoMetadataToken(NanoClrTable.TBL_Strings, referenceId)}]");
+ }
+ else if (instruction.OpCode.OperandType == OperandType.InlineI
+ || instruction.OpCode.OperandType == OperandType.ShortInlineI)
+ {
+ ilDescription.Append($"{instruction.Operand:x8}");
+ }
+ else if (instruction.OpCode.OperandType == OperandType.InlineSig)
+ {
+ Debug.Fail("Check this");
+ ilDescription.Append($"InlineSig ???? /*{realToken}*/");
}
-
}
+ // clean-up trailing spaces
+ ilCode.IL = ilDescription.ToString().TrimEnd();
+
methodDef.ILCode.Add(ilCode);
}
}
@@ -405,11 +562,19 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
// list interface implementations
foreach (InterfaceImplementation i in t.Interfaces)
{
+ string realInterfaceToken = i.MetadataToken.ToInt32().ToString("X8");
+ string realInterfaceTypeToken = i.InterfaceType.MetadataToken.ToInt32().ToString("X8");
+
+ // TODO
+ //_tablesContext.TypeDefinitionTable.TryGetTypeReferenceId(i as TypeDefinition, out ushort interfaceTypeReferenceId);
+ _tablesContext.TypeDefinitionTable.TryGetTypeReferenceId(i.InterfaceType as TypeDefinition, out ushort interfaceTypeReferenceId);
+ ushort interfaceReferenceId = 0xFFFF;
+
typeDef.InterfaceDefinitions.Add(
new InterfaceDef()
{
- ReferenceId = i.MetadataToken.ToInt32().ToString("x8"),
- Interface = i.InterfaceType.MetadataToken.ToInt32().ToString("x8")
+ ReferenceId = $"[{interfaceReferenceId:x4}] /*{realInterfaceToken}*/",
+ Interface = $"[{interfaceTypeReferenceId:x4}] /*{realInterfaceTypeToken}*/"
});
}
@@ -421,19 +586,17 @@ private void DumpTypeReferences(DumpAllTable dumpTable)
{
foreach (var t in _tablesContext.TypeReferencesTable.Items.OrderBy(tr => tr.MetadataToken.ToInt32()))
{
- ushort refId;
+ string realToken = t.MetadataToken.ToInt32().ToString("X8");
var typeRef = new TypeRef()
{
Name = t.FullName,
// need to add 1 to match the index on the old MDP
- Scope = new MetadataToken(TokenType.AssemblyRef, _tablesContext.TypeReferencesTable.GetScope(t) + 1).ToInt32().ToString("x8")
+ Scope = $"[{_tablesContext.TypeReferencesTable.GetScope(t):x4}] /*{realToken}*/"
};
- if (_tablesContext.TypeReferencesTable.TryGetTypeReferenceId(t, out refId))
- {
- typeRef.ReferenceId = t.MetadataToken.ToInt32().ToString("x8");
- }
+ _tablesContext.TypeReferencesTable.TryGetTypeReferenceId(t, out ushort referenceId);
+ typeRef.ReferenceId = $"[{new nanoMetadataToken(t.MetadataToken, referenceId)}] /*{realToken}*/";
// list member refs
foreach (var m in _tablesContext.MethodReferencesTable.Items.Where(mr => mr.DeclaringType == t))
@@ -443,11 +606,12 @@ private void DumpTypeReferences(DumpAllTable dumpTable)
Name = m.Name
};
- if (_tablesContext.MethodReferencesTable.TryGetMethodReferenceId(m, out refId))
- {
- memberRef.ReferenceId = m.MetadataToken.ToInt32().ToString("x8");
- memberRef.Signature = PrintSignatureForMethod(m);
- }
+ realToken = m.MetadataToken.ToInt32().ToString("X8");
+
+ _tablesContext.MethodReferencesTable.TryGetMethodReferenceId(m, out referenceId);
+
+ memberRef.ReferenceId = $"[{new nanoMetadataToken(m.MetadataToken, referenceId)}] /*{realToken}*/";
+ memberRef.Signature = PrintSignatureForMethod(m);
typeRef.MemberReferences.Add(memberRef);
}
@@ -465,17 +629,119 @@ private void DumpAssemblyReferences(DumpAllTable dumpTable)
{
foreach (var a in _tablesContext.AssemblyReferenceTable.Items)
{
+ string realToken = a.MetadataToken.ToInt32().ToString("X8");
+
+ var referenceId = _tablesContext.AssemblyReferenceTable.GetReferenceId(a);
+
dumpTable.AssemblyReferences.Add(new AssemblyRef()
{
Name = a.Name,
// need to add 1 to match the index on the old MDP
- ReferenceId = new MetadataToken(TokenType.AssemblyRef, _tablesContext.AssemblyReferenceTable.GetReferenceId(a) + 1).ToInt32().ToString("x8"),
+ ReferenceId = $"[{new nanoMetadataToken(a.MetadataToken, referenceId)}] /*{realToken}*/",
Flags = "00000000"
});
}
}
- private string PrintSignatureForMethod(MethodReference method)
+ private void DumpTypeSpecifications(
+ TypeReference typeReference,
+ DumpAllTable dumpTable)
+ {
+
+ // get real token for the TypeSpec
+ string realToken = string.Empty;
+
+ _tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(typeReference, out ushort index);
+
+ var typeSpec = new TypeSpec();
+
+ // assume that real token index is the same as ours
+ // need to add one because ours is 0 indexed
+ realToken = new MetadataToken(TokenType.TypeSpec, index + 1).ToUInt32().ToString("X8");
+
+ typeSpec.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_TypeSpec, index)}] /*{realToken}*/";
+
+ // build name
+ StringBuilder typeSpecName = new StringBuilder();
+
+ if (typeReference is GenericParameter)
+ {
+ var genericParam = typeReference as GenericParameter;
+
+ typeSpecName.Append(typeReference.MetadataType);
+
+ if (genericParam.Owner is TypeDefinition)
+ {
+ typeSpecName.Append("!");
+ }
+ if (genericParam.Owner is MethodDefinition)
+ {
+ typeSpecName.Append("!!");
+ }
+
+ typeSpecName.Append(genericParam.Owner.GenericParameters.IndexOf(genericParam));
+
+ typeSpec.Name = typeSpecName.ToString();
+ }
+ else if (typeReference is GenericInstanceType)
+ {
+ // type is a GenericInstance
+ // can't compare with Cecil MetadataToken because the tables have been cleaned-up and re-indexed
+
+ typeSpec.Name = typeReference.FullName;
+
+ foreach (var mr in _tablesContext.MethodReferencesTable.Items)
+ {
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId) &&
+ referenceId == index)
+ {
+ var memberRef = new MemberRef()
+ {
+ Name = mr.Name
+ };
+
+ if (_tablesContext.MethodReferencesTable.TryGetMethodReferenceId(mr, out ushort memberRefId))
+ {
+ realToken = mr.MetadataToken.ToInt32().ToString("X8");
+
+ memberRef.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_MethodRef, memberRefId)}] /*{realToken}*/";
+ memberRef.Signature = PrintSignatureForMethod(mr);
+ }
+
+ typeSpec.MemberReferences.Add(memberRef);
+ }
+ }
+
+ foreach (var ms in _tablesContext.MethodSpecificationTable.Items)
+ {
+ if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(ms.DeclaringType, out ushort referenceId) &&
+ referenceId == index)
+ {
+ var memberRef = new MemberRef()
+ {
+ Name = ms.Name
+ };
+
+ if (_tablesContext.MethodSpecificationTable.TryGetMethodSpecificationId(ms, out ushort methodSpecId))
+ {
+ realToken = ms.MetadataToken.ToInt32().ToString("X8");
+
+ memberRef.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_MethodSpec, methodSpecId)}] /*{realToken}*/";
+ memberRef.Signature = PrintSignatureForMethod(ms);
+ }
+
+ typeSpec.MemberReferences.Add(memberRef);
+ }
+ }
+
+ Debug.Assert(typeSpec.MemberReferences.Count > 0, $"Couldn't find any MethodRef for TypeSpec[{typeReference}] {typeReference.FullName}");
+ }
+
+ dumpTable.TypeSpecifications.Add(typeSpec);
+ }
+
+
+ internal static string PrintSignatureForMethod(MethodReference method)
{
var sig = new StringBuilder(method.ReturnType.TypeSignatureAsString());
@@ -504,26 +770,98 @@ private string PrintSignatureForMethod(MethodReference method)
private string PrintSignatureForLocalVar(Collection variables)
{
- const string localIdentation = " ";
-
StringBuilder sig = new StringBuilder();
+ sig.Append("( ");
- sig.Append('(');
-
- for (int localIndex = 0; localIndex < variables.Count; localIndex++)
+ foreach (var l in variables)
{
- sig.Append($"{(localIndex > 0 ? localIdentation : "")} [{localIndex}] ");
- sig.Append(variables[localIndex].VariableType.TypeSignatureAsString());
+ // ident locals after the 1st one
+ if (l.Index > 0)
+ {
+ sig.Append(" ");
+ }
+
+ sig.Append($"[{l.Index}] ");
+
+ if (l.VariableType.MetadataType == MetadataType.Class)
+ {
+ sig.Append($"class {l.VariableType.FullName}");
+
+ _tablesContext.TypeDefinitionTable.TryGetTypeReferenceId(l.VariableType as TypeDefinition, out ushort referenceId);
+
+ sig.Append($"[{new nanoMetadataToken(NanoClrTable.TBL_TypeDef, referenceId)}] /*{l.VariableType.MetadataToken.ToInt32().ToString("X8")}*/");
+ }
+ else if (l.VariableType.IsGenericInstance)
+ {
+ sig.Append($"class {l.VariableType.FullName}");
+
+ _tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(l.VariableType as TypeSpecification, out ushort referenceId);
+
+ sig.Append($"[{new nanoMetadataToken(NanoClrTable.TBL_TypeSpec, referenceId)}] /*{l.VariableType.GetElementType().MetadataToken.ToInt32().ToString("X8")}*/");
+
+ // now the generic parameters
+ sig.Append("<");
+
+ foreach (var p in l.VariableType.GenericParameters)
+ {
+ sig.Append(p.Name);
+
+ if (!p.Equals(l.VariableType.GenericParameters.Last()))
+ {
+ sig.Append(",");
+ }
+ }
- if (localIndex < variables.Count - 1)
+ sig.Append(">");
+ }
+ else
{
- sig.AppendLine(", ");
+ sig.Append(l.VariableType.TypeSignatureAsString());
}
+
+ sig.AppendLine(", ");
+ }
+
+ // remove trailing", "
+ if (variables.Count > 0)
+ {
+ sig.Remove(sig.Length - 4, 4);
+ }
+ else
+ {
+ sig.Append(" ");
}
sig.Append(" )");
return sig.ToString();
}
+
+ internal static string TypeDefExtendsTypeToString(
+ TypeReference baseType,
+ ushort referenceId)
+ {
+ string realToken = baseType.MetadataToken.ToInt32().ToString("X8");
+
+ return $"{baseType.FullName}[{new nanoMetadataToken(baseType.MetadataToken, referenceId)}] /*{realToken}*/";
+ }
+
+ internal static string TypeDefRefIdToString(
+ TypeDefinition typeDef,
+ ushort referenceId)
+ {
+ string realToken = typeDef.MetadataToken.ToInt32().ToString("X8");
+
+ return $"[{new nanoMetadataToken(typeDef.MetadataToken, referenceId)}] /*{realToken}*/";
+ }
+
+ internal static string MethodDefIdToString(
+ MethodReference methodRef,
+ ushort referenceId)
+ {
+ string realToken = methodRef.MetadataToken.ToInt32().ToString("X8");
+
+ return $"[{new nanoMetadataToken(methodRef.MetadataToken, referenceId)}] /*{realToken}*/";
+ }
}
}
diff --git a/MetadataProcessor.Shared/nanoFramework.Tools.MetaDataProcessor.Core.targets b/MetadataProcessor.Shared/nanoFramework.Tools.MetaDataProcessor.Core.targets
index b6e00e04..7b9846a3 100644
--- a/MetadataProcessor.Shared/nanoFramework.Tools.MetaDataProcessor.Core.targets
+++ b/MetadataProcessor.Shared/nanoFramework.Tools.MetaDataProcessor.Core.targets
@@ -1,22 +1,22 @@
-
-
- MSBuild
- nanoFramework\v1.0\
- Always
- true
-
-
- MSBuild
- nanoFramework\v1.0\
- Always
- true
-
-
- MSBuild
- nanoFramework\v1.0\
- Always
- true
-
-
+
+
+ MSBuild
+ nanoFramework\v1.0\
+ Always
+ true
+
+
+ MSBuild
+ nanoFramework\v1.0\
+ Always
+ true
+
+
+ MSBuild
+ nanoFramework\v1.0\
+ Always
+ true
+
+
diff --git a/MetadataProcessor.Shared/nanoSkeletonGenerator.cs b/MetadataProcessor.Shared/nanoSkeletonGenerator.cs
index 093bbad0..0af6a405 100644
--- a/MetadataProcessor.Shared/nanoSkeletonGenerator.cs
+++ b/MetadataProcessor.Shared/nanoSkeletonGenerator.cs
@@ -1,17 +1,20 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// uncomment this for verbose output of library method lookup
+#if DEBUG
+//#define VERBOSE_OUTPUT
+#endif
-using Mono.Cecil;
-using Mustache;
-using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using Mono.Cecil;
+using Mustache;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor.Core
{
@@ -66,9 +69,9 @@ public void GenerateSkeleton()
GenerateStubs();
// output native checksum so it shows in build log
- Console.WriteLine("++++++++++++++++++++++++++++++++++++++++++++");
+ Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++");
Console.WriteLine($"+ Native declaration checksum: 0x{_tablesContext.NativeMethodsCrc.CurrentCrc.ToString("X8")} +");
- Console.WriteLine("++++++++++++++++++++++++++++++++++++++++++++");
+ Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++");
}
else
{
@@ -89,7 +92,7 @@ private void GenerateStubs()
IsInterop = !_withoutInteropCode
};
- foreach (TypeDefinition c in _tablesContext.TypeDefinitionTable.TypeDefinitions)
+ foreach (TypeDefinition c in _tablesContext.TypeDefinitionTable.Items)
{
if (ShouldIncludeType(c))
{
@@ -151,7 +154,7 @@ private void GenerateStubs()
{
int parameterIndex = 0;
- foreach (var item in m.Parameters)
+ foreach (ParameterDefinition item in m.Parameters)
{
// get the parameter type
string parameterType = string.Empty;
@@ -228,7 +231,6 @@ private void GenerateStubs()
newMethod.ParameterDeclaration.Add(parameterDeclaration);
parameterIndex++;
}
-
declaration.Append("HRESULT &hr )");
marshallingCall.Append("hr )");
}
@@ -399,10 +401,10 @@ private void GenerateAssemblyLookup()
// need to add a NULL entry for it
assemblyLookup.LookupTable.Add(new MethodStub()
{
-#if DEBUG
- Declaration = $"NULL, // <<<<< Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}",
+#if DEBUG && VERBOSE_OUTPUT
+ Declaration = $"nullptr, // <<<<< Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}",
#else
- Declaration = "NULL"
+ Declaration = "nullptr"
#endif
});
}
@@ -416,10 +418,10 @@ private void GenerateAssemblyLookup()
{
assemblyLookup.LookupTable.Add(new MethodStub()
{
-#if DEBUG
- Declaration = $"NULL, // <<<<< Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}",
+#if DEBUG && VERBOSE_OUTPUT
+ Declaration = $"nullptr, // <<<<< Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}",
#else
- Declaration = "NULL"
+ Declaration = "nullptr"
#endif
});
}
@@ -604,11 +606,12 @@ private int GetInstanceFieldsOffset(TypeDefinition c)
private int GetNestedFieldsCount(TypeDefinition c)
{
+ ushort tt;
+
int fieldCount = 0;
if (c.BaseType != null &&
- c.BaseType.FullName != "System.Object" &&
- c.BaseType.FullName != "System.MarshalByRefObject")
+ c.BaseType.FullName != "System.Object")
{
// get parent type fields count
fieldCount = GetNestedFieldsCount(c.BaseType.Resolve());
diff --git a/MetadataProcessor.Tests/Core/ClrIntegrationTests.cs b/MetadataProcessor.Tests/Core/ClrIntegrationTests.cs
index 1cd29857..aa8f1bf3 100644
--- a/MetadataProcessor.Tests/Core/ClrIntegrationTests.cs
+++ b/MetadataProcessor.Tests/Core/ClrIntegrationTests.cs
@@ -21,12 +21,6 @@ namespace nanoFramework.Tools.MetadataProcessor.Tests.Core
[TestClass]
public class ClrIntegrationTests
{
-
-#if DEBUG
- // path to local instance of nanoCLR DLL (to be used when debugging)
- private static string _localClrInstancePath = "E:\\GitHub\\nf-interpreter\\build\\bin\\Debug\\net6.0\\NanoCLR\\nanoFramework.nanoCLR.dll";
-#endif
-
public static bool NanoClrIsInstalled { get; private set; } = false;
[ClassInitialize]
@@ -140,7 +134,7 @@ public static void InstallNanoClr(TestContext context)
// Tool 'nanoclr' was successfully updated from version '1.0.205' to version '1.0.208'.
// or (update becoming reinstall with same version, if there is no new version):
// Tool 'nanoclr' was reinstalled with the latest stable version (version '1.0.208').
- var regexResult = Regex.Match(cliResult.StandardOutput, @"((?>version ')(?'version'\d+\.\d+\.\d+)(?>'))");
+ Match regexResult = Regex.Match(cliResult.StandardOutput, @"((?>version ')(?'version'\d+\.\d+\.\d+)(?>'))");
if (regexResult.Success)
{
@@ -172,19 +166,10 @@ public static void InstallNanoClr(TestContext context)
}
}
-#if DEBUG
- if (!string.IsNullOrEmpty(_localClrInstancePath))
- {
- // done here as we are using a local instance of nanoCLR DLL
- return;
- }
-#else
if (!string.IsNullOrEmpty(TestObjectHelper.NanoClrLocalInstance))
{
// done here as we are using a local instance of nanoCLR DLL
- return;
}
-#endif
else
{
Console.WriteLine("Upate nanoCLR instance");
@@ -245,14 +230,13 @@ public async Task RunBCLTest()
.WithArguments(arguments)
.WithValidation(CommandResultValidation.None);
- // setup cancellation token with a timeout of 1 minute
+ // setup cancellation token with a timeout of 30 seconds
using (var cts = new CancellationTokenSource())
{
- cts.CancelAfter(TimeSpan.FromMinutes(1));
+ cts.CancelAfter(TimeSpan.FromSeconds(30));
BufferedCommandResult cliResult = await cmd.ExecuteBufferedAsync(cts.Token);
int exitCode = cliResult.ExitCode;
-
// read standard output
string output = cliResult.StandardOutput;
@@ -263,10 +247,12 @@ public async Task RunBCLTest()
// look for the error message reporting that there is no entry point
Assert.IsTrue(output.Contains("Cannot find any entrypoint!"));
+
+ Console.WriteLine($"\r\n>>>>>>>>>>>>>\r\n{output}\r\n>>>>>>>>>>>>>");
}
else
{
- Assert.Fail($"nanoCLR ended with '{exitCode}' exit code.\r\n>>>>>>>>>>>>>\r\n{output}\r\n<<<<<<<<<<<<<");
+ Assert.Fail($"nanoCLR ended with '{exitCode}' exit code.\r\n>>>>>>>>>>>>>\r\n{output}\r\n>>>>>>>>>>>>>");
}
}
}
@@ -292,14 +278,13 @@ public async Task RunTestNFAppTest()
.WithArguments(arguments)
.WithValidation(CommandResultValidation.None);
- // setup cancellation token with a timeout of 1 minute
- using (var cts = new CancellationTokenSource())
+ // setup cancellation token with a timeout of 30 seconds
+ using (CancellationTokenSource cts = new CancellationTokenSource())
{
- cts.CancelAfter(TimeSpan.FromMinutes(1));
+ cts.CancelAfter(TimeSpan.FromSeconds(30));
BufferedCommandResult cliResult = await cmd.ExecuteBufferedAsync(cts.Token);
int exitCode = cliResult.ExitCode;
-
// read standard output
string output = cliResult.StandardOutput;
@@ -318,10 +303,12 @@ public async Task RunTestNFAppTest()
// look for the error message reporting that there is no entry point
Assert.IsFalse(output.Contains("Cannot find any entrypoint!"));
+
+ Console.WriteLine($"\r\n>>>>>>>>>>>>>\r\n{output}\r\n>>>>>>>>>>>>>");
}
else
{
- Assert.Fail($"nanoCLR ended with '{exitCode}' exit code.\r\n>>>>>>>>>>>>>\r\n{output}\r\n<<<<<<<<<<<<<");
+ Assert.Fail($"nanoCLR ended with '{exitCode}' exit code.\r\n>>>>>>>>>>>>>\r\n{output}\r\n>>>>>>>>>>>>>");
}
}
}
@@ -330,10 +317,6 @@ private string ComposeLocalClrInstancePath()
{
StringBuilder arguments = new StringBuilder(" --localinstance");
-#if DEBUG
- arguments.Append($" \"{_localClrInstancePath}\"");
-
-#else
if (string.IsNullOrEmpty(TestObjectHelper.NanoClrLocalInstance))
{
return null;
@@ -342,7 +325,6 @@ private string ComposeLocalClrInstancePath()
{
arguments.Append($" \"{TestObjectHelper.NanoClrLocalInstance}\"");
}
-#endif
return arguments.ToString();
}
diff --git a/MetadataProcessor.Tests/Core/Endianness/nanoBinaryWriterTests.cs b/MetadataProcessor.Tests/Core/Endianness/nanoBinaryWriterTests.cs
index 44312a59..caa0c6d3 100644
--- a/MetadataProcessor.Tests/Core/Endianness/nanoBinaryWriterTests.cs
+++ b/MetadataProcessor.Tests/Core/Endianness/nanoBinaryWriterTests.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.IO;
diff --git a/MetadataProcessor.Tests/Core/Extensions/ByteArrayExtensionsTests.cs b/MetadataProcessor.Tests/Core/Extensions/ByteArrayExtensionsTests.cs
index 4ea38383..97d7cfa0 100644
--- a/MetadataProcessor.Tests/Core/Extensions/ByteArrayExtensionsTests.cs
+++ b/MetadataProcessor.Tests/Core/Extensions/ByteArrayExtensionsTests.cs
@@ -1,9 +1,6 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
diff --git a/MetadataProcessor.Tests/Core/Extensions/ParameterDefintionExtensionsTests.cs b/MetadataProcessor.Tests/Core/Extensions/ParameterDefintionExtensionsTests.cs
index 65750e70..0f1f0aa5 100644
--- a/MetadataProcessor.Tests/Core/Extensions/ParameterDefintionExtensionsTests.cs
+++ b/MetadataProcessor.Tests/Core/Extensions/ParameterDefintionExtensionsTests.cs
@@ -1,9 +1,6 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
diff --git a/MetadataProcessor.Tests/Core/Extensions/TypeDefinitionExtensionsTests.cs b/MetadataProcessor.Tests/Core/Extensions/TypeDefinitionExtensionsTests.cs
index 75a20fcf..4bdddf8d 100644
--- a/MetadataProcessor.Tests/Core/Extensions/TypeDefinitionExtensionsTests.cs
+++ b/MetadataProcessor.Tests/Core/Extensions/TypeDefinitionExtensionsTests.cs
@@ -1,15 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
-using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mono.Cecil;
-using System.IO;
-using System.Collections.Generic;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Extensions
{
diff --git a/MetadataProcessor.Tests/Core/Extensions/TypeReferenceExtensionsTests.cs b/MetadataProcessor.Tests/Core/Extensions/TypeReferenceExtensionsTests.cs
index f15ac330..4083cd9a 100644
--- a/MetadataProcessor.Tests/Core/Extensions/TypeReferenceExtensionsTests.cs
+++ b/MetadataProcessor.Tests/Core/Extensions/TypeReferenceExtensionsTests.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Linq;
diff --git a/MetadataProcessor.Tests/Core/Mono.Cecil/CodeWriterTests.cs b/MetadataProcessor.Tests/Core/Mono.Cecil/CodeWriterTests.cs
index 4a52e1b5..7c2845d1 100644
--- a/MetadataProcessor.Tests/Core/Mono.Cecil/CodeWriterTests.cs
+++ b/MetadataProcessor.Tests/Core/Mono.Cecil/CodeWriterTests.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
@@ -435,9 +433,9 @@ public void WriteMethodBodyIntegrationTest()
#if DEBUG
- var expectedBytesWritten = new byte[] { 0x00, 0x16, 0x0A, 0x00, 0x03, 0x04, 0x58, 0x0A, 0x00, 0xDE, 0x18, 0x0B, 0x00, 0x72, 0x84, 0x01, 0x07, 0x73, 0x0D, 0x80, 0x0C, 0x08, 0x6F, 0x0E, 0x80, 0x0A, 0x00, 0xDE, 0x00, 0x06, 0x0D, 0x2B, 0x00, 0x09, 0x2A, 0x00, 0x00, 0x11, 0x80, 0x03, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x23, 0x00, 0x01 };
+ var expectedBytesWritten = new byte[] { 0x00, 0x16, 0x0A, 0x00, 0x03, 0x04, 0x58, 0x0A, 0x00, 0xDE, 0x18, 0x0B, 0x00, 0x72, 0xAE, 0x01, 0x07, 0x73, 0x15, 0x80, 0x0C, 0x08, 0x6F, 0x16, 0x80, 0x0A, 0x00, 0xDE, 0x00, 0x06, 0x0D, 0x2B, 0x00, 0x09, 0x2A, 0x00, 0x00, 0x11, 0x80, 0x03, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x23, 0x00, 0x01 };
#else
- var expectedBytesWritten = new byte[] { 0x16, 0x0A, 0x03, 0x04, 0x58, 0x0A, 0xDE, 0x16, 0x0B, 0x72, 0x48, 0x01, 0x07, 0x73, 0x0C, 0x80, 0x0C, 0x08, 0x6F, 0x0D, 0x80, 0x0A, 0xDE, 0x00, 0x06, 0x2A, 0x00, 0x00, 0x0F, 0x80, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1E, 0x00, 0x01 };
+ var expectedBytesWritten = new byte[] { 0x16, 0x0A, 0x03, 0x04, 0x58, 0x0A, 0xDE, 0x16, 0x0B, 0x72, 0x72, 0x01, 0x07, 0x73, 0x13, 0x80, 0x0C, 0x08, 0x6F, 0x14, 0x80, 0x0A, 0xDE, 0x00, 0x06, 0x2A, 0x00, 0x00, 0x0F, 0x80, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1E, 0x00, 0x01 };
#endif
Assert.AreEqual(expectedBytesWritten.Length, bytesWritten.Length, "Method body length differs.");
diff --git a/MetadataProcessor.Tests/Core/Tables/nanoAssemblyReferenceTableTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoAssemblyReferenceTableTests.cs
index b25f56d6..982463ee 100644
--- a/MetadataProcessor.Tests/Core/Tables/nanoAssemblyReferenceTableTests.cs
+++ b/MetadataProcessor.Tests/Core/Tables/nanoAssemblyReferenceTableTests.cs
@@ -1,13 +1,11 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
{
@@ -90,9 +88,6 @@ public void WriteTest()
{
writerTestOutput.Write(context.StringTable.GetOrCreateStringId(a.Name));
- // padding
- writerTestOutput.Write((ushort)0x0);
-
// version
writerTestOutput.Write((ushort)a.Version.Major);
writerTestOutput.Write((ushort)a.Version.Minor);
diff --git a/MetadataProcessor.Tests/Core/Tables/nanoAttributesTableTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoAttributesTableTests.cs
index 4390b9ac..8b0fa5e6 100644
--- a/MetadataProcessor.Tests/Core/Tables/nanoAttributesTableTests.cs
+++ b/MetadataProcessor.Tests/Core/Tables/nanoAttributesTableTests.cs
@@ -1,15 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Mono.Cecil;
-using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
using CustomAttribute = Mono.Cecil.CustomAttribute;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
diff --git a/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs
index e2e19b0e..2a4ca859 100644
--- a/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs
+++ b/MetadataProcessor.Tests/Core/Tables/nanoMethodDefinitionTableTests.cs
@@ -1,11 +1,9 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mono.Cecil;
-using System.Linq;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
{
diff --git a/MetadataProcessor.Tests/Core/Tables/nanoReferenceTableBaseTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoReferenceTableBaseTests.cs
index 01107e41..a8c9c27b 100644
--- a/MetadataProcessor.Tests/Core/Tables/nanoReferenceTableBaseTests.cs
+++ b/MetadataProcessor.Tests/Core/Tables/nanoReferenceTableBaseTests.cs
@@ -1,15 +1,13 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
{
diff --git a/MetadataProcessor.Tests/Core/Tables/nanoSignaturesTableTests.cs b/MetadataProcessor.Tests/Core/Tables/nanoSignaturesTableTests.cs
index 833a75bf..0cf66d04 100644
--- a/MetadataProcessor.Tests/Core/Tables/nanoSignaturesTableTests.cs
+++ b/MetadataProcessor.Tests/Core/Tables/nanoSignaturesTableTests.cs
@@ -15,14 +15,14 @@ namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Tables
[TestClass]
public class nanoSignaturesTableTests
{
- [DataRow("System.DateTime", nanoCLR_DataType.DATATYPE_DATETIME)]
- [DataRow("System.TimeSpan", nanoCLR_DataType.DATATYPE_TIMESPAN)]
- [DataRow("System.String", nanoCLR_DataType.DATATYPE_STRING)]
- [DataRow("System.Object", nanoCLR_DataType.DATATYPE_CLASS)]
- [DataRow("System.IntPtr", nanoCLR_DataType.DATATYPE_VALUETYPE)]
- [DataRow("System.WeakReference", nanoCLR_DataType.DATATYPE_WEAKCLASS)]
+ [DataRow("System.DateTime", NanoCLRDataType.DATATYPE_DATETIME)]
+ [DataRow("System.TimeSpan", NanoCLRDataType.DATATYPE_TIMESPAN)]
+ [DataRow("System.String", NanoCLRDataType.DATATYPE_STRING)]
+ [DataRow("System.Object", NanoCLRDataType.DATATYPE_CLASS)]
+ [DataRow("System.IntPtr", NanoCLRDataType.DATATYPE_VALUETYPE)]
+ [DataRow("System.WeakReference", NanoCLRDataType.DATATYPE_WEAKCLASS)]
[TestMethod]
- public void WriteDataTypeForTypeRef_ShouldWriteCorrectDataType(string typeFullName, nanoCLR_DataType dataType)
+ public void WriteDataTypeForTypeRef_ShouldWriteCorrectDataType(string typeFullName, NanoCLRDataType dataType)
{
// Arrange
AssemblyDefinition mscorlibAssemblyDefinition = AssemblyDefinition.ReadAssembly(TestObjectHelper.MscorlibFullPath);
diff --git a/MetadataProcessor.Tests/Core/Utility/Crc32Tests.cs b/MetadataProcessor.Tests/Core/Utility/Crc32Tests.cs
index 0955fe28..7757de0b 100644
--- a/MetadataProcessor.Tests/Core/Utility/Crc32Tests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/Crc32Tests.cs
@@ -1,10 +1,8 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
diff --git a/MetadataProcessor.Tests/Core/Utility/DumperTests.cs b/MetadataProcessor.Tests/Core/Utility/DumperTests.cs
index 03c9120a..284fdf79 100644
--- a/MetadataProcessor.Tests/Core/Utility/DumperTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/DumperTests.cs
@@ -2,17 +2,25 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics;
using System.IO;
-using System.Text.RegularExpressions;
+using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Mono.Cecil;
using nanoFramework.Tools.MetadataProcessor.Core;
+using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
[TestClass]
public class DumperTests
{
+ private ushort refId;
+
[TestMethod]
+#if !DEBUG
+ [Ignore("This test is ignored in Release builds.")]
+#endif
public void DumpAssemblyTest()
{
nanoTablesContext nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext();
@@ -36,42 +44,114 @@ public void DumpAssemblyTest()
// search for several bits
// AssemblyRefs
- Assert.IsTrue(dumpFileContent.Contains("AssemblyRefProps [23000001]: Flags: 00000000 'mscorlib'"), "Wrong entry for mscorlib in assembly ref");
- Assert.IsTrue(dumpFileContent.Contains("AssemblyRefProps [23000002]: Flags: 00000000 'TestNFClassLibrary'"), "Wrong entry for TestNFClassLibrary in assembly ref");
+ Assert.IsTrue(dumpFileContent.Contains("AssemblyRef [00000000] /*23000001*/\r\n-------------------------------------------------------\r\n'mscorlib'"));
+ Assert.IsTrue(dumpFileContent.Contains("AssemblyRef [00000001] /*23000002*/\r\n-------------------------------------------------------\r\n'TestNFClassLibrary'"));
// TypeRefs
- Assert.IsTrue(dumpFileContent.Contains("TypeRefProps [01000001]: Scope: 23000001 'System.Diagnostics.DebuggableAttribute'"), "Wrong entry for System.Diagnostics.DebuggableAttribute in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Scope: 23000002 'TestNFClassLibrary.ClassOnAnotherAssembly'"), "Wrong entry for TestNFClassLibrary.ClassOnAnotherAssembly in type ref");
+ Assert.IsTrue(dumpFileContent.Contains("TypeRef [01000000] /*01000001*/\r\n-------------------------------------------------------\r\nScope: [0000] /*01000001*/\r\n 'System.Diagnostics.DebuggableAttribute'"));
+ Assert.IsTrue(dumpFileContent.Contains("TypeRef [0100001E] /*0100001F*/\r\n-------------------------------------------------------\r\nScope: [0001] /*0100001F*/\r\n 'TestNFClassLibrary.ClassOnAnotherAssembly'"));
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 00001001 Extends: 01000010 Enclosed: 02000000 'TestNFApp.DummyCustomAttribute1'"), "Wrong entry for TestNFApp.DummyCustomAttribute1 in type ref");
+ // TestNFApp.DummyCustomAttribute1
+ string typeName = "TestNFApp.DummyCustomAttribute1";
+ TypeDefinition type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out ushort typeRefId);
+ nanoTablesContext.TypeReferencesTable.TryGetTypeReferenceId(type1.BaseType, out ushort baseTypeReferenceId);
+ uint typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 00001001 Extends: 01000010 Enclosed: 02000000 'TestNFApp.DummyCustomAttribute2'"), "Wrong entry for TestNFApp.DummyCustomAttribute2 in type ref");
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{typeName}'\r\n Flags: {typeFlags:X8}\r\n Extends: {nanoDumperGenerator.TypeDefExtendsTypeToString(type1.BaseType, baseTypeReferenceId)}\r\n Enclosed: (none)"));
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 00001061 Extends: 01000000 Enclosed: 02000000 'TestNFApp.IOneClassOverAll'"), "Wrong entry for TestNFApp.IOneClassOverAll in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 000007c6 Impl: 00000000 RVA: 00000000 'get_DummyProperty' [I4( )]"), "Wrong entry for get_DummyProperty in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 000007c6 Impl: 00000000 RVA: 00000000 'set_DummyProperty' [VOID(I4)]"), "Wrong entry for set_DummyProperty in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 000003c6 Impl: 00000000 RVA: 00000000 'DummyMethod' [VOID( )]"), "Wrong entry for DummyMethod in type ref");
+ // TestNFApp.DummyCustomAttribute2
+ typeName = "TestNFApp.DummyCustomAttribute2";
+ type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out typeRefId);
+ nanoTablesContext.TypeReferencesTable.TryGetTypeReferenceId(type1.BaseType, out baseTypeReferenceId);
+ typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
- Assert.IsTrue(dumpFileContent.Contains("Enclosed: 02000000 'TestNFApp.OneClassOverAll'"), "Wrong entry for TestNFApp.OneClassOverAll in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Attr: 00000001 Flags: 00000001 'dummyField' [STRING]"), "Wrong entry for dummyField in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Attr: 00000001 Flags: 00000001 'k__BackingField' [I4]"), "Wrong entry for k__BackingField in type ref");
- Assert.IsTrue(dumpFileContent.Contains(": Flags: 00000086 Impl: 00000000 RVA: 00000000 'DummyExternMethod' [VOID( )]"), "Wrong entry for DummyExternMethod in type ref");
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{typeName}'\r\n Flags: {typeFlags:X8}\r\n Extends: {nanoDumperGenerator.TypeDefExtendsTypeToString(type1.BaseType, baseTypeReferenceId)}\r\n Enclosed: (none)"));
- Assert.IsTrue(dumpFileContent.Contains("'TestNFApp.Program'"), "Wrong entry for TestNFApp.Program in type ref");
+ // TestNFApp.IOneClassOverAll
+ typeName = "TestNFApp.IOneClassOverAll";
+ type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out typeRefId);
+ typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
- Assert.IsTrue(dumpFileContent.Contains("'SubClass'"), "Wrong entry for SubClass in type ref");
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{typeName}'\r\n Flags: {typeFlags:X8}\r\n Extends: (none)\r\n Enclosed: (none)"));
- // skip this assert to locals listing as the debug build will differ as it not optimized
-#if !DEBUG
- Assert.IsTrue(Regex.IsMatch(dumpFileContent, @"Locals \( \[0\] I4, \r\n\s+\[1\] CLASS System\.Exception \[\d{8}\], \r\n\s+\[2\] CLASS System\.ApplicationException \[\d{8}\] \)"), "Wrong listing of locals in UglyAdd method");
-#endif
- Assert.IsTrue(dumpFileContent.Contains("callvirt System.Void TestNFApp.TestingDelegates/SimpleDelegate::Invoke(System.String)"), "Wrong reference to callvirt in DelegateTests body");
- Assert.IsTrue(dumpFileContent.Contains("ldstr \" DataRowAttribute.Arg[{0}] has: {1}\""), "Wrong reference to ldstr in ReflectionTests body");
+ foreach (MethodDefinition m in type1.Methods)
+ {
+ _ = nanoTablesContext.MethodDefinitionTable.TryGetMethodReferenceId(m, out ushort methodReferenceId);
+
+ Assert.IsTrue(dumpFileContent.Contains($" MethodDef {nanoDumperGenerator.MethodDefIdToString(m, methodReferenceId)}\r\n -------------------------------------------------------\r\n '{m.FullName()}'\r\n Flags: {nanoMethodDefinitionTable.GetFlags(m):X8}\r\n Impl: 00000000\r\n RVA: 0000FFFF\r\n [{nanoDumperGenerator.PrintSignatureForMethod(m)}]"));
+ }
+
+ // TestNFApp.ComplexAttribute
+ typeName = "TestNFApp.ComplexAttribute";
+ type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out typeRefId);
+ nanoTablesContext.TypeReferencesTable.TryGetTypeReferenceId(type1.BaseType, out baseTypeReferenceId);
+
+ FieldDefinition maxField = nanoTablesContext.FieldsTable.Items.FirstOrDefault(f => f.Name == "_max");
+ string maxFieldRealToken = maxField.MetadataToken.ToInt32().ToString("X8");
+ nanoTablesContext.FieldsTable.TryGetFieldReferenceId(maxField, false, out ushort maxFieldReferenceId);
+
+ FieldDefinition sField = nanoTablesContext.FieldsTable.Items.FirstOrDefault(f => f.Name == "_s");
+ string sFieldRealToken = sField.MetadataToken.ToInt32().ToString("X8");
+ nanoTablesContext.FieldsTable.TryGetFieldReferenceId(sField, false, out ushort sFieldReferenceId);
+
+ FieldDefinition bField = nanoTablesContext.FieldsTable.Items.FirstOrDefault(f => f.Name == "_b");
+ string bFieldRealToken = bField.MetadataToken.ToInt32().ToString("X8");
+ nanoTablesContext.FieldsTable.TryGetFieldReferenceId(bField, false, out ushort bFieldReferenceId);
+
+
+ typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
+
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{typeName}'\r\n Flags: {typeFlags:X8}\r\n Extends: {nanoDumperGenerator.TypeDefExtendsTypeToString(type1.BaseType, baseTypeReferenceId)}\r\n Enclosed: (none)"));
+ Assert.IsTrue(dumpFileContent.Contains($" FieldDef [{new nanoMetadataToken(maxField.MetadataToken, maxFieldReferenceId)}] /*{maxFieldRealToken}*/\r\n -------------------------------------------------------\r\n Attr: 00000021\r\n Flags: 00000021\r\n '_max'\r\n [U4]\r\n"));
+ Assert.IsTrue(dumpFileContent.Contains($" FieldDef [{new nanoMetadataToken(sField.MetadataToken, sFieldReferenceId)}] /*{sFieldRealToken}*/\r\n -------------------------------------------------------\r\n Attr: 00000021\r\n Flags: 00000021\r\n '_s'\r\n [STRING]\r\n"));
+ Assert.IsTrue(dumpFileContent.Contains($" FieldDef [{new nanoMetadataToken(bField.MetadataToken, bFieldReferenceId)}] /*{bFieldRealToken}*/\r\n -------------------------------------------------------\r\n Attr: 00000021\r\n Flags: 00000021\r\n '_b'\r\n [BOOLEAN]\r\n"));
+
+ foreach (MethodDefinition m in type1.Methods)
+ {
+ _ = nanoTablesContext.MethodDefinitionTable.TryGetMethodReferenceId(m, out ushort methodReferenceId);
+
+ Assert.IsTrue(dumpFileContent.Contains($" MethodDef {nanoDumperGenerator.MethodDefIdToString(m, methodReferenceId)}\r\n -------------------------------------------------------\r\n '{m.FullName()}'\r\n Flags: {nanoMethodDefinitionTable.GetFlags(m):X8}\r\n Impl: 00000000\r\n RVA: 0000FFFF\r\n [{nanoDumperGenerator.PrintSignatureForMethod(m)}]"));
+ }
+
+ // TestNFApp.Program
+ typeName = "TestNFApp.Program";
+ type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out typeRefId);
+ nanoTablesContext.TypeReferencesTable.TryGetTypeReferenceId(type1.BaseType, out baseTypeReferenceId);
+ typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
+
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{typeName}'\r\n Flags: {typeFlags:X8}\r\n Extends: {nanoDumperGenerator.TypeDefExtendsTypeToString(type1.BaseType, baseTypeReferenceId)}\r\n Enclosed: (none)"));
+
+ // OneClassOverAll/SubClass
+ typeName = "TestNFApp.OneClassOverAll/SubClass";
+ type1 = nanoTablesContext.TypeDefinitionTable.Items.FirstOrDefault(t => t.FullName == typeName);
+ nanoTablesContext.TypeDefinitionTable.TryGetTypeReferenceId(type1, out typeRefId);
+ nanoTablesContext.TypeReferencesTable.TryGetTypeReferenceId(type1.BaseType, out baseTypeReferenceId);
+ typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(type1, nanoTablesContext.MethodDefinitionTable);
+
+ Assert.IsTrue(dumpFileContent.Contains($"TypeDef {nanoDumperGenerator.TypeDefRefIdToString(type1, typeRefId)}\r\n-------------------------------------------------------\r\n '{type1.Name}'\r\n Flags: {typeFlags:X8}\r\n Extends: {nanoDumperGenerator.TypeDefExtendsTypeToString(type1.BaseType, baseTypeReferenceId)}\r\n Enclosed: TestNFApp.OneClassOverAll[04000000] /*0200001B*/"));
+
+ // String heap
+ foreach (string stringKey in nanoTablesContext.StringTable.GetItems().Keys)
+ {
+ // skip initial empty string
+ if (string.IsNullOrEmpty(stringKey))
+ {
+ continue;
+ }
+
+ string expectedString = $"{nanoTablesContext.StringTable.GetItems()[stringKey]:X8}: {stringKey}";
+
+ Assert.IsTrue(dumpFileContent.Contains(expectedString));
+ }
// UserStrings
- Assert.IsTrue(dumpFileContent.Contains(": 'TestNFClassLibrary'"), "Wrong entry for TestNFClassLibrary in user string");
- Assert.IsTrue(dumpFileContent.Contains(": 'get_DummyProperty'"), "Wrong entry for get_DummyProperty in user string");
- Assert.IsTrue(dumpFileContent.Contains(": 'blabla'"), "Wrong entry for blabla in user string");
+ System.Collections.Generic.KeyValuePair lastStringEntry = nanoTablesContext.StringTable.GetItems().OrderBy(i => i.Value).Last();
+ Assert.IsTrue(dumpFileContent.Contains($"{new nanoMetadataToken(NanoClrTable.TBL_Strings, nanoTablesContext.StringTable.GetOrCreateStringId(lastStringEntry.Key, true))} : ({lastStringEntry.Key.Length:x2}) \"{lastStringEntry.Key}\""));
}
}
}
diff --git a/MetadataProcessor.Tests/Core/Utility/LoadHintsAssemblyResolverTests.cs b/MetadataProcessor.Tests/Core/Utility/LoadHintsAssemblyResolverTests.cs
index b526c6ad..f72adf03 100644
--- a/MetadataProcessor.Tests/Core/Utility/LoadHintsAssemblyResolverTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/LoadHintsAssemblyResolverTests.cs
@@ -1,11 +1,9 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
@@ -19,7 +17,7 @@ public void ConstructorTest()
using (var iut = new LoadHintsAssemblyResolver(new Dictionary()))
{
// no op
- };
+ }
}
[TestMethod]
diff --git a/MetadataProcessor.Tests/Core/Utility/NativeMethodsCrcTests.cs b/MetadataProcessor.Tests/Core/Utility/NativeMethodsCrcTests.cs
index 7a324ccb..71386720 100644
--- a/MetadataProcessor.Tests/Core/Utility/NativeMethodsCrcTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/NativeMethodsCrcTests.cs
@@ -1,12 +1,10 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Mono.Cecil;
using System;
using System.Collections.Generic;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Mono.Cecil;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
@@ -72,46 +70,46 @@ public void GetMethodNameTest()
}
[TestMethod]
- public void GetnanoClrTypeNameTest()
+ public void GetNanoCLRTypeNameTest()
{
var assemblyDefinition = TestObjectHelper.GetTestNFAppAssemblyDefinition();
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(void), "DATATYPE_VOID");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(sbyte), "DATATYPE_I1");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(short), "DATATYPE_I2");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(int), "DATATYPE_I4");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(long), "DATATYPE_I8");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(void), "DATATYPE_VOID");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(sbyte), "DATATYPE_I1");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(short), "DATATYPE_I2");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(int), "DATATYPE_I4");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(long), "DATATYPE_I8");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(byte), "DATATYPE_U1");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(ushort), "DATATYPE_U2");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(uint), "DATATYPE_U4");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(ulong), "DATATYPE_U8");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(byte), "DATATYPE_U1");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(ushort), "DATATYPE_U2");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(uint), "DATATYPE_U4");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(ulong), "DATATYPE_U8");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(float), "DATATYPE_R4");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(double), "DATATYPE_R8");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(float), "DATATYPE_R4");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(double), "DATATYPE_R8");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(char), "DATATYPE_CHAR");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(string), "DATATYPE_STRING");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(bool), "DATATYPE_BOOLEAN");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(char), "DATATYPE_CHAR");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(string), "DATATYPE_STRING");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(bool), "DATATYPE_BOOLEAN");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(object), "DATATYPE_OBJECT");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(IntPtr), "DATATYPE_I4");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(UIntPtr), "DATATYPE_U4");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(object), "DATATYPE_OBJECT");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(IntPtr), "DATATYPE_I4");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(UIntPtr), "DATATYPE_U4");
- DoGetnanoClrTypeNameTest(assemblyDefinition, typeof(System.WeakReference), "DATATYPE_WEAKCLASS");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, typeof(System.WeakReference), "DATATYPE_WEAKCLASS");
- DoGetnanoClrTypeNameTest(assemblyDefinition, this.GetType(), "nanoFrameworkToolsMetadataProcessorTestsCoreUtilityNativeMethodsCrcTests");
+ DoGetNanoCLRTypeNameTest(assemblyDefinition, this.GetType(), "nanoFrameworkToolsMetadataProcessorTestsCoreUtilityNativeMethodsCrcTests");
}
- private void DoGetnanoClrTypeNameTest(AssemblyDefinition assemblyDefinition, Type type, string expectedNanoClrTypeName)
+ private void DoGetNanoCLRTypeNameTest(AssemblyDefinition assemblyDefinition, Type type, string expectedNanoCLRTypeName)
{
var typeReference = assemblyDefinition.MainModule.ImportReference(type);
// test
- var r = NativeMethodsCrc.GetnanoClrTypeName(typeReference);
+ var r = NativeMethodsCrc.GetNanoCLRTypeName(typeReference);
- Assert.AreEqual(expectedNanoClrTypeName, r);
+ Assert.AreEqual(expectedNanoCLRTypeName, r);
}
@@ -157,7 +155,7 @@ public void CrcWithMethodDefinitionTest()
// test
iut.UpdateCrc(nonExternMethodDefinition);
- Assert.AreEqual((uint)2748897355, iut.CurrentCrc);
+ Assert.AreEqual((uint)882012044, iut.CurrentCrc);
}
[TestMethod]
diff --git a/MetadataProcessor.Tests/Core/Utility/nanoBitmapProcessorTests.cs b/MetadataProcessor.Tests/Core/Utility/nanoBitmapProcessorTests.cs
index e7d206c8..b89d246d 100644
--- a/MetadataProcessor.Tests/Core/Utility/nanoBitmapProcessorTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/nanoBitmapProcessorTests.cs
@@ -1,10 +1,8 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Drawing;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
diff --git a/MetadataProcessor.Tests/Core/Utility/nanoDependencyGeneratorWriterTests.cs b/MetadataProcessor.Tests/Core/Utility/nanoDependencyGeneratorWriterTests.cs
index 2cc209d4..9068bb6d 100644
--- a/MetadataProcessor.Tests/Core/Utility/nanoDependencyGeneratorWriterTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/nanoDependencyGeneratorWriterTests.cs
@@ -1,11 +1,9 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Xml;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
diff --git a/MetadataProcessor.Tests/Core/Utility/nanoStringsConstantsTests.cs b/MetadataProcessor.Tests/Core/Utility/nanoStringsConstantsTests.cs
index a39a78dc..ccb639aa 100644
--- a/MetadataProcessor.Tests/Core/Utility/nanoStringsConstantsTests.cs
+++ b/MetadataProcessor.Tests/Core/Utility/nanoStringsConstantsTests.cs
@@ -1,10 +1,8 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace nanoFramework.Tools.MetadataProcessor.Tests.Core.Utility
{
diff --git a/MetadataProcessor.Tests/Core/nanoAssemblyBuilderTests.cs b/MetadataProcessor.Tests/Core/nanoAssemblyBuilderTests.cs
new file mode 100644
index 00000000..be6f5b89
--- /dev/null
+++ b/MetadataProcessor.Tests/Core/nanoAssemblyBuilderTests.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace nanoFramework.Tools.MetadataProcessor.Tests.Core
+{
+ [TestClass]
+ public class nanoAssemblyBuilderTests
+ {
+ [TestMethod]
+ public void AssemblyTablesCountTest()
+ {
+ var nanoTablesContext = TestObjectHelper.GetTestNFAppNanoTablesContext();
+
+ Assert.IsTrue(
+ nanoAssemblyBuilder.GetTables(nanoTablesContext).Count() == nanoAssemblyBuilder.TablesCount,
+ "Tables count from context doesn't match the nanoAssemblyBuilder.TablesCount property.");
+
+ Assert.IsTrue(
+ nanoAssemblyBuilder.GetTables(nanoTablesContext).Count() == Enum.GetNames(typeof(NanoClrTable)).Length,
+ "Tables count from context doesn't match number of items in CLR Tables enum.");
+ }
+ }
+}
diff --git a/MetadataProcessor.Tests/MdpNFTestApp/MdpNFTestApp.sln b/MetadataProcessor.Tests/MdpNFTestApp/MdpNFTestApp.sln
index a213d3af..6dcad06b 100644
--- a/MetadataProcessor.Tests/MdpNFTestApp/MdpNFTestApp.sln
+++ b/MetadataProcessor.Tests/MdpNFTestApp/MdpNFTestApp.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33530.505
diff --git a/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj b/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj
index 5320fe42..760a930e 100644
--- a/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj
+++ b/MetadataProcessor.Tests/MetadataProcessor.Tests.csproj
@@ -55,12 +55,12 @@
+
-
@@ -101,19 +101,23 @@
{e32f7d15-2499-440c-8026-4d5ee1c5ec3a}
MetadataProcessor.Core
+
+ {9e5e0766-701d-4266-9eba-7b3e4338ed21}
+ TestNFApp
+
- 3.8.0
+ 3.8.2
0.11.6
- 3.7.2
+ 3.8.3
- 3.7.2
+ 3.8.3
13.0.3
@@ -124,8 +128,8 @@
nuget restore "$(ProjectDir)mscorlib\nanoFramework.CoreLibrary.sln"
- "$(MSBuildBinPath)\msbuild" "$(ProjectDir)mscorlib\nanoFramework.CoreLibrary.sln" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472" /m
- "$(MSBuildBinPath)\msbuild" "$(ProjectDir)TestNFClassLibrary\TestNFClassLibrary\TestNFClassLibrary.nfproj" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472"
+ "$(MSBuildBinPath)\msbuild" "$(ProjectDir)mscorlib\nanoFramework.CoreLibrary\CoreLibrary.nfproj" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472" /m
+ "$(MSBuildBinPath)\msbuild" "$(ProjectDir)TestNFClassLibrary\TestNFClassLibrary\TestNFClassLibrary.nfproj" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472" -p:MDP_UNIT_TESTS_BUILD=1 /m
"$(MSBuildBinPath)\msbuild" "$(ProjectDir)TestNFApp\TestNFApp.nfproj" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472"
"$(MSBuildBinPath)\msbuild" "$(ProjectDir)StubsGenerationTestNFApp\StubsGenerationTestNFApp.nfproj" -t:Build -nr:False -p:Configuration=$(Configuration) -p:NF_MDP_MSBUILDTASK_PATH="$(ProjectDir)..\MetadataProcessor.MsBuildTask\bin\$(Configuration)\net472"
mkdir "$(TargetDir)\TestNFApp"
diff --git a/MetadataProcessor.Tests/MsbuildTask/MsbuildTaskTests.cs b/MetadataProcessor.Tests/MsbuildTask/MsbuildTaskTests.cs
index 72806204..ab56b27d 100644
--- a/MetadataProcessor.Tests/MsbuildTask/MsbuildTaskTests.cs
+++ b/MetadataProcessor.Tests/MsbuildTask/MsbuildTaskTests.cs
@@ -1,18 +1,12 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Mono.Cecil;
-using nanoFramework.Tools.MetadataProcessor.Core;
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Mono.Cecil;
+using nanoFramework.Tools.MetadataProcessor.Core;
namespace nanoFramework.Tools.MetadataProcessor.Tests.MsbuildTask
{
@@ -111,10 +105,7 @@ private void ProcessAssembly(
}
// output PDBX
- using (var writer = XmlWriter.Create(Path.ChangeExtension(fileToCompile, "pdbx")))
- {
- _assemblyBuilder.Write(writer);
- }
+ _assemblyBuilder.Write(Path.ChangeExtension(fileToCompile, "pdbx"));
// output assembly metadata
dumpFile = Path.ChangeExtension(fileToCompile, "dump.txt");
diff --git a/MetadataProcessor.Tests/Properties/AssemblyInfo.cs b/MetadataProcessor.Tests/Properties/AssemblyInfo.cs
index d22763be..ea925b68 100644
--- a/MetadataProcessor.Tests/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Tests/Properties/AssemblyInfo.cs
@@ -1,5 +1,7 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("nanoFramework.MetadataProcessor.Tests")]
diff --git a/MetadataProcessor.Tests/StubsGenerationTestNFApp/NativeMethodGeneration.cs b/MetadataProcessor.Tests/StubsGenerationTestNFApp/NativeMethodGeneration.cs
index 137c281c..c49c1e0a 100644
--- a/MetadataProcessor.Tests/StubsGenerationTestNFApp/NativeMethodGeneration.cs
+++ b/MetadataProcessor.Tests/StubsGenerationTestNFApp/NativeMethodGeneration.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
diff --git a/MetadataProcessor.Tests/StubsGenerationTestNFApp/Program.cs b/MetadataProcessor.Tests/StubsGenerationTestNFApp/Program.cs
index def10b41..9216110f 100644
--- a/MetadataProcessor.Tests/StubsGenerationTestNFApp/Program.cs
+++ b/MetadataProcessor.Tests/StubsGenerationTestNFApp/Program.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
diff --git a/MetadataProcessor.Tests/StubsGenerationTestNFApp/Properties/AssemblyInfo.cs b/MetadataProcessor.Tests/StubsGenerationTestNFApp/Properties/AssemblyInfo.cs
index 14a6d733..122dcb38 100644
--- a/MetadataProcessor.Tests/StubsGenerationTestNFApp/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Tests/StubsGenerationTestNFApp/Properties/AssemblyInfo.cs
@@ -1,5 +1,7 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/MetadataProcessor.Tests/TestNFApp/AuthorAttribute.cs b/MetadataProcessor.Tests/TestNFApp/AuthorAttribute.cs
index ee239bc5..a77e9175 100644
--- a/MetadataProcessor.Tests/TestNFApp/AuthorAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/AuthorAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/ClassWithNullAttribs.cs b/MetadataProcessor.Tests/TestNFApp/ClassWithNullAttribs.cs
index b7502371..d8a723dc 100644
--- a/MetadataProcessor.Tests/TestNFApp/ClassWithNullAttribs.cs
+++ b/MetadataProcessor.Tests/TestNFApp/ClassWithNullAttribs.cs
@@ -1,4 +1,7 @@
-using System;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
using System.Diagnostics.CodeAnalysis;
namespace TestNFApp
diff --git a/MetadataProcessor.Tests/TestNFApp/ComplexAttribute.cs b/MetadataProcessor.Tests/TestNFApp/ComplexAttribute.cs
index 36e582ee..8aab6ee6 100644
--- a/MetadataProcessor.Tests/TestNFApp/ComplexAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/ComplexAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -13,7 +11,7 @@ public class ComplexAttribute : Attribute
private readonly string _s;
private readonly bool _b;
- public uint Max => _max;
+ public uint Max => _max;
public string S => _s;
public bool B => _b;
diff --git a/MetadataProcessor.Tests/TestNFApp/DataRowAttribute.cs b/MetadataProcessor.Tests/TestNFApp/DataRowAttribute.cs
index 732aa4ba..8a3ed032 100644
--- a/MetadataProcessor.Tests/TestNFApp/DataRowAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/DataRowAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute1.cs b/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute1.cs
index 13c503c6..99b2d174 100644
--- a/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute1.cs
+++ b/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute1.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute2.cs b/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute2.cs
index 87d194cf..7a2db31d 100644
--- a/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute2.cs
+++ b/MetadataProcessor.Tests/TestNFApp/DummyCustomAttribute2.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/GenericClass.cs b/MetadataProcessor.Tests/TestNFApp/GenericClass.cs
new file mode 100644
index 00000000..c7ddd462
--- /dev/null
+++ b/MetadataProcessor.Tests/TestNFApp/GenericClass.cs
@@ -0,0 +1,235 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+
+namespace TestNFApp
+{
+ interface IDo
+ {
+ void Do1();
+ void Do2();
+ }
+
+ interface IDoThat
+ {
+ void DoThat1();
+ void DoThat2();
+ }
+
+ class ClassDoThis : IDo
+ {
+ public void Do1()
+ {
+ Debug.WriteLine($"{nameof(Do1)}");
+ }
+
+ public void Do2()
+ {
+ Debug.WriteLine($"{nameof(Do2)}");
+ }
+
+ public void DoThis1()
+ {
+ Debug.WriteLine($"{nameof(DoThis1)}");
+ }
+
+ public void DoThis2()
+ {
+ Debug.WriteLine($"{nameof(DoThis2)}");
+ }
+ }
+
+ class ClassDoInt : IDo
+ {
+ public void Do1()
+ {
+ Debug.WriteLine($"{nameof(Do1)}");
+ }
+
+ public void Do2()
+ {
+ Debug.WriteLine($"{nameof(Do2)}");
+ }
+ }
+
+ class ClassDoThatInt : IDo, IDoThat
+ {
+ public void Do1()
+ {
+ Debug.WriteLine($"{nameof(Do1)}");
+ }
+
+ public void Do2()
+ {
+ Debug.WriteLine($"{nameof(Do2)}");
+ }
+
+ public void DoThat1()
+ {
+ Debug.WriteLine($"{nameof(DoThat1)}");
+ }
+
+ public void DoThat2()
+ {
+ Debug.WriteLine($"{nameof(DoThat2)}");
+ }
+
+ }
+
+ class ClassDoThisAndThat : ClassDoThis, IDoThat
+ {
+ public void DoThat1()
+ {
+ Debug.WriteLine($"{nameof(DoThat1)}");
+ }
+
+ public void DoThat2()
+ {
+ Debug.WriteLine($"{nameof(DoThat2)}");
+ }
+ }
+
+ public class ClassDoString : IDo
+ {
+ public void Do1()
+ {
+ Debug.WriteLine($"{nameof(Do1)}");
+ }
+
+ public void Do2()
+ {
+ Debug.WriteLine($"{nameof(Do2)}");
+ }
+ }
+
+ class GenericClass
+ {
+ public int NativeField;
+
+ public T GenericField;
+
+ public void NoGenerics()
+ {
+ int v = 1;
+ }
+
+ public void InstanceGenericDoOne(T t)
+ {
+ T v = t;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoOne)} --> {v} is <{v.GetType()}>");
+ }
+
+ public void InstanceGenericDoTwo(T p1, T2 p2)
+ {
+ T v1 = p1;
+ T2 v2 = p2;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoTwo)}<{v2.GetType()}> --> {v1},{v2} is <{v1.GetType()},{v2.GetType()}>");
+ }
+
+ public void InstanceGenericDoOneOther(T1 t)
+ {
+ T1 v1 = t;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoOneOther)}<{v1.GetType()}> --> {v1} is <{v1.GetType()}>");
+ }
+ }
+
+ class AnotherGenericClass
+ {
+ public int NativeField;
+
+ public T GenericField;
+ public T1 AnotherGenericField;
+
+ public void InstanceGenericDoOne(T t)
+ {
+ T v = t;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoOne)} --> {v} is <{typeof(T).FullName}>");
+ }
+
+ public void InstanceGenericDoTwo(T p1, T1 p2, T2 p3)
+ {
+ T v1 = p1;
+ T1 v2 = p2;
+ T2 v3 = p3;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoTwo)}<{v3.GetType()}> --> {v1},{v2},{v3} is <{v1.GetType()},{v2.GetType()},{v3.GetType()}>");
+ }
+
+ public void InstanceGenericDoOneOther(T1 p1, T2 p2)
+ {
+ T1 v1 = p1;
+ T2 v2 = p2;
+
+ Debug.WriteLine($"{nameof(InstanceGenericDoOneOther)}<{v1.GetType()}> --> {v1},{v2} is <{typeof(T1).FullName},{typeof(T2).FullName}>");
+ }
+ }
+
+ public class GenericClassTests
+ {
+ private static void StaticGenericDo(T1 val, T2 val2) where T1 : IDo where T2 : IDo
+ {
+ Debug.WriteLine($">> {nameof(StaticGenericDo)}<{val.GetType()},{val2.GetType()}>");
+
+ val.Do1();
+ val.Do2();
+ val2.Do1();
+ val2.Do2();
+ }
+
+ private static void StaticGenericDoThisAndThat(T1 val, T2 val2) where T1 : ClassDoThis, IDo where T2 : ClassDoThatInt
+ {
+ Debug.WriteLine($">> {nameof(StaticGenericDoThisAndThat)}<{val.GetType()},{val2.GetType()}>");
+
+ val.DoThis1();
+ val.DoThis2();
+ val2.DoThat1();
+ val2.DoThat2();
+ }
+
+ public GenericClassTests()
+ {
+ Debug.WriteLine("++++++++++++++++++++");
+ Debug.WriteLine("++ Generics Tests ++");
+ Debug.WriteLine("++++++++++++++++++++");
+ Debug.WriteLine("");
+
+
+ var other = new ClassDoString();
+ other.Do1();
+ other.Do2();
+
+ var gc1 = new GenericClass();
+ gc1.NoGenerics();
+ gc1.InstanceGenericDoOne(1);
+ gc1.InstanceGenericDoTwo(1, "TWO");
+ gc1.InstanceGenericDoOneOther(false);
+ gc1.GenericField = 10;
+
+ var agc1 = new AnotherGenericClass();
+ agc1.InstanceGenericDoOne(22);
+ agc1.InstanceGenericDoTwo(33, false, "NINE");
+ agc1.InstanceGenericDoOneOther(true, 44);
+ agc1.GenericField = 11;
+ agc1.AnotherGenericField = false;
+
+ var gc2 = new GenericClass();
+ gc2.InstanceGenericDoOne("ONE");
+ gc2.InstanceGenericDoTwo("ONE", "TWO");
+ gc2.InstanceGenericDoOneOther(33.33);
+ gc2.GenericField = "TEN";
+
+ StaticGenericDo(new ClassDoInt(), new ClassDoString());
+
+ StaticGenericDo(new ClassDoString(), new ClassDoInt());
+
+ StaticGenericDoThisAndThat(new ClassDoThis(), new ClassDoThatInt());
+
+ StaticGenericDoThisAndThat(new ClassDoThisAndThat(), new ClassDoThatInt());
+ }
+ }
+}
diff --git a/MetadataProcessor.Tests/TestNFApp/IOneClassOverAll.cs b/MetadataProcessor.Tests/TestNFApp/IOneClassOverAll.cs
index a98a434e..77978300 100644
--- a/MetadataProcessor.Tests/TestNFApp/IOneClassOverAll.cs
+++ b/MetadataProcessor.Tests/TestNFApp/IOneClassOverAll.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace TestNFApp
{
diff --git a/MetadataProcessor.Tests/TestNFApp/IgnoreAttribute.cs b/MetadataProcessor.Tests/TestNFApp/IgnoreAttribute.cs
index 80c8a647..5d665022 100644
--- a/MetadataProcessor.Tests/TestNFApp/IgnoreAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/IgnoreAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/MaxAttribute.cs b/MetadataProcessor.Tests/TestNFApp/MaxAttribute.cs
index fa7c230c..5c50389c 100644
--- a/MetadataProcessor.Tests/TestNFApp/MaxAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/MaxAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -11,7 +9,7 @@ public class MaxAttribute : Attribute
{
private readonly uint _max;
- public uint Max => _max;
+ public uint Max => _max;
public MaxAttribute(uint m)
{
diff --git a/MetadataProcessor.Tests/TestNFApp/MyAttribute.cs b/MetadataProcessor.Tests/TestNFApp/MyAttribute.cs
index dc4aa410..0069eec8 100644
--- a/MetadataProcessor.Tests/TestNFApp/MyAttribute.cs
+++ b/MetadataProcessor.Tests/TestNFApp/MyAttribute.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/MyClass1.cs b/MetadataProcessor.Tests/TestNFApp/MyClass1.cs
index 2e905909..388cdab0 100644
--- a/MetadataProcessor.Tests/TestNFApp/MyClass1.cs
+++ b/MetadataProcessor.Tests/TestNFApp/MyClass1.cs
@@ -1,17 +1,19 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using TestNFClassLibrary;
namespace TestNFApp
{
// Define a class that has the custom attribute associated with one of its members.
[Attribute2]
[Attribute4]
+ [Attribute1OnAnotherAssembly]
public class MyClass1
{
[Attribute1]
[Attribute3]
+ [Attribute2OnAnotherAssembly]
public void MyMethod1(int i)
{
return;
diff --git a/MetadataProcessor.Tests/TestNFApp/OneClassOverAll.cs b/MetadataProcessor.Tests/TestNFApp/OneClassOverAll.cs
index 227ca6b1..d348e77e 100644
--- a/MetadataProcessor.Tests/TestNFApp/OneClassOverAll.cs
+++ b/MetadataProcessor.Tests/TestNFApp/OneClassOverAll.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -64,7 +62,7 @@ public void DummyMethodWithUglyParams(ref int p5, byte[] p6, OneClassOverAll p7,
public int UglyAdd(int left, int right)
{
int ret = 0;
-
+
try
{
ret = left + right;
diff --git a/MetadataProcessor.Tests/TestNFApp/Program.cs b/MetadataProcessor.Tests/TestNFApp/Program.cs
index f512a956..a135f8e9 100644
--- a/MetadataProcessor.Tests/TestNFApp/Program.cs
+++ b/MetadataProcessor.Tests/TestNFApp/Program.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
@@ -17,7 +15,13 @@ public static void Main()
{
Console.WriteLine("Starting TestNFApp");
- ////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // referenced class
+ Debug.WriteLine("++++++++++++++++++++++++++++");
+ Debug.WriteLine("++ Referenced class tests ++");
+ Debug.WriteLine("++++++++++++++++++++++++++++");
+ Debug.WriteLine("");
+
// instantiating a class on another assembly
ClassOnAnotherAssembly anotherClass = new ClassOnAnotherAssembly();
@@ -34,7 +38,7 @@ public static void Main()
//////////////////////////////
// accessing property on class
- dummyMirror1 = anotherClass.DummyProperty;
+ _ = anotherClass.DummyProperty;
Console.WriteLine($"Accessed property on class: {dummyMirror1}");
@@ -73,6 +77,10 @@ public static void Main()
break;
}
+ ///////////////////////////////////////////////////////////////////
+ // Generics Tests
+ _ = new GenericClassTests();
+
// null attributes tests
Console.WriteLine("Null attributes tests");
_ = new ClassWithNullAttribs();
@@ -80,10 +88,21 @@ public static void Main()
Console.WriteLine("Exiting TestNFApp");
}
+ private static void MiscelaneousTests()
+ {
+ var type = typeof(short[]);
+ if (type.FullName != "System.Int16[]")
+ {
+ throw new Exception($"Type name is wrong. Got '{type.FullName}' should be System.Int16[]");
+ }
+ }
+
public static void ReflectionTests()
{
- Console.WriteLine("");
- Console.WriteLine("+++Starting ReflectionTests");
+ Debug.WriteLine("++++++++++++++++++++++");
+ Debug.WriteLine("++ Reflection tests ++");
+ Debug.WriteLine("++++++++++++++++++++++");
+ Debug.WriteLine("");
// Get the type of MyClass1.
Type myType = typeof(MyClass1);
@@ -107,17 +126,17 @@ public static void ReflectionTests()
// Get the methods associated with MyClass1.
MemberInfo[] myMethods = myType.GetMethods();
-
- //Console.WriteLine("");
- //Console.WriteLine($"'{myType.Name}' type has '{myMethods.Length}' methods");
+
+ Debug.WriteLine("");
+ Debug.WriteLine($"'{myType.Name}' type has '{myMethods.Length}' methods");
// Display the attributes for each of the methods of MyClass1.
for (int i = 0; i < myMethods.Length; i++)
{
string methodName = myMethods[i].Name;
- //Console.WriteLine("");
- //Console.WriteLine($"Getting custom attributes for '{methodName}'");
+ Debug.WriteLine("");
+ Debug.WriteLine($"Getting custom attributes for '{methodName}'");
myAttributes = myMethods[i].GetCustomAttributes(true);
@@ -184,12 +203,12 @@ public static void ReflectionTests()
Console.WriteLine($"MaxAttribute value is: 0x{attMax.Max.ToString("X8")}");
AuthorAttribute attAuthor = (AuthorAttribute)myFieldAttributes[1];
- Console.WriteLine("");
- Console.WriteLine($"AuthorAttribute value is: '{attAuthor.Author}'");
+ Debug.WriteLine("");
+ Debug.WriteLine($"AuthorAttribute value is: '{attAuthor.Author}'");
- Console.WriteLine("");
- Console.WriteLine("+++ReflectionTests completed");
- Console.WriteLine("");
+ Debug.WriteLine("");
+ Debug.WriteLine("+++ReflectionTests completed");
+ Debug.WriteLine("");
}
}
}
diff --git a/MetadataProcessor.Tests/TestNFApp/Properties/AssemblyInfo.cs b/MetadataProcessor.Tests/TestNFApp/Properties/AssemblyInfo.cs
index 0a617ec9..47fa9106 100644
--- a/MetadataProcessor.Tests/TestNFApp/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Tests/TestNFApp/Properties/AssemblyInfo.cs
@@ -1,5 +1,7 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/MetadataProcessor.Tests/TestNFApp/TestEnumInAnotherAssembly.cs b/MetadataProcessor.Tests/TestNFApp/TestEnumInAnotherAssembly.cs
index 1f1fc49e..ca65ae18 100644
--- a/MetadataProcessor.Tests/TestNFApp/TestEnumInAnotherAssembly.cs
+++ b/MetadataProcessor.Tests/TestNFApp/TestEnumInAnotherAssembly.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace System.IO
{
@@ -10,11 +8,23 @@ public class TestEnumInAnotherAssembly
public void CallTestEnumInAnotherAssembly()
{
// This test checks if MDP can minimize the assembly using an enum that is defined in another assembly
- // and the class calling it is in a different assembly BUT in the same namespace.
- var ioException = new IOException(
+ // as a nested type
+ IOException.IOExceptionErrorCode dummyEnum = IOException.IOExceptionErrorCode.DirectoryNotFound;
+
+ _ = new IOException(
string.Empty,
- (int)IOException.IOExceptionErrorCode.DirectoryNotFound);
+ (int)dummyEnum);
+
+ // This test checks if MDP can minimize the assembly using an enum that is defined in another assembly
+ Base64FormattingOptions formattingOptions = Base64FormattingOptions.InsertLineBreaks;
+
+ byte[] testBytes = new byte[] { 0x01, 0x03, 0x05, 0x07, 0x09 };
+
+ _ = Convert.ToBase64String(
+ testBytes,
+ 0,
+ testBytes.Length,
+ formattingOptions);
}
}
-
}
diff --git a/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj b/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj
index 6d66b685..10f82e28 100644
--- a/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj
+++ b/MetadataProcessor.Tests/TestNFApp/TestNFApp.nfproj
@@ -30,6 +30,7 @@
+
diff --git a/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs b/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs
index 8f432977..f7848ea0 100644
--- a/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs
+++ b/MetadataProcessor.Tests/TestNFApp/TestingDelegates.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
diff --git a/MetadataProcessor.Tests/TestNFApp/TestingDestructors.cs b/MetadataProcessor.Tests/TestNFApp/TestingDestructors.cs
index dd34d0d5..37a9b3e2 100644
--- a/MetadataProcessor.Tests/TestNFApp/TestingDestructors.cs
+++ b/MetadataProcessor.Tests/TestNFApp/TestingDestructors.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -44,7 +42,7 @@ public class DestructorsTestClass
{
// Calling Destructor for Test Class 3
intI = 2;
-
+
Console.WriteLine("Calling Destructor for Test Class 3");
}
@@ -103,7 +101,7 @@ public class DestructorsTestAnotherClass : DestructorsTestAnotherClassBase
public static bool TestMethod()
{
DestructorsTestAnotherClass mc = new DestructorsTestAnotherClass();
-
+
mc = null;
// should be calling GC
@@ -111,15 +109,15 @@ public static bool TestMethod()
int sleepTime = 5000;
int slept = 0;
-
+
while (intI != 8 && slept < sleepTime)
{
System.Threading.Thread.Sleep(10);
slept += 10;
}
-
+
Console.WriteLine($"Thread has slept for {slept}");
-
+
if (intI == 8)
{
return true;
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/AttributesOnAnotherAssembly.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/AttributesOnAnotherAssembly.cs
new file mode 100644
index 00000000..36f816a1
--- /dev/null
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/AttributesOnAnotherAssembly.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+namespace TestNFClassLibrary
+{
+ [AttributeUsage(AttributeTargets.All)]
+ public class Attribute1OnAnotherAssemblyAttribute : Attribute
+ {
+ }
+
+ [AttributeUsage(AttributeTargets.All)]
+ public class Attribute2OnAnotherAssemblyAttribute : Attribute
+ {
+ }
+}
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassOnAnotherAssembly.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassOnAnotherAssembly.cs
index b2eec0ef..9d040b09 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassOnAnotherAssembly.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassOnAnotherAssembly.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace TestNFClassLibrary
{
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassWithNativeImplementation.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassWithNativeImplementation.cs
index 5a0311de..3977c24c 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassWithNativeImplementation.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/ClassWithNativeImplementation.cs
@@ -1,12 +1,14 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// this class should be added only for unit tests in MDP
+#if MDP_UNIT_TESTS_BUILD
using System.Runtime.CompilerServices;
namespace TestNFClassLibrary
{
+
public class ClassWithNativeImplementation
{
private static int _staticField;
@@ -33,3 +35,5 @@ public void ManagedMethod2()
public static extern void NativeMethod2();
}
}
+
+#endif
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAClassWithAnEnum.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAClassWithAnEnum.cs
index 4a45c107..936b155e 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAClassWithAnEnum.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAClassWithAnEnum.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace TestNFClassLibrary
{
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmATypeToExclude.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmATypeToExclude.cs
index ac9e7e71..61663044 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmATypeToExclude.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmATypeToExclude.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
namespace TestNFClassLibrary
{
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAlsoATypeToExclude.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAlsoATypeToExclude.cs
index 0d9ec2cc..b32a648e 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAlsoATypeToExclude.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAlsoATypeToExclude.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAnEnumToExclude.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAnEnumToExclude.cs
index 00da52f4..947fa2c9 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAnEnumToExclude.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/IAmAnEnumToExclude.cs
@@ -1,7 +1,5 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/Properties/AssemblyInfo.cs b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/Properties/AssemblyInfo.cs
index 0a0b1cd5..98cef7e3 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/Properties/AssemblyInfo.cs
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/Properties/AssemblyInfo.cs
@@ -1,10 +1,7 @@
-//
-// Copyright (c) .NET Foundation and Contributors
-// See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -36,9 +33,3 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("11.22.33.44")]
[assembly: AssemblyFileVersion("11.22.33.44")]
-
-/////////////////////////////////////////////////////////////////
-// This attribute is mandatory when building Interop libraries //
-// update this whenever the native assembly signature changes //
-[assembly: AssemblyNativeVersion("0.0.0.0")]
-/////////////////////////////////////////////////////////////////
diff --git a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/TestNFClassLibrary.nfproj b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/TestNFClassLibrary.nfproj
index 7ddd2bd5..3966ae0e 100644
--- a/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/TestNFClassLibrary.nfproj
+++ b/MetadataProcessor.Tests/TestNFClassLibrary/TestNFClassLibrary/TestNFClassLibrary.nfproj
@@ -18,6 +18,7 @@
+
diff --git a/MetadataProcessor.Tests/TestObjectHelper.cs b/MetadataProcessor.Tests/TestObjectHelper.cs
index e2301fd6..1c66ff16 100644
--- a/MetadataProcessor.Tests/TestObjectHelper.cs
+++ b/MetadataProcessor.Tests/TestObjectHelper.cs
@@ -7,7 +7,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Text;
using Mono.Cecil;
@@ -15,7 +15,7 @@ namespace nanoFramework.Tools.MetadataProcessor.Tests
{
public static class TestObjectHelper
{
- private const string _varNameForLocalNanoCLRInstancePath = "MDP_TEST_NANOCLR_INSTANCE_PATH";
+ private const string _varNameForLocalNanoCLRInstancePath = "NF_MDP_NANOCLR_INSTANCE_PATH";
private static string _testExecutionLocation;
private static string _testNFAppLocation;
@@ -29,7 +29,7 @@ public static nanoTablesContext GetTestNFAppNanoTablesContext()
{
nanoTablesContext ret = null;
- var assemblyDefinition = GetTestNFAppAssemblyDefinition();
+ var assemblyDefinition = GetTestNFAppAssemblyDefinitionWithLoadHints();
ret = new nanoTablesContext(
assemblyDefinition,
@@ -65,7 +65,7 @@ public static string TestExecutionLocation
{
if (string.IsNullOrEmpty(_testExecutionLocation))
{
- _testExecutionLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ _testExecutionLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (_testExecutionLocation.Contains("Debug"))
{
@@ -214,7 +214,9 @@ public static AssemblyDefinition GetTestNFAppAssemblyDefinition()
{
AssemblyDefinition ret = null;
- ret = AssemblyDefinition.ReadAssembly(TestNFAppFullPath);
+ ret = AssemblyDefinition.ReadAssembly(
+ TestNFAppFullPath,
+ new ReaderParameters { AssemblyResolver = ProvideLoadHints() });
return ret;
}
@@ -237,7 +239,9 @@ public static AssemblyDefinition GetTestNFClassLibraryDefinition()
{
AssemblyDefinition ret = null;
- ret = AssemblyDefinition.ReadAssembly(TestNFClassLibFullPath);
+ ret = AssemblyDefinition.ReadAssembly(
+ TestNFClassLibFullPath,
+ new ReaderParameters { AssemblyResolver = ProvideLoadHints() });
return ret;
}
@@ -358,7 +362,7 @@ public static Stream GetResourceStream(string resourceName)
Stream ret = null;
- var thisAssembly = Assembly.GetExecutingAssembly();
+ var thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
ret = thisAssembly.GetManifestResourceStream(String.Concat(thisAssembly.GetName().Name, ".", resourceName));
@@ -485,6 +489,14 @@ internal static MethodDefinition GetMethodDefinition(
// no need to check if path exists as this validation is performed by nanoclr
public static string NanoClrLocalInstance => Environment.GetEnvironmentVariable(
_varNameForLocalNanoCLRInstancePath,
- EnvironmentVariableTarget.User);
+ EnvironmentVariableTarget.Process);
+
+ private static DefaultAssemblyResolver ProvideLoadHints()
+ {
+ var resolver = new DefaultAssemblyResolver();
+ resolver.AddSearchDirectory(TestExecutionLocation);
+
+ return resolver;
+ }
}
}
diff --git a/MetadataProcessor.Tests/TestPreprocessedFiles.cs b/MetadataProcessor.Tests/TestPreprocessedFiles.cs
index ef0a3814..8c037e0d 100644
--- a/MetadataProcessor.Tests/TestPreprocessedFiles.cs
+++ b/MetadataProcessor.Tests/TestPreprocessedFiles.cs
@@ -1,11 +1,5 @@
-//using System;
-//using System.Collections.Generic;
-//using System.IO;
-//using System.Linq;
-//using System.Xml;
-//using System.Xml.Xsl;
-//using Microsoft.VisualStudio.TestTools.UnitTesting;
-//using Mono.Cecil;
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
//namespace nanoFramework.Tools.MetadataProcessor.Tests
//{
@@ -498,7 +492,7 @@
// "Microsoft.SPOT.Native", "Microsoft.SPOT.TinyCore", "Microsoft.SPOT.Hardware.Usb",
// "Microsoft.SPOT.Hardware");
// }
-
+
// [TestMethod]
// public void WeakDelegatesTest()
// {
diff --git a/MetadataProcessor.Tests/mscorlib b/MetadataProcessor.Tests/mscorlib
index 981cb43f..6abe4b8f 160000
--- a/MetadataProcessor.Tests/mscorlib
+++ b/MetadataProcessor.Tests/mscorlib
@@ -1 +1 @@
-Subproject commit 981cb43f79461cf719b3dc718ab636c51abb26e1
+Subproject commit 6abe4b8f267ecf8c57cbc06be3ae113dc943ba78
diff --git a/README.md b/README.md
index 046ea956..a265424e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://opensource.org/licenses/MIT) [](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [](https://dev.azure.com/nanoframework/metadata-processor/_build/latest?definitionId=43&branchName=develop) [](https://discord.gg/gCyBu8T)
+[](https://opensource.org/licenses/MIT) [](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [](https://dev.azure.com/nanoframework/metadata-processor/_build/latest?definitionId=43&branchName=develop) [](https://discord.gg/gCyBu8T)

@@ -43,6 +43,17 @@ When adding a project to the solution the following points have to be kept in mi
1. This flag disables "nodeReuse", this is needed as a custom MsBuildTask is used which also gets rebuilt. "NodeReuse" keeps instances of MsBuild running which interferes with the rebuilding of the custom MsBuildTask.
+### Code sync between MDP, native code and other tools
+
+There are several code snippets, structures and details that are shared between the metadata processor, the native code and other tools. These need to be kept in sync.
+For those that need to be keep in sync with native code, there is a tag `` in a comment before the relevant code snippet.
+For sync with Visual Studio extension, the tag `` is used.
+For sync with the debugger, the tag `` is used.
+
+### Miscellaneous
+
+If there is a need to override the nanoCLR DLL to be used in the virtual device set the environment variable `NF_MDP_NANOCLR_INSTANCE_PATH` to the path of the DLL.
+
## Feedback and documentation
For documentation, providing feedback, issues and finding out how to contribute please refer to the [Home repo](https://github.com/nanoframework/Home).
diff --git a/azure-pipelines-templates/check-nf-interpreter-to-test.yml b/azure-pipelines-templates/check-nf-interpreter-to-test.yml
new file mode 100644
index 00000000..eb8e3fcb
--- /dev/null
+++ b/azure-pipelines-templates/check-nf-interpreter-to-test.yml
@@ -0,0 +1,74 @@
+# Copyright (c) .NET Foundation and Contributors
+# See LICENSE file in the project root for full license information.
+
+steps:
+ - task: PowerShell@2
+ displayName: Check nf-interpreter to test
+ condition: ne(variables['System.PullRequest.PullRequestNumber'], '')
+ inputs:
+ failOnStderr: false
+ targetType: "inline"
+ script: |
+
+ # compute authorization header in format "AUTHORIZATION: basic 'encoded token'"
+ # 'encoded token' is the Base64 of the string "nfbot:personal-token"
+ $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)")))"
+
+ # find PR
+ "Getting PR #$env:System_PullRequest_PullRequestNumber details..." | Write-Host -ForegroundColor White -NoNewline
+ $pr = Invoke-WebRequest "https://api.github.com/repos/$env:Build_Repository_Name/pulls/$env:System_PullRequest_PullRequestNumber" | ConvertFrom-Json
+
+ if($($pr.number) -eq "$env:System_PullRequest_PullRequestNumber")
+ {
+ 'OK' | Write-Host -ForegroundColor Green
+ }
+
+ # grab PR commit message
+ $prCommitMessage = $($pr.body)
+
+ # look for test prompt in PR commit message
+ # pattern is "[tested against nanoclr buildId NNN]"
+
+ if($prCommitMessage -match "\[tested against nanoclr buildId (\d+)\]")
+ {
+ $buildId = $matches[1]
+ "AZDO build ID found: $buildId" | Write-Host -ForegroundColor White
+
+ echo "##vso[task.setvariable variable=NFINTERPRETER_BUILDID]$buildId"
+ }
+ else
+ {
+ "No build ID found" | Write-Host -ForegroundColor Red
+ }
+ env:
+ GITHUB_TOKEN: $(GitHubToken)
+
+ - task: DownloadPipelineArtifact@2
+ condition: >-
+ and(
+ eq(variables['DownloadNanoClrPreview'], true),
+ ne(variables['NFINTERPRETER_BUILDID'], '')
+ )
+ displayName: Download nanoCLR preview
+ inputs:
+ buildType: specific
+ project: 'nf-interpreter'
+ definition: '34'
+ buildVersionToDownload: specific
+ allowFailedBuilds: true
+ pipelineId: $(NFINTERPRETER_BUILDID)
+ artifactName: 'nanoclr_cli'
+ targetPath: '$(Pipeline.Workspace)/nanoclr'
+
+ - task: PowerShell@2
+ condition: >-
+ and(
+ succeeded(),
+ eq(variables['DownloadNanoClrPreview'], true),
+ ne(variables['NFINTERPRETER_BUILDID'], '')
+ )
+ displayName: Set nanoCLR preview path
+ inputs:
+ targetType: 'inline'
+ script: |
+ Write-Host "##vso[task.setvariable variable=NF_MDP_NANOCLR_INSTANCE_PATH]$(Pipeline.Workspace)/nanoclr/nanoFramework.nanoCLR.dll"
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 56cb76dd..05686fd2 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -49,7 +49,7 @@ variables:
jobs:
##############################
-- job: Get_Build_Flags
+- job: Build_Prep
pool:
vmImage: 'windows-latest'
@@ -63,10 +63,36 @@ jobs:
# default to false
$update = $false
+ $downloadPreview = $false
- if($env:Build_Reason -eq 'PullRequest')
+ if($env:System_PullRequest_PullRequestNumber -ne $null)
{
- # PR build, nothing interesting in commit message
+ # PR build
+ # compute authorization header in format "AUTHORIZATION: basic 'encoded token'"
+ # 'encoded token' is the Base64 of the string "nfbot:personal-token"
+ $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)")))"
+
+ # find PR
+ "Getting PR #$env:System_PullRequest_PullRequestNumber details..." | Write-Host -ForegroundColor White -NoNewline
+ $pr = Invoke-WebRequest "https://api.github.com/repos/$env:Build_Repository_Name/pulls/$env:System_PullRequest_PullRequestNumber" | ConvertFrom-Json
+
+ if($($pr.number) -eq "$env:System_PullRequest_PullRequestNumber")
+ {
+ 'OK' | Write-Host -ForegroundColor Green
+ }
+
+ # grab PR commit message
+ $prCommitMessage = $($pr.body)
+
+ # debug output
+ # echo "=====`r`n$($prCommitMessage)`r`n====="
+
+ # check if should download nanoCLR to run unit tests
+ if($prCommitMessage -match "\[tested against nanoclr buildId (\d+)\]")
+ {
+ Write-Host "##[command] **Download preview nanoCLR for unit tests**"
+ $downloadPreview = $true
+ }
}
else
{
@@ -103,10 +129,11 @@ jobs:
}
}
- # set variable to foward to jobs
+ # set variables to forward to jobs
echo "##vso[task.setvariable variable=RUN_UPDATE_DEPENDENTS;isOutput=true]$update"
+ echo "##vso[task.setvariable variable=DOWNLOAD_PREVIEW_NANOCLR;isOutput=true]$downloadPreview"
name: GetPRLabels
- displayName: Check build labels
+ displayName: Check build conditions
##############################
# build MDP
@@ -118,7 +145,7 @@ jobs:
)
dependsOn:
- - Get_Build_Flags
+ - Build_Prep
pool:
vmImage: 'windows-latest'
@@ -133,6 +160,8 @@ jobs:
value: 'nanoFramework.Tools.MetadataProcessor.sln'
- name: NF_MDP_MSBUILDTASK_PATH
value: '$(System.DefaultWorkingDirectory)/MetadataProcessor.MsBuildTask/bin/Release/net472'
+ - name: DownloadNanoClrPreview
+ value: $[ dependencies.Build_Prep.outputs['GetPRLabels.DOWNLOAD_PREVIEW_NANOCLR'] ]
steps:
@@ -151,7 +180,7 @@ jobs:
git config --global user.name "nfbot"
displayName: Setup git identity
- - template: azure-pipelines-templates/install-nuget.yml@templates
+ - template: azure-pipelines-templates/install-nuget.yml@templates
- task: InstallNanoMSBuildComponents@1
condition: ne( variables['StartReleaseCandidate'], true )
@@ -159,13 +188,15 @@ jobs:
env:
GITHUB_TOKEN: $(GitHubToken)
+ - template: azure-pipelines-templates/check-nf-interpreter-to-test.yml
+
- task: NuGetCommand@2
displayName: NuGet restore
inputs:
restoreSolution: '$(solution)'
feedsToUse: config
nugetConfigPath: 'NuGet.config'
-
+
- task: VSBuild@1
inputs:
solution: '$(solution)'
@@ -188,7 +219,11 @@ jobs:
versionSelector: latestStable
- task: VSTest@2
- condition: succeeded()
+ condition: >-
+ and(
+ succeeded(),
+ ne(variables['System.PullRequest.PullRequestNumber'], '')
+ )
displayName: 'Running tests'
inputs:
testSelector: 'testAssemblies'
@@ -205,7 +240,7 @@ jobs:
configuration: '$(BuildConfiguration)'
diagnosticsEnabled: true
vsTestVersion: toolsInstaller
- codeCoverageEnabled: true
+ codeCoverageEnabled: true
- task: CopyFiles@1
condition: failed()
@@ -252,15 +287,15 @@ jobs:
sourceFolder: $(Build.SourcesDirectory)
Contents: |
**\bin\Release\nanoFramework.Tools.MetaDataProcessor.exe
- **\bin\Release\nanoFramework.Tools.MetadataProcessor.MsBuildTask.dll
+ **\bin\Release\net472\nanoFramework.Tools.MetadataProcessor.MsBuildTask.dll
TargetFolder: '$(Build.ArtifactStagingDirectory)'
flattenFolders: true
- # set cloud build vars again as they've been overriten by the tests run
+ # set cloud build vars again as they've been overwritten by the tests run
- script: nbgv cloud -a -c
condition: succeeded()
displayName: Set build number
-
+
- task: PowerShell@2
condition: succeeded()
displayName: Save cloud build number
@@ -292,7 +327,7 @@ jobs:
command: custom
custom: tool
arguments: install --tool-path . sign --version 0.9.1-beta.24170.3
-
+
- pwsh: |
.\sign code azure-key-vault `
"**/*.nupkg" `
@@ -312,7 +347,7 @@ jobs:
succeeded(),
eq(variables['System.PullRequest.PullRequestId'], '')
)
-
+
# publish artifacts (only possible if this is not a PR originated on a fork)
- task: PublishPipelineArtifact@1
displayName: Publish deployables artifacts
@@ -371,11 +406,12 @@ jobs:
condition: >-
or(
startsWith(variables['Build.SourceBranch'], 'refs/tags/v'),
- eq(variables['UPDATE_DEPENDENTS'], 'true')
+ eq(variables['UPDATE_DEPENDENTS'], 'true'),
+ eq(dependencies.Build_Prep.outputs['GetPRLabels.RUN_UPDATE_DEPENDENTS'], 'true')
)
dependsOn:
- - Get_Build_Flags
+ - Build_Prep
- Build_MDP
pool:
@@ -388,7 +424,7 @@ jobs:
# update dependents
# use this to make sure nuget package is published
- - template: azure-pipelines-templates/update-dependents.yml@templates
+ - template: azure-pipelines-templates/update-dependents.yml@templates
parameters:
packageName: '$(nugetPackageName)'
repositoriesToUpdate:
@@ -418,7 +454,7 @@ jobs:
fetchDepth: 1
# step from template @ nf-tools repo
- - template: azure-pipelines-templates/discord-webhook.yml@templates
+ - template: azure-pipelines-templates/discord-webhook.yml@templates
parameters:
status: 'failure'
webhookUrl: '$(DiscordWebhook)'
diff --git a/nanoFramework.Tools.MetadataProcessor.sln b/nanoFramework.Tools.MetadataProcessor.sln
index 9cee60c5..4c3afb9e 100644
--- a/nanoFramework.Tools.MetadataProcessor.sln
+++ b/nanoFramework.Tools.MetadataProcessor.sln
@@ -10,6 +10,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BFDB4F1F-D22B-4BDE-AA52-AD2EA3EDBBFF}"
ProjectSection(SolutionItems) = preProject
NuGet.Config = NuGet.Config
+ README.md = README.md
version.json = version.json
EndProjectSection
EndProject
diff --git a/version.json b/version.json
index 75430b42..f536ade2 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "3.0",
+ "version": "4.0-preview.{height}",
"release": {
"branchName" : "release-v{version}",
"versionIncrement" : "build",