From 046f29cabf15933f8894f4e3dcd7ff9a6d6d9b52 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 | 18 +++++++++++++++--- tests/CSharp/CSharp.Tests.cs | 6 +++++- tests/CSharp/CSharp.cpp | 10 ++++++++++ tests/CSharp/CSharp.h | 3 +++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index bdf6f80eaa..5b30c18889 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -199,9 +199,9 @@ where typedefDecl.Type.Desugar() is FunctionType 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,18 @@ private static IEnumerable GetFunctionsWithTheSameParams(Function func 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 ? + 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 89da0626c8..42f13a7d2d 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -61,7 +61,11 @@ public void TestUncompilableCode() 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 48ad12f8a0..7ad1fd8174 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 2894cdc270..5c02e30dcb 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -85,6 +85,7 @@ class DLL_API Qux 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 @@ class DLL_API Bar : public Qux int publicInt; double publicDouble; }; + static const int Type = 4; + int type() const override; protected: enum class ProtectedNestedEnum