From e9c65f6719e754b1be37517649c742b2bc31d190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6llner?= Date: Sun, 15 Sep 2019 19:09:43 +0200 Subject: [PATCH] More WIP --- .gitignore | 5 + .../Capnp.Net.Runtime.Tests.Core21.csproj | 3 + .../Capnp.Net.Runtime.Tests.Std20.csproj | 3 + Capnp.Net.Runtime/Capnp.Net.Runtime.csproj | 10 +- Capnp.Net.sln | 2 +- .../CapnpC.CSharp.Generator.Tests.csproj | 3 + .../CapnpC.CSharp.Generator.csproj | 1 + CapnpC.CSharp.Generator/CapnpCompilation.cs | 7 +- ...npC.CSharp.MsBuild.Generation.Tests.csproj | 2 + .../CapnpCodeBehindGenerator.cs | 20 +- .../CapnpFileCodeBehindGenerator.cs | 18 +- .../Capnpc.Csharp.MsBuild.Generation.csproj | 16 +- .../GenerateCapnpFileCodeBehindTask.cs | 46 +- .../ICapnpCsharpGenerator.cs | 2 +- .../CPS/Buildsystem/Rules/CapnpFileType.xaml | 25 +- .../Capnpc.Csharp.MsBuild.Generation.props | 1 + MsBuildGenerationTest/AddressBook.capnp | 31 + .../MsBuildGenerationTest.csproj | 56 + .../MsBuildGenerationTest.sln | 25 + MsBuildGenerationTest/capnp/c++.capnp | 26 + .../capnp/compat/json-test.capnp | 116 ++ MsBuildGenerationTest/capnp/compat/json.capnp | 112 ++ MsBuildGenerationTest/capnp/persistent.capnp | 139 ++ .../capnp/rpc-twoparty.capnp | 169 ++ MsBuildGenerationTest/capnp/rpc.capnp | 1409 +++++++++++++++++ MsBuildGenerationTest/capnp/schema.capnp | 529 +++++++ MsBuildGenerationTest/capnp/test-import.capnp | 28 + .../capnp/test-import2.capnp | 32 + MsBuildGenerationTest/capnp/test.capnp | 969 ++++++++++++ .../capnp/testdata/annotated-json.binary | Bin 0 -> 544 bytes .../capnp/testdata/annotated.json | 22 + MsBuildGenerationTest/capnp/testdata/binary | Bin 0 -> 2816 bytes .../capnp/testdata/errors.capnp.nobuild | 161 ++ .../capnp/testdata/errors.txt | 60 + MsBuildGenerationTest/capnp/testdata/flat | Bin 0 -> 2808 bytes .../capnp/testdata/lists.binary | Bin 0 -> 1096 bytes MsBuildGenerationTest/capnp/testdata/packed | Bin 0 -> 831 bytes .../capnp/testdata/packedflat | Bin 0 -> 828 bytes .../capnp/testdata/pretty.json | 88 + .../capnp/testdata/pretty.txt | 187 +++ .../capnp/testdata/segmented | Bin 0 -> 5520 bytes .../capnp/testdata/segmented-packed | Bin 0 -> 1352 bytes .../capnp/testdata/short.json | 1 + .../capnp/testdata/short.txt | 1 + MsBuildGenerationTest/nuget.config | 10 + appveyor.yml | 4 +- capnpc-csharp/capnpc-csharp.csproj | 5 +- test.capnp.bin | 0 48 files changed, 4295 insertions(+), 49 deletions(-) create mode 100644 MsBuildGenerationTest/AddressBook.capnp create mode 100644 MsBuildGenerationTest/MsBuildGenerationTest.csproj create mode 100644 MsBuildGenerationTest/MsBuildGenerationTest.sln create mode 100644 MsBuildGenerationTest/capnp/c++.capnp create mode 100644 MsBuildGenerationTest/capnp/compat/json-test.capnp create mode 100644 MsBuildGenerationTest/capnp/compat/json.capnp create mode 100644 MsBuildGenerationTest/capnp/persistent.capnp create mode 100644 MsBuildGenerationTest/capnp/rpc-twoparty.capnp create mode 100644 MsBuildGenerationTest/capnp/rpc.capnp create mode 100644 MsBuildGenerationTest/capnp/schema.capnp create mode 100644 MsBuildGenerationTest/capnp/test-import.capnp create mode 100644 MsBuildGenerationTest/capnp/test-import2.capnp create mode 100644 MsBuildGenerationTest/capnp/test.capnp create mode 100644 MsBuildGenerationTest/capnp/testdata/annotated-json.binary create mode 100644 MsBuildGenerationTest/capnp/testdata/annotated.json create mode 100644 MsBuildGenerationTest/capnp/testdata/binary create mode 100644 MsBuildGenerationTest/capnp/testdata/errors.capnp.nobuild create mode 100644 MsBuildGenerationTest/capnp/testdata/errors.txt create mode 100644 MsBuildGenerationTest/capnp/testdata/flat create mode 100644 MsBuildGenerationTest/capnp/testdata/lists.binary create mode 100644 MsBuildGenerationTest/capnp/testdata/packed create mode 100644 MsBuildGenerationTest/capnp/testdata/packedflat create mode 100644 MsBuildGenerationTest/capnp/testdata/pretty.json create mode 100644 MsBuildGenerationTest/capnp/testdata/pretty.txt create mode 100644 MsBuildGenerationTest/capnp/testdata/segmented create mode 100644 MsBuildGenerationTest/capnp/testdata/segmented-packed create mode 100644 MsBuildGenerationTest/capnp/testdata/short.json create mode 100644 MsBuildGenerationTest/capnp/testdata/short.txt create mode 100644 MsBuildGenerationTest/nuget.config delete mode 100644 test.capnp.bin diff --git a/.gitignore b/.gitignore index cc27174..1f39135 100644 --- a/.gitignore +++ b/.gitignore @@ -332,3 +332,8 @@ ASALocalRun/ .mfractor/ .vscode/tasks.json .vscode/launch.json + +# Capnp code behind +.capnp.cs +/globalPackages +*.cs diff --git a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj index d72aa67..d4a9e68 100644 --- a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj +++ b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj @@ -4,6 +4,8 @@ netcoreapp2.2 false + + Debug;Release @@ -31,6 +33,7 @@ + diff --git a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj index 5048b1c..d722dd3 100644 --- a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj +++ b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj @@ -8,6 +8,8 @@ 7.1 Library + + Debug;Release @@ -15,6 +17,7 @@ + diff --git a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj index ae162a8..90555c9 100644 --- a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj +++ b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj @@ -7,6 +7,7 @@ Capnp.Net.Runtime Capnp.Net.Runtime true + ..\bin\$(Configuration) Christian Köllner and contributors A Cap'n Proto implementation for .NET Standard & Core capnproto-dotnetcore @@ -17,17 +18,14 @@ MIT Git capnp "Cap'n Proto" RPC serialization cerealization - 1.0.0 + 1.0-local$([System.DateTime]::UtcNow.ToString(yyMMddHHmm)) + Debug;Release TRACE - - - - - + diff --git a/Capnp.Net.sln b/Capnp.Net.sln index 38c77ca..ff53c1c 100644 --- a/Capnp.Net.sln +++ b/Capnp.Net.sln @@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CapnpC.CSharp.MsBuild.Gener EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CapnpC.CSharp.Generator", "CapnpC.CSharp.Generator\CapnpC.CSharp.Generator.csproj", "{C3A3BB49-356E-4762-A190-76D877BE18F7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CapnpC.CSharp.MsBuild.Generation.Tests", "CapnpC.CSharp.MsBuild.Generation.Tests\CapnpC.CSharp.MsBuild.Generation.Tests.csproj", "{EF05AD68-DE31-448E-B88D-4144F928ED5D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CapnpC.CSharp.MsBuild.Generation.Tests", "CapnpC.CSharp.MsBuild.Generation.Tests\CapnpC.CSharp.MsBuild.Generation.Tests.csproj", "{EF05AD68-DE31-448E-B88D-4144F928ED5D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj b/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj index 5228560..0f3fa11 100644 --- a/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj +++ b/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj @@ -5,6 +5,8 @@ CapnpC.CSharp.Generator.Tests false + + Debug;Release @@ -61,6 +63,7 @@ SpecFlowSingleFileGenerator CodeGenerator.feature.cs + diff --git a/CapnpC.CSharp.Generator/CapnpC.CSharp.Generator.csproj b/CapnpC.CSharp.Generator/CapnpC.CSharp.Generator.csproj index 377d454..e752fdf 100644 --- a/CapnpC.CSharp.Generator/CapnpC.CSharp.Generator.csproj +++ b/CapnpC.CSharp.Generator/CapnpC.CSharp.Generator.csproj @@ -2,6 +2,7 @@ netstandard2.0;netcoreapp2.1 + Debug;Release diff --git a/CapnpC.CSharp.Generator/CapnpCompilation.cs b/CapnpC.CSharp.Generator/CapnpCompilation.cs index ec4c342..3c01261 100644 --- a/CapnpC.CSharp.Generator/CapnpCompilation.cs +++ b/CapnpC.CSharp.Generator/CapnpCompilation.cs @@ -45,9 +45,10 @@ namespace CapnpC.CSharp.Generator /// Invokes "capnp.exe -o-" with given additional arguments and redirects the output to the C# generator backend. /// /// additional command line arguments + /// optional working directory /// generation result /// is null - public static GenerationResult InvokeCapnpAndGenerate(IEnumerable arguments) + public static GenerationResult InvokeCapnpAndGenerate(IEnumerable arguments, string workingDirectory = null) { if (arguments == null) throw new ArgumentNullException(nameof(arguments)); @@ -64,6 +65,10 @@ namespace CapnpC.CSharp.Generator compiler.StartInfo.UseShellExecute = false; compiler.StartInfo.RedirectStandardOutput = true; compiler.StartInfo.RedirectStandardError = true; + if (!string.IsNullOrWhiteSpace(workingDirectory)) + { + compiler.StartInfo.WorkingDirectory = workingDirectory; + } try { diff --git a/CapnpC.CSharp.MsBuild.Generation.Tests/CapnpC.CSharp.MsBuild.Generation.Tests.csproj b/CapnpC.CSharp.MsBuild.Generation.Tests/CapnpC.CSharp.MsBuild.Generation.Tests.csproj index fe274f1..4b48f59 100644 --- a/CapnpC.CSharp.MsBuild.Generation.Tests/CapnpC.CSharp.MsBuild.Generation.Tests.csproj +++ b/CapnpC.CSharp.MsBuild.Generation.Tests/CapnpC.CSharp.MsBuild.Generation.Tests.csproj @@ -4,6 +4,8 @@ netcoreapp2.2 false + + Debug;Release diff --git a/Capnpc.Csharp.MsBuild.Generation/CapnpCodeBehindGenerator.cs b/Capnpc.Csharp.MsBuild.Generation/CapnpCodeBehindGenerator.cs index 71c0592..6bc73be 100644 --- a/Capnpc.Csharp.MsBuild.Generation/CapnpCodeBehindGenerator.cs +++ b/Capnpc.Csharp.MsBuild.Generation/CapnpCodeBehindGenerator.cs @@ -13,8 +13,10 @@ namespace CapnpC.CSharp.MsBuild.Generation } - public CsFileGeneratorResult GenerateCodeBehindFile(string capnpFile) + public CsFileGeneratorResult GenerateCodeBehindFile(CapnpGenJob job) { + string capnpFile = job.CapnpPath; + // Works around a weird capnp.exe behavior: When the input file is empty, it will spit out an exception dump // instead of a parse error. But the parse error is nice because it contains a generated ID. We want the parse error! // Workaround: Generate a temporary file that contains a single line break (such that it is not empty...) @@ -27,7 +29,15 @@ namespace CapnpC.CSharp.MsBuild.Generation File.WriteAllText(tempFile, Environment.NewLine); try { - return GenerateCodeBehindFile(tempFile); + var jobCopy = new CapnpGenJob() + { + CapnpPath = tempFile, + WorkingDirectory = job.WorkingDirectory + }; + + jobCopy.AdditionalArguments.AddRange(job.AdditionalArguments); + + return GenerateCodeBehindFile(jobCopy); } finally { @@ -39,7 +49,11 @@ namespace CapnpC.CSharp.MsBuild.Generation { } - var result = CapnpCompilation.InvokeCapnpAndGenerate(new string[] { capnpFile }); + var args = new List(); + args.AddRange(job.AdditionalArguments); + args.Add(capnpFile); + + var result = CapnpCompilation.InvokeCapnpAndGenerate(args, job.WorkingDirectory); if (result.IsSuccess) { diff --git a/Capnpc.Csharp.MsBuild.Generation/CapnpFileCodeBehindGenerator.cs b/Capnpc.Csharp.MsBuild.Generation/CapnpFileCodeBehindGenerator.cs index 188830b..26af336 100644 --- a/Capnpc.Csharp.MsBuild.Generation/CapnpFileCodeBehindGenerator.cs +++ b/Capnpc.Csharp.MsBuild.Generation/CapnpFileCodeBehindGenerator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace CapnpC.CSharp.MsBuild.Generation @@ -18,10 +19,8 @@ namespace CapnpC.CSharp.MsBuild.Generation public IEnumerable GenerateFilesForProject( string projectPath, - List capnpFiles, - string projectFolder, - string workingDirectory, - string additionalOptions) + List capnpFiles, + string projectFolder) { using (var capnpCodeBehindGenerator = new CapnpCodeBehindGenerator()) { @@ -34,9 +33,14 @@ namespace CapnpC.CSharp.MsBuild.Generation yield break; } - foreach (var capnpFile in capnpFiles) + foreach (var genJob in capnpFiles) { - var generatorResult = capnpCodeBehindGenerator.GenerateCodeBehindFile(capnpFile); + Log.LogMessage(MessageImportance.Normal, "Generate {0}, working dir = {1}, options = {2}", + genJob.CapnpPath, + genJob.WorkingDirectory, + string.Join(" ", genJob.AdditionalArguments)); + + var generatorResult = capnpCodeBehindGenerator.GenerateCodeBehindFile(genJob); if (!generatorResult.Success) { @@ -55,7 +59,7 @@ namespace CapnpC.CSharp.MsBuild.Generation subcategory: null, errorCode: null, helpKeyword: null, - file: capnpFile, + file: genJob.CapnpPath, lineNumber: message.Line, columnNumber: message.Column, endLineNumber: message.Line, diff --git a/Capnpc.Csharp.MsBuild.Generation/Capnpc.Csharp.MsBuild.Generation.csproj b/Capnpc.Csharp.MsBuild.Generation/Capnpc.Csharp.MsBuild.Generation.csproj index 6c20fd2..c45d18d 100644 --- a/Capnpc.Csharp.MsBuild.Generation/Capnpc.Csharp.MsBuild.Generation.csproj +++ b/Capnpc.Csharp.MsBuild.Generation/Capnpc.Csharp.MsBuild.Generation.csproj @@ -11,19 +11,22 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb 1.0.0.0 1.0.0.0 - 1.0.0 - + 1.0-local$([System.DateTime]::UtcNow.ToString(yyMMddHHmm)) + $(MSBuildThisFileDirectory)CapnpC.CSharp.MsBuild.Generation.nuspec version=$(Version);configuration=$(Configuration) true + ..\bin\$(Configuration) + Debug;Release - + + @@ -41,7 +44,8 @@ - + + @@ -103,4 +107,8 @@ + + + + \ No newline at end of file diff --git a/Capnpc.Csharp.MsBuild.Generation/GenerateCapnpFileCodeBehindTask.cs b/Capnpc.Csharp.MsBuild.Generation/GenerateCapnpFileCodeBehindTask.cs index d29cf8d..459af9b 100644 --- a/Capnpc.Csharp.MsBuild.Generation/GenerateCapnpFileCodeBehindTask.cs +++ b/Capnpc.Csharp.MsBuild.Generation/GenerateCapnpFileCodeBehindTask.cs @@ -25,13 +25,43 @@ namespace CapnpC.CSharp.MsBuild.Generation public ITaskItem[] CapnpFiles { get; set; } - public string WorkingDirectory { get; set; } - - public string AdditionalOptions { get; set; } - [Output] public ITaskItem[] GeneratedFiles { get; private set; } + static CapnpGenJob ToGenJob(ITaskItem item) + { + var job = new CapnpGenJob() + { + CapnpPath = item.GetMetadata("FullPath"), + WorkingDirectory = item.GetMetadata("WorkingDirectory") + }; + + string importPaths = item.GetMetadata("ImportPaths"); + + if (!string.IsNullOrWhiteSpace(importPaths)) + { + job.AdditionalArguments.AddRange(importPaths.Split(new char[] { ';' }, + StringSplitOptions.RemoveEmptyEntries).Select(p => $"-I\"{p.TrimEnd('\\')}\"")); + } + + string sourcePrefix = item.GetMetadata("SourcePrefix"); + + if (!string.IsNullOrWhiteSpace(sourcePrefix)) + { + job.AdditionalArguments.Add(sourcePrefix); + } + + + string verbose = item.GetMetadata("Verbose"); + + if ("true".Equals(verbose, StringComparison.OrdinalIgnoreCase)) + { + job.AdditionalArguments.Add("--verbose"); + } + + return job; + } + public override bool Execute() { try @@ -56,16 +86,14 @@ namespace CapnpC.CSharp.MsBuild.Generation var generator = CodeBehindGenerator ?? new CapnpFileCodeBehindGenerator(Log); - Log.LogWithNameTag(Log.LogMessage, "Starting GenerateFeatureFileCodeBehind"); + Log.LogWithNameTag(Log.LogMessage, "Starting GenerateCapnpFileCodeBehind"); - var capnpFiles = CapnpFiles?.Select(i => i.ItemSpec).ToList() ?? new List(); + var capnpFiles = CapnpFiles?.Select(ToGenJob).ToList() ?? new List(); var generatedFiles = generator.GenerateFilesForProject( ProjectPath, capnpFiles, - ProjectFolder, - WorkingDirectory, - AdditionalOptions); + ProjectFolder); GeneratedFiles = generatedFiles.Select(file => new TaskItem { ItemSpec = file }).ToArray(); diff --git a/Capnpc.Csharp.MsBuild.Generation/ICapnpCsharpGenerator.cs b/Capnpc.Csharp.MsBuild.Generation/ICapnpCsharpGenerator.cs index de828fd..965b0ce 100644 --- a/Capnpc.Csharp.MsBuild.Generation/ICapnpCsharpGenerator.cs +++ b/Capnpc.Csharp.MsBuild.Generation/ICapnpCsharpGenerator.cs @@ -4,6 +4,6 @@ namespace CapnpC.CSharp.MsBuild.Generation { public interface ICapnpcCsharpGenerator { - IEnumerable GenerateFilesForProject(string projectPath, List capnpFiles, string projectFolder, string workingDirectory, string additionalOptions); + IEnumerable GenerateFilesForProject(string projectPath, List jobs, string projectFolder); } } \ No newline at end of file diff --git a/Capnpc.Csharp.MsBuild.Generation/build/CPS/Buildsystem/Rules/CapnpFileType.xaml b/Capnpc.Csharp.MsBuild.Generation/build/CPS/Buildsystem/Rules/CapnpFileType.xaml index 72e5c94..c938967 100644 --- a/Capnpc.Csharp.MsBuild.Generation/build/CPS/Buildsystem/Rules/CapnpFileType.xaml +++ b/Capnpc.Csharp.MsBuild.Generation/build/CPS/Buildsystem/Rules/CapnpFileType.xaml @@ -27,17 +27,20 @@ - + - - - - - - --> + + + + + + + \ No newline at end of file diff --git a/Capnpc.Csharp.MsBuild.Generation/build/Capnpc.Csharp.MsBuild.Generation.props b/Capnpc.Csharp.MsBuild.Generation/build/Capnpc.Csharp.MsBuild.Generation.props index bc41f4e..2d2682c 100644 --- a/Capnpc.Csharp.MsBuild.Generation/build/Capnpc.Csharp.MsBuild.Generation.props +++ b/Capnpc.Csharp.MsBuild.Generation/build/Capnpc.Csharp.MsBuild.Generation.props @@ -47,6 +47,7 @@ %(RelativeDir)%(Filename).capnp.cs $(UsingMicrosoftNETSdk) + $(ProjectDir)