From 575088aeb67caddb1f644027a5456a16d9ac0a94 Mon Sep 17 00:00:00 2001 From: Pyry Kontio Date: Fri, 6 Feb 2015 22:05:18 +0200 Subject: [PATCH] Extended namespaces tests to consider taking a parameter and returning a value of types declared in other libraries. Implemented QualifiedIdentifierIfNeeded(). --- .../Generators/CSharp/CSharpTextTemplate.cs | 45 +++++++++++++++-- tests/NamespacesBase/NamespacesBase.h | 6 ++- tests/NamespacesDerived/NamespacesDerived.cpp | 50 ++++++++++++++++++- tests/NamespacesDerived/NamespacesDerived.h | 35 ++++++++++++- 4 files changed, 127 insertions(+), 9 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index c2bfde18..3dd42d21 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -105,6 +105,43 @@ namespace CppSharp.Generators.CSharp #region Identifiers + // Takes a declaration (type, class etc.) that is referenced from a context, and the context. + // If the referenced name needs a qualification in the context, add it. Otherwise, return just the name. + public string QualifiedIdentifierIfNeeded(Declaration context, Declaration reference) + { + var refNames = new Stack(); + var ctxNames = new Stack(); + + var refCtx = reference; + while (refCtx != null) + { + if (!string.IsNullOrWhiteSpace(refCtx.Name)) + refNames.Push(refCtx.Name); + refCtx = refCtx.Namespace; + } + + var ctxCtx = context; + while (ctxCtx != null) + { + if (!string.IsNullOrWhiteSpace(ctxCtx.Name)) + ctxNames.Push(ctxCtx.Name); + ctxCtx = ctxCtx.Namespace; + } + + if (context.GenerationKind == GenerationKind.Generate && Options.GenerateLibraryNamespace) + ctxNames.Push(Options.OutputNamespace); + if (reference.GenerationKind == GenerationKind.Generate && Options.GenerateLibraryNamespace) + refNames.Push(Options.OutputNamespace); + + while (refNames.Count > 0 && ctxNames.Count > 0 &&refNames.Peek() == ctxNames.Peek()) + { + refNames.Pop(); + ctxNames.Pop(); + } + + return string.Join(".", refNames); + } + public string QualifiedIdentifier(Declaration decl) { var names = new List { decl.Name }; @@ -633,7 +670,7 @@ namespace CppSharp.Generators.CSharp bases.AddRange( from @base in @class.Bases where @base.IsClass - select QualifiedIdentifier(@base.Class)); + select QualifiedIdentifierIfNeeded(@class, @base.Class)); } if (@class.IsGenerated) @@ -1781,7 +1818,7 @@ namespace CppSharp.Generators.CSharp var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; if (hasBaseClass) WriteLineIndent(": base(({0}.Internal*) native{1})", - QualifiedIdentifier(@class.BaseClass), @class.IsAbstractImpl ? ", true" : string.Empty); + QualifiedIdentifierIfNeeded(@class, @class.BaseClass), @class.IsAbstractImpl ? ", true" : string.Empty); WriteStartBraceIndent(); @@ -1828,7 +1865,7 @@ namespace CppSharp.Generators.CSharp // Allocate memory for a new native object and call the ctor. WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); WriteLine("{0}.Internal.{1}(ret, new global::System.IntPtr(&native));", - QualifiedIdentifier(@class), GetFunctionNativeIdentifier(copyCtorMethod)); + QualifiedIdentifierIfNeeded(@class, @class), GetFunctionNativeIdentifier(copyCtorMethod)); WriteLine("return ({0}.Internal*) ret;", className); } else @@ -2243,7 +2280,7 @@ namespace CppSharp.Generators.CSharp if (construct == null) { WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"), - QualifiedIdentifier(retClass.OriginalClass ?? retClass)); + QualifiedIdentifierIfNeeded(function, retClass.OriginalClass ?? retClass)); } else { diff --git a/tests/NamespacesBase/NamespacesBase.h b/tests/NamespacesBase/NamespacesBase.h index 5459d8d3..0caa7020 100644 --- a/tests/NamespacesBase/NamespacesBase.h +++ b/tests/NamespacesBase/NamespacesBase.h @@ -3,7 +3,7 @@ namespace OverlappingNamespace { - enum Colors { + enum ColorsEnum { white, black, red, @@ -21,6 +21,8 @@ namespace OverlappingNamespace }; } + + class DLL_API Base { public: @@ -29,4 +31,4 @@ public: private: int b; -}; \ No newline at end of file +}; diff --git a/tests/NamespacesDerived/NamespacesDerived.cpp b/tests/NamespacesDerived/NamespacesDerived.cpp index 209262cb..88c00324 100644 --- a/tests/NamespacesDerived/NamespacesDerived.cpp +++ b/tests/NamespacesDerived/NamespacesDerived.cpp @@ -1,12 +1,60 @@ #include "NamespacesDerived.h" +OverlappingNamespace::InDerivedLib::InDerivedLib() : parentNSComponent(), color(black) +{ +} + Derived::Derived() : Base(10), baseComponent(5), nestedNSComponent(), color(OverlappingNamespace::blue) { } +Base Derived::getBase() +{ + return baseComponent; +} -OverlappingNamespace::InDerivedLib::InDerivedLib() : parentNSComponent(), color(black) +void Derived::setBase(Base b) +{ + baseComponent = b; +} + +OverlappingNamespace::InBaseLib Derived::getNestedNSComponent() +{ + return nestedNSComponent; +} + +void Derived::setNestedNSComponent(OverlappingNamespace::InBaseLib c) +{ + nestedNSComponent = c; +} + + +Base2::Base2() +{ +} + + +Derived2::Derived2() : Base2() +{ +} + +Base2 Derived2::getBase() { + return baseComponent; +} + +void Derived2::setBase(Base2 b) +{ + baseComponent = b; +} +OverlappingNamespace::InDerivedLib Derived2::getNestedNSComponent() +{ + return nestedNSComponent; +} + +void Derived2::setNestedNSComponent(OverlappingNamespace::InDerivedLib c) +{ + nestedNSComponent = c; } diff --git a/tests/NamespacesDerived/NamespacesDerived.h b/tests/NamespacesDerived/NamespacesDerived.h index 13f0d96f..5f4d5287 100644 --- a/tests/NamespacesDerived/NamespacesDerived.h +++ b/tests/NamespacesDerived/NamespacesDerived.h @@ -1,6 +1,8 @@ #include "../Tests.h" #include "../NamespacesBase/NamespacesBase.h" +// Namespace clashes with NamespacesBase.OverlappingNamespace +// Test whether qualified names turn out right. namespace OverlappingNamespace { @@ -9,21 +11,50 @@ namespace OverlappingNamespace public: InDerivedLib(); Base parentNSComponent; - Colors color; + ColorsEnum color; }; } + +// Using a type imported from a different library. class DLL_API Derived : public Base { public: Derived(); Base baseComponent; + Base getBase(); + void setBase(Base); OverlappingNamespace::InBaseLib nestedNSComponent; + OverlappingNamespace::InBaseLib getNestedNSComponent(); + void setNestedNSComponent(OverlappingNamespace::InBaseLib); - OverlappingNamespace::Colors color; + OverlappingNamespace::ColorsEnum color; private: int d; }; + + +// For reference: using a type derived in the same library +class Base2 +{ +public: + Base2(); +}; + +class Derived2 : public Base2 +{ +public: + Derived2(); + + Base2 baseComponent; + Base2 getBase(); + void setBase(Base2); + + OverlappingNamespace::InDerivedLib nestedNSComponent; + OverlappingNamespace::InDerivedLib getNestedNSComponent(); + void setNestedNSComponent(OverlappingNamespace::InDerivedLib); + +};