Skip to content

Commit 712ee6f

Browse files
authored
Add skeleton generator (#11)
1 parent 1f11a56 commit 712ee6f

20 files changed

+793
-131
lines changed

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ jobs:
145145
nuGetFeedType: external
146146
packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
147147
publishFeedCredentials: 'AzureArtifacts'
148-
continueOnError: true
148+
continueOnError: true
149149
condition: succeeded()
150150
displayName: Push NuGet packages to Azure Artifacts
151151

source/MetadataProcessor.Console/MetadataProcessor.Console.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<Reference Include="Costura, Version=3.3.3.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
3636
<HintPath>..\packages\Costura.Fody.3.3.3\lib\net40\Costura.dll</HintPath>
3737
</Reference>
38+
<Reference Include="Microsoft.CSharp" />
3839
<Reference Include="Mono.Cecil, Version=0.11.1.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
3940
<HintPath>..\packages\Mono.Cecil.0.11.1\lib\net40\Mono.Cecil.dll</HintPath>
4041
</Reference>

source/MetadataProcessor.Console/Program.cs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//
66

77
using Mono.Cecil;
8+
using nanoFramework.Tools.MetadataProcessor.Core;
89
using System;
910
using System.Collections.Generic;
1011
using System.Globalization;
@@ -22,6 +23,7 @@ private sealed class MetadataProcessor
2223
new Dictionary<string, string>(StringComparer.Ordinal);
2324

2425
private AssemblyDefinition _assemblyDefinition;
26+
private nanoAssemblyBuilder _assemblyBuilder;
2527

2628
private List<string> _classNamesToExclude = new List<string>();
2729

@@ -52,17 +54,17 @@ public void Compile(string fileName)
5254
{
5355
if (Verbose) System.Console.WriteLine("Compiling assembly...");
5456

55-
var builder = new nanoAssemblyBuilder(_assemblyDefinition, _classNamesToExclude, Minimize, Verbose);
57+
_assemblyBuilder = new nanoAssemblyBuilder(_assemblyDefinition, _classNamesToExclude, Minimize, Verbose);
5658

5759
using (var stream = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite))
5860
using (var writer = new BinaryWriter(stream))
5961
{
60-
builder.Write(GetBinaryWriter(writer));
62+
_assemblyBuilder.Write(GetBinaryWriter(writer));
6163
}
6264

6365
using (var writer = XmlWriter.Create(Path.ChangeExtension(fileName, "pdbx")))
6466
{
65-
builder.Write(writer);
67+
_assemblyBuilder.Write(writer);
6668
}
6769
}
6870
catch (Exception)
@@ -90,6 +92,41 @@ public void AddClassToExclude(
9092
{
9193
_classNamesToExclude.Add(className);
9294
}
95+
96+
public void GenerateSkeleton(
97+
string file,
98+
string name,
99+
string project,
100+
bool interopCode)
101+
{
102+
try
103+
{
104+
if (interopCode)
105+
{
106+
System.Console.Error.WriteLine("Generator for Interop stubs is not supported yet.");
107+
108+
Environment.Exit(1);
109+
}
110+
111+
if (Verbose) System.Console.WriteLine("Generating skeleton files...");
112+
113+
var skeletonGenerator = new nanoSkeletonGenerator(
114+
_assemblyBuilder.TablesContext,
115+
file,
116+
name,
117+
project,
118+
interopCode);
119+
120+
skeletonGenerator.GenerateSkeleton();
121+
}
122+
catch (Exception ex)
123+
{
124+
System.Console.Error.WriteLine(
125+
"Unable to generate skeleton files");
126+
127+
Environment.Exit(1);
128+
}
129+
}
93130
}
94131

95132
public static void Main(string[] args)
@@ -124,6 +161,7 @@ public static void Main(string[] args)
124161
System.Console.WriteLine("-compile <path-to-PE-file> Compiles an assembly into nanoCLR format.");
125162
System.Console.WriteLine("-loadHints <assembly-name> <path-to-assembly-file> Loads one (or more) assembly file(s) as a dependency(ies).");
126163
System.Console.WriteLine("-excludeClassByName <class-name> Removes the class from an assembly.");
164+
System.Console.WriteLine("-generateskeleton Generate skeleton files with stubs to add native code for an assembly.");
127165
System.Console.WriteLine("-minimize Minimizes the assembly, removing unwanted elements.");
128166
System.Console.WriteLine("-verbose Outputs each command before executing it.");
129167
System.Console.WriteLine("");
@@ -136,7 +174,7 @@ public static void Main(string[] args)
136174
{
137175
md.Compile(args[++i]);
138176
}
139-
else if (arg == "-excludeclassbyName" && i + 1 < args.Length)
177+
else if (arg == "-excludeclassbyname" && i + 1 < args.Length)
140178
{
141179
md.AddClassToExclude(args[++i]);
142180
}
@@ -153,6 +191,29 @@ public static void Main(string[] args)
153191
md.AddLoadHint(args[i + 1], args[i + 2]);
154192
i += 2;
155193
}
194+
else if (arg == "-generateskeleton" && i + 2 < args.Length)
195+
{
196+
// fill in arguments
197+
string file = args[i + 1];
198+
string name = args[i + 2];
199+
string project = args[i + 3];
200+
bool interopCode = false;
201+
202+
if (!bool.TryParse(args[i + 4], out interopCode))
203+
{
204+
System.Console.Error.WriteLine("Bad parameter for generateSkeleton. Generate code without Interop support has to be 'true' or 'false'.");
205+
206+
Environment.Exit(1);
207+
}
208+
209+
md.GenerateSkeleton(
210+
file,
211+
name,
212+
project,
213+
interopCode);
214+
215+
i += 4;
216+
}
156217
else
157218
{
158219
System.Console.Error.WriteLine("Unknown command line option '{0}' ignored.", arg);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using Mono.Cecil;
7+
8+
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
9+
{
10+
internal static class TypeDefinitionExtensions
11+
{
12+
public static bool IncludeInStub(this TypeDefinition value)
13+
{
14+
var typeDefFlags = nanoTypeDefinitionTable.GetFlags(value);
15+
16+
if (typeDefFlags.HasFlag(
17+
nanoTypeDefinitionFlags.TD_Delegate |
18+
nanoTypeDefinitionFlags.TD_MulticastDelegate))
19+
{
20+
return false;
21+
}
22+
23+
// Only generate a stub for classes and value types.
24+
if (value.IsClass ||
25+
value.IsValueType)
26+
{
27+
return true;
28+
}
29+
30+
return false;
31+
}
32+
}
33+
}

source/MetadataProcessor.Core/MetadataProcessor.Core.csproj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
3434
</PropertyGroup>
3535
<ItemGroup>
36+
<Reference Include="Microsoft.CSharp" />
3637
<Reference Include="Mono.Cecil, Version=0.11.1.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
3738
<HintPath>..\packages\Mono.Cecil.0.11.1\lib\net40\Mono.Cecil.dll</HintPath>
3839
</Reference>
@@ -45,17 +46,34 @@
4546
<Reference Include="Mono.Cecil.Rocks, Version=0.11.1.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
4647
<HintPath>..\packages\Mono.Cecil.0.11.1\lib\net40\Mono.Cecil.Rocks.dll</HintPath>
4748
</Reference>
49+
<Reference Include="Stubble.Core, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
50+
<HintPath>..\packages\Stubble.Core.1.6.3\lib\net45\Stubble.Core.dll</HintPath>
51+
</Reference>
4852
<Reference Include="System" />
53+
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
54+
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
55+
</Reference>
4956
<Reference Include="System.Drawing" />
57+
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
58+
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
59+
</Reference>
60+
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
61+
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
62+
</Reference>
5063
<Reference Include="System.Windows.Forms" />
5164
<Reference Include="System.Xml" />
5265
</ItemGroup>
5366
<ItemGroup>
5467
<Compile Include="Endianness\nanoBinaryWriter.cs" />
68+
<Compile Include="Extensions\TypeDefinitionExtensions.cs" />
5569
<Compile Include="InanoTable.cs" />
5670
<Compile Include="Mono.Cecil\CodeWriter.cs" />
5771
<Compile Include="nanoAssemblyBuilder.cs" />
5872
<Compile Include="nanoAssemblyDefinition.cs" />
73+
<Compile Include="nanoSkeletonGenerator.cs" />
74+
<Compile Include="SkeletonGenerator\AssemblyClass.cs" />
75+
<Compile Include="SkeletonGenerator\AssemblyClassStubs.cs" />
76+
<Compile Include="SkeletonGenerator\AssemblyLookupTable.cs" />
5977
<Compile Include="Tables\ICustomStringSorter.cs" />
6078
<Compile Include="Tables\nanoAssemblyReferenceTable.cs" />
6179
<Compile Include="Tables\nanoAttributesTable.cs" />
@@ -82,13 +100,16 @@
82100
<Compile Include="Utility\nanoCLR_DataType.cs" />
83101
<Compile Include="Utility\nanoFontProcessor.cs" />
84102
<Compile Include="Utility\nanoPdbxFileWriter.cs" />
103+
<Compile Include="Utility\nanoTypeDefinitionFlags.cs" />
85104
<Compile Include="Utility\nanoSerializationType.cs" />
86105
<Compile Include="Utility\nanoStringsConstants.cs" />
87106
<Compile Include="Utility\NativeMethodsCrc.cs" />
88107
</ItemGroup>
89108
<ItemGroup>
90109
<None Include="packages.config" />
110+
<Compile Include="SkeletonGenerator\SkeletonTemplates.cs" />
91111
</ItemGroup>
112+
<ItemGroup />
92113
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
93114
<Import Project="..\packages\Nerdbank.GitVersioning.3.0.28\build\Nerdbank.GitVersioning.targets" Condition="Exists('..\packages\Nerdbank.GitVersioning.3.0.28\build\Nerdbank.GitVersioning.targets')" />
94115
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Collections.Generic;
7+
8+
namespace nanoFramework.Tools.MetadataProcessor.Core
9+
{
10+
public class AssemblyDeclaration
11+
{
12+
public string Name;
13+
public string ShortName;
14+
public string ShortNameUpper;
15+
16+
public List<Class> Classes = new List<Class>();
17+
}
18+
19+
public class Class
20+
{
21+
public string Name;
22+
public string AssemblyName;
23+
24+
public List<StaticField> StaticFields = new List<StaticField>();
25+
public List<InstanceField> InstanceFields = new List<InstanceField>();
26+
public List<Method> Methods = new List<Method>();
27+
}
28+
29+
public class StaticField
30+
{
31+
public string Name;
32+
public int ReferenceIndex;
33+
}
34+
35+
public class InstanceField
36+
{
37+
public string Name;
38+
public int ReferenceIndex;
39+
40+
public string FieldWarning;
41+
}
42+
43+
public class Method
44+
{
45+
public string Declaration;
46+
}
47+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Collections.Generic;
7+
8+
namespace nanoFramework.Tools.MetadataProcessor.Core
9+
{
10+
public class AssemblyClassStubs
11+
{
12+
public string HeaderFileName;
13+
14+
public List<Method> Functions = new List<Method>();
15+
}
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// Copyright (c) 2019 The nanoFramework project contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
using System.Collections.Generic;
8+
9+
namespace nanoFramework.Tools.MetadataProcessor.Core
10+
{
11+
public class AssemblyLookupTable
12+
{
13+
public string Name;
14+
public string AssemblyName;
15+
public string HeaderFileName;
16+
public string NativeCRC32;
17+
18+
public Version NativeVersion;
19+
20+
public List<Method> LookupTable = new List<Method>();
21+
}
22+
}

0 commit comments

Comments
 (0)