From 573272e855078f9197b1455ea710446025ea38bb Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sun, 14 Jul 2019 00:56:03 +0300 Subject: [PATCH] Generate valid C# when a renamed override causes conflicts Signed-off-by: Dimitar Dobrev --- src/Generator/Passes/RenamePass.cs | 19 ++++++++++++++++--- tests/CSharp/CSharp.Tests.cs | 6 +++++- tests/CSharp/CSharp.cpp | 10 ++++++++++ tests/CSharp/CSharp.h | 3 +++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index bdf6f80e..d04b298e 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -199,9 +199,9 @@ namespace CppSharp.Passes declarations.AddRange(@class.TemplateParameters); } - var result = declarations.Any(d => d != decl && d.Name == newName); - if (result) - return true; + var existing = declarations.Find(d => d != decl && d.Name == newName); + if (existing != null) + return CheckExisting(decl, existing); if (decl is Method && decl.IsGenerated) return @class.GetPropertyByName(newName) != null; @@ -226,6 +226,19 @@ namespace CppSharp.Passes f => !f.Ignore && f.Parameters.SequenceEqual(function.Parameters, new ParameterComparer())); } + private static bool CheckExisting(Declaration decl, Declaration existing) + { + var method = decl as Method; + var property = decl as Property; + if (method?.IsOverride != true && property?.IsOverride != true) + return true; + + existing.Name = existing.Name == existing.OriginalName || + string.IsNullOrEmpty(existing.OriginalName) ? + existing.Name + "_" : existing.OriginalName; + return false; + } + public override bool VisitClassDecl(Class @class) { if (!base.VisitClassDecl(@class)) diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 89da0626..42f13a7d 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -61,7 +61,11 @@ public unsafe class CSharpTests : GeneratorTestFixture hasOverride.CauseRenamingError(); using (var qux = new Qux()) { - new Bar(qux).Dispose(); + qux.Type.GetHashCode(); + using (Bar bar = new Bar(qux)) + { + bar.Type.GetHashCode(); + } } using (var quux = new Quux()) { diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index 48ad12f8..7ad1fd81 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -230,6 +230,11 @@ int Qux::takeReferenceToPointer(Foo*& ret) return ret->A; } +int Qux::type() const +{ + return 0; +} + Bar::Bar(Qux qux) { } @@ -286,6 +291,11 @@ void Bar::setIndex(int value) index = value; } +int Bar::type() const +{ + return 1; +} + ForceCreationOfInterface::ForceCreationOfInterface() { } diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 2894cdc2..5c02e30d 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -85,6 +85,7 @@ public: void setInterface(Qux* qux); virtual void makeClassDynamic(); virtual int takeReferenceToPointer(Foo*& ret); + virtual int type() const; }; class DLL_API Bar : public Qux @@ -115,6 +116,8 @@ public: int publicInt; double publicDouble; }; + static const int Type = 4; + int type() const override; protected: enum class ProtectedNestedEnum