public void UnionsWithPointersGeneratesStructure() { var config = new ConfigFile { Id = nameof(UnionsWithPointersGeneratesStructure), Namespace = nameof(UnionsWithPointersGeneratesStructure), Includes = { new IncludeRule { File = "test.h", Attach = true, Namespace = nameof(UnionsWithPointersGeneratesStructure) } }, Bindings = { new BindRule("int", "System.Int32") } }; var structure = new CppStruct { Name = "Test", IsUnion = true }; structure.Add(new CppField { Name = "pointer", TypeName = "int", Pointer = "*" }); structure.Add(new CppField { Name = "scalar", TypeName = "int" }); var include = new CppInclude { Name = "test" }; include.Add(structure); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(); foreach (var field in csStruct.Fields) { Assert.Equal(0, field.Offset); } Assert.False(Logger.HasErrors); }
public void IntFieldMappedToBoolIsMarkedAsBoolToInt() { var structName = "BoolToInt"; var config = new ConfigFile { Id = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt), Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt), Includes = { new IncludeRule { File = "test.h", Attach = true, Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt) } }, Bindings = { new BindRule("int", "System.Int32"), new BindRule("bool", "System.Boolean") }, Mappings = { new MappingRule { Field = $"{structName}::field", MappingType = "bool", }, } }; var structure = new CppStruct { Name = structName }; structure.Add(new CppField { Name = "field", TypeName = "int" }); var include = new CppInclude { Name = "test" }; include.Add(structure); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); Assert.Single(solution.EnumerateDescendants().OfType <CsStruct>().Where(csStruct => csStruct.Name == structName)); var generatedStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(csStruct => csStruct.Name == structName); Assert.Single(generatedStruct.Fields); var field = generatedStruct.Fields.First(); Assert.True(field.IsBoolToInt); }
public void MultipleBitfieldOffsetsGeneratedCorrectly() { var config = new ConfigFile { Id = nameof(MultipleBitfieldOffsetsGeneratedCorrectly), Namespace = nameof(MultipleBitfieldOffsetsGeneratedCorrectly), Includes = { new IncludeRule { File = "test.h", Attach = true, Namespace = nameof(MultipleBitfieldOffsetsGeneratedCorrectly) } }, Bindings = { new BindRule("int", "System.Int32") } }; var structure = new CppStruct { Name = "Test" }; structure.Add(new CppField { Name = "bitfield1", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 0, }); structure.Add(new CppField { Name = "field", TypeName = "int", Offset = 1, }); structure.Add(new CppField { Name = "bitfield2", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 2 }); var include = new CppInclude { Name = "test" }; include.Add(structure); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(); var bitField1 = csStruct.Fields.First(field => field.Name == "Bitfield1"); Assert.Equal(0, bitField1.BitOffset); Assert.Equal(0, bitField1.Offset); Assert.Equal((1 << 16) - 1, bitField1.BitMask); Assert.True(bitField1.IsBitField); var csField = csStruct.Fields.First(field => field.Name == "Field"); Assert.Equal(4, csField.Offset); Assert.False(csField.IsBitField); var bitField2 = csStruct.Fields.First(field => field.Name == "Bitfield2"); Assert.Equal(0, bitField2.BitOffset); Assert.Equal(8, bitField2.Offset); Assert.Equal((1 << 16) - 1, bitField2.BitMask); Assert.True(bitField2.IsBitField); }
public void NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling() { var config = new Config.ConfigFile { Id = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling), Namespace = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling), Includes = { new Config.IncludeRule { File = "test.h", Attach = true, Namespace = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling) } }, Bindings = { new Config.BindRule("int", "System.Int32") }, Mappings = { new Config.MappingRule { Struct = "Test", StructCustomMarshal = true } } }; var structure = new CppStruct { Name = "Test" }; structure.Add(new CppField { Name = "bitfield1", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 0, }); structure.Add(new CppField { Name = "bitfield2", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 0 }); structure.Add(new CppField { Name = "pointer", TypeName = "int", Pointer = "*", Offset = 1 }); structure.Add(new CppField { Name = "field", TypeName = "int", Offset = 2, }); var include = new CppInclude { Name = "test" }; include.Add(structure); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); Assert.False(Logger.HasErrors); }
public void InheritingStructs() { var config = new ConfigFile { Id = nameof(InheritingStructs), Namespace = nameof(InheritingStructs), Includes = { new IncludeRule { File = "struct.h", Attach = true, Namespace = nameof(SequentialOffsets) } }, Bindings = { new BindRule("int", "System.Int32") } }; var baseStruct = new CppStruct { Name = "base" }; baseStruct.Add(new CppField { Name = "field", TypeName = "int" }); var inheritingStruct = new CppStruct { Name = "inheriting", Base = "base" }; inheritingStruct.Add(new CppField { Name = "field2", TypeName = "int", Offset = 1 }); var cppInclude = new CppInclude { Name = "struct" }; var cppModule = new CppModule(); cppModule.Add(cppInclude); cppInclude.Add(baseStruct); cppInclude.Add(inheritingStruct); var(solution, _) = MapModel(cppModule, config); var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(@struct => @struct.Name == "Inheriting"); var field = csStruct.Fields.First(fld => fld.Name == "Field"); var field2 = csStruct.Fields.First(fld => fld.Name == "Field2"); Assert.Equal(0, field.Offset); Assert.Equal(4, field2.Offset); }
public void NonPortableStructAlignmentRaisesError() { var config = new Config.ConfigFile { Id = nameof(NonPortableStructAlignmentRaisesError), Namespace = nameof(NonPortableStructAlignmentRaisesError), Includes = { new Config.IncludeRule { File = "test.h", Attach = true, Namespace = nameof(NonPortableStructAlignmentRaisesError) } }, Bindings = { new Config.BindRule("int", "System.Int32") } }; var structure = new CppStruct { Name = "Test" }; structure.Add(new CppField { Name = "bitfield1", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 0, }); structure.Add(new CppField { Name = "bitfield2", TypeName = "int", IsBitField = true, BitOffset = 16, Offset = 0 }); structure.Add(new CppField { Name = "pointer", TypeName = "int", Pointer = "*", Offset = 1 }); structure.Add(new CppField { Name = "field", TypeName = "int", Offset = 2, }); var include = new CppInclude { Name = "test" }; include.Add(structure); var module = new CppModule(); module.Add(include); using (LoggerMessageCountEnvironment(1, LogLevel.Error)) using (LoggerCodeRequiredEnvironment(LoggingCodes.NonPortableAlignment)) { MapModel(module, config); } }
public void DualCallbackFlowsNativeImplementation() { var config = new Config.ConfigFile { Id = nameof(Simple), Namespace = nameof(Simple), Includes = { new Config.IncludeRule { File = "interface.h", Attach = true, Namespace = nameof(Simple) } }, Bindings = { new Config.BindRule("int", "System.Int32") }, Mappings = { new Config.MappingRule { Interface = "Interface", IsCallbackInterface = true, IsDualCallbackInterface = true } } }; var iface = new CppInterface { Name = "Interface", TotalMethodCount = 1 }; iface.Add(new CppMethod { Name = "method", ReturnValue = new CppReturnValue { TypeName = "int" } }); var include = new CppInclude { Name = "interface" }; include.Add(iface); var module = new CppModule(); module.Add(include); var(_, defines) = GetConsumerBindings(module, config); var interfaceDefine = defines.First(define => define.Interface == "Simple.Interface"); Assert.Equal("Simple.InterfaceNative", interfaceDefine.NativeImplementation); }
public void Simple() { var config = new Config.ConfigFile { Id = nameof(Simple), Namespace = nameof(Simple), Includes = { new Config.IncludeRule { File = "interface.h", Attach = true, Namespace = nameof(Simple) } }, Bindings = { new Config.BindRule("int", "System.Int32") } }; var iface = new CppInterface { Name = "Interface", TotalMethodCount = 1 }; iface.Add(new CppMethod { Name = "method", ReturnValue = new CppReturnValue { TypeName = "int" } }); var include = new CppInclude { Name = "interface" }; include.Add(iface); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); Assert.Single(solution.EnumerateDescendants().OfType <CsInterface>()); var csIface = solution.EnumerateDescendants().OfType <CsInterface>().First(); Assert.Single(csIface.Methods); var method = csIface.Methods.First(); Assert.Equal(0, method.Offset); Assert.IsType <CsFundamentalType>(method.ReturnValue.PublicType); Assert.Equal(typeof(int), ((CsFundamentalType)method.ReturnValue.PublicType).Type); }
public void DefineWithNativeImplementationDefinesNativeImplementationType() { var config = new Config.ConfigFile { Id = nameof(Simple), Namespace = nameof(Simple), Includes = { new Config.IncludeRule { File = "interface.h", Attach = true, Namespace = nameof(Simple) } }, Extension = { new Config.DefineExtensionRule { Interface = "Imported.Param", NativeImplementation = "Imported.ParamNative" } }, Bindings = { new Config.BindRule("int", "System.Int32"), new Config.BindRule("Param", "Imported.Param") } }; var iface = new CppInterface { Name = "Interface", TotalMethodCount = 1 }; var method = new CppMethod { Name = "method", ReturnValue = new CppReturnValue { TypeName = "int" } }; method.Add(new CppParameter { Name = "param", TypeName = "Param", Pointer = "*" }); iface.Add(method); var include = new CppInclude { Name = "interface" }; include.Add(iface); var module = new CppModule(); module.Add(include); var(solution, _) = MapModel(module, config); Assert.Single(solution.EnumerateDescendants().OfType <CsParameter>()); var param = solution.EnumerateDescendants().OfType <CsParameter>().First(); Assert.IsType <CsInterface>(param.PublicType); Assert.NotNull(((CsInterface)param.PublicType).NativeImplementation); Assert.False(Logger.HasErrors); }
public void ContextRuleLimitsWhereMappingRuleExecutes() { var config = new Config.ConfigFile { Id = nameof(ContextRuleLimitsWhereMappingRuleExecutes), Assembly = nameof(ContextRuleLimitsWhereMappingRuleExecutes), Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes), Includes = { new Config.IncludeRule { Attach = true, File = "cppEnum.h", Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes) }, new Config.IncludeRule { Attach = true, File = "secondFile.h", Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes) } }, Mappings = { new Config.ContextRule("cppEnum"), new Config.MappingRule { Enum = "AnotherEnum", MappingNameFinal = "NewEnum" }, new Config.ClearContextRule() } }; var cppModel = new CppModule(); var cppInclude = new CppInclude { Name = "cppEnum" }; var cppEnum = new CppEnum { Name = "TestEnum" }; var secondInclude = new CppInclude { Name = "secondFile" }; var cppEnum2 = new CppEnum { Name = "AnotherEnum" }; cppEnum.AddEnumItem("Element1", "0"); cppEnum.AddEnumItem("Element2", "1"); cppInclude.Add(cppEnum); cppModel.Add(cppInclude); var(solution, _) = MapModel(cppModel, config); Assert.Empty(solution.EnumerateDescendants().OfType <CsEnum>().Where(csEnum => csEnum.Name == "AnotherEnum")); }