From 7ecafc985833c8868eb56597ced53b497eb6b204 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 6 Nov 2013 17:14:27 +0200 Subject: [PATCH] Prevented renaming of methods when a base class has a property of the same name. Made the delegates used in abstract implementations prefixed with an underscore and internal. Signed-off-by: Dimitar Dobrev --- src/AST/Class.cs | 34 ++++++++++++++++++ .../Generators/CSharp/CSharpTextTemplate.cs | 7 ++-- .../GenerateAbstractImplementationsPass.cs | 5 +-- .../GetterSetterToPropertyAdvancedPass.cs | 2 +- .../Passes/MultipleInheritancePass.cs | 1 + src/Generator/Passes/RenamePass.cs | 10 ++++-- src/Generator/Utils/Utils.cs | 8 +++++ tests/CSharpTemp/CSharpTemp.Tests.cs | 36 +++++++++---------- tests/CSharpTemp/CSharpTemp.cpp | 10 ++++++ tests/CSharpTemp/CSharpTemp.cs | 11 +++++- tests/CSharpTemp/CSharpTemp.h | 4 +++ 11 files changed, 100 insertions(+), 28 deletions(-) diff --git a/src/AST/Class.cs b/src/AST/Class.cs index fbb874b7..300f2ac2 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -245,6 +245,40 @@ namespace CppSharp.AST select rootBaseProperty).FirstOrDefault(); } + public Property GetPropertyByName(string propertyName) + { + Property property = Properties.FirstOrDefault(m => m.Name == propertyName); + if (property != null) + return property; + Declaration decl; + foreach (var baseClassSpecifier in Bases.Where( + b => b.Type.IsTagDecl(out decl) && !b.Class.Ignore)) + { + property = baseClassSpecifier.Class.GetPropertyByName(propertyName); + if (property != null) + return property; + } + return null; + } + + public Property GetPropertyByConstituentMethod(Method method) + { + var property = Properties.FirstOrDefault(p => p.GetMethod == method); + if (property != null) + return property; + property = Properties.FirstOrDefault(p => p.SetMethod == method); + if (property != null) + return property; + Declaration decl; + foreach (BaseClassSpecifier @base in Bases.Where(b => b.Type.IsTagDecl(out decl))) + { + property = @base.Class.GetPropertyByConstituentMethod(method); + if (property != null) + return property; + } + return null; + } + public Method GetMethodByName(string methodName) { var method = Methods.FirstOrDefault(m => m.Name == methodName); diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index d6423103..5ce41223 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1122,8 +1122,7 @@ namespace CppSharp.Generators.CSharp { var entries = VTables.GatherVTableMethodEntries(@class); return entries.Where(e => !e.Method.Ignore || - @class.Properties.Any(p => !p.Ignore && - (p.GetMethod == e.Method || p.SetMethod == e.Method))).ToList(); + @class.GetPropertyByConstituentMethod(e.Method) != null).ToList(); } public List GetUniqueVTableMethodEntries(Class @class) @@ -1843,7 +1842,7 @@ namespace CppSharp.Generators.CSharp GenerateFunctionCall(delegateId, method.Parameters, method); } - public static string GetVirtualCallDelegate(INamedDecl method, Class @class, + public static string GetVirtualCallDelegate(Function method, Class @class, bool is32Bit, out string delegateId) { var virtualCallBuilder = new StringBuilder(); @@ -1857,7 +1856,7 @@ namespace CppSharp.Generators.CSharp "void* slot = *((void**) vtable + {0} * {1});", i, is32Bit ? 4 : 8); virtualCallBuilder.AppendLine(); - string @delegate = method.Name + "Delegate"; + string @delegate = ASTHelpers.GetDelegateName(method); delegateId = Generator.GeneratedIdentifier(@delegate); virtualCallBuilder.AppendFormat( diff --git a/src/Generator/Passes/GenerateAbstractImplementationsPass.cs b/src/Generator/Passes/GenerateAbstractImplementationsPass.cs index 0f3850a2..b96504c0 100644 --- a/src/Generator/Passes/GenerateAbstractImplementationsPass.cs +++ b/src/Generator/Passes/GenerateAbstractImplementationsPass.cs @@ -59,10 +59,11 @@ namespace CppSharp.Passes internalImpl.Methods.Add(method); var @delegate = new TypedefDecl { - Name = abstractMethod.Name + "Delegate", + Name = ASTHelpers.GetDelegateName(abstractMethod), QualifiedType = abstractMethod.GetFunctionType(), IgnoreFlags = abstractMethod.IgnoreFlags, - Namespace = internalImpl + Namespace = internalImpl, + Access = AccessSpecifier.Private }; internalImpl.Typedefs.Add(@delegate); } diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index f4ca7b99..86e7b01d 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -198,7 +198,7 @@ namespace CppSharp.Passes private static string GetPropertyName(string name) { - if (GetFirstWord(name) == "get") + if (GetFirstWord(name) == "get" && name != "get") { if (char.IsLower(name[0])) { diff --git a/src/Generator/Passes/MultipleInheritancePass.cs b/src/Generator/Passes/MultipleInheritancePass.cs index e25004ee..03ac85a8 100644 --- a/src/Generator/Passes/MultipleInheritancePass.cs +++ b/src/Generator/Passes/MultipleInheritancePass.cs @@ -79,6 +79,7 @@ namespace CppSharp.Passes if (@interface.Bases.Count == 0) { Property instance = new Property(); + instance.Namespace = @interface; instance.Name = Helpers.InstanceIdentifier; instance.QualifiedType = new QualifiedType(new BuiltinType(PrimitiveType.IntPtr)); instance.GetMethod = new Method(); diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index df5ba64b..1b436b44 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -79,7 +79,7 @@ namespace CppSharp.Passes private bool Rename(Declaration decl) { string newName; - if (Rename(decl.Name, out newName) && AreThereConflicts(decl, newName)) + if (Rename(decl.Name, out newName) && !AreThereConflicts(decl, newName)) decl.Name = newName; return true; } @@ -92,7 +92,13 @@ namespace CppSharp.Passes declarations.AddRange(decl.Namespace.Events); declarations.AddRange(decl.Namespace.Functions); declarations.AddRange(decl.Namespace.Variables); - return declarations.All(d => d == decl || d.Name != newName); + bool result = declarations.Any(d => d != decl && d.Name == newName); + if (result) + return true; + Method method = decl as Method; + if (method == null || !method.IsGenerated) + return false; + return ((Class) method.Namespace).GetPropertyByName(newName) != null; } public override bool VisitEnumItem(Enumeration.Item item) diff --git a/src/Generator/Utils/Utils.cs b/src/Generator/Utils/Utils.cs index 86694451..b5958152 100644 --- a/src/Generator/Utils/Utils.cs +++ b/src/Generator/Utils/Utils.cs @@ -234,4 +234,12 @@ namespace CppSharp return assembly.GetTypes().Where(baseType.IsAssignableFrom); } } + + public static class ASTHelpers + { + public static string GetDelegateName(Function method) + { + return "_" + char.ToLowerInvariant(method.Name[0]) + method.Name.Substring(1) + "Delegate"; + } + } } diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index bb7bdfdf..37c9f1aa 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -35,24 +35,24 @@ public class CSharpTempTests { Qux qux = new Qux(); var array = new[] { 1, 2, 3 }; - qux.array = array; - for (int i = 0; i < qux.array.Length; i++) - Assert.That(array[i], Is.EqualTo(qux.array[i])); + qux.Array = array; + for (int i = 0; i < qux.Array.Length; i++) + Assert.That(array[i], Is.EqualTo(qux.Array[i])); } [Test] public void TestMultipleInheritance() { Baz baz = new Baz(); - Assert.That(baz.method, Is.EqualTo(1)); + Assert.That(baz.Method, Is.EqualTo(1)); var bar = (IBar) baz; - Assert.That(bar.method, Is.EqualTo(2)); + Assert.That(bar.Method, Is.EqualTo(2)); Assert.That(baz[0], Is.EqualTo(50)); bar[0] = new Foo { A = 1000 }; Assert.That(bar[0].A, Is.EqualTo(1000)); - Assert.That(baz.farAwayFunc, Is.EqualTo(20)); - Assert.That(baz.takesQux(baz), Is.EqualTo(20)); - Assert.That(baz.returnQux().farAwayFunc, Is.EqualTo(20)); + Assert.That(baz.FarAwayFunc, Is.EqualTo(20)); + Assert.That(baz.TakesQux(baz), Is.EqualTo(20)); + Assert.That(baz.ReturnQux().FarAwayFunc, Is.EqualTo(20)); int cast = baz; Assert.That(cast, Is.EqualTo(500)); var nested = new Baz.Nested(); @@ -64,18 +64,18 @@ public class CSharpTempTests public void TestProperties() { var proprietor = new Proprietor(); - proprietor.value = 20; - Assert.That(proprietor.value, Is.EqualTo(20)); - proprietor.prop = 50; - Assert.That(proprietor.prop, Is.EqualTo(50)); + proprietor.Value = 20; + Assert.That(proprietor.Value, Is.EqualTo(20)); + proprietor.Prop = 50; + Assert.That(proprietor.Prop, Is.EqualTo(50)); var p = new P(); - p.value = 20; - Assert.That(p.value, Is.EqualTo(30)); - p.prop = 50; - Assert.That(p.prop, Is.EqualTo(150)); + p.Value = 20; + Assert.That(p.Value, Is.EqualTo(30)); + p.Prop = 50; + Assert.That(p.Prop, Is.EqualTo(150)); ComplexType complexType = new ComplexType(); - p.complexType = complexType; - Assert.That(p.complexType.check(), Is.EqualTo(5)); + p.ComplexType = complexType; + Assert.That(p.ComplexType.Check(), Is.EqualTo(5)); } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index 5a8a6295..cc8e5134 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -100,6 +100,11 @@ void AbstractProprietor::setProp(long property) m_property = property; } +int AbstractProprietor::parent() +{ + return 0; +} + void Proprietor::setValue(int value) { m_value = value; @@ -134,3 +139,8 @@ void P::setComplexType(const ComplexType& value) { m_complexType = value; } + +void P::parent(int i) +{ + +} diff --git a/tests/CSharpTemp/CSharpTemp.cs b/tests/CSharpTemp/CSharpTemp.cs index a122ffc7..4e1431a9 100644 --- a/tests/CSharpTemp/CSharpTemp.cs +++ b/tests/CSharpTemp/CSharpTemp.cs @@ -1,4 +1,6 @@ -using CppSharp.Generators; +using CppSharp.AST; +using CppSharp.Generators; +using CppSharp.Passes; using CppSharp.Utils; namespace CppSharp.Tests @@ -17,6 +19,13 @@ namespace CppSharp.Tests driver.Options.GenerateVirtualTables = true; } + public override void Postprocess(Driver driver, ASTContext lib) + { + new CaseRenamePass( + RenameTargets.Function | RenameTargets.Method | RenameTargets.Property | RenameTargets.Delegate, + RenameCasePattern.UpperCamelCase).VisitLibrary(driver.ASTContext); + } + public static void Main(string[] args) { ConsoleDriver.Run(new CSharpTempTests(GeneratorKind.CSharp)); diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 9d254119..4d6998d0 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -78,6 +78,8 @@ public: virtual long prop() = 0; virtual void setProp(long prop); + virtual int parent(); + protected: int m_value; long m_property; @@ -106,6 +108,8 @@ public: ComplexType complexType(); void setComplexType(const ComplexType& value); + virtual void parent(int i); + private: ComplexType m_complexType; };