# HG changeset patch # User maxter # Date 1253109362 0 # Node ID 17b5e13364b72a0358f0d70397efe9feb774176d # Parent b1abe7f5732164ee99549269739edc16cef6171a diff -r b1abe7f57321 -r 17b5e13364b7 build/core.txt --- a/build/core.txt Mon Aug 31 12:07:28 2009 +0000 +++ b/build/core.txt Wed Sep 16 13:56:02 2009 +0000 @@ -50,6 +50,8 @@ QUrl QAbstractItemModel QAbstractFileEngine + QAbstractFileEngineIterator + QFSFileEngine QFile QDir QFileInfo diff -r b1abe7f57321 -r 17b5e13364b7 cmake/FindD.cmake --- a/cmake/FindD.cmake Mon Aug 31 12:07:28 2009 +0000 +++ b/cmake/FindD.cmake Wed Sep 16 13:56:02 2009 +0000 @@ -70,9 +70,9 @@ endif(NOT ONE_BUILD_COMMAND) ## Specific flags for build configurations. -## TODO: Add another targets. +## TODO: Add other targets. set(D_RELEASE_FLAGS -O -release) -set(D_DEBUG_FLAGS -g ) +set(D_DEBUG_FLAGS -g -debug=QtdVerbose) if(D_IS_LLVM) set(D_RELEASE_FLAGS ${D_RELEASE_FLAGS} -enable-inlining) set(D_DEBUG_FLAGS ${D_DEBUG_FLAGS} -d-debug) diff -r b1abe7f57321 -r 17b5e13364b7 cpp/qt_core/QVariant_shell.h --- a/cpp/qt_core/QVariant_shell.h Mon Aug 31 12:07:28 2009 +0000 +++ b/cpp/qt_core/QVariant_shell.h Wed Sep 16 13:56:02 2009 +0000 @@ -2,7 +2,7 @@ #define QVARIANT_SHELL_H #include -#include +#include #include #include diff -r b1abe7f57321 -r 17b5e13364b7 cpp/qt_qtd/qtd_core.cpp --- a/cpp/qt_qtd/qtd_core.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/cpp/qt_qtd/qtd_core.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -11,11 +11,16 @@ #include "qtd_core.h" #include - +#include -extern "C" DLL_PUBLIC void* qtd_qobject(void* parent) +extern "C" DLL_PUBLIC void* qtd_test_Object() { - return new QObject((QObject*)parent); + return new QCryptographicHash(QCryptographicHash::Md5); +} + +extern "C" DLL_PUBLIC void qtd_test_delete_Object(void* obj) +{ + delete (QCryptographicHash*)obj; } extern "C" DLL_PUBLIC QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia) @@ -48,10 +53,13 @@ #ifdef CPP_SHARED QTD_EXPORT_VAR(qtd_toUtf8); QTD_EXPORT_VAR(qtd_dummy); +QTD_EXPORT_VAR(qtd_delete_d_object); -extern "C" DLL_PUBLIC void qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr dummy) { +extern "C" DLL_PUBLIC void qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr dummy + , pfunc_abstr del_d_obj) { QTD_EXPORT_VAR_SET(qtd_toUtf8, d_func); QTD_EXPORT_VAR_SET(qtd_dummy, dummy); + QTD_EXPORT_VAR_SET(qtd_delete_d_object, del_d_obj); //std::cout << "qtd_core initialized" << std::endl; } #endif @@ -73,3 +81,31 @@ { return qUnregisterResourceData(version, tree, name, data); } + + +QtD_QObjectEntity::QtD_QObjectEntity(QObject *qObject, void *dId) : QtD_Entity(dId) +{ + qObject->setUserData(userDataId, this); +} + +QtD_QObjectEntity::~QtD_QObjectEntity() +{ + if (dId) + destroyEntity(); +} + +void QtD_QObjectEntity::destroyEntity(QObject *qObject) +{ + Q_ASSERT(dId); + qtd_delete_d_object(dId); + if (qObject) + { + qObject->setUserData(userDataId, NULL); + dId = NULL; + } +} + +QtD_QObjectEntity* QtD_QObjectEntity::getQObjectEntity(const QObject *qObject) +{ + return static_cast(qObject->userData(userDataId)); +} diff -r b1abe7f57321 -r 17b5e13364b7 generator/CMakeLists.txt --- a/generator/CMakeLists.txt Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/CMakeLists.txt Wed Sep 16 13:56:02 2009 +0000 @@ -251,7 +251,7 @@ --source-directory=${CMAKE_SOURCE_DIR}/generator qtjambi_masterinclude.h ${CMAKE_BINARY_DIR}/CMakeFiles/build.txt - COMMENT "Generating binding..." + COMMENT "Generating binding... ${inc_paths} ${GEN_OPT}" DEPENDS ${gen_sources} ${CMAKE_BINARY_DIR}/CMakeFiles/build.txt ) add_custom_target(dgen ALL DEPENDS ${dgen_impl} COMMENT "") diff -r b1abe7f57321 -r 17b5e13364b7 generator/abstractmetabuilder.cpp --- a/generator/abstractmetabuilder.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/abstractmetabuilder.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -1310,10 +1310,8 @@ meta_class->setHasNonPrivateConstructor(true); } - // Classes with virtual destructors should always have a shell class - // (since we aren't registering the destructors, we need this extra check) - if (meta_function->isDestructor() && !meta_function->isFinal()) - meta_class->setForceShellClass(true); + if (meta_function->isDestructor() && !meta_function->isFinal()) + meta_class->setHasVirtualDestructor(true); if (!meta_function->isDestructor() && !meta_function->isInvalid() @@ -1563,8 +1561,8 @@ TypeInfo function_type = function_item->type(); if (function_name.startsWith('~')) { - meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction); - meta_function->setInvalid(true); + meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction); + //meta_function->setInvalid(true); } else if (strip_template_args(function_name) == stripped_class_name) { meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction); meta_function->setName(m_current_class->name()); diff -r b1abe7f57321 -r 17b5e13364b7 generator/abstractmetalang.cpp --- a/generator/abstractmetalang.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/abstractmetalang.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -42,6 +42,7 @@ #include "abstractmetalang.h" #include "reporthandler.h" #include "jumptable.h" +#include /******************************************************************************* * AbstractMetaType @@ -1110,7 +1111,8 @@ m_functions << function; qSort(m_functions.begin(), m_functions.end(), function_sorter); } - + else + qFatal("blah"); m_has_virtual_slots |= function->isVirtualSlot(); m_has_virtuals |= !function->isFinal() || function->isVirtualSlot(); @@ -1160,11 +1162,12 @@ bool AbstractMetaClass::generateShellClass() const { return m_force_shell_class || - (!isFinal() - && (hasVirtualFunctions() - || hasProtectedFunctions() - || hasFieldAccessors() - || typeEntry()->isObject())); // qtd2 for being more consistent + m_has_virtual_destructor || + (!isFinal() + && (hasVirtualFunctions() + || hasProtectedFunctions() + || hasFieldAccessors() + || typeEntry()->isObject())); // qtd2 for being more consistent } QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const @@ -1323,6 +1326,11 @@ return queryFunctions(Constructors).size() != 0; } +bool AbstractMetaClass::isPolymorphic() +{ + return typeEntry()->isObject() && m_has_virtual_destructor; +} + void AbstractMetaClass::addDefaultConstructor() { AbstractMetaFunction *f = new AbstractMetaFunction; @@ -1339,7 +1347,7 @@ f->setImplementingClass(this); f->setOriginalAttributes(f->attributes()); - addFunction(f); + /*addFunction*/(f); } bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const diff -r b1abe7f57321 -r 17b5e13364b7 generator/abstractmetalang.h --- a/generator/abstractmetalang.h Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/abstractmetalang.h Wed Sep 16 13:56:02 2009 +0000 @@ -685,6 +685,7 @@ m_functions_fixed(false), m_has_public_destructor(true), m_force_shell_class(false), + m_has_virtual_destructor(false), m_has_hash_function(false), m_has_equals_operator(false), m_has_clone_operator(false), @@ -755,9 +756,17 @@ QString baseClassName() const { return m_base_class ? m_base_class->name() : QString(); } - AbstractMetaClass *baseClass() const { return m_base_class; } + AbstractMetaClass *baseClass() const { return m_base_class;} void setBaseClass(AbstractMetaClass *base_class) { m_base_class = base_class; } + const AbstractMetaClass *rootClass() const + { + const AbstractMetaClass *root = this; + while (root->baseClass()) + root = root->baseClass(); + return root; + } + const AbstractMetaClass *enclosingClass() const { return m_enclosing_class; } void setEnclosingClass(AbstractMetaClass *cl) { m_enclosing_class = cl; } @@ -775,8 +784,10 @@ void setForceShellClass(bool on) { m_force_shell_class = on; } bool generateShellClass() const; - bool hasVirtualSlots() const { return m_has_virtual_slots; } + bool hasVirtualSlots() const { return m_has_virtual_slots; } bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals; } + bool hasVirtualDestructor() const { return m_has_virtual_destructor; } + bool setHasVirtualDestructor(bool value) { m_has_virtual_destructor = value; } bool hasProtectedFunctions() const; QList templateArguments() const { return m_template_args; } @@ -843,6 +854,8 @@ void setTypeAlias(bool typeAlias) { m_is_type_alias = typeAlias; } bool isTypeAlias() const { return m_is_type_alias; } + + bool isPolymorphic(); const QStringList &depends() { return m_type_entry->depends(); } @@ -857,6 +870,7 @@ uint m_functions_fixed : 1; uint m_has_public_destructor : 1; uint m_force_shell_class : 1; + uint m_has_virtual_destructor : 1; uint m_has_hash_function : 1; uint m_has_equals_operator : 1; uint m_has_clone_operator :1; diff -r b1abe7f57321 -r 17b5e13364b7 generator/cppgenerator.cpp --- a/generator/cppgenerator.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/cppgenerator.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -230,7 +230,7 @@ s << "("; const AbstractMetaClass *owner = java_function->ownerClass(); - bool has_d_ptr = java_function->isConstructor() && owner && (owner->hasVirtualFunctions()/* || owner->typeEntry()->isObject()*/ ); + bool has_d_ptr = java_function->isConstructor() && owner && owner->typeEntry()->isObject(); const AbstractMetaArgumentList arg_list = java_function->arguments(); if (has_d_ptr) { s << "void *d_ptr"; diff -r b1abe7f57321 -r 17b5e13364b7 generator/cppheadergenerator.cpp --- a/generator/cppheadergenerator.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/cppheadergenerator.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -126,7 +126,7 @@ << "#define " << include_block << endl << endl // << "#include " << endl << "#include " << endl - << "#include " << endl; + << "#include " << endl; Include inc = java_class->typeEntry()->include(); s << "#include "; @@ -180,7 +180,7 @@ << " : public " << java_class->qualifiedCppName(); if (java_class->isQObject()) s << ", public QtD_QObjectEntity"; - else if(java_class->hasVirtualFunctions()) + else if (java_class->hasVirtualFunctions()) s << ", public QtD_Entity"; s << endl << "{" << endl; @@ -207,9 +207,10 @@ if (function->isConstructor() && !function->isPrivate()) writeFunction(s, function); } - - s << " ~" << shellClassName(java_class) << "();" << endl; - s << endl; + + if (java_class->hasVirtualFunctions()) + s << " ~" << shellClassName(java_class) << "();" << endl << endl; + // All functions in original class that should be reimplemented in shell class AbstractMetaFunctionList shell_functions = java_class->functionsInShellClass(); diff -r b1abe7f57321 -r 17b5e13364b7 generator/cppimplgenerator.cpp --- a/generator/cppimplgenerator.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/cppimplgenerator.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -541,18 +541,17 @@ #endif */ if (shellInclude) - s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl; + { + s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl + << "#include " << endl; + } + /* qtd if (java_class->isQObject()) s << "#include " << endl; */ - if (java_class->isQObject()) - s << "#include " << endl; - s << "#include " << endl; - - Include inc = java_class->typeEntry()->include(); if (!inc.name.isEmpty()) { s << "#include "; @@ -589,24 +588,27 @@ writeDefaultConstructedValues(s, java_class); if (hasCustomDestructor(java_class)) */ - if (!java_class->isQObject()) - writeFinalDestructor(s, java_class); + + if (java_class->hasPublicDestructor() && (!java_class->baseClass() || !java_class->hasVirtualFunctions())) + writeDestructor(s, java_class); if (java_class->isQObject()) writeSignalsHandling(s, java_class); if (shellClass) { foreach (AbstractMetaFunction *function, java_class->functions()) { - if (function->isConstructor() && !function->isPrivate()) + if (function->isConstructor()) writeShellConstructor(s, function); } - writeShellDestructor(s, java_class); - - if (!java_class->isQObject() && java_class->hasVirtualFunctions()) - writeQtdEntityFunction(s, java_class); + + if (java_class->typeEntry()->isObject()) + writeShellDestructor(s, java_class); if (java_class->isQObject()) writeQObjectFunctions(s, java_class); + else if (java_class->typeEntry()->isObject()) + writeObjectFunctions(s, java_class); + // Virtual overrides s << "// Virtual overrides" << endl; @@ -1386,9 +1388,10 @@ s << ", "; } s << ")"; + if (cls->isQObject()) s << "," << endl << " QtD_QObjectEntity(this, d_ptr)"; - else if (cls->hasVirtualFunctions()) + else if (cls->typeEntry()->isObject() && cls->hasVirtualFunctions()) s << "," << endl << " QtD_Entity(d_ptr)"; /* qtd s << " m_meta_object(0)," << endl; s << " m_vtable(0)," << endl @@ -1402,7 +1405,7 @@ writeCodeInjections(s, java_function, cls, CodeSnip::Beginning, TypeSystem::ShellCode); writeCodeInjections(s, java_function, cls, CodeSnip::End, TypeSystem::ShellCode); } - s << "}" << endl << endl; + s << "}" << endl << endl; } void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class) @@ -1411,9 +1414,11 @@ << shellClassName(java_class) << "()" << endl << "{" << endl; { - //s << " std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;"; + s << " std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;"; if (java_class->isQObject()) - s << " destroyEntity(this);"; + s << " destroyEntity(this);" << endl; + else + s << " qtd_delete_d_object(dId);" << endl; } s << "}" << endl << endl; } @@ -1729,19 +1734,43 @@ s << "}" << endl << endl; } -void CppImplGenerator::writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class) +void CppImplGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class) { - s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl; + s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_staticTypeId()" << endl; s << "{" << endl; { Indentation indent(INDENT); - s << INDENT << "QtD_Entity* a = dynamic_cast((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl - << INDENT << "if (a != NULL)" << endl - << INDENT << " return a->dId;" << endl - << INDENT << "else" << endl - << INDENT << " return NULL;" << endl; + s << INDENT << "return &typeid(" << java_class->qualifiedCppName() << ");" << endl; } s << "}" << endl << endl; + + if (java_class->hasVirtualFunctions()) + { + if (!java_class->baseClass()) + { + s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *q_ptr)" << endl; + s << "{" << endl; + { + Indentation indent(INDENT); + s << INDENT << "QtD_Entity* a = dynamic_cast((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl + << INDENT << "if (a != NULL)" << endl + << INDENT << " return a->dId;" << endl + << INDENT << "else" << endl + << INDENT << " return NULL;" << endl; + } + s << "}" << endl << endl; + + s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl; + s << "{" << endl; + { + Indentation indent(INDENT); + s << INDENT << "return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl; + } + s << "}" << endl << endl; + } + else + s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->rootClass()->name() << "_dId(void *q_ptr);" << endl; + } } void CppImplGenerator::writeVirtualFunctionOverride(QTextStream &s, @@ -1863,9 +1892,9 @@ */ uint nativeArgCount = 0; const AbstractMetaClass *cls = java_function->ownerClass(); + if (java_function->isConstructor() && - ( cls->hasVirtualFunctions() - || cls->typeEntry()->isObject() ) ) + cls->typeEntry()->isObject()) { s << "void *d_ptr"; nativeArgCount++; @@ -2057,7 +2086,8 @@ foreach (const AbstractMetaArgument *argument, arguments) { s << INDENT << "Q_UNUSED(" << argument->indexedName() << ")" << endl; } - s << INDENT << default_return_statement_qt(java_function->type()) << ""; + s << INDENT << default_return_statement_qt(java_function->type()) << ""; + } else { writeFinalFunctionSetup(s, java_function, qt_object_name, cls); @@ -2085,7 +2115,7 @@ if (java_class->isQObject()) s << "QtD_QObjectEntity::getQObjectEntity((QObject*)__this_nativeId) : false;" << endl; else - s << "__" << java_class->name() << "_entity(__this_nativeId) : false;" << endl; + s << "qtd_" << java_class->rootClass()->name() << "_dId(__this_nativeId) : false;" << endl; } else { option = OriginalName; } @@ -2288,17 +2318,19 @@ } } -void CppImplGenerator::writeFinalDestructor(QTextStream &s, const AbstractMetaClass *cls) -{ - if (cls->hasConstructors()) { - s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl - << INDENT << "{" << endl; - { - s << INDENT << "delete (" << shellClassName(cls) << " *)ptr;" << endl; - } - - s << INDENT << "}" << endl << endl; +void CppImplGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *cls) +{ + if (!cls->hasConstructors()) + return; + + s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl + << INDENT << "{" << endl; + { + QString className = cls->hasVirtualFunctions() ? cls->typeEntry()->name() : shellClassName(cls); + s << INDENT << "delete (" << className << " *)ptr;" << endl; } + + s << INDENT << "}" << endl << endl; } void CppImplGenerator::writeFinalConstructor(QTextStream &s, @@ -3051,7 +3083,7 @@ // return_type = fixCppTypeName(java_type->typeEntry()->qualifiedCppName()); } /* if( (java_type->isValue() && !java_type->typeEntry()->isStructInD()) - || java_type->isObject() ) +// || java_type->isObject() ) s << INDENT << return_type << " *" << java_name << " = (" << return_type << "*) "; else*/ s << INDENT << return_type << " " << java_name << " = (" << return_type << ") "; @@ -3510,7 +3542,7 @@ int written_arguments = 0; const AbstractMetaClass *cls = java_function->ownerClass(); - if (java_function->isConstructor() && cls->hasVirtualFunctions()) { + if (java_function->isConstructor() && cls->typeEntry()->isObject()) { s << "d_ptr"; written_arguments++; } diff -r b1abe7f57321 -r 17b5e13364b7 generator/cppimplgenerator.h --- a/generator/cppimplgenerator.h Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/cppimplgenerator.h Wed Sep 16 13:56:02 2009 +0000 @@ -105,11 +105,12 @@ const AbstractMetaFunction *java_function, const AbstractMetaClass *java_class, Option options = NoOption); - void writeFinalDestructor(QTextStream &s, const AbstractMetaClass *cls); + void writeDestructor(QTextStream &s, const AbstractMetaClass *cls); void writeFinalConstructor(QTextStream &s, const AbstractMetaFunction *java_function, const QString &qt_object_name, const QString &java_object_name); + void writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class); void writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class); void writeFunctionCall(QTextStream &s, const QString &variable_name, diff -r b1abe7f57321 -r 17b5e13364b7 generator/dgenerator.cpp --- a/generator/dgenerator.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/dgenerator.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -61,7 +61,7 @@ m_docs_enabled(false), m_native_jump_table(false), m_recursive(0), - m_isRecursive(false) + m_isRecursive(false) { excludedTypes << "long long" << "bool" << "int" << "QString" << "char" << "WId" << "unsigned char" << "uint" << "double" << "short" << "float" @@ -479,9 +479,9 @@ static QString function_call_for_ownership(TypeSystem::Ownership owner) { if (owner == TypeSystem::CppOwnership) { - return "__setFlags(QtdObjectFlags.nativeOwnership, true)"; + return "__nativeOwnership = true"; } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { - return "__setFlags(QtdObjectFlags.nativeOwnership, false)"; + return "__nativeOwnership = false"; }/* else if (owner == TypeSystem::DefaultOwnership) { return "__no_real_delete = false"; @@ -639,6 +639,7 @@ } } + /* QList referenceCounts; for (int i=0; ireferenceCounts(d_function->implementingClass(), @@ -649,6 +650,8 @@ } referenceCounts = d_function->referenceCounts(d_function->implementingClass(), 0); + */ + AbstractMetaType *return_type = d_function->type(); QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.'); bool has_return_type = new_return_type != "void" @@ -880,7 +883,7 @@ s << INDENT << "this." << function_call_for_ownership(owner) << ";" << endl; } - // return value marschalling + // return value marshalling if(return_type) { if (!returnImmediately && !d_function->storeResult()) { s << INDENT; @@ -892,37 +895,36 @@ s << " __d_return_value = "; } - if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd - { - if(return_type->isQObject()) - s << return_type->name() << ".__getObject(ret);" << endl; - } - - if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) + if(return_type->isQObject()) + s << return_type->name() << ".__wrap(ret);" << endl; + + + if (return_type->isValue() && !return_type->typeEntry()->isStructInD() + || return_type->isNativePointer() && return_type->typeEntry()->isValue() + || return_type->name() == "QVariant") s << "new " << return_type->name() << "(ret);" << endl; - - if (return_type->isVariant()) - s << "new QVariant(ret);" << endl; - - if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) - s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl; - + if (return_type->isObject()) { if(d_function->storeResult()) - s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl - << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; + { + QString fieldName = QString("__m_%1;").arg(d_function->name()); + s << INDENT << "if (!" << fieldName << " || " << fieldName << ".__nativeId != ret) {" << endl + << INDENT << " " << fieldName << " = " << return_type->name() << ".__wrap(ret);" << endl + << INDENT << "return " << fieldName << ";" << endl; + } else - s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl; - s << endl; + s << return_type->name() << ".__wrap(ret);" << endl; } if (return_type->isArray()) { s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl; } + /* foreach (ReferenceCount referenceCount, referenceCounts) { writeReferenceCount(s, referenceCount, "__d_return_value"); } + */ if (!returnImmediately && !d_function->storeResult()) s << INDENT << "return __d_return_value;" << endl; @@ -1682,26 +1684,19 @@ if (!d_class->hasConstructors()) return; - bool isTheQObject = d_class->name() == "QObject"; - if (isTheQObject || !d_class->isQObject()) - { - s << INDENT << "protected override void __deleteNative() {" << endl; - { - if (isTheQObject) - s << INDENT << "qtd_delete_qobject(__nativeId);" << endl; - else if (!d_class->isQObject()) - s << INDENT << "qtd_" << d_class->name() << "_destructor(__nativeId);" << endl; - } - s << INDENT << "}" << endl << endl; - } + s << " override void __deleteNative() {" << endl + << " qtd_" << d_class->name() << "_destructor(__nativeId);" << endl + << " }" << endl; } -void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class) +void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class) { if (d_class->isInterface() || d_class->isNamespace()) - s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);"; - else // COMPILER BUG: - s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }"; + s << INDENT << "void __nativeOwnership(bool value);"; + else if (d_class->typeEntry()->isObject()) + {// COMPILER BUG: + s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }"; + } } void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) @@ -1763,7 +1758,7 @@ if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; s << INDENT << "scope " << arg_name << " = new " << type_name - << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl; + << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl; } s << endl; } @@ -1785,7 +1780,7 @@ void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class) { - ReportHandler::debugSparse("Generating class: " + d_class->fullName()); + ReportHandler::debugSparse("Generating class: " + d_class->fullName()); bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; @@ -1795,7 +1790,7 @@ auxFile.isDone = true; auxFile.stream << "module " << auxModName << ";" << endl << endl; - bool staticInit = d_class->isQObject() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); + bool staticInit = (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); if (staticInit) { auxFile.isDone = false; @@ -1901,17 +1896,17 @@ if (!m_isRecursive) { s << "public import qt.QGlobal;" << endl << "public import qt.core.Qt;" << endl - << "private import qt.QtdObject;" << endl + << "public import qt.QtdObject;" << endl << "private import qt.core.QString;" << endl << "private import qt.qtd.Array;" << endl; if (d_class->isQObject()) { - s << "public import qt.Signal;" << endl - << "public import qt.core.QMetaObject;" << endl - << "public import qt.qtd.Traits;" << endl; - + s << "public import qt.Signal;" << endl; if (d_class->name() != "QObject") s << "public import qt.core.QObject;" << endl; } + + if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) + s << "public import qt.core.QMetaObject;" << endl; // qtd2 hack! if (d_class->name() == "QCoreApplication") @@ -2003,12 +1998,15 @@ } if (!d_class->isNamespace() && !d_class->isInterface()) { - if (!d_class->baseClassName().isEmpty()) { - s << " : " << d_class->baseClass()->name(); - } else { - QString sc = type->defaultSuperclass(); - if ((sc != d_class->name()) && !sc.isEmpty()) - s << " : " << sc; + s << " : "; + if (d_class->baseClass()) { + s << d_class->baseClass()->name(); + } else { + if (d_class->typeEntry()->isValue()) + s << "QtdObjectBase"; + else if (d_class->typeEntry()->isObject()) + s << "QtdObject"; + } }/* qtd else if (d_class->isInterface()) { s << " extends QtJambiInterface"; @@ -2194,7 +2192,6 @@ if(d_class->isInterface()) s << endl << INDENT << "public void* __ptr_" << d_class->name() << "();" << endl << endl; - s << "// Field accessors" << endl; // Field accessors AbstractMetaFieldList fields = d_class->fields(); @@ -2203,38 +2200,20 @@ writeFieldAccessors(s, field); } -/* qtd - - // the static fromNativePointer function... - if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { - s << endl - << INDENT << "public static native " << d_class->name() << " fromNativePointer(" - << "QNativePointer nativePointer);" << endl; - } - - if (d_class->isQObject()) { - s << endl; - if (TypeDatabase::instance()->includeEclipseWarnings()) - s << INDENT << "@SuppressWarnings(\"unused\")" << endl; - - s << INDENT << "private static native long originalMetaObject();" << endl; + if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) + { + if (d_class->isQObject()) + writeQObjectFunctions(s, d_class); + else + writeObjectFunctions(s, d_class); + + s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl + << " return new(flags) " << d_class->name() << "(nativeId, flags);" << endl + << " }" << endl << endl; } - - // The __qt_signalInitialization() function - if (signal_funcs.size() > 0) { - s << endl - << INDENT << "@Override" << endl - << INDENT << "@QtBlockedSlot protected boolean __qt_signalInitialization(String name) {" << endl - << INDENT << " return (__qt_signalInitialization(nativeId(), name)" << endl - << INDENT << " || super.__qt_signalInitialization(name));" << endl - << INDENT << "}" << endl - << endl - << INDENT << "@QtBlockedSlot" << endl - << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl; - } -*/ - if (d_class->isQObject()) - writeQObjectFunctions(s, d_class); + + if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions())) + writeDestructor(s, d_class); // Add dummy constructor for use when constructing subclasses if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { @@ -2244,20 +2223,19 @@ Indentation indent(INDENT); - - s << "(void* native_id, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl - << INDENT << "super(native_id, flags);" << endl; - + + + QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none"; + s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl + << INDENT << "super(nativeId, flags);" << endl; + if (d_class->name() == "QObject") { - // To prevent GC from collecting the object, add it to the statically rooted linked list - s << INDENT << " __next = __root;" << endl - << INDENT << " __root = this;" << endl - << INDENT << " if (__next) {" << endl - << INDENT << " __next.__prev = this;" << endl - << INDENT << " }" << endl << endl; + s << INDENT << "if (!(__flags & QtdObjectFlags.hasDId))" << endl + << INDENT << " __createEntity;" << endl; } - + + /* if (cpp_shared) { if (d_class->generateShellClass() && !d_class->isInterface()) @@ -2266,6 +2244,7 @@ } */ + // customized store-result instances d_funcs = d_class->functionsInTargetLang(); for (int i=0; iisAbstract()) type_name = type_name + "_ConcreteWrapper"; - s << INDENT << " __m_" << d_function->name() << " = new " - << type_name << "(cast(void*)null);" << endl; - if (d_function->type()->isQObject()) - s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; + s << INDENT << " __m_" << d_function->name() << ";" << endl; } } @@ -2340,9 +2316,7 @@ s << INDENT << "private void* __m_ptr_" << iface->name() << ";" << endl << INDENT << "public void* __ptr_" << iface->name() << "() { return __m_ptr_" << iface->name() << "; }" << endl << endl; } - } - - writeDestructor(s, d_class); + } } /* qtd @@ -2371,7 +2345,7 @@ /* qtd writeJavaLangObjectOverrideFunctions(s, d_class); */ - writeFlagsSetter(s, d_class); + writeOwnershipSetter(s, d_class); s << "// Injected code in class" << endl; writeExtraFunctions(s, d_class); // qtd2 writeToStringFunction(s, d_class); @@ -2411,9 +2385,8 @@ s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl; { - Indentation indent(INDENT); - QString hasShellFlag = d_class->generateShellClass() ? " | QtdObjectFlags.hasShell" : ""; - s << INDENT << "public this(void* native_id, QtdObjectFlags flags = QtdObjectFlags.nativeOwnership) {" << endl + Indentation indent(INDENT); + s << INDENT << "public this(void* native_id, QtdObjectFlags flags) {" << endl << INDENT << " super(native_id, flags);" << endl << endl; /******************!!!DUPLICATE!!!*********************/ @@ -2432,9 +2405,7 @@ if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; s << INDENT << " __m_" << d_function->name() << " = new " - << type_name << "(cast(void*)null);" << endl; - if (d_function->type()->isQObject()) - s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; + << type_name << "(cast(void*)null);" << endl; } } @@ -2489,18 +2460,22 @@ s << INDENT << "}" << endl << endl; } - if (d_class->generateShellClass()) { // qtd2 - if (d_class->hasVirtualFunctions() - && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) ) - s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; + if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) + { + if (!d_class->typeEntry()->isQObject()) + { + s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl; + s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; + } + + s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl; } - // if (d_class->needsConversionFunc) - writeConversionFunction(s, d_class); - - if (d_class->hasConstructors() && !d_class->isQObject()) - s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; +// writeConversionFunction(s, d_class); + + if (d_class->hasConstructors()) + s << "extern(C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; // qtd s << endl << "// C wrappers" << endl; @@ -2525,7 +2500,7 @@ writePrivateNativeFunction(s, d_function); } } - } + } foreach (const AbstractMetaField *field, fields) { @@ -2558,7 +2533,7 @@ s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; - if (d_class->isQObject()) { + if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) { s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; } @@ -2620,6 +2595,7 @@ } } +/* void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) { const ComplexTypeEntry *ctype = d_class->typeEntry(); @@ -2640,20 +2616,74 @@ // if class has virtual functions then it has classname_entity function so // we can look for D Object pointer. otherwise create new wrapper if (d_class->hasVirtualFunctions()) { - s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(ret);" << endl + s << INDENT << "void* d_obj = qtd_" << ctype->targetLangName() << "_dId(ret);" << endl << INDENT << "if (d_obj !is null) {" << endl << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl << INDENT << "} else {" << endl - << INDENT << " auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl + << INDENT << " auto return_value = new " << type_name << "(ret, QtdObjectFlags.skipNativeDelete);" << endl << INDENT << " return return_value;" << endl << INDENT << "}" << endl; } else { - s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl + s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.skipNativeDelete);" << endl << INDENT << "return return_value;" << endl; } s << "}" << endl << endl; } +*/ + +// Polymorphic non-QObject +void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) +{ + QString rootClassName = d_class->rootClass()->name(); + QString concreteArg; + if (d_class->isAbstract()) + concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; + + s << " private static QtdMetaObject _staticMetaObject;" << endl + //<< " private static QtdMetaObject[void*] _nativeToTargetMap;" << endl + + << " protected static void createStaticMetaObject() {" << endl + << " assert(!_staticMetaObject);" << endl + << " QtdMetaObject base;" << endl; + + if (d_class->baseClass()) + { + QString baseName = d_class->baseClassName(); + s << " if (!" << baseName << "._staticMetaObject)" << endl + << " " << baseName << ".createStaticMetaObject;" << endl + << " base = " << baseName << "._staticMetaObject;" << endl; + } + + s << " _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);" << endl + << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl + << " }" << endl << endl + + << " QtdMetaObject metaObject() {" << endl + << " return _staticMetaObject;" << endl + << " }" << endl << endl + + << " static QtdMetaObject staticMetaObject() {" << endl + << " return _staticMetaObject;" << endl + << " }" << endl << endl + + << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl + << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl + << " if (!obj)" << endl + << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId," + "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl + << " return obj;" << endl + << " }" << endl << endl; + /* + << " overrive protected void __addMapping() {" << endl + << " _nativeToTargetMap[__nativeId] = this;" << endl + << " }" << endl << endl + + << " override protected void __removeMapping() {" << endl + << " _nativeToTargetMap.remove(__nativeId);" << endl + << " }" << endl << endl + */ +} void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) { @@ -2686,12 +2716,12 @@ << " return _staticMetaObject;" << endl << " }" << endl << endl - << " static " << d_class->name() << " __getObject(void* nativeId) {" << endl - << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl + << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl + << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl << " }" << endl << endl - << " static void __createEntity(void* nativeId, void* dId) {" << endl - << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl + << " void __createEntity() {" << endl + << " return qtd_" << d_class->name() << "_createEntity(__nativeId, cast(void*)this);" << endl << " }" << endl << endl; } @@ -2701,23 +2731,62 @@ } */ -void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype) + +// Returns the name of the resulting variable +QString DGenerator::marshalToD(QTextStream &s, QString argName, const TypeEntry* type, MarshalFlags flags) { - if(ctype->isQObject()) { - QString type_name = ctype->name(); - if (ctype->isAbstract()) - type_name += "_ConcreteWrapper"; - s << "return " << type_name << ".__getObject(ret);" << endl; - } else if (ctype->isValue() && !ctype->isStructInD()) { - s << INDENT << "return new " << ctype->name() << "(ret);" << endl; - } else if (ctype->isVariant()) { - s << INDENT << "return new QVariant(ret);" << endl; + if (type->isBasicValue()) + return argName; + + QString qtdObjFlags = "QtdObjectFlags.none"; + const ObjectTypeEntry *ctype = 0; + bool stackObject = false; + + if (type->isObject()) + ctype = static_cast(ctype); + + if (type->isValue()) + flags |= MarshalScope; + + if (flags & MarshalScope) + { + if (type->isObject() && type->hasVirtualDestructor()) + { + qtdObjectFlags += " | QtdObjectFlags.stackAllocated"; + bool stackObject = true; + } + else + s << INDENT << "scope "; + + qtdObjectFlags += "| QtdObjectFlags.skipNativeDelete"; + } + else + s << INDENT << "auto "; + + s << resultName << " = "; + + + if (ctype->isObject() && type->hasVirtualDestructor()) { + exp = type->name() + ".__wrap(ret);" + endl; + } + else if (type->isValue()) + { + if (type->actualIndirections() == 0) + s << "new " << type->name() << "(" << argName << ");" << endl; + else if (type->actualIndirections() == 1) + s << "new " + } + + } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { s << INDENT << "return ret;" << endl; - } else if (ctype->isObject()) { - QString type_name = ctype->name(); - s << "return qtd_" << type_name << "_from_ptr(ret);" << endl; } + + if (stackObject) + { + s << "" + } + } void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) @@ -2850,29 +2919,57 @@ else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") { s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; - } else if(type->isVariant()) - s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; + } else if (type->typeEntry()->isStructInD()) continue; - else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer())) + else if ((type->typeEntry()->isValue() && type->isNativePointer()) + || type->isValue() || type->isVariant()){ + s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ");" << endl; + + (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", " + << implementor->name() << "::" << d_function->name(); + + if (type->typeEntry()->isValue()) + (*logstream) << ", type entry value"; + + if (type->typeEntry()->isValue()) + (*logstream) << ", value"; + + if (type->isNativePointer()) + (*logstream) << ", native pointer"; + + const ComplexTypeEntry* ctype = dynamic_cast(type->typeEntry()); + if (ctype && ctype->hasVirtualFunctions()) + (*logstream) << ", polymorphic"; + + (*logstream) << endl; + } + else if (!type->hasNativeId()) continue; - else if(type->isObject() - || (type->typeEntry()->isValue() && type->isNativePointer()) - || type->isValue() || type->isVariant()) { - QString type_name = type->typeEntry()->name(); - const ComplexTypeEntry *ctype = static_cast(type->typeEntry()); - if(ctype->isAbstract()) - type_name = type_name + "_ConcreteWrapper"; - s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; + else if (type->isObject() || type->isQObject()) + { + if (!type->isQObject()) + { + (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", " + << implementor->name() << "::" << d_function->name(); + + (*logstream) << ", object"; + + const ComplexTypeEntry* ctype = dynamic_cast(type->typeEntry()); + if (ctype && ctype->hasVirtualFunctions()) + (*logstream) << ", polymorphic"; + + (*logstream) << endl; + } + + if (((ComplexTypeEntry*)type->typeEntry())->hasVirtualFunctions() || !d_function->resetObjectAfterUse(argument->argumentIndex() + 1)) + s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name << ");"; + else + s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);"; } - else if (type->isQObject()) { - QString type_name = type->name(); - const ComplexTypeEntry *ctype = static_cast(type->typeEntry()); - if(ctype->isAbstract()) - type_name = type_name + "_ConcreteWrapper"; - - s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);" << endl; - } + else + qFatal(qPrintable(type->typeEntry()->name())); + s << endl; } } @@ -2973,15 +3070,18 @@ void DGenerator::generate() { + log = new QFile("arglog.txt"); + log->open(QFile::ReadWrite); + logstream = new QTextStream(log); // qtd // code for including classses in 1 module for avoiding circular imports foreach (AbstractMetaClass *cls, m_classes) { - const ComplexTypeEntry *ctype = cls->typeEntry(); - - if (!cls->isInterface() && cls->isAbstract()) { - ComplexTypeEntry *ctype_m = (ComplexTypeEntry *)ctype; - ctype_m->setAbstract(true); - } + ComplexTypeEntry *ctype = const_cast(cls->typeEntry()); + + if (!cls->isInterface() && cls->isAbstract()) + ctype->setAbstract(true); + + ctype->setHasVirtualFunctions(cls->hasVirtualFunctions()); foreach(QString child, ctype->includedClasses) { ComplexTypeEntry *ctype_child = TypeDatabase::instance()->findComplexType(child); @@ -2990,20 +3090,6 @@ foreach (AbstractMetaFunction *function, cls->functions()) function->checkStoreResult(); -/* we don't need this anymore - // generate QObject conversion functions only those that are required - AbstractMetaFunctionList d_funcs = cls->functionsInTargetLang(); - for (int i=0; itype(); - if (!f_type) - continue; - if (f_type->isQObject() || f_type->isObject()) { - const ComplexTypeEntry* cte = static_cast(f_type->typeEntry()); - AbstractMetaClass* d_class = ClassFromEntry::get(cte); - if (d_class) - d_class->needsConversionFunc = true; - } - }*/ } Generator::generate(); @@ -3079,6 +3165,9 @@ } file.close(); } + + delete logstream; + delete log; } void DGenerator::writeFunctionAttributes(QTextStream &s, const AbstractMetaFunction *d_function, diff -r b1abe7f57321 -r 17b5e13364b7 generator/dgenerator.h --- a/generator/dgenerator.h Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/dgenerator.h Wed Sep 16 13:56:02 2009 +0000 @@ -45,6 +45,7 @@ #include "generator.h" #include "metajava.h" #include "cppimplgenerator.h" +#include "fileout.h" #include @@ -137,7 +138,13 @@ void writeShellVirtualFunction(QTextStream &s, const AbstractMetaFunction *function, const AbstractMetaClass *implementor, int id); - void marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype); + + enum MarshalFlags + { + MarhsalScope = 0x1 + } + + void marshalToD(QTextStream &s, const ComplexTypeEntry* ctype); private: QString subDirectoryForPackage(const QString &package) const { return QString(package).replace(".", "/"); } @@ -151,11 +158,12 @@ const TypeEntry* fixedTypeEntry(const TypeEntry *type); void writeDestructor(QTextStream &s, const AbstractMetaClass *d_class); - void writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class); + void writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class); void writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class); void writeEnumAlias(QTextStream &s, const AbstractMetaEnum *d_enum); void writeSignalSignatures(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunctionList signal_funcs); void writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class); + void writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class); void writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class); // void writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class); @@ -178,6 +186,8 @@ QList m_nativepointer_functions; QList m_resettable_object_functions; QList m_reference_count_candidate_functions; + QFile *log; + QTextStream *logstream; }; class ClassFromEntry : Generator diff -r b1abe7f57321 -r 17b5e13364b7 generator/generator.cpp --- a/generator/generator.cpp Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/generator.cpp Wed Sep 16 13:56:02 2009 +0000 @@ -61,6 +61,24 @@ .arg(metaObject()->className())); return; } + + { + FileOut fileOut("temp.txt"); + foreach (AbstractMetaClass *cls, m_classes) { + + fileOut.stream << cls->name(); + if (cls->typeEntry()->isValue()) + fileOut.stream << ", value"; + if (cls->isQObject()) + fileOut.stream << ", QObject"; + else if (cls->typeEntry()->isObject()) + fileOut.stream << ", object"; + if (cls->hasVirtualFunctions()) + fileOut.stream << ", polymorphic"; + fileOut.stream << endl; + + } + } foreach (AbstractMetaClass *cls, m_classes) { diff -r b1abe7f57321 -r 17b5e13364b7 generator/typesystem.h --- a/generator/typesystem.h Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/typesystem.h Wed Sep 16 13:56:02 2009 +0000 @@ -884,6 +884,9 @@ bool isAbstract() const { return m_isAbstract; } void setAbstract(bool isAbstract) { m_isAbstract = isAbstract; } + bool hasVirtualFunctions() const { return m_hasVirtualFunctions; } + void setHasVirtualFunctions(bool value) { m_hasVirtualFunctions = value; } + void setDepends(const QStringList &depends) {m_depends = depends; } const QStringList &depends() {return m_depends; } @@ -916,6 +919,7 @@ // qtd bool m_isStructInD; bool m_isAbstract; + bool m_hasVirtualFunctions; QStringList m_depends; }; diff -r b1abe7f57321 -r 17b5e13364b7 generator/typesystem_core-java.java --- a/generator/typesystem_core-java.java Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/typesystem_core-java.java Wed Sep 16 13:56:02 2009 +0000 @@ -72,14 +72,7 @@ } } */ - - private - { - static QObject __root; - QObject __next; - QObject __prev; - } - + override void onSignalHandlerCreated(ref SignalHandler sh) { sh.signalEvent = &onSignalEvent; @@ -88,16 +81,16 @@ private void onSignalEvent(int signalId, SignalEventId event) { stringz signature; - signalSignature(signalId, signature); + signalSignature(signalId, signature); if (signature) { switch (event) { case SignalEventId.firstSlotConnected: - qtd_connect(__nativeId, signature, signalId, cast(bool)(__flags_ & QtdObjectFlags.dynamicEntity)); + qtd_connect(__nativeId, signature, signalId, cast(bool)(__flags & QtdObjectFlags.hasDId)); break; case SignalEventId.lastSlotDisconnected: - qtd_disconnect(__nativeId, signature, signalId, cast(bool)(__flags_ & QtdObjectFlags.dynamicEntity)); + qtd_disconnect(__nativeId, signature, signalId, cast(bool)(__flags & QtdObjectFlags.hasDId)); break; default: assert (false); @@ -105,17 +98,6 @@ } } - ~this() - { - if (__prev) - __prev.__next = __next; - else - __root = __next; - - if (__next) - __next.__prev = __prev; - } - /** */ T findChild(T : QObject = QObject)(string name = null) @@ -153,7 +135,7 @@ find(children); return result; - } + } }// class abstract class QAbstractItemModel___ extends QAbstractItemModel { diff -r b1abe7f57321 -r 17b5e13364b7 generator/typesystem_core.xml --- a/generator/typesystem_core.xml Mon Aug 31 12:07:28 2009 +0000 +++ b/generator/typesystem_core.xml Wed Sep 16 13:56:02 2009 +0000 @@ -2363,27 +2363,12 @@ -#ifdef CPP_SHARED -QTD_EXPORT_VAR(qtd_delete_d_qobject); - -extern "C" DLL_PUBLIC void qtd_QObjectEntity_initCallBacks(pfunc_abstr del_d_qobj) -{ - QTD_EXPORT_VAR_SET(qtd_delete_d_qobject, del_d_qobj); -} -#endif - - extern "C" DLL_PUBLIC void* qtd_get_d_qobject(void *nativeId) { QtD_QObjectEntity *entity = QtD_QObjectEntity::getQObjectEntity((QObject*)nativeId); return entity ? entity->dId : NULL; } -extern "C" DLL_PUBLIC void qtd_delete_qobject(void *nativeId) -{ - delete (QObject*)nativeId; -} - extern "C" DLL_PUBLIC void qtd_create_qobject_entity(void* nativeId, void *dId) { new QtD_QObjectEntity((QObject*)nativeId, dId); @@ -2394,20 +2379,20 @@ return (void*)((QObject*)nativeId)->metaObject(); } -extern "C" DLL_PUBLIC void qtd_connect(void* nativeId, char* signal, int id, bool dynamicEntity) -{ +extern "C" DLL_PUBLIC void qtd_connect(void* nativeId, char* signal, int id, bool hasDId) +{ QObject *sender = (QObject*)nativeId; - QObject *receiver = dynamicEntity ? dynamic_cast<QObject*>(QtD_QObjectEntity::getQObjectEntity(sender)) : sender; + QObject *receiver = hasDId ? sender : dynamic_cast<QObject*>(QtD_QObjectEntity::getQObjectEntity(sender)); const QMetaObject *mo = sender->metaObject(); int nativeSigId = mo->indexOfSignal(signal); QMetaObject::connect(sender, nativeSigId, receiver, receiver->metaObject()->methodCount() + id); } -extern "C" DLL_PUBLIC void qtd_disconnect(void* nativeId, char* signal, int id, bool dynamicEntity) +extern "C" DLL_PUBLIC void qtd_disconnect(void* nativeId, char* signal, int id, bool hasDId) { QObject *sender = (QObject*)nativeId; - QObject *receiver = dynamicEntity ? dynamic_cast<QObject*>(QtD_QObjectEntity::getQObjectEntity(sender)) : sender; - const QMetaObject *mo = sender->metaObject(); + QObject *receiver = hasDId ? sender : dynamic_cast<QObject*>(QtD_QObjectEntity::getQObjectEntity(sender)); + const QMetaObject *mo = sender->metaObject(); int nativeSigId = mo->indexOfSignal(signal); QMetaObject::disconnect(sender, nativeSigId, receiver, receiver->metaObject()->methodCount() + id); } @@ -2416,23 +2401,11 @@ extern(C) void* qtd_get_d_qobject(void* nativeId); -extern(C) void qtd_delete_qobject(void* nativeId); extern(C) void* qtd_create_qobject_entity(void* nativeId, void* dId); extern(C) void* qtd_QObject_metaObject(void* nativeId); -extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool dynamicEntity); -extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool dynamicEntity); - -extern(C) void qtd_delete_d_qobject(void* dId) -{ - auto obj = cast(QObject)dId; - - if (!(obj.__flags & QtdObjectFlags.dOwnership)) - { - // Avoid deleting native object twice - obj.__setFlags(QtdObjectFlags.nativeOwnership, true); - delete obj; - } -} +extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool hasDId); +extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool hasDId); + @@ -2589,8 +2562,8 @@ - - + + diff -r b1abe7f57321 -r 17b5e13364b7 include/qtd_core.h --- a/include/qtd_core.h Mon Aug 31 12:07:28 2009 +0000 +++ b/include/qtd_core.h Wed Sep 16 13:56:02 2009 +0000 @@ -13,6 +13,7 @@ #define QTD_CORE_H #include +#include #if defined WIN32 #define DLL_PUBLIC __declspec(dllexport) @@ -34,6 +35,10 @@ extern "C" TYPE NAME ARGS; #endif + +//TODO: user data ID must be registered with QObject::registerUserData; +#define userDataId 0 + struct QModelIndexAccessor { int row; int col; @@ -46,14 +51,6 @@ void* ptr; }; -enum QtdObjectFlags -{ - qNone, - qNativeOwnership = 0x01, - qDOwnership = 0x02 - //gcManaged = 0x04 -}; - class QtD_Entity { public: @@ -64,6 +61,15 @@ } }; +class QtD_QObjectEntity : public QtD_Entity, public QObjectUserData +{ +public: + QtD_QObjectEntity(QObject *qObject, void *dId); + virtual ~QtD_QObjectEntity(); + void destroyEntity(QObject *qObject = NULL); + static QtD_QObjectEntity* getQObjectEntity(const QObject *qObject); +}; + #define Array DArray #ifdef CPP_SHARED @@ -72,10 +78,12 @@ QTD_EXPORT(void, qtd_toUtf8, (const unsigned short* arr, uint size, void* str)) QTD_EXPORT(void, qtd_dummy, ()) +QTD_EXPORT(void, qtd_delete_d_object, (void* dPtr)) #ifdef CPP_SHARED #define qtd_toUtf8 qtd_get_qtd_toUtf8() #define qtd_dummy qtd_get_qtd_dummy() +#define qtd_delete_d_object qtd_get_qtd_delete_d_object() #endif extern "C" QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia); diff -r b1abe7f57321 -r 17b5e13364b7 mini/test1/build --- a/mini/test1/build Mon Aug 31 12:07:28 2009 +0000 +++ b/mini/test1/build Wed Sep 16 13:56:02 2009 +0000 @@ -1,3 +1,3 @@ #! /bin/bash -dmd main.d -L-L../../lib -L-lqtdcore -I../../ -I../../qt/d2 -L-lQtCore \ No newline at end of file +dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui \ No newline at end of file diff -r b1abe7f57321 -r 17b5e13364b7 mini/test1/main.d --- a/mini/test1/main.d Mon Aug 31 12:07:28 2009 +0000 +++ b/mini/test1/main.d Wed Sep 16 13:56:02 2009 +0000 @@ -1,30 +1,125 @@ +module main; + +/+ +import qt.gui.QApplication; import qt.core.QCoreApplication; +import qt.gui.QDialogButtonBox; ++/ +import tango.io.Stdout; -version(Tango) {} else { import std.stdio; } +extern(C) void* qtd_test_Object(); +extern(C) void qtd_test_delete_Object(void* obj); + +import qt.core.QObject; +import qt.core.QCryptographicHash; +import qt.core.QFSFileEngine; +import qt.QtdObject; + -int main(string[] args) +void main() +{ + //auto nativeId = qtd_test_Object(); + scope obj = new QCryptographicHash(QCryptographicHash_Algorithm.Md5); + obj.__nativeOwnership = true; + qtd_test_delete_Object(obj.__nativeId); + //Stdout(obj).newline; +} + +/+ +void main(char[][] args) { - auto app = new QCoreApplication(args); + /+ + scope app = new QCoreApplication(args); + app.aboutToQuit.connect(&quit); + Stdout(app.children[0]).newline; + +/ + + /+ + scope parent = new QObject; + qtd_qobject(parent.__nativeId); + Stdout(parent.children[0]).newline; + +/ + + + - auto parent = new QObject(); - parent.setObjectName("papa"); - auto child1 = new QObject(parent); - child1.setObjectName("child1"); - auto child2 = new QObject(parent); - child2.setObjectName("child2"); - auto child3 = new QObject(parent); - child3.setObjectName("child3"); - - auto cd = parent.children; + //return app.exec(); +} + +void quit() +{ + Stdout("Quitting").newline; +} ++/ + +/+ +import tango.io.Stdout; + +import qt.gui.QMainWindow; + +public class TestWindow : QMainWindow +{ + public this() + { + //Stdout(qVersion).newline; + + //Stdout(this.children.length).newline; + auto box = new QDialogButtonBox(this); + auto closeButton = box.addButton(QDialogButtonBox.Close); + closeButton.clicked.connect(&onCloseClick); + } - writeln(app.arguments); - foreach(child; cd) - writeln(child.objectName); - - app.setLibraryPaths(["freakin", "bloody", "awesome!"]); + void onCloseClick() + { + Stdout("Close clicked").newline; + } +} + +void main(char[][] args) +{ + scope app = new QApplication(args); + scope mainWin = new TestWindow; + mainWin.show(); + return app.exec(); +} ++/ + +/+ - writeln(app.libraryPaths); +import qt.gui.QListWidget; +import qt.gui.QApplication; +import qt.gui.QMainWindow; +import tango.io.Stdout; +void main( char[][] args ) +{ - return 5; -// return app.exec(); + Stdout(qVersion).newline; + static void itemChanged( QListWidgetItem cur, QListWidgetItem prev ) + { + if(prev ) + { + Stdout("Here prev", prev, prev.__nativeId).newline; + prev.text; // This causes the SIGSEGV + Stdout("There prev").newline; + } + + if( cur ) + { + Stdout("Here", cur, cur.__nativeId).newline; + cur.text; // This causes the SIGSEGV + Stdout("There").newline; + } + } + scope app = new QApplication(args); + scope mainWin = new QMainWindow; + scope lw = new QListWidget( mainWin ); + scope lwi = new QListWidgetItem("text", lw); + lwi.text; + Stdout("Here 0 ", lwi.__nativeId).newline; + + lw.currentItemChanged.connect( &itemChanged ); + mainWin.show; + return app.exec; } + ++/ \ No newline at end of file diff -r b1abe7f57321 -r 17b5e13364b7 qt/QGlobal.d --- a/qt/QGlobal.d Mon Aug 31 12:07:28 2009 +0000 +++ b/qt/QGlobal.d Wed Sep 16 13:56:02 2009 +0000 @@ -3,9 +3,17 @@ public import qt.qtd.Str; public import qt.QDefines; -version (Tango) +version (D_Version2) +{ + import std.stdio; + package import std.c.stdlib, + core.memory; +} +else { import tango.io.Stdout; + import tango.core.Thread; + void writeln(string s) { Stdout(s).newline; @@ -13,11 +21,67 @@ package import tango.stdc.stdlib, tango.core.Memory; } + +private enum : size_t { stackSize = 1024 * 1024 } + +final class StackAlloc +{ + alias typeof(this) This; + private void* _data; + + private static size_t align16(size_t size) + { + return size + 16 - (size - size & ~15); + } + + this(size_t size) + { + _data = (new void[size]).ptr; + } + + void* alloc(size_t size) + { + void* res = _data; + _data += align16(size); + return res; + } + + void free(size_t size) + { + _data -= align16(size); + } +} + +version (D_Version2) +{ + void StackAlloc __stackAlloc() + { + static StackAlloc instance; // thread-local instance + // COMPILER BUG: No thread-local static constructors, Using lazy construction + if (!instance) + instance = new This(stackSize); + return instance; + } +} else { - import std.stdio; - package import std.c.stdlib, - core.memory; + private static ThreadLocal!(StackAlloc) stackAllocInst; + + static this() + { + stackAllocInst = new ThreadLocal!(StackAlloc); + } + + static StackAlloc __stackAlloc() + { + auto res = stackAllocInst.val; + if (!res) + { + res = new This(stackSize); + stackAllocInst.val = res; + } + return res; + } } T static_cast(T, U)(U obj) @@ -40,21 +104,15 @@ mixin QT_BEGIN_HEADER; mixin QT_BEGIN_NAMESPACE; -//TODO: this sucks extern(C) void qtd_dummy() {} -// Defined in QObject.d -extern(C) void qtd_delete_d_qobject(void* dPtr); +// Defined in QtdObject.d +extern(C) void qtd_delete_d_object(void* dPtr); version(cpp_shared) { - extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy); + extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy, void* del_d_obj); static this() { - qtd_core_initCallBacks(&qtd_toUtf8, &qtd_dummy); - } - - extern (C) void qtd_QObjectEntity_initCallBacks(void* del_d_obj); - static this() { - qtd_QObjectEntity_initCallBacks(&qtd_delete_d_qobject); + qtd_core_initCallBacks(&qtd_toUtf8, &qtd_dummy, &qtd_delete_d_object); } } @@ -225,7 +283,7 @@ //class QString; //char[] qPrintable(QString string) { string.toLocal8Bit().constData(); } //TODO(katrina) These should probably actually call into the c++ functions -void qDebug( char[] str ) /* print debug message */ +void qDebug(string str) /* print debug message */ { writeln(str); } extern (C) void Qt_qWarning( char * ); diff -r b1abe7f57321 -r 17b5e13364b7 qt/d1/qt/core/QVariant.d --- a/qt/d1/qt/core/QVariant.d Mon Aug 31 12:07:28 2009 +0000 +++ b/qt/d1/qt/core/QVariant.d Wed Sep 16 13:56:02 2009 +0000 @@ -33,7 +33,7 @@ } -public class QVariant : QtdObject +public class QVariant : QtdObjectBase { enum Type { Invalid = 0, @@ -481,7 +481,7 @@ public final QVariant operator_assign(QVariant other) { void* __qt_return_value = qtd_QVariant_operator_assign_QVariant(__nativeId, other is null ? null : other.__nativeId); - return new QVariant(__qt_return_value, QtdObjectFlags.nativeOwnership); + return new QVariant(__qt_return_value, QtdObjectFlags.skipNativeDelete); } private final bool operator_equal(QVariant v) {