Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unity IL2CPP and New CodeGenerator #591

Merged
merged 18 commits into from
Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions MessagePack.sln
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Internal", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Internal.Tests", "tests\MessagePack.Internal.Tests\MessagePack.Internal.Tests.csproj", "{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.GeneratorCore", "src\MessagePack.GeneratorCore\MessagePack.GeneratorCore.csproj", "{9962132D-A271-4E68-ACC1-18FA93462552}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.Generator", "src\MessagePack.Generator\MessagePack.Generator.csproj", "{32C91908-5CAD-4C95-B240-ACBBACAC9476}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.MSBuild.Tasks", "src\MessagePack.MSBuild.Tasks\MessagePack.MSBuild.Tasks.csproj", "{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -161,6 +167,18 @@ Global
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Release|Any CPU.Build.0 = Release|Any CPU
{9962132D-A271-4E68-ACC1-18FA93462552}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9962132D-A271-4E68-ACC1-18FA93462552}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9962132D-A271-4E68-ACC1-18FA93462552}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9962132D-A271-4E68-ACC1-18FA93462552}.Release|Any CPU.Build.0 = Release|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Release|Any CPU.Build.0 = Release|Any CPU
{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -186,6 +204,9 @@ Global
{4142EA80-FEF4-44A5-8553-1AE84BEBAFED} = {51A614B0-E583-4DD2-AC7D-6A65634582E0}
{C100FBA6-4164-4D6A-A532-5984D2B8DCB0} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
{9962132D-A271-4E68-ACC1-18FA93462552} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{32C91908-5CAD-4C95-B240-ACBBACAC9476} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{8DB135F5-A6FE-44E4-9853-7B48ED21F21B} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B3911209-2DBF-47F8-98F6-BBC0EDFE63DE}
Expand Down
25 changes: 25 additions & 0 deletions src/MessagePack.Generator/MessagePack.Generator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>latest</LangVersion>
<PackAsTool>true</PackAsTool>
<ToolCommandName>dotnet-mpc</ToolCommandName>

<!-- NuGet Info -->
<Title>MessagePack Code Generator</Title>
<Description>MessagePack standalone code generator.</Description>
<PackageTags>MsgPack;MessagePack;Serialization;Formatter;Serializer;Unity;Xamarin</PackageTags>
<AssemblyName>MessagePack.Generator</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MicroBatchFramework" Version="1.5.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MessagePack.GeneratorCore\MessagePack.GeneratorCore.csproj" />
</ItemGroup>

</Project>
38 changes: 38 additions & 0 deletions src/MessagePack.Generator/MessagepackCompiler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Threading.Tasks;
using MicroBatchFramework;
using Microsoft.Extensions.Hosting;

namespace MessagePack.Generator
{
public class MessagepackCompiler : BatchBase
{
private static async Task Main(string[] args)
{
await BatchHost.CreateDefaultBuilder().RunBatchEngineAsync<MessagepackCompiler>(args);
}

public async Task RunAsync(
[Option("i", "Input path of analyze csproj or directory, if input multiple csproj split with ','.")]string input,
[Option("o", "Output file path(.cs) or directory(multiple generate file).")]string output,
[Option("c", "Conditional compiler symbols, split with ','.")]string conditionalSymbol = null,
[Option("r", "Set resolver name.")]string resolverName = "GeneratedResolver",
[Option("n", "Set namespace root name.")]string @namespace = "MessagePack",
[Option("m", "Force use map mode serialization.")]bool useMapMode = false,
[Option("ms", "Generate #if-- files by symbols, split with ','.")]string multipleIfDiretiveOutputSymbols = null)
{
await new MessagePackCompiler.CodeGenerator(x => Console.WriteLine(x), this.Context.CancellationToken)
.GenerateFileAsync(
input,
output,
conditionalSymbol,
resolverName,
@namespace,
useMapMode,
multipleIfDiretiveOutputSymbols);
}
}
}
213 changes: 213 additions & 0 deletions src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

#pragma warning disable SA1649 // File name should match first type name

namespace MessagePackCompiler.CodeAnalysis
{
public interface IResolverRegisterInfo
{
string FullName { get; }

string FormatterName { get; }
}

public class ObjectSerializationInfo : IResolverRegisterInfo
{
public string Name { get; set; }

public string FullName { get; set; }

public string Namespace { get; set; }

public bool IsIntKey { get; set; }

public bool IsStringKey
{
get { return !this.IsIntKey; }
}

public bool IsClass { get; set; }

public bool IsStruct
{
get { return !this.IsClass; }
}

public MemberSerializationInfo[] ConstructorParameters { get; set; }

public MemberSerializationInfo[] Members { get; set; }

public bool HasIMessagePackSerializationCallbackReceiver { get; set; }

public bool NeedsCastOnBefore { get; set; }

public bool NeedsCastOnAfter { get; set; }

public string FormatterName => (this.Namespace == null ? this.Name : this.Namespace + "." + this.Name) + "Formatter";

public int WriteCount
{
get
{
if (this.IsStringKey)
{
return this.Members.Count(x => x.IsReadable);
}
else
{
return this.MaxKey;
}
}
}

public int MaxKey
{
get
{
return this.Members.Where(x => x.IsReadable).Select(x => x.IntKey).DefaultIfEmpty(-1).Max();
}
}

public MemberSerializationInfo GetMember(int index)
{
return this.Members.FirstOrDefault(x => x.IntKey == index);
}

public string GetConstructorString()
{
var args = string.Join(", ", this.ConstructorParameters.Select(x => "__" + x.Name + "__"));
return $"{this.FullName}({args})";
}
}

public class MemberSerializationInfo
{
public bool IsProperty { get; set; }

public bool IsField { get; set; }

public bool IsWritable { get; set; }

public bool IsReadable { get; set; }

public int IntKey { get; set; }

public string StringKey { get; set; }

public string Type { get; set; }

public string Name { get; set; }

public string ShortTypeName { get; set; }

public string CustomFormatterTypeName { get; set; }

private readonly HashSet<string> primitiveTypes = new HashSet<string>(new string[]
{
"short",
"int",
"long",
"ushort",
"uint",
"ulong",
"float",
"double",
"bool",
"byte",
"sbyte",
"char",
////"global::System.DateTime",
////"byte[]",
////"string",
});

public string GetSerializeMethodString()
{
if (CustomFormatterTypeName != null)
{
return $"this.__{this.Name}CustomFormatter__.Serialize(ref writer, value.{this.Name}, options)";
}
else if (this.primitiveTypes.Contains(this.Type))
{
return $"writer.Write(value.{this.Name})";
}
else
{
return $"formatterResolver.GetFormatterWithVerify<{this.Type}>().Serialize(ref writer, value.{this.Name}, options)";
}
}

public string GetDeserializeMethodString()
{
if (CustomFormatterTypeName != null)
{
return $"this.__{this.Name}CustomFormatter__.Deserialize(ref reader, options)";
}
else if (this.primitiveTypes.Contains(this.Type))
{
return $"reader.Read{this.ShortTypeName.Replace("[]", "s")}()";
}
else
{
return $"formatterResolver.GetFormatterWithVerify<{this.Type}>().Deserialize(ref reader, options)";
}
}
}

public class EnumSerializationInfo : IResolverRegisterInfo
{
public string Namespace { get; set; }

public string Name { get; set; }

public string FullName { get; set; }

public string UnderlyingType { get; set; }

public string FormatterName => (this.Namespace == null ? this.Name : this.Namespace + "." + this.Name) + "Formatter";
}

public class GenericSerializationInfo : IResolverRegisterInfo, IEquatable<GenericSerializationInfo>
{
public string FullName { get; set; }

public string FormatterName { get; set; }

public bool Equals(GenericSerializationInfo other)
{
return this.FullName.Equals(other.FullName);
}

public override int GetHashCode()
{
return this.FullName.GetHashCode();
}
}

public class UnionSerializationInfo : IResolverRegisterInfo
{
public string Namespace { get; set; }

public string Name { get; set; }

public string FullName { get; set; }

public string FormatterName => (this.Namespace == null ? this.Name : this.Namespace + "." + this.Name) + "Formatter";

public UnionSubTypeInfo[] SubTypes { get; set; }
}

public class UnionSubTypeInfo
{
public string Type { get; set; }

public int Key { get; set; }
}
}