From 7cff21aa7893b1e8eea33436f2009e34c746b40c Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 15 Jun 2015 01:20:00 +0300 Subject: [PATCH] Fixed default args with template types; added an option for expressions to use in type maps. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpTypePrinter.cs | 5 +- .../Passes/HandleDefaultParamValuesPass.cs | 47 +++++++++++-------- tests/CSharpTemp/CSharpTemp.cpp | 4 ++ tests/CSharpTemp/CSharpTemp.cs | 37 +++++++++++++++ tests/CSharpTemp/CSharpTemp.h | 6 +++ 5 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index 1e77f3b8..3b592188 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -13,7 +13,8 @@ namespace CppSharp.Generators.CSharp Native, Managed, ManagedPointer, - GenericDelegate + GenericDelegate, + DefaultExpression } public class CSharpTypePrinterContext : TypePrinterContext @@ -53,7 +54,7 @@ namespace CppSharp.Generators.CSharp public class CSharpTypePrinter : ITypePrinter, IDeclVisitor { - private Driver driver; + private readonly Driver driver; private readonly Stack contexts; diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 71ff76ee..cb5bef5f 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -42,7 +42,8 @@ namespace CppSharp.Passes CheckFloatSyntax(desugared, parameter); - bool? defaultConstruct = CheckForDefaultConstruct(desugared, parameter.DefaultArgument); + bool? defaultConstruct = CheckForDefaultConstruct(desugared, parameter.DefaultArgument, + parameter.QualifiedType.Qualifiers); if (defaultConstruct == null || (!Driver.Options.MarshalCharAsManagedChar && parameter.Type.Desugar().IsPrimitiveType(PrimitiveType.UChar))) @@ -106,12 +107,10 @@ namespace CppSharp.Passes return false; } - private bool? CheckForDefaultConstruct(Type desugared, Expression arg) + private bool? CheckForDefaultConstruct(Type desugared, Expression arg, TypeQualifiers qualifiers) { // Unwrapping the underlying type behind a possible pointer/reference - Type type; - desugared.IsPointerTo(out type); - type = type ?? desugared; + Type type = desugared.GetFinalPointee() ?? desugared; Class decl; if (!type.TryGetClass(out decl)) @@ -120,38 +119,48 @@ namespace CppSharp.Passes var ctor = arg.Declaration as Method; TypeMap typeMap; + var typePrinterContext = new CSharpTypePrinterContext + { + CSharpKind = CSharpTypePrinterContextKind.DefaultExpression, + Type = type + }; + + string typePrinterResult = null; if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap)) { - var typePrinterContext = new CSharpTypePrinterContext - { - CSharpKind = CSharpTypePrinterContextKind.Managed, - Type = type - }; var typeInSignature = typeMap.CSharpSignatureType(typePrinterContext).SkipPointerRefs(); - var mappedTo = typeMap.CSharpSignature(typePrinterContext); Enumeration @enum; if (typeInSignature.TryGetEnum(out @enum)) - { return false; - } if (ctor == null || !ctor.IsConstructor) return false; - if (mappedTo == "string" && ctor.Parameters.Count == 0) + + typePrinterResult = typeMap.CSharpSignature(typePrinterContext); + if (typePrinterResult == "string" && ctor.Parameters.Count == 0) { arg.String = "\"\""; return true; } } - if (regexCtor.IsMatch(arg.String)) + var match = regexCtor.Match(arg.String); + if (match.Success) { - arg.String = string.Format("new {0}", arg.String); - if (ctor != null && ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress()) + if (ctor != null) { - arg.String = arg.String.Replace("(0)", "()"); - return decl.IsValueType ? true : (bool?) null; + var templateSpecializationType = type as TemplateSpecializationType; + var typePrinter = new CSharpTypePrinter(Driver); + typePrinterResult = typePrinterResult ?? (templateSpecializationType != null + ? typePrinter.VisitTemplateSpecializationType(templateSpecializationType, qualifiers) + : typePrinter.VisitClassDecl((Class) ctor.Namespace)).Type; + + arg.String = string.Format("new {0}{1}", typePrinterResult, match.Groups[2].Value); + if (ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress()) + arg.String = arg.String.Replace("(0)", "()"); } + else + arg.String = string.Format("new {0}", arg.String); } else { diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index ffcd2292..0bc838d5 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -294,6 +294,10 @@ MethodsWithDefaultValues::MethodsWithDefaultValues(int a) m_foo.A = a; } +MethodsWithDefaultValues::MethodsWithDefaultValues(double d, QList list) +{ +} + void MethodsWithDefaultValues::defaultPointer(Foo *ptr) { } diff --git a/tests/CSharpTemp/CSharpTemp.cs b/tests/CSharpTemp/CSharpTemp.cs index 41a0decb..cdb6081a 100644 --- a/tests/CSharpTemp/CSharpTemp.cs +++ b/tests/CSharpTemp/CSharpTemp.cs @@ -41,6 +41,43 @@ namespace CppSharp.Tests } } + [TypeMap("QList")] + public class QList : TypeMap + { + public override bool IsIgnored + { + get + { + var type = (TemplateSpecializationType) this.Type; + var pointeeType = type.Arguments[0].Type; + var checker = new TypeIgnoreChecker(TypeMapDatabase); + pointeeType.Visit(checker); + return checker.IsIgnored; + } + } + + public override string CSharpSignature(CSharpTypePrinterContext ctx) + { + if (ctx.CSharpKind == CSharpTypePrinterContextKind.Native) + return Type.IsAddress() ? "QList.Internal*" : "QList.Internal"; + + return string.Format("System.Collections.Generic.{0}<{1}>", + ctx.CSharpKind == CSharpTypePrinterContextKind.DefaultExpression ? "List" : "IList", + ctx.GetTemplateParameterList()); + } + + public override void CSharpMarshalToNative(MarshalContext ctx) + { + // pointless, put just so that the generated code compiles + ctx.Return.Write("new QList.Internal()"); + } + + public override void CSharpMarshalToManaged(MarshalContext ctx) + { + ctx.Return.Write(ctx.ReturnVarName); + } + } + public class TestAttributesPass : TranslationUnitPass { public override bool VisitFunctionDecl(Function function) diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 83ad63a9..666e5605 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -251,11 +251,17 @@ public: QColor(Qt::GlobalColor color); }; +template +class QList +{ +}; + class DLL_API MethodsWithDefaultValues { public: MethodsWithDefaultValues(Foo foo = Foo()); MethodsWithDefaultValues(int a); + MethodsWithDefaultValues(double d, QList list = QList()); void defaultPointer(Foo* ptr = 0); void defaultVoidStar(void* ptr = 0); void defaultValueType(QGenericArgument valueType = QGenericArgument());