diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 8df9cbde..9793602b 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -491,6 +491,10 @@ namespace CppSharp.Generators.CLI { PushIndent(); + if (@class.IsValueType) + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) + GenerateClassMethods(@base.Class); + var staticMethods = new List(); foreach (var method in @class.Methods) { diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index a3e233a7..68bd47b9 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -138,17 +138,7 @@ namespace CppSharp.Generators.CLI GenerateClassConstructors(@class); - foreach (var method in @class.Methods) - { - if (ASTUtils.CheckIgnoreMethod(method, Options)) - continue; - - // C++/CLI does not allow special member funtions for value types. - if (@class.IsValueType && method.IsCopyConstructor) - continue; - - GenerateMethod(method, @class); - } + GenerateClassMethods(@class, @class); if (CSharpTextTemplate.ShouldGenerateClassNativeField(@class)) { @@ -217,6 +207,25 @@ namespace CppSharp.Generators.CLI } } + private void GenerateClassMethods(Class @class, Class realOwner) + { + if (@class.IsValueType) + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) + GenerateClassMethods(@base.Class, realOwner); + + foreach (var method in @class.Methods) + { + if (ASTUtils.CheckIgnoreMethod(method, this.Options)) + continue; + + // C++/CLI does not allow special member funtions for value types. + if (@class.IsValueType && method.IsCopyConstructor) + continue; + + GenerateMethod(method, realOwner); + } + } + private void GenerateClassProperties(Class @class, Class realOwner) { if (@class.IsValueType) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 0b946a06..9a016aa9 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -471,9 +471,12 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - private IEnumerable GatherClassInternalFunctions(Class @class) + private IEnumerable GatherClassInternalFunctions(Class @class, bool includeCtors = true) { - var functions = new HashSet(); + var functions = new List(); + if (@class.IsValueType) + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) + functions.AddRange(GatherClassInternalFunctions(@base.Class, false)); Action tryAddOverload = method => { @@ -487,18 +490,21 @@ namespace CppSharp.Generators.CSharp functions.Add(method); }; - foreach (var ctor in @class.Constructors) + if (includeCtors) { - if (@class.IsStatic) - continue; + foreach (var ctor in @class.Constructors) + { + if (@class.IsStatic) + continue; - if (ctor.IsMoveConstructor) - continue; + if (ctor.IsMoveConstructor) + continue; - if (ctor.IsDefaultConstructor && !@class.HasNonTrivialDefaultConstructor) - continue; + if (ctor.IsDefaultConstructor && !@class.HasNonTrivialDefaultConstructor) + continue; - tryAddOverload(ctor); + tryAddOverload(ctor); + } } if (@class.HasNonTrivialDestructor && !@class.IsStatic) @@ -521,7 +527,7 @@ namespace CppSharp.Generators.CSharp if (prop.GetMethod != null) tryAddOverload(prop.GetMethod); - if (prop.SetMethod != null) + if (prop.SetMethod != null && prop.SetMethod != prop.GetMethod) tryAddOverload(prop.SetMethod); } @@ -1119,6 +1125,10 @@ namespace CppSharp.Generators.CSharp public void GenerateClassMethods(Class @class) { + if (@class.IsValueType) + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) + GenerateClassMethods(@base.Class); + var staticMethods = new List(); foreach (var method in @class.Methods) { @@ -1145,6 +1155,10 @@ namespace CppSharp.Generators.CSharp public void GenerateClassVariables(Class @class) { + if (@class.IsValueType) + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) + GenerateClassVariables(@base.Class); + foreach (var variable in @class.Variables) { if (!variable.IsGenerated) continue; @@ -1161,12 +1175,8 @@ namespace CppSharp.Generators.CSharp private void GenerateClassProperties(Class @class) { if (@class.IsValueType) - { - foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared)) - { + foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore && b.Class.IsDeclared)) GenerateClassProperties(@base.Class); - } - } GenerateProperties(@class); } diff --git a/tests/Basic/Basic.Tests.cs b/tests/Basic/Basic.Tests.cs index f097b5e5..d9984a7c 100644 --- a/tests/Basic/Basic.Tests.cs +++ b/tests/Basic/Basic.Tests.cs @@ -368,5 +368,15 @@ public class BasicTests : GeneratorTestFixture var ret = basic.TestNullPtrTypeRet(); Assert.AreEqual(IntPtr.Zero, new IntPtr(ret)); } + + [Test] + public void TestValueTypeInheritance() + { + var bar2 = new Bar2 { A = 24 }; + Assert.That(bar2.RetItem1(), Is.EqualTo(Bar.Item.Item1)); + Assert.That(bar2.returnPointerToValueType().A, Is.EqualTo(24)); + var inheritTestIndexedPropertiesInValueType = new InheritTestIndexedPropertiesInValueType(); + Assert.That(inheritTestIndexedPropertiesInValueType[2], Is.EqualTo(2)); + } } \ No newline at end of file diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index b405fe0e..296c56d3 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -433,7 +433,7 @@ const foo_t& TestIndexedProperties::operator[](double f) { return p; } TestProperties* TestIndexedProperties::operator[](unsigned char b) { return &f; } const TestProperties& TestIndexedProperties::operator[](short b) { return f; } -struct DLL_API TestIndexedPropertiesInValueType +struct DLL_API CS_VALUETYPE TestIndexedPropertiesInValueType { public: int operator[](int i); @@ -441,6 +441,10 @@ public: int TestIndexedPropertiesInValueType::operator[](int i) { return i; } +struct DLL_API CS_VALUETYPE InheritTestIndexedPropertiesInValueType : public TestIndexedPropertiesInValueType +{ +}; + enum struct MyEnum { A, B, C }; class DLL_API TestArraysPointers diff --git a/tests/Tests.h b/tests/Tests.h index 1c2cbaf2..04c3c8a5 100644 --- a/tests/Tests.h +++ b/tests/Tests.h @@ -23,4 +23,5 @@ #endif #define CS_OUT -#define CS_IN_OUT \ No newline at end of file +#define CS_IN_OUT +#define CS_VALUETYPE