diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 3fec967e..f349adcf 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -73,10 +73,11 @@ namespace CppSharp.Generators.CSharp } public static string GetSuffixForInternal(ClassTemplateSpecialization specialization, - CSharpTypePrinter typePrinter) + CSharpTypePrinter typePrinter, bool nested = false) { - if (specialization.TemplatedDecl.TemplatedClass.Fields.All( - f => !f.IsDependent || f.Type.IsAddress())) + if (!nested && + specialization.TemplatedDecl.TemplatedClass.Fields.All( + f => !f.IsDependent || f.Type.IsAddress())) return string.Empty; if (specialization.Arguments.All( @@ -84,18 +85,44 @@ namespace CppSharp.Generators.CSharp return "_Ptr"; // we don't want internals in the names of internals :) - typePrinter.PushContext(CSharpTypePrinterContextKind.Managed); - typePrinter.PushMarshalKind(CSharpMarshalKind.Unknown); + if (!nested) + { + typePrinter.PushContext(CSharpTypePrinterContextKind.Managed); + typePrinter.PushMarshalKind(CSharpMarshalKind.Unknown); + } var suffix = new StringBuilder(); foreach (var argType in from argType in specialization.Arguments where argType.Type.Type != null - select argType.Type.ToString()) + select argType.Type.Type) { suffix.Append('_'); + ClassTemplateSpecialization nestedSpecialization; + if (argType.TryGetDeclaration(out nestedSpecialization)) + { + suffix.Append(typePrinter.GetNestedQualifiedName(nestedSpecialization)); + suffix.Append(GetSuffixForInternal(nestedSpecialization, typePrinter, true)); + continue; + } + Class @class; + if (argType.TryGetClass(out @class)) + { + nestedSpecialization = @class.Namespace as ClassTemplateSpecialization; + if (nestedSpecialization != null) + { + suffix.Append(typePrinter.GetNestedQualifiedName(nestedSpecialization)); + suffix.Append(GetSuffixForInternal(nestedSpecialization, typePrinter, true)); + suffix.Append('_'); + suffix.Append(@class.Name); + continue; + } + } suffix.Append(argType); } - typePrinter.PopContext(); - typePrinter.PopMarshalKind(); + if (!nested) + { + typePrinter.PopContext(); + typePrinter.PopMarshalKind(); + } FormatTypesStringForIdentifier(suffix); return suffix.ToString(); } diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 16d8e1bd..39a3e9c1 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -611,6 +611,11 @@ namespace CppSharp.Generators.CSharp return GetNestedQualifiedName(@enum); } + public string GetNestedQualifiedName(ClassTemplateSpecialization decl) + { + return GetNestedQualifiedName(decl.Namespace, decl); + } + private string GetNestedQualifiedName(Declaration decl) { return GetNestedQualifiedName(decl.Namespace, decl); diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 8e40ac50..a2c438bc 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -514,7 +514,7 @@ public class CSharpTests : GeneratorTestFixture typeof(CSharp.DependentValueFields.Internal_float), typeof(CSharp.DependentPointerFields.Internal), typeof(CSharp.DependentValueFields.Internal_Ptr), - typeof(CSharp.HasDefaultTemplateArgument.Internal_int_IndependentFields) + typeof(CSharp.HasDefaultTemplateArgument.Internal_int_IndependentFields_int) }) { var independentFields = internalType.GetFields(); diff --git a/tests/CSharp/CSharpTemplates.h b/tests/CSharp/CSharpTemplates.h index 121fa10f..bceff8a4 100644 --- a/tests/CSharp/CSharpTemplates.h +++ b/tests/CSharp/CSharpTemplates.h @@ -57,6 +57,8 @@ private: HasDefaultTemplateArgument hasDefaultTemplateArgument; DependentValueFields dependentPointerFieldsT1; DependentValueFields dependentPointerFieldsT2; + DependentValueFields> specializeWithSpecialization; + DependentValueFields> specializeWithSameSpecialization; void completeSpecializationInParameter(DependentValueFields p1, DependentValueFields p2, DependentValueFields p3);