changeset 298:adae77fdc1ea signals

Native QList implementation is now used throughout QtD
author eldar
date Sun, 06 Dec 2009 17:26:37 +0000
parents bc783e20da2b
children 87db643519a4
files generator/abstractmetalang.h generator/cppimplgenerator.cpp generator/dgenerator.cpp generator/dgenerator.h generator/typesystem.h generator/typesystem_gui-java.java generator/typesystem_gui.xml include/qtd_core.h qt/QGlobal.d qt/core/QList.d qt/core/QTypeInfo.d qt/d2/qt/core/QVariant.d
diffstat 12 files changed, 202 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/generator/abstractmetalang.h	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/abstractmetalang.h	Sun Dec 06 17:26:37 2009 +0000
@@ -970,4 +970,12 @@
                           | NotRemovedFromTargetLang);
 }
 
+inline bool isNativeContainer(AbstractMetaType *argumentType)
+{
+    if (argumentType && argumentType->isContainer())
+        if (((const ContainerTypeEntry *)argumentType->typeEntry())->isQList())
+            return true;
+    return false;
+}
+
 #endif // ABSTRACTMETALANG_H
--- a/generator/cppimplgenerator.cpp	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/cppimplgenerator.cpp	Sun Dec 06 17:26:37 2009 +0000
@@ -721,18 +721,23 @@
           << "}" << endl;
     }
 
-    if (java_class->typeEntry()->isValue() && java_class->hasCloneOperator())
+    if (java_class->typeEntry()->isValue())
     {
-        AbstractMetaFunction *ctor = java_class->copyConstructor();
-        if(ctor)
         {
-            QString argName = ctor->arguments().at(0)->indexedName();
+            QString argName = "orig";
             s << endl << endl
-              << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_placed_copy(void* "
-              << argName << ", " << "void* place) {" << endl
-              << QString("    const %1&  __qt_%2 = (const %1& ) *(%1 *)%2;").arg(java_class->name()).arg(argName) << endl;
-
-            writeFinalConstructor(s, ctor, "result", "original", "(place)");
+              << "extern \"C\" DLL_PUBLIC void qtd_" << java_class->name() << "_placed_copy(void* "
+              << argName << ", void* place) {" << endl
+              << QString("    const %1&  __qt_%2 = (const %1& ) *(%1 *)%2;").arg(shellClassName(java_class)).arg(argName) << endl
+              << QString("    %1 *result = new (place) %1 (__qt_%2);").arg(java_class->qualifiedCppName()).arg(argName) << endl;
+//            writeFinalConstructor(s, ctor, "result", "original", "(place)");
+            s << "}";
+
+            s << endl << endl
+              << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_native_copy(void* " << argName << ") {" << endl
+              << QString("    const %1&  __qt_%2 = (const %1& ) *(%1 *)%2;").arg(shellClassName(java_class)).arg(argName) << endl
+              << QString("    %1 *result = new %1 (__qt_%2);").arg(java_class->qualifiedCppName()).arg(argName) << endl
+              << "    return result;" << endl;
             s << "}";
         }
     }
@@ -744,11 +749,11 @@
 
 void CppImplGenerator::writeValueFunctions(QTextStream &s, const AbstractMetaClass *java_class)
 {
-    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isComplex() { return (bool) QTypeInfo<%1>::isComplex; }\n").arg(java_class->name());
-    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isStatic() { return (bool) QTypeInfo<%1>::isStatic; }\n").arg(java_class->name());
-    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isLarge() { return (bool) QTypeInfo<%1>::isLarge; }\n").arg(java_class->name());
-    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isPointer() { return (bool) QTypeInfo<%1>::isPointer; }\n").arg(java_class->name());
-    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isDummy() { return (bool) QTypeInfo<%1>::isDummy; }\n").arg(java_class->name());
+    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isComplex() { return (bool) QTypeInfo<%2>::isComplex; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
+    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isStatic() { return (bool) QTypeInfo<%2>::isStatic; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
+    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isLarge() { return (bool) QTypeInfo<%2>::isLarge; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
+    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isPointer() { return (bool) QTypeInfo<%2>::isPointer; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
+    s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isDummy() { return (bool) QTypeInfo<%2>::isDummy; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
 }
 
 void CppImplGenerator::writeVirtualDispatchFunction(QTextStream &s, const AbstractMetaFunction *function, bool d_export)
@@ -811,27 +816,35 @@
                     s << INDENT << f_type->typeEntry()->qualifiedCppName() << " __d_return_value;" << endl;
 
                 if (f_type->isContainer())
-                    s << INDENT << "void* __d_return_value;" << endl
-                      << INDENT << "size_t __d_return_value_size;" << endl;
+                {
+                    if (isNativeContainer(f_type))
+                    {
+                        s << INDENT;
+                        writeTypeInfo(s, f_type, ForceValueType);
+                        s << "__d_return_value;" << endl;
+                    }
+                    else
+                        s << INDENT << "void* __d_return_value;" << endl
+                          << INDENT << "size_t __d_return_value_size;" << endl;
+                }
             }
 
             AbstractMetaArgumentList arguments = function->arguments();
             foreach (AbstractMetaArgument *argument, arguments) {
                 if (!function->argumentRemoved(argument->argumentIndex()+1)) {
-                    if (!argument->type()->isPrimitive()
+                    AbstractMetaType *atype = argument->type();
+                    if (!atype->isPrimitive()
                         || !function->conversionRule(TypeSystem::NativeCode, argument->argumentIndex()+1).isEmpty()) {
-                        if(argument->type()->isContainer()) {
+                        if(atype->isContainer()) {
                             QString arg_name = argument->indexedName();
-                            s << INDENT << QString("DArray %1_arr;").arg(arg_name) << endl
-                              << INDENT << QString("DArray *__d_%1 = &%1_arr;").arg(arg_name);
-
-                            writeQtToJava(s,
-                                        argument->type(),
-                                        arg_name,
-                                        "__d_" + arg_name,
-                                        function,
-                                        argument->argumentIndex() + 1,
-                                        Option(VirtualDispatch));
+                            if(!isNativeContainer(atype))
+                                writeQtToJava(s,
+                                              argument->type(),
+                                              arg_name,
+                                              "__d_" + arg_name,
+                                              function,
+                                              argument->argumentIndex() + 1,
+                                              Option(VirtualDispatch));
                         }
                     }
                 }
@@ -867,9 +880,13 @@
                     if (f_type->isTargetLangString())
                         s << ", &ret_str";
                     if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
-                        s << ", &__d_return_value";
-                    if (f_type->isContainer())
-                        s << ", &__d_return_value, &__d_return_value_size";
+                        s << ", &__d_return_value";       // TODO should both be refactored into isNativeType function
+                    if (f_type->isContainer()) {
+                        if ( ((const ContainerTypeEntry *)f_type->typeEntry())->isQList() )
+                            s << ", &__d_return_value";
+                        else
+                            s << ", &__d_return_value, &__d_return_value_size";
+                    }
                 }
 
                 if (function->arguments().size() > 0)
@@ -891,9 +908,14 @@
                         s << INDENT << "return __d_return_value;" << endl;
 
                     if (f_type->isContainer()) {
-                        writeJavaToQt(s, f_type, "__qt_return_value", "__d_return_value",
-                                      function, 0, GlobalRefJObject);
-                        s << INDENT << "return __qt_return_value;" << endl;
+                        if (isNativeContainer(f_type))
+                            s << INDENT << "return __d_return_value;" << endl;
+                        else
+                        {
+                            writeJavaToQt(s, f_type, "__qt_return_value", "__d_return_value",
+                                          function, 0, GlobalRefJObject);
+                            s << INDENT << "return __qt_return_value;" << endl;
+                        }
                     }
 
                     if (f_type->isTargetLangString())
@@ -927,8 +949,16 @@
         else if(ret_type->typeEntry()->isStructInD())
             s << ", " << ret_type->typeEntry()->qualifiedCppName() << " *__d_return_value";
 
-        if (ret_type->isContainer())
-            s << ", void** __d_arr_ptr, size_t* __d_arr_size";
+        if (ret_type->isContainer()) {
+            if(isNativeContainer(ret_type)) {
+                if(d_export)
+                    s << ", " << DGenerator::translateType(ret_type, d_function->ownerClass(), NoOption) << "* __d_arr";
+                else
+                    s << ", void * __d_arr";
+            }
+            else
+                s << ", void** __d_arr_ptr, size_t* __d_arr_size";
+        }
     }
 
     if (d_function->arguments().size() > 0)
@@ -948,9 +978,11 @@
             if (d_type->name() == "QModelIndex")
                 s << "QModelIndexAccessor" << QString(d_type->actualIndirections(), '*') << " " << arg_name;
             else if (d_type->isContainer()) {
-                if (d_export) {
+                if ( isNativeContainer(d_type) )
+                    s << "void* ";
+                else if (d_export)
                     s << DGenerator::translateType(d_type, d_function->ownerClass(), NoOption) << "* ";
-                } else
+                else
                     s << "DArray* ";
                 s << arg_name;
             } else if (d_type->typeEntry()->isStructInD())
@@ -1980,8 +2012,10 @@
             } else if (d_type->isContainer()) {
                 const ContainerTypeEntry *cte =
                         static_cast<const ContainerTypeEntry *>(te);
-                if(isLinearContainer(cte))
-                    s << QString("void *%1, size_t %1_size").arg(arg_name);
+                if(cte->isQList())
+                    s << "void* " << arg_name;
+                else if(isLinearContainer(cte))
+                    s << "DArray* " << arg_name;
             } else {
                 if (!d_type->hasNativeId()) {
                     if(d_type->isVariant()) {
@@ -2350,7 +2384,7 @@
 
         s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_call_destructor(" << shellClassName(cls) << " *ptr)" << endl
           << INDENT << "{" << endl
-          << INDENT << QString ("    ptr->~%1();").arg(shellClassName(cls)) << endl
+          << INDENT << "    call_destructor(ptr);" << endl
           << INDENT << "}" << endl << endl;
     }
 }
@@ -3188,9 +3222,7 @@
     const ContainerTypeEntry *type =
         static_cast<const ContainerTypeEntry *>(java_type->typeEntry());
 
-    if (type->type() == ContainerTypeEntry::ListContainer
-        || type->type() == ContainerTypeEntry::VectorContainer
-        || type->type() == ContainerTypeEntry::StringListContainer
+    if (type->type() == ContainerTypeEntry::VectorContainer
         || type->type() == ContainerTypeEntry::LinkedListContainer
         || type->type() == ContainerTypeEntry::StackContainer
         || type->type() == ContainerTypeEntry::SetContainer
@@ -3203,7 +3235,6 @@
         cls_name.remove("_ConcreteWrapper");
 
         s << endl
-//          << INDENT << "{" << endl // qtd2 hack, additional scope for avoiding duplicating of "i"
           << INDENT;
 
         switch (type->type()) {
@@ -3251,7 +3282,14 @@
             s << INDENT << "++" << index << ";" << endl;
         }
         s << INDENT << "}" << endl;
-//          << INDENT << "}" << endl;
+
+    } else if (type->isQList()) {
+//            QList<QObject*> & list2 = (*(QList<QObject*> *)nativeId);
+        writeTypeInfo(s, java_type, ForceValueType);
+        s << "&" << java_name << "_tmp = (*(";
+        writeTypeInfo(s, java_type, ForceValueType);
+        s << "*)" <<  java_name << ");" << endl
+          << INDENT << java_name << "_tmp = " << qt_name << ";" << endl;
 
     } else if (type->type() == ContainerTypeEntry::PairContainer) {
         QList<AbstractMetaType *> args = java_type->instantiations();
@@ -3378,9 +3416,7 @@
     const ContainerTypeEntry *type =
         static_cast<const ContainerTypeEntry *>(java_type->typeEntry());
 
-    if (type->type() == ContainerTypeEntry::ListContainer
-        || type->type() == ContainerTypeEntry::VectorContainer
-        || type->type() == ContainerTypeEntry::StringListContainer
+    if (type->type() == ContainerTypeEntry::VectorContainer
         || type->type() == ContainerTypeEntry::LinkedListContainer
         || type->type() == ContainerTypeEntry::StackContainer
         || type->type() == ContainerTypeEntry::SetContainer
@@ -3394,23 +3430,17 @@
         writeTypeInfo(s, java_type, ForceValueType);
         s << qt_name << ";" << endl;
 
-// qtd       s << INDENT << "if (" << java_name << " != 0) {" << endl;
         {
-/* qtd           Indentation indent(INDENT);
-            s << INDENT << "jobjectArray __qt__array = qtjambi_collection_toArray(__jni_env, "
-              << java_name << ");" << endl
-              << INDENT << "jsize __qt__size = __jni_env->GetArrayLength(__qt__array);" << endl;
-*/
             if (type->type() == ContainerTypeEntry::VectorContainer
                 || type->type() == ContainerTypeEntry::StackContainer)
-                s << INDENT << qt_name << ".reserve(" << java_name << "_size);" << endl;
-
-            s << INDENT << "for (int i=0; i<" << java_name << "_size; ++i) {" << endl;
+                s << INDENT << qt_name << ".reserve(" << java_name << "->length);" << endl;
+
+            s << INDENT << "for (int i=0; i<" << java_name << "->length; ++i) {" << endl;
             {
                 Indentation indent(INDENT);
                 if(targ->isTargetLangString())
                     s << INDENT << "DArray __d_element;" << endl
-                      << INDENT << "qtd_get_string_from_array(" << java_name << ", i, &__d_element);" << endl;
+                      << INDENT << "qtd_get_string_from_array(" << java_name << "->ptr, i, &__d_element);" << endl;
                 else {
                     s << INDENT;
                     writeTypeInfo(s, targ, Option(VirtualDispatch | ForcePointer | EnumAsInts));
@@ -3421,8 +3451,6 @@
                     s << "__d_element;" << endl
                       << INDENT << "qtd_get_" << elem_type << "_from_array(" << java_name << ", i, &__d_element);" << endl;
                 }
-/* qtd                   s << INDENT << "jobject __d_element = "
-                      << "__jni_env->GetObjectArrayElement(__qt__array, i);" << endl;*/
                 writeJavaToQt(s, targ, "__qt_element", "__d_element", 0, -1, BoxedPrimitive);
                 QString cont_element = "__qt_element";
                 if(targ->typeEntry()->isStructInD() && targ->name() != "QModelIndex")
@@ -3432,6 +3460,11 @@
 // qtd            s << INDENT << "}" << endl;
         }
         s << INDENT << "}" << endl;
+    } else if (type->isQList()) {
+        writeTypeInfo(s, java_type, ForceValueType);
+        s << qt_name << " = (*(";
+        writeTypeInfo(s, java_type, ForceValueType);
+        s << "*)" <<  java_name << ");" << endl;
     } else if (type->type() == ContainerTypeEntry::PairContainer) {
         QList<AbstractMetaType *> targs = java_type->instantiations();
         Q_ASSERT(targs.size() == 2);
@@ -3597,7 +3630,10 @@
 
         if ( (options & VirtualDispatch)
              && a_type->isContainer()) {
-            s << "__d_" << argument->indexedName();
+            if ( ((const ContainerTypeEntry *)a_type->typeEntry())->isQList() )
+                s << "(void*)&" <<  argument->indexedName();
+            else
+                s << "__d_" << argument->indexedName();
             continue;
         }
 
--- a/generator/dgenerator.cpp	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/dgenerator.cpp	Sun Dec 06 17:26:37 2009 +0000
@@ -176,9 +176,10 @@
 
             if ((option & SkipTemplateParameters) == 0) {
                 QList<AbstractMetaType *> args = d_type->instantiations();
-
+                const ContainerTypeEntry *cte =
+                        static_cast<const ContainerTypeEntry *>(d_type->typeEntry());
                 if (args.size() == 1) { // QVector or QList
-                    if(d_type->typeEntry()->name() == "QList")
+                    if(cte->isQList())
                         s = "QList!(" + translateType(args.at(0), context, BoxedPrimitive) + ")";
                     else
                         s = translateType(args.at(0), context, BoxedPrimitive) + "[]";
@@ -593,7 +594,10 @@
         if (!d_function->argumentRemoved(i+1)) {
             TypeSystem::Ownership owner = d_function->ownership(d_function->implementingClass(), TypeSystem::TargetLangCode, i+1);
             if (owner != TypeSystem::InvalidOwnership) {
-                s << INDENT << "if (" << arg->argumentName() << " !is null) {" << endl;
+                QString empty_condition = " !is null";
+                if (arg->type()->isContainer())
+                    empty_condition = ".length != 0";
+                s << INDENT << "if (" << arg->argumentName() << empty_condition << ") {" << endl;
                 {
                     Indentation indent(INDENT);
                     if (arg->type()->isContainer())
@@ -649,7 +653,7 @@
                                                          i == 0 ? -1 : i);
 
         foreach (ReferenceCount refCount, referenceCounts)
-            writeReferenceCount(s, refCount, i == 0 ? "this" : arguments.at(i-1)->argumentName());
+            writeReferenceCount(s, refCount, i == 0 ? "this" : arguments.at(i-1)->argumentName(), arguments.at(i-1)->type());
     }
 
     referenceCounts = d_function->referenceCounts(d_function->implementingClass(), 0);
@@ -684,7 +688,9 @@
 
         if(return_type->isContainer())
         {
-            if(d_function->type()->typeEntry()->name() == "QList")
+            const ContainerTypeEntry *type =
+                    static_cast<const ContainerTypeEntry *>(return_type->typeEntry());
+            if(type->isQList()) // QList is a native type now
                 s << INDENT << "auto res = " << this->translateType(d_function->type(), d_function->ownerClass(), NoOption) << ".opCall();" << endl;
             else
                 s << INDENT << this->translateType(d_function->type(), d_function->ownerClass(), NoOption) << " res;" << endl;
@@ -821,7 +827,7 @@
                 const ContainerTypeEntry *cte =
                         static_cast<const ContainerTypeEntry *>(te);
                 if(isLinearContainer(cte))
-                    s << QString("%1.ptr, %1.length").arg(arg_name);
+                    s << QString("&%1").arg(arg_name);
             } else if (type->typeEntry()->qualifiedCppName() == "QChar") {
                 s << arg_name;
             } else if (type->isTargetLangString() || (te && te->qualifiedCppName() == "QString")) {
@@ -925,7 +931,7 @@
         }
 
         foreach (ReferenceCount referenceCount, referenceCounts) {
-            writeReferenceCount(s, referenceCount, "__d_return_value");
+            writeReferenceCount(s, referenceCount, "__d_return_value", return_type);
         }
 
         if (!returnImmediately)
@@ -1015,7 +1021,7 @@
 }
 
 void DGenerator::writeReferenceCount(QTextStream &s, const ReferenceCount &refCount,
-                                        const QString &argumentName)
+                                        const QString &argumentName, AbstractMetaType *argumentType)
 {
     if (refCount.action == ReferenceCount::Ignore)
         return;
@@ -1025,9 +1031,13 @@
         s << INDENT << "auto __rcTmp = " << refCountVariableName << ";" << endl;
         refCountVariableName = "__rcTmp";
     }
+    QString empty_condition = " !is null";
+    if (argumentType && argumentType->isContainer())
+//        if (((const ContainerTypeEntry *)argumentType->typeEntry())->isQList())
+            empty_condition = ".length != 0";
 
     if (refCount.action != ReferenceCount::Set) {
-        s << INDENT << "if (" << argumentName << " !is null";
+        s << INDENT << "if (" << argumentName << empty_condition;
 
         if (!refCount.conditional.isEmpty())
             s << " && " << refCount.conditional;
@@ -1041,12 +1051,15 @@
 
     {
         Indentation indent(INDENT);
+        QString summand = argumentName;
         switch (refCount.action) {
         case ReferenceCount::Add:
             s << INDENT << refCountVariableName << " ~= cast(Object) " << argumentName << ";" << endl;
             break;
         case ReferenceCount::AddAll:
-            s << INDENT << refCountVariableName << " ~= " << argumentName << ";" << endl;
+            if(isNativeContainer(argumentType))
+                summand = argumentName + ".toArray()";
+            s << INDENT << refCountVariableName << " ~= " << summand << ";" << endl;
             break;
         case ReferenceCount::Remove:
             s << INDENT << "remove(" << refCountVariableName
@@ -1947,7 +1960,8 @@
           << "public import qt.core.Qt;" << endl
           << "private import qt.QtdObject;" << endl
           << "private import qt.core.QString;" << endl
-          << "private import qt.qtd.Array;" << endl;
+          << "private import qt.qtd.Array;" << endl
+          << "private import qt.core.QList;" << endl;
         if (d_class->isQObject()) {
             s << "public import qt.Signal;" << endl
               << "public import qt.qtd.MOC;" << endl
@@ -2271,16 +2285,14 @@
     s << INDENT << "public alias void __isQtType_" << d_class->name() << ";" << endl << endl;
 
     // construction of a native copy of a Value
-    if (d_class->typeEntry()->isValue() && d_class->hasCloneOperator())
+    if (d_class->typeEntry()->isValue())
     {
-        AbstractMetaFunction *copyCtor = d_class->copyConstructor();
-        if(copyCtor)
             s << INDENT << "static void* __constructNativeCopy(const void* orig) {" << endl
-              << INDENT << "    return " << copyCtor->marshalledName() << "(cast(void*)orig);" << endl
+              << INDENT << "    return qtd_" << d_class->name() << "_native_copy(orig);" << endl
               << INDENT << "}" << endl << endl
 
-              << INDENT << "static void* __constructPlacedNativeCopy(const void* orig, void* place) {" << endl
-              << INDENT << "    return qtd_" << d_class->name() << "_placed_copy(orig, place);" << endl
+              << INDENT << "static void __constructPlacedNativeCopy(const void* orig, void* place) {" << endl
+              << INDENT << "    qtd_" << d_class->name() << "_placed_copy(orig, place);" << endl
               << INDENT << "}" << endl << endl;
     }
 
@@ -2456,11 +2468,12 @@
         s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl;
     }
 
-    if (d_class->typeEntry()->isValue() && d_class->hasCloneOperator())
+    if (d_class->typeEntry()->isValue())
     {
-        AbstractMetaFunction *copyCtor = d_class->copyConstructor();
-        if(copyCtor)
-            s << "private extern(C) void* qtd_" << d_class->name() << "_placed_copy(const void* orig, void* place);" << endl << endl;
+        {
+            s << "private extern(C) void qtd_" << d_class->name() << "_placed_copy(const void* orig, void* place);" << endl
+              << "private extern(C) void* qtd_" << d_class->name() << "_native_copy(const void* orig);" << endl;
+        }
     }
 
 //    if (d_class->needsConversionFunc)
@@ -2966,7 +2979,13 @@
             AbstractMetaType *type = argument->type();
             // if has QString argument we have to pass char* and str.length to QString constructor
             {
-                if(type->isEnum())
+                if (type->isContainer())
+                {
+                    if ( ((const ContainerTypeEntry *)type->typeEntry())->isQList() ) {
+                        s << INDENT;
+                        s << "auto " << arg_name << "_d_ref = cast(" << translateType(type, implementor) << "*)" << arg_name << ";" << endl;
+                    }
+                } else if(type->isEnum())
                     s << INDENT << "auto " << arg_name << "_enum = cast("
                                 << type->typeEntry()->qualifiedTargetLangName() << ") " << arg_name << ";";
                 else if (type->typeEntry()->qualifiedCppName() == "QChar")
@@ -3044,11 +3063,14 @@
 
             if (modified_type == "string" /* && type->fullName() == "char" */)
                 s << "fromStringz(" << arg_name << ")";
-            else {
+            else
+            {
                 if(type->isContainer()
                    || (type->isReference() && type->typeEntry()->isStructInD()))
                     s << "*";
                 s << arg_name;
+                if (type->isContainer() && ((const ContainerTypeEntry *)type->typeEntry())->isQList() )
+                    s << "_d_ref";
             }
             if (type->typeEntry()->isStructInD()) ;
             else if (type->isQObject() || type->isObject()
@@ -3084,10 +3106,13 @@
                 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl;
             } else if (f_type->isTargetLangString())
                 s << INDENT << "*ret_str = _d_str;" << endl;
-            else if (f_type->isContainer())
-                s << INDENT << "*__d_arr_ptr = return_value.ptr;" << endl
-                  << INDENT << "*__d_arr_size = return_value.length;" << endl;
-            else if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
+            else if (f_type->isContainer()) {
+                if (isNativeContainer(f_type))
+                    s << INDENT << "*__d_arr = return_value;" << endl;
+                else
+                    s << INDENT << "*__d_arr_ptr = return_value.ptr;" << endl
+                      << INDENT << "*__d_arr_size = return_value.length;" << endl;
+            } else if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
                 ;
             else
                 s << INDENT << "return return_value;" << endl;
--- a/generator/dgenerator.h	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/dgenerator.h	Sun Dec 06 17:26:37 2009 +0000
@@ -98,7 +98,7 @@
                                     const QString &arg_name);
     void writePrivateNativeFunction(QTextStream &s, const AbstractMetaFunction *d_function);
     void writeJavaLangObjectOverrideFunctions(QTextStream &s, const AbstractMetaClass *cls);
-    void writeReferenceCount(QTextStream &s, const ReferenceCount &refCount, const QString &argumentName);
+    void writeReferenceCount(QTextStream &s, const ReferenceCount &refCount, const QString &argumentName, AbstractMetaType *argumentType = 0);
     void retrieveModifications(const AbstractMetaFunction *f, const AbstractMetaClass *d_class,
          uint *exclude_attributes, uint *include_attributes) const;
     QString functionSignature(const AbstractMetaFunction *d_function,
--- a/generator/typesystem.h	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/typesystem.h	Sun Dec 06 17:26:37 2009 +0000
@@ -950,6 +950,8 @@
     QString javaPackage() const;
     QString qualifiedCppName() const;
 
+    bool isQList() const { return type() == ListContainer || type() == StringListContainer; }
+
 private:
     Type m_type;
 };
--- a/generator/typesystem_gui-java.java	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/typesystem_gui-java.java	Sun Dec 06 17:26:37 2009 +0000
@@ -1694,15 +1694,13 @@
     
     static if (QT_VERSION >= QT_VERSION_CHECK(4, 5, 0))
     {
-	public static int getInt(QWidget _parent, string title, string label, int value = 0, int minValue = -2147483647, int maxValue = 2147483647, int step = 1, ref bool ok = false, int flags = 0) {
+        public static int getInt(QWidget _parent, string title, string label, int value = 0, int minValue = -2147483647, int maxValue = 2147483647, int step = 1, ref bool ok = false, int flags = 0) {
             return qtd_QInputDialog_getInt_private_QWidget_string_string_int_int_int_int_nativepointerbool_WindowFlags(_parent is null ? null : _parent.__nativeId, title, label, value, minValue, maxValue, step, &ok, flags);
-	}
+    }
     }
 
-    public static string getItem(QWidget _parent, string title, string label, string[] items, int current = 0, bool editable = true, ref bool ok = false, int flags = 0) {
-        string res;
-        qtd_QInputDialog_getItem_private_QWidget_string_string_List_int_bool_nativepointerbool_WindowFlags(&res, _parent is null ? null : _parent.__nativeId, title, label, items.ptr, items.length, current, editable, &ok, flags);
-        return res;
+    public static string getItem(QWidget _parent, string title, string label, QList!(string) items, int current = 0, bool editable = true, ref bool ok = false, int flags = 0) {
+        return getItem_private(_parent, title, label, items, current, editable, &ok, flags);
     }
 
     public static string getText(QWidget _parent, string title, string label, QLineEdit_EchoMode echo = QLineEdit_EchoMode.Normal, string text = null, ref bool ok = false, int flags = 0) {
--- a/generator/typesystem_gui.xml	Sun Nov 22 22:18:06 2009 +0000
+++ b/generator/typesystem_gui.xml	Sun Dec 06 17:26:37 2009 +0000
@@ -1298,7 +1298,7 @@
     </modify-function>
     <modify-function signature="operator QVariant()const" access="private"/>
     <inject-code class="java">
-        public final QVariant toVariant() {
+        public final QVariant toVariant() const {
             return operator_cast_QVariant();
         }
     </inject-code>
--- a/include/qtd_core.h	Sun Nov 22 22:18:06 2009 +0000
+++ b/include/qtd_core.h	Sun Dec 06 17:26:37 2009 +0000
@@ -81,6 +81,9 @@
 extern "C" QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia);
 extern "C" QModelIndexAccessor qtd_from_QModelIndex(const QModelIndex &index);
 
-
-
+template <class T>
+void call_destructor(T *a)
+{
+    a->~T();
+}
 #endif // QTD_CORE_H
--- a/qt/QGlobal.d	Sun Nov 22 22:18:06 2009 +0000
+++ b/qt/QGlobal.d	Sun Dec 06 17:26:37 2009 +0000
@@ -740,5 +740,7 @@
 }
 +/
 
+alias void DArray;
+
 mixin QT_END_HEADER;
 
--- a/qt/core/QList.d	Sun Nov 22 22:18:06 2009 +0000
+++ b/qt/core/QList.d	Sun Dec 06 17:26:37 2009 +0000
@@ -315,6 +315,7 @@
 }
 
 import std.stdio;
+import std.conv;
 
 alias void Dummy; // DMD bug #3538 
 
@@ -323,8 +324,8 @@
     static if (is(Default == Dummy))
         alias QTypeInfo!T TI;
     else
-        alias Default TI; 
-  
+        alias Default TI;
+
     struct Node
     {
         void *v;
@@ -456,7 +457,7 @@
     }
     else
     {
-        ref const (T) at(int i) const
+        const (T) at(int i) const
         {
             assert(i >= 0 && i < p.size(), "QList!T.at(): index out of range");
             return (cast(Node*)(p.at(i))).t();
@@ -528,6 +529,20 @@
                 q_new_at(from++, *cast(T*)(src++));
     }
     
+    T[] toArray()
+    {
+        T[] res;
+        res.length = this.length;
+        for(int i = 0; i < res.length; ++i)
+        {
+            static if (isValueType!T)
+                res[i] = new T(T.__constructNativeCopy(this.at(i).__nativeId)); // Node should probably provide a ptr method to directly extract pointer to the native value stored in the list to avoid creating a dummy D object in t()
+            else
+                res[i] = this.opIndex(i);
+        }
+        return res;
+    }
+    
     void free(QListData.Data* data)
     {
         writeln("QList data destroyed");
--- a/qt/core/QTypeInfo.d	Sun Nov 22 22:18:06 2009 +0000
+++ b/qt/core/QTypeInfo.d	Sun Dec 06 17:26:37 2009 +0000
@@ -15,17 +15,11 @@
 
 template isBasicType(T)
 {
-    enum isBasicType = isNumeric!T || is(T == bool);
+    enum isBasicType = isNumeric!T || is(T == bool) || is(T == enum);
 }
 
 template QTypeInfo(T)
 {
-    static if(T.stringof == "QModelIndex")
-    {
-        pragma(msg, T.stringof ~ " has QTypeInfo");
-        pragma(msg, T.QTypeInfo.stringof);
-    }
-    
     static if(is(T == string))
     {
         alias QString.QTypeInfo QTypeInfo;
@@ -43,7 +37,6 @@
     }
     else static if(is(T.QTypeInfo))
     {
-        pragma(msg, T.stringof ~ " has struct");
         alias T.QTypeInfo QTypeInfo; // alias member QTypeInfo
     }
     else static if ( isQObjectType!T || isObjectType!T )
--- a/qt/d2/qt/core/QVariant.d	Sun Nov 22 22:18:06 2009 +0000
+++ b/qt/d2/qt/core/QVariant.d	Sun Dec 06 17:26:37 2009 +0000
@@ -633,13 +633,22 @@
     static void* __constructPlacedNativeCopy(const void* orig, void* place) {
         return qtd_QVariant_placed_copy(orig, place);
     }
+    
+    public static void __deleteNativeObject(void* ptr) {
+        qtd_QVariant_destructor(ptr);
+    }
+    
+    public static void __callNativeDestructor(void* ptr) {
+        qtd_QVariant_call_destructor(ptr);
+    }
 // Injected code in class
 }
+
 extern (C) void qtd_QVariant_destructor(void *ptr);
+extern (C) void qtd_QVariant_call_destructor(void *ptr);
 
 private extern(C) void* qtd_QVariant_placed_copy(const void* orig, void* place);
 
-extern (C) void qtd_QVariant_call_destructor(void *ptr);
 
 // C wrappers
 private extern(C) void* qtd_QVariant_QVariant();