Merge pull request #32 from aboulart/test-compile-rb

Fix default value of enums inside unions
This commit is contained in:
c80k 2019-12-11 21:17:56 +01:00 committed by GitHub
commit 2354dafe3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 85 deletions

View File

@ -22,45 +22,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="*.cs" /> <Compile Remove="Embedded Resources\*.cs" />
<Compile Remove="Embedded Resources\test.cs" /> <Compile Remove="CodeGenerator.feature.cs" />
<None Remove="Embedded Resources\Empty.capnp" />
<None Remove="Embedded Resources\Empty1.capnp" />
<None Remove="Embedded Resources\invalid.capnp" />
<None Remove="Embedded Resources\Issue19.capnp.bin" />
<None Remove="Embedded Resources\Issue21.capnp.bin" />
<None Remove="Embedded Resources\Issue22.capnp.bin" />
<None Remove="Embedded Resources\null.bin" />
<None Remove="Embedded Resources\test.capnp" />
<None Remove="Embedded Resources\test.capnp.bin" />
<None Remove="Embedded Resources\UnitTest1.capnp" />
<Compile Include="CapnpMessageUnitTests.cs" />
<Compile Include="CodeGeneratorUnitTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Embedded Resources\test.cs" /> <EmbeddedResource Include="Embedded Resources\*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Embedded Resources\Issue19.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\Empty.capnp" />
<EmbeddedResource Include="Embedded Resources\Empty1.capnp" />
<EmbeddedResource Include="Embedded Resources\invalid.capnp" />
<EmbeddedResource Include="Embedded Resources\Issue21.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\Issue22.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\null.bin" />
<EmbeddedResource Include="Embedded Resources\test.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\test.cs" />
<EmbeddedResource Include="Embedded Resources\UnitTest1.capnp" />
<EmbeddedResource Include="Embedded Resources\UnitTest1.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest2.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest3.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest4.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest10.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest11.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\UnitTest20.capnp.bin" />
<EmbeddedResource Include="Embedded Resources\schema-with-offsets.capnp.bin" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -12,8 +12,6 @@ namespace CapnpC.CSharp.Generator.Tests
[TestClass] [TestClass]
public class CodeGeneratorUnitTests public class CodeGeneratorUnitTests
{ {
static readonly Dictionary<int, string> GeneratedCode = new Dictionary<int, string>();
[TestMethod] [TestMethod]
public void Test00Enumerant() public void Test00Enumerant()
{ {
@ -24,9 +22,9 @@ namespace CapnpC.CSharp.Generator.Tests
[TestMethod] [TestMethod]
public void Test01NestedClash() public void Test01NestedClash()
{ {
var run = LoadAndGenerate("UnitTest1.capnp.bin", 1); var (model, codegen) = LoadAndGenerate("UnitTest1.capnp.bin");
var structFoo = GetTypeDef(0x93db6ba5509bac24, run.Model); var structFoo = GetTypeDef(0x93db6ba5509bac24, model);
var names = run.CodeGen.GetNames(); var names = codegen.GetNames();
var fieldName = names.GetCodeIdentifier(structFoo.Fields[0]).ToString(); var fieldName = names.GetCodeIdentifier(structFoo.Fields[0]).ToString();
Assert.AreEqual("Foo", structFoo.Name); Assert.AreEqual("Foo", structFoo.Name);
Assert.AreNotEqual(structFoo.Name, fieldName); Assert.AreNotEqual(structFoo.Name, fieldName);
@ -35,33 +33,30 @@ namespace CapnpC.CSharp.Generator.Tests
[TestMethod] [TestMethod]
public void Test02ForwardInheritance() public void Test02ForwardInheritance()
{ {
LoadAndGenerate("UnitTest2.capnp.bin", 2); LoadAndGenerate("UnitTest2.capnp.bin");
// Should not throw
} }
[TestMethod] [TestMethod]
public void Test03NonGeneratedNodeSkip() public void Test03NonGeneratedNodeSkip()
{ {
LoadAndGenerate("UnitTest3.capnp.bin", 3); LoadAndGenerate("UnitTest3.capnp.bin");
// Should not throw
} }
[TestMethod] [TestMethod]
public void Test04MutualDependencies() public void Test04MutualDependencies()
{ {
LoadAndGenerate("UnitTest4.capnp.bin", 4); LoadAndGenerate("UnitTest4.capnp.bin");
// Should not throw
} }
[TestMethod] [TestMethod]
public void Test10ImportedNamespaces() public void Test10ImportedNamespaces()
{ {
var run = LoadAndGenerate("UnitTest10.capnp.bin", 10); var (model, codegen) = LoadAndGenerate("UnitTest10.capnp.bin");
var outerTypeDef = run.FirstFile.NestedTypes.First(); var outerTypeDef = GetGeneratedFile("UnitTest10.capnp", model).NestedTypes.First();
var outerType = Model.Types.FromDefinition(outerTypeDef); var outerType = Model.Types.FromDefinition(outerTypeDef);
var innerType = outerTypeDef.Fields[0].Type; var innerType = outerTypeDef.Fields[0].Type;
var innerTypeDef = innerType.Definition; var innerTypeDef = innerType.Definition;
var names = run.CodeGen.GetNames(); var names = codegen.GetNames();
var outerNameSyntax = names.GetQName(outerType, outerTypeDef); var outerNameSyntax = names.GetQName(outerType, outerTypeDef);
var innerNameSyntax = names.GetQName(innerType, outerTypeDef); var innerNameSyntax = names.GetQName(innerType, outerTypeDef);
string[] outerNamespace = { "Foo", "Bar", "Baz" }; string[] outerNamespace = { "Foo", "Bar", "Baz" };
@ -77,45 +72,43 @@ namespace CapnpC.CSharp.Generator.Tests
[TestMethod] [TestMethod]
public void Test11ImportedConst() public void Test11ImportedConst()
{ {
LoadAndGenerate("UnitTest11.capnp.bin", 11); LoadAndGenerate("UnitTest11.capnp.bin");
// Should not throw }
[TestMethod]
public void Test12ConstEnum()
{
LoadAndGenerate("UnitTest12.capnp.bin");
} }
[TestMethod] [TestMethod]
public void Test20AnnotationAndConst() public void Test20AnnotationAndConst()
{ {
LoadAndGenerate("UnitTest20.capnp.bin", 20); LoadAndGenerate("UnitTest20.capnp.bin");
// Should not throw
} }
[TestMethod] [TestMethod]
public void Test30SchemaCapnp() public void Test30SchemaCapnp()
{ {
LoadAndGenerate("schema-with-offsets.capnp.bin"); LoadAndGenerate("schema-with-offsets.capnp.bin");
// Should not throw
} }
struct Run static (Model.SchemaModel, CodeGen.CodeGenerator) LoadAndGenerate(string inputName)
{ {
public Model.SchemaModel Model; var model = Load(inputName);
public CodeGen.CodeGenerator CodeGen; var codegen = new CodeGen.CodeGenerator(model, new CodeGen.GeneratorOptions());
public Model.GenFile FirstFile;
public string Code; var code = model.FilesToGenerate.Select(f => codegen.Transform(f)).ToArray();
Assert.IsTrue(Util.InlineAssemblyCompiler.TryCompileCapnp(code), "Compilation was not successful");
return (model, codegen);
} }
static CodeGen.CodeGenerator NewGeneratorFor(Model.SchemaModel model) static Model.GenFile GetGeneratedFile(string name, Model.SchemaModel model)
=> new CodeGen.CodeGenerator(model, new CodeGen.GeneratorOptions());
Run LoadAndGenerate(string inputName, int? testNum = null)
{ {
var run = new Run(); var file = model.FilesToGenerate.SingleOrDefault(f => f.Name.EndsWith(name));
run.Model = Load(inputName); Assert.IsNotNull(file, $"Could not find '{name}' in generated files");
run.CodeGen = NewGeneratorFor(run.Model); return file;
run.FirstFile = run.Model.FilesToGenerate.First();
run.Code = run.CodeGen.Transform(run.FirstFile);
if (testNum is int num)
GeneratedCode[num] = run.Code;
return run;
} }
static Model.TypeDefinition GetTypeDef(ulong id, Model.SchemaModel model) static Model.TypeDefinition GetTypeDef(ulong id, Model.SchemaModel model)

View File

@ -0,0 +1,17 @@
@0xb7069c462537ddd6;
enum TestEnum {
a @0;
b @1;
}
const globalConstant: TestEnum = b;
struct Struct {
const structConstant: TestEnum = a;
union {
enumValue @0: TestEnum;
intValue @1: Int64;
}
}

View File

@ -11,13 +11,16 @@ namespace CapnpC.CSharp.Generator.Tests.Util
class InlineAssemblyCompiler class InlineAssemblyCompiler
{ {
public static bool TryCompileCapnp(string code) public static bool TryCompileCapnp(string code)
{
return TryCompileCapnp(new[] {code});
}
public static bool TryCompileCapnp(string[] code)
{ {
var options = new CSharpCompilationOptions( var options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary, OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: OptimizationLevel.Debug); optimizationLevel: OptimizationLevel.Debug);
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
string assemblyRoot = Path.GetDirectoryName(typeof(object).Assembly.Location); string assemblyRoot = Path.GetDirectoryName(typeof(object).Assembly.Location);
string capnpRuntimePath = Path.GetFullPath(Path.Combine( string capnpRuntimePath = Path.GetFullPath(Path.Combine(
@ -29,8 +32,6 @@ namespace CapnpC.CSharp.Generator.Tests.Util
"netcoreapp2.1", "netcoreapp2.1",
"Capnp.Net.Runtime.dll")); "Capnp.Net.Runtime.dll"));
var capnpRuntimeMetadataRef = MetadataReference.CreateFromFile(capnpRuntimePath);
var compilation = CSharpCompilation.Create( var compilation = CSharpCompilation.Create(
"CompilationTestAssembly", "CompilationTestAssembly",
options: options, options: options,
@ -40,13 +41,26 @@ namespace CapnpC.CSharp.Generator.Tests.Util
MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Core.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Core.dll")),
MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Runtime.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Runtime.dll")),
MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Private.CoreLib.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Private.CoreLib.dll")),
capnpRuntimeMetadataRef }, MetadataReference.CreateFromFile(capnpRuntimePath) },
syntaxTrees: new SyntaxTree[] { syntaxTree }); syntaxTrees: Array.ConvertAll(code, new Converter<string, SyntaxTree>(c => CSharpSyntaxTree.ParseText(c))));
using (var stream = new MemoryStream()) using (var stream = new MemoryStream())
{ {
var emitResult = compilation.Emit(stream); var emitResult = compilation.Emit(stream);
foreach (var diag in emitResult.Diagnostics)
Console.WriteLine($"{diag}");
if (!emitResult.Success)
{
foreach (var c in code)
{
string path = Path.ChangeExtension(Path.GetTempFileName(), ".capnp.cs");
File.WriteAllText(path, c);
Console.WriteLine($"[See {path} for generated code]");
}
}
return emitResult.Success; return emitResult.Success;
} }
} }

View File

@ -343,10 +343,9 @@ namespace CapnpC.CSharp.Generator.CodeGen
return LiteralExpression(SyntaxKind.FalseLiteralExpression); return LiteralExpression(SyntaxKind.FalseLiteralExpression);
case TypeTag.Enum: case TypeTag.Enum:
return MemberAccessExpression( return CastExpression(
SyntaxKind.SimpleMemberAccessExpression,
_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.NotRelevant), _names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.NotRelevant),
_names.UnionDiscriminatorUndefined.IdentifierName); LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)));
case TypeTag.F32: case TypeTag.F32:
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0.0f)); return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0.0f));

View File

@ -78,9 +78,9 @@ namespace CapnpC.CSharp.Generator.CodeGen
ContextParameter = new Name(options.ContextParameterName); ContextParameter = new Name(options.ContextParameterName);
GroupReaderContextArg = new Name(options.GroupReaderContextArgName); GroupReaderContextArg = new Name(options.GroupReaderContextArgName);
GroupWriterContextArg = new Name(options.GroupWriterContextArgName); GroupWriterContextArg = new Name(options.GroupWriterContextArgName);
UnionDiscriminatorEnum = new Name(options.UnionDisciminatorEnumName); UnionDiscriminatorEnum = new Name(options.UnionDiscriminatorEnumName);
UnionDiscriminatorProp = new Name(options.UnionDiscriminatorPropName); UnionDiscriminatorProp = new Name(options.UnionDiscriminatorPropName);
UnionDiscriminatorUndefined = new Name(options.UnionDisciminatorUndefinedName); UnionDiscriminatorUndefined = new Name(options.UnionDiscriminatorUndefinedName);
UnionDiscriminatorField = new Name(options.UnionDiscriminatorFieldName); UnionDiscriminatorField = new Name(options.UnionDiscriminatorFieldName);
UnionContentField = new Name(options.UnionContentFieldName); UnionContentField = new Name(options.UnionContentFieldName);
SerializeMethod = new Name(options.SerializeMethodName); SerializeMethod = new Name(options.SerializeMethodName);

View File

@ -12,10 +12,10 @@
public string ContextParameterName { get; set; } = "ctx"; public string ContextParameterName { get; set; } = "ctx";
public string GroupReaderContextArgName { get; set; } = "ctx"; public string GroupReaderContextArgName { get; set; } = "ctx";
public string GroupWriterContextArgName { get; set; } = "ctx"; public string GroupWriterContextArgName { get; set; } = "ctx";
public string UnionDisciminatorEnumName { get; set; } = "WHICH"; public string UnionDiscriminatorEnumName { get; set; } = "WHICH";
public string UnionDiscriminatorPropName { get; set; } = "which"; public string UnionDiscriminatorPropName { get; set; } = "which";
public string UnionDiscriminatorFieldName { get; set; } = "_which"; public string UnionDiscriminatorFieldName { get; set; } = "_which";
public string UnionDisciminatorUndefinedName { get; set; } = "undefined"; public string UnionDiscriminatorUndefinedName { get; set; } = "undefined";
public string UnionContentFieldName { get; set; } = "_content"; public string UnionContentFieldName { get; set; } = "_content";
public string SerializeMethodName { get; set; } = "serialize"; public string SerializeMethodName { get; set; } = "serialize";
public string ApplyDefaultsMethodName { get; set; } = "applyDefaults"; public string ApplyDefaultsMethodName { get; set; } = "applyDefaults";