Mercurial > projects > qtd
comparison generator/dgenerator.cpp @ 248:7664de4a55e5
Fixed #23.
QtD_QObjectEntity is not created dynamically for shell classes any more.
Class initialization is now performed by static constructors.
When wrapping QObjects returned from functions, their run-time types are now taken into account.
QObjects are allocated on GC heap, a doubly-linked list is used to prevent them from been collected (arguably a better solution than allocating on C heap and adding GC ranges)
Minor changes (including unnecessary).
author | maxter |
---|---|
date | Thu, 20 Aug 2009 14:47:17 +0000 |
parents | 0c7abb1e6a9d |
children | 37eed70de029 |
comparison
equal
deleted
inserted
replaced
247:27497bbe62a1 | 248:7664de4a55e5 |
---|---|
315 && !d_enum->hasQEnumsDeclaration()) { | 315 && !d_enum->hasQEnumsDeclaration()) { |
316 s << " @QtBlockedEnum" << endl; | 316 s << " @QtBlockedEnum" << endl; |
317 } | 317 } |
318 */ | 318 */ |
319 // Generates Java 1.5 type enums | 319 // Generates Java 1.5 type enums |
320 s << " public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl; | 320 s << "public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl; |
321 const AbstractMetaEnumValueList &values = d_enum->values(); | 321 const AbstractMetaEnumValueList &values = d_enum->values(); |
322 EnumTypeEntry *entry = d_enum->typeEntry(); | 322 EnumTypeEntry *entry = d_enum->typeEntry(); |
323 | 323 |
324 for (int i=0; i<values.size(); ++i) { | 324 for (int i=0; i<values.size(); ++i) { |
325 AbstractMetaEnumValue *enum_value = values.at(i); | 325 AbstractMetaEnumValue *enum_value = values.at(i); |
475 s << ";" << endl; | 475 s << ";" << endl; |
476 } | 476 } |
477 } | 477 } |
478 | 478 |
479 static QString function_call_for_ownership(TypeSystem::Ownership owner) | 479 static QString function_call_for_ownership(TypeSystem::Ownership owner) |
480 { | 480 { |
481 if (owner == TypeSystem::CppOwnership) { | 481 if (owner == TypeSystem::CppOwnership) { |
482 return "__set_native_ownership(true)"; | 482 return "__setFlags(QtdObjectFlags.nativeOwnership, true)"; |
483 } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { | 483 } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { |
484 return "__set_native_ownership(false)"; | 484 return "__setFlags(QtdObjectFlags.nativeOwnership, false)"; |
485 }/* else if (owner == TypeSystem::DefaultOwnership) { | 485 }/* else if (owner == TypeSystem::DefaultOwnership) { |
486 return "__no_real_delete = false"; | 486 return "__no_real_delete = false"; |
487 | 487 |
488 } else { | 488 } else { |
489 Q_ASSERT(false); | 489 Q_ASSERT(false); |
694 bool returnImmediately = return_in_arg; | 694 bool returnImmediately = return_in_arg; |
695 | 695 |
696 s << INDENT; | 696 s << INDENT; |
697 if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd | 697 if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd |
698 if(d_function->type() && d_function->type()->isQObject()) { // qtd | 698 if(d_function->type() && d_function->type()->isQObject()) { // qtd |
699 s << "void *__qt_return_value = "; | 699 s << "void *ret = "; |
700 } else if(return_in_arg) // qtd | 700 } else if(return_in_arg) // qtd |
701 ; | 701 ; |
702 else if (d_function->isConstructor()) { // qtd | 702 else if (d_function->isConstructor()) { // qtd |
703 s << "void* __qt_return_value = "; | 703 s << "void* ret = "; |
704 } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) { | 704 } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) { |
705 s << "void* __qt_return_value = "; | 705 s << "void* ret = "; |
706 } else if (return_type && return_type->isVariant()) { | 706 } else if (return_type && return_type->isVariant()) { |
707 s << "void* __qt_return_value = "; | 707 s << "void* ret = "; |
708 } else if (return_type && ( return_type->isObject() || | 708 } else if (return_type && ( return_type->isObject() || |
709 (return_type->isNativePointer() && return_type->typeEntry()->isValue()) || | 709 (return_type->isNativePointer() && return_type->typeEntry()->isValue()) || |
710 return_type->typeEntry()->isInterface()) ) { | 710 return_type->typeEntry()->isInterface()) ) { |
711 s << "void* __qt_return_value = "; | 711 s << "void* ret = "; |
712 } else if (return_type && return_type->isArray()) { | 712 } else if (return_type && return_type->isArray()) { |
713 s << return_type->arrayElementType()->name() + "* __qt_return_value = "; | 713 s << return_type->arrayElementType()->name() + "* ret = "; |
714 } else { | 714 } else { |
715 returnImmediately = true; | 715 returnImmediately = true; |
716 s << "return "; | 716 s << "return "; |
717 } | 717 } |
718 | 718 |
763 s << d_function->marshalledName() << "("; | 763 s << d_function->marshalledName() << "("; |
764 } | 764 } |
765 | 765 |
766 if (!d_function->isConstructor() && !d_function->isStatic()) { | 766 if (!d_function->isConstructor() && !d_function->isStatic()) { |
767 if(dVersion == 2 && d_function->isConstant()) | 767 if(dVersion == 2 && d_function->isConstant()) |
768 s << "(cast(" << d_function->ownerClass()->name() << ")this).nativeId"; | 768 s << "(cast(" << d_function->ownerClass()->name() << ")this).__nativeId"; |
769 else | 769 else |
770 s << "nativeId"; | 770 s << "__nativeId"; |
771 } | 771 } |
772 | 772 |
773 if (d_function->isConstructor() && | 773 if (d_function->isConstructor() && |
774 ( d_function->implementingClass()->hasVirtualFunctions() | 774 ( d_function->implementingClass()->hasVirtualFunctions() |
775 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd | 775 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd |
799 modified_type = modified_type.replace('$', '.'); | 799 modified_type = modified_type.replace('$', '.'); |
800 | 800 |
801 QString arg_name = arg->argumentName(); | 801 QString arg_name = arg->argumentName(); |
802 | 802 |
803 if (type->isVariant()) | 803 if (type->isVariant()) |
804 s << arg_name << " is null ? null : " << arg_name << ".nativeId"; | 804 s << arg_name << " is null ? null : " << arg_name << ".__nativeId"; |
805 else if (te->designatedInterface()) | 805 else if (te->designatedInterface()) |
806 s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name(); | 806 s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name(); |
807 else if (modified_type == "string" /* && type->fullName() == "char" */) { | 807 else if (modified_type == "string" /* && type->fullName() == "char" */) { |
808 s << "toStringz(" << arg_name << ")"; | 808 s << "toStringz(" << arg_name << ")"; |
809 } else if (type->isArray()) { | 809 } else if (type->isArray()) { |
829 if (!force_abstract) { | 829 if (!force_abstract) { |
830 s << arg_name << " is null ? null : "; | 830 s << arg_name << " is null ? null : "; |
831 } // else if (value type is abstract) then we will get a null pointer exception, which is all right | 831 } // else if (value type is abstract) then we will get a null pointer exception, which is all right |
832 | 832 |
833 if(dVersion == 2 && type->isConstant()) | 833 if(dVersion == 2 && type->isConstant()) |
834 s << "(cast(" << type->name() << ")" << arg_name << ").nativeId"; | 834 s << "(cast(" << type->name() << ")" << arg_name << ").__nativeId"; |
835 else | 835 else |
836 s << arg_name << ".nativeId"; | 836 s << arg_name << ".__nativeId"; |
837 } | 837 } |
838 } | 838 } |
839 } | 839 } |
840 | 840 |
841 if (useJumpTable) { | 841 if (useJumpTable) { |
862 s << ";" << endl; | 862 s << ";" << endl; |
863 | 863 |
864 /* qtd2 | 864 /* qtd2 |
865 if (needs_return_variable) { | 865 if (needs_return_variable) { |
866 if (owner != TypeSystem::InvalidOwnership) { | 866 if (owner != TypeSystem::InvalidOwnership) { |
867 s << INDENT << "if (__qt_return_value != null) {" << endl; | 867 s << INDENT << "if (ret != null) {" << endl; |
868 if (return_type->isContainer()) | 868 if (return_type->isContainer()) |
869 writeOwnershipForContainer(s, owner, return_type, "__qt_return_value"); | 869 writeOwnershipForContainer(s, owner, return_type, "ret"); |
870 else | 870 else |
871 s << INDENT << " __qt_return_value." << function_call_for_ownership(owner) << ";" << endl; | 871 s << INDENT << " ret." << function_call_for_ownership(owner) << ";" << endl; |
872 s << INDENT << "}" << endl; | 872 s << INDENT << "}" << endl; |
873 } | 873 } |
874 s << INDENT << "return __qt_return_value;" << endl; | 874 s << INDENT << "return ret;" << endl; |
875 } | 875 } |
876 */ | 876 */ |
877 if (d_function->isConstructor()) { | 877 if (d_function->isConstructor()) { |
878 TypeSystem::Ownership owner = d_function->ownership(d_function->implementingClass(), TypeSystem::TargetLangCode, -1); | 878 TypeSystem::Ownership owner = d_function->ownership(d_function->implementingClass(), TypeSystem::TargetLangCode, -1); |
879 if (owner != TypeSystem::InvalidOwnership && d_function->isConstructor()) | 879 if (owner != TypeSystem::InvalidOwnership && d_function->isConstructor()) |
891 s << modified_type.replace('$', '.'); | 891 s << modified_type.replace('$', '.'); |
892 s << " __d_return_value = "; | 892 s << " __d_return_value = "; |
893 } | 893 } |
894 | 894 |
895 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd | 895 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd |
896 { | |
896 if(return_type->isQObject()) | 897 if(return_type->isQObject()) |
897 s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl; | 898 s << return_type->name() << ".getObject(ret);" << endl; |
899 } | |
898 | 900 |
899 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) | 901 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) |
900 s << "new " << return_type->name() << "(__qt_return_value, false);" << endl; | 902 s << "new " << return_type->name() << "(ret);" << endl; |
901 | 903 |
902 if (return_type->isVariant()) | 904 if (return_type->isVariant()) |
903 s << "new QVariant(__qt_return_value, false);" << endl; | 905 s << "new QVariant(ret);" << endl; |
904 | 906 |
905 if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) | 907 if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) |
906 s << "new " << return_type->name() << "(__qt_return_value, true);" << endl; | 908 s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl; |
907 | 909 |
908 if (return_type->isObject()) { | 910 if (return_type->isObject()) { |
909 if(d_function->storeResult()) | 911 if(d_function->storeResult()) |
910 s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl | 912 s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl |
911 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; | 913 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; |
912 else | 914 else |
913 s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl; | 915 s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl; |
914 s << endl; | 916 s << endl; |
915 } | 917 } |
916 | 918 |
917 if (return_type->isArray()) { | 919 if (return_type->isArray()) { |
918 s << "__qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl; | 920 s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl; |
919 } | 921 } |
920 | 922 |
921 foreach (ReferenceCount referenceCount, referenceCounts) { | 923 foreach (ReferenceCount referenceCount, referenceCounts) { |
922 writeReferenceCount(s, referenceCount, "__d_return_value"); | 924 writeReferenceCount(s, referenceCount, "__d_return_value"); |
923 } | 925 } |
1678 void DGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *d_class) | 1680 void DGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *d_class) |
1679 { | 1681 { |
1680 if (!d_class->hasConstructors()) | 1682 if (!d_class->hasConstructors()) |
1681 return; | 1683 return; |
1682 | 1684 |
1683 s << endl; | 1685 bool isTheQObject = d_class->name() == "QObject"; |
1684 if (d_class->baseClassName().isEmpty()) { | 1686 if (isTheQObject || !d_class->isQObject()) |
1685 s << INDENT << "~this() { " << endl; | 1687 { |
1688 s << INDENT << "protected override void __deleteNative() {" << endl; | |
1686 { | 1689 { |
1687 Indentation indent(INDENT); | 1690 if (isTheQObject) |
1688 | 1691 s << INDENT << "qtd_delete_qobject(__nativeId);" << endl; |
1689 /* | 1692 else if (!d_class->isQObject()) |
1690 if(d_class->name() == "QObject") | 1693 s << INDENT << "qtd_" << d_class->name() << "_destructor(__nativeId);" << endl; |
1691 s << INDENT << "if(!__gc_managed)" << endl | |
1692 << INDENT << " remove(__gc_ref_list, this);" << endl | |
1693 << INDENT << "if(!__no_real_delete && __gc_managed) {" << endl | |
1694 << INDENT << " __qobject_is_deleting = true;" << endl | |
1695 << INDENT << " scope(exit) __qobject_is_deleting = false;" << endl | |
1696 << INDENT << " __free_native_resources();" << endl | |
1697 << INDENT << "}" << endl; | |
1698 */ | |
1699 if(d_class->name() == "QObject") | |
1700 s << INDENT << "if(!__no_real_delete) {" << endl | |
1701 << INDENT << " __qobject_is_deleting = true;" << endl | |
1702 << INDENT << " scope(exit) __qobject_is_deleting = false;" << endl | |
1703 << INDENT << " __free_native_resources();" << endl | |
1704 << INDENT << "}" << endl; | |
1705 else | |
1706 s << INDENT << "if(!__no_real_delete)" << endl | |
1707 << INDENT << " __free_native_resources();" << endl; | |
1708 } | 1694 } |
1709 s << INDENT << "}" << endl << endl; | 1695 s << INDENT << "}" << endl << endl; |
1710 } | 1696 } |
1711 | 1697 } |
1712 s << INDENT << "protected void __free_native_resources() {" << endl; | 1698 |
1713 { | 1699 void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class) |
1714 Indentation indent(INDENT); | 1700 { |
1715 s << INDENT << "qtd_" << d_class->name() << "_destructor(nativeId());" << endl; | |
1716 } | |
1717 s << INDENT << "}" << endl << endl; | |
1718 } | |
1719 | |
1720 void DGenerator::writeOwnershipMethods(QTextStream &s, const AbstractMetaClass *d_class) | |
1721 { | |
1722 s << INDENT << "void __set_native_ownership(bool ownership_)"; | |
1723 if (d_class->isInterface() || d_class->isNamespace()) | 1701 if (d_class->isInterface() || d_class->isNamespace()) |
1724 s << ";"; | 1702 s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);"; |
1725 else { | 1703 else // COMPILER BUG: |
1726 s << " {" << endl | 1704 s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }"; |
1727 << INDENT << " __no_real_delete = ownership_;" << endl | |
1728 << INDENT << "}" << endl << endl; | |
1729 } | |
1730 } | 1705 } |
1731 | 1706 |
1732 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) | 1707 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) |
1733 { | 1708 { |
1734 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); | 1709 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); |
1735 | 1710 |
1736 //TODO: linkage trivia should be abstracted away | |
1737 QString attr; | 1711 QString attr; |
1738 | 1712 |
1739 s << "// signal handlers" << endl; | 1713 s << "// signal handlers" << endl; |
1740 foreach(AbstractMetaFunction *signal, signal_funcs) { | 1714 foreach(AbstractMetaFunction *signal, signal_funcs) { |
1741 QString sigExternName = signalExternName(d_class, signal); | 1715 QString sigExternName = signalExternName(d_class, signal); |
1787 QString type_name = type->name(); | 1761 QString type_name = type->name(); |
1788 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); | 1762 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); |
1789 if(ctype->isAbstract()) | 1763 if(ctype->isAbstract()) |
1790 type_name = type_name + "_ConcreteWrapper"; | 1764 type_name = type_name + "_ConcreteWrapper"; |
1791 s << INDENT << "scope " << arg_name << " = new " << type_name | 1765 s << INDENT << "scope " << arg_name << " = new " << type_name |
1792 << "(cast(void*)(" << arg_ptr << "), true);" << endl | 1766 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl; |
1793 << INDENT << arg_name << ".__no_real_delete = true;"; | |
1794 } | 1767 } |
1795 s << endl; | 1768 s << endl; |
1796 } | 1769 } |
1797 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl; | 1770 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl; |
1798 s << INDENT << "d_object." << signal->name() << ".emit("; | 1771 s << INDENT << "d_object." << signal->name() << ".emit("; |
1813 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class) | 1786 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class) |
1814 { | 1787 { |
1815 ReportHandler::debugSparse("Generating class: " + d_class->fullName()); | 1788 ReportHandler::debugSparse("Generating class: " + d_class->fullName()); |
1816 | 1789 |
1817 bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; | 1790 bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; |
1791 | |
1792 | |
1793 QString auxModName = d_class->package() + "." + d_class->name() + "_aux"; | |
1794 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d"); | |
1795 auxFile.isDone = true; | |
1796 auxFile.stream << "module " << auxModName << ";" << endl << endl; | |
1797 | |
1798 bool staticInit = d_class->isQObject() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); | |
1799 if (staticInit) | |
1800 { | |
1801 auxFile.isDone = false; | |
1802 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl; | |
1803 auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl; | |
1804 } | |
1818 | 1805 |
1819 if (m_docs_enabled) { | 1806 if (m_docs_enabled) { |
1820 m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc"); | 1807 m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc"); |
1821 } | 1808 } |
1822 if (!m_isRecursive) | 1809 if (!m_isRecursive) |
1895 if (inc.type == Include::TargetLangImport) { | 1882 if (inc.type == Include::TargetLangImport) { |
1896 s << inc.toString() << endl; | 1883 s << inc.toString() << endl; |
1897 } | 1884 } |
1898 } | 1885 } |
1899 | 1886 |
1887 // Enums aliases outside of the class - hack | |
1888 if (!d_class->enums().isEmpty()) { | |
1889 auxFile.isDone = false; | |
1890 foreach (AbstractMetaEnum *d_enum, d_class->enums()) | |
1891 writeEnum(auxFile.stream, d_enum); | |
1892 } | |
1893 | |
1894 // Auxiliary file contents should have been written at this point | |
1895 if (!auxFile.isDone) | |
1896 { | |
1897 s << "public import " << auxModName << ";" << endl; | |
1898 auxFile.done(); | |
1899 } | |
1900 | |
1900 if (!m_isRecursive) { | 1901 if (!m_isRecursive) { |
1901 s << "public import qt.QGlobal;" << endl | 1902 s << "public import qt.QGlobal;" << endl |
1902 << "public import qt.core.Qt;" << endl | 1903 << "public import qt.core.Qt;" << endl |
1903 << "private import qt.QtDObject;" << endl | 1904 << "private import qt.QtdObject;" << endl |
1904 << "private import qt.core.QString;" << endl | 1905 << "private import qt.core.QString;" << endl |
1905 << "private import qt.qtd.Array;" << endl; | 1906 << "private import qt.qtd.Array;" << endl; |
1906 if (d_class->isQObject()) { | 1907 if (d_class->isQObject()) { |
1907 s << "public import qt.Signal;" << endl; | 1908 s << "public import qt.Signal;" << endl |
1909 << "public import qt.core.QMetaObject;" << endl | |
1910 << "public import qt.qtd.Traits;" << endl; | |
1911 | |
1908 if (d_class->name() != "QObject") | 1912 if (d_class->name() != "QObject") |
1909 s << "public import qt.core.QObject;" << endl; | 1913 s << "public import qt.core.QObject;" << endl; |
1910 } | 1914 } |
1911 | 1915 |
1912 // qtd2 hack! | 1916 // qtd2 hack! |
1922 for other usages - then restrict it just for namespaces/interfaces | 1926 for other usages - then restrict it just for namespaces/interfaces |
1923 */ | 1927 */ |
1924 if(d_class->isQObject()) | 1928 if(d_class->isQObject()) |
1925 s << "private import " << d_class->package() << ".ArrayOps2;" << endl; | 1929 s << "private import " << d_class->package() << ".ArrayOps2;" << endl; |
1926 | 1930 |
1927 if (!d_class->enums().isEmpty()) | |
1928 s << "public import " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl; | |
1929 | |
1930 s << "// automatic imports-------------" << endl; | 1931 s << "// automatic imports-------------" << endl; |
1931 writeRequiredImports(s, d_class); | 1932 writeRequiredImports(s, d_class); |
1932 s << endl; | 1933 s << endl; |
1933 if (dPhobos) | 1934 if (dPhobos) |
1934 { | 1935 { |
1935 s << "import std.stdio;" << endl | 1936 s << "import std.stdio;" << endl |
1936 << "import std.string;" << endl | 1937 << "import std.string;" << endl |
1937 << "import std.utf;" << endl | 1938 << "import std.utf;" << endl |
1938 << "import core.memory;"; | 1939 << "import core.memory;" << endl; |
1939 } | 1940 } |
1940 else | 1941 else |
1941 { | 1942 { |
1942 s << "import tango.io.Stdout;" << endl | 1943 s << "import tango.io.Stdout;" << endl |
1943 << "import tango.stdc.stringz;" << endl | 1944 << "import tango.stdc.stringz;" << endl |
1944 << "import tango.text.convert.Utf;" << endl | 1945 << "import tango.text.convert.Utf;" << endl |
1945 << "import tango.core.Memory;"; | 1946 << "import tango.core.Memory;" << endl; |
1946 } | 1947 } |
1947 s << endl << endl << endl; | 1948 |
1949 s << endl << endl; | |
1948 } | 1950 } |
1949 | 1951 |
1950 if (m_doc_parser) { | 1952 if (m_doc_parser) { |
1951 s << m_doc_parser->documentation(d_class) << endl << endl; | 1953 s << m_doc_parser->documentation(d_class) << endl << endl; |
1952 } | 1954 } |
1953 | |
1954 // Enums aliases outside of the class - hack | |
1955 if (!d_class->enums().isEmpty()) { | |
1956 QString fileName = QString("%1_enum.d").arg(d_class->name()); | |
1957 FileOut fileOut(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + fileName); | |
1958 | |
1959 fileOut.stream << "module " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl; | |
1960 foreach (AbstractMetaEnum *d_enum, d_class->enums()) | |
1961 writeEnum(fileOut.stream, d_enum); | |
1962 } | |
1963 | |
1964 | |
1965 s << endl; | |
1966 | 1955 |
1967 /* qtd s << "@QtJambiGeneratedClass" << endl; | 1956 /* qtd s << "@QtJambiGeneratedClass" << endl; |
1968 | 1957 |
1969 if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) { | 1958 if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) { |
1970 s << "@Deprecated" << endl; | 1959 s << "@Deprecated" << endl; |
2153 */ | 2142 */ |
2154 | 2143 |
2155 // Enums aliaases | 2144 // Enums aliaases |
2156 foreach (AbstractMetaEnum *d_enum, d_class->enums()) | 2145 foreach (AbstractMetaEnum *d_enum, d_class->enums()) |
2157 writeEnumAlias(s, d_enum); | 2146 writeEnumAlias(s, d_enum); |
2158 | |
2159 if (!d_class->enums().isEmpty() && !d_class->functions().isEmpty()) | |
2160 s << endl; | |
2161 | 2147 |
2162 // Signals | 2148 // Signals |
2163 AbstractMetaFunctionList signal_funcs; | 2149 AbstractMetaFunctionList signal_funcs; |
2164 | 2150 |
2165 signal_funcs = signalFunctions(d_class); | 2151 signal_funcs = signalFunctions(d_class); |
2249 << endl | 2235 << endl |
2250 << INDENT << "@QtBlockedSlot" << endl | 2236 << INDENT << "@QtBlockedSlot" << endl |
2251 << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl; | 2237 << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl; |
2252 } | 2238 } |
2253 */ | 2239 */ |
2240 if (d_class->isQObject()) | |
2241 writeQObjectFunctions(s, d_class); | |
2242 | |
2254 // Add dummy constructor for use when constructing subclasses | 2243 // Add dummy constructor for use when constructing subclasses |
2255 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { | 2244 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { |
2256 s << endl | 2245 s << endl |
2257 << INDENT << "public " | 2246 << INDENT << "public " |
2258 << "this"; | 2247 << "this"; |
2259 | 2248 |
2260 if(d_class->name() == "QObject") | 2249 |
2250 Indentation indent(INDENT); | |
2251 | |
2252 s << "(void* native_id, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl | |
2253 << INDENT << "super(native_id, flags);" << endl; | |
2254 | |
2255 if (d_class->name() == "QObject") | |
2261 { | 2256 { |
2262 { | 2257 // To prevent GC from collecting the object, add it to the statically rooted linked list |
2263 Indentation indent(INDENT); | 2258 s << INDENT << " __next = __root;" << endl |
2264 s << "(void* native_id, bool gc_managed) {" << endl | 2259 << INDENT << " __root = this;" << endl |
2265 /* << INDENT << "if(!gc_managed)" << endl | 2260 << INDENT << " if (__next) {" << endl |
2266 << INDENT << " __gc_ref_list ~= this;" << endl | 2261 << INDENT << " __next.__prev = this;" << endl |
2267 << INDENT << "__gc_managed = gc_managed;" << endl */ | 2262 << INDENT << " }" << endl << endl; |
2268 << INDENT << "super(native_id);" << endl; | 2263 } |
2269 } | 2264 |
2270 } | 2265 /* |
2271 else { | |
2272 Indentation indent(INDENT); | |
2273 if(d_class->isQObject()) | |
2274 s << "(void* native_id, bool gc_managed) {" << endl | |
2275 << INDENT << "super(native_id, gc_managed);" << endl; | |
2276 else | |
2277 s << "(void* native_id, bool no_real_delete = false) {" << endl | |
2278 << INDENT << "super(native_id, no_real_delete);" << endl; | |
2279 } | |
2280 if (cpp_shared) { | 2266 if (cpp_shared) { |
2281 if (d_class->generateShellClass() && !d_class->isInterface()) | 2267 if (d_class->generateShellClass() && !d_class->isInterface()) |
2282 s << INDENT << "if (!init_flag_" << d_class->name() << ")" << endl | 2268 s << INDENT << "if (!static_inited)" << endl |
2283 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl; | 2269 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl; |
2284 } | 2270 } |
2271 */ | |
2272 | |
2285 // customized store-result instances | 2273 // customized store-result instances |
2286 d_funcs = d_class->functionsInTargetLang(); | 2274 d_funcs = d_class->functionsInTargetLang(); |
2287 for (int i=0; i<d_funcs.size(); ++i) { | 2275 for (int i=0; i<d_funcs.size(); ++i) { |
2288 AbstractMetaFunction *d_function = d_funcs.at(i); | 2276 AbstractMetaFunction *d_function = d_funcs.at(i); |
2289 uint included_attributes = 0; | 2277 uint included_attributes = 0; |
2302 type_name = type_name + "_ConcreteWrapper"; | 2290 type_name = type_name + "_ConcreteWrapper"; |
2303 | 2291 |
2304 s << INDENT << " __m_" << d_function->name() << " = new " | 2292 s << INDENT << " __m_" << d_function->name() << " = new " |
2305 << type_name << "(cast(void*)null);" << endl; | 2293 << type_name << "(cast(void*)null);" << endl; |
2306 if (d_function->type()->isQObject()) | 2294 if (d_function->type()->isQObject()) |
2307 s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl; | 2295 s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; |
2308 } | 2296 } |
2309 } | 2297 } |
2310 | 2298 |
2311 // pointers to native interface objects for classes that implement interfaces | 2299 // pointers to native interface objects for classes that implement interfaces |
2312 // initializing | 2300 // initializing |
2314 if (!interfaces.isEmpty()) { | 2302 if (!interfaces.isEmpty()) { |
2315 for (int i=0; i<interfaces.size(); ++i) { | 2303 for (int i=0; i<interfaces.size(); ++i) { |
2316 AbstractMetaClass *iface = interfaces.at(i); | 2304 AbstractMetaClass *iface = interfaces.at(i); |
2317 | 2305 |
2318 s << INDENT << " __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName() | 2306 s << INDENT << " __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName() |
2319 << "(nativeId);" << endl; | 2307 << "(__nativeId);" << endl; |
2320 } | 2308 } |
2321 } | 2309 } |
2322 | 2310 |
2323 | 2311 |
2324 s << INDENT << "}" << endl << endl; | 2312 s << INDENT << "}" << endl << endl; |
2325 | 2313 |
2326 /******************!!!DUBLICATE OF ABOVE!!!*********************/ | 2314 /******************!!!DUPLICATE OF ABOVE!!!*********************/ |
2327 for (int i=0; i<d_funcs.size(); ++i) { | 2315 for (int i=0; i<d_funcs.size(); ++i) { |
2328 AbstractMetaFunction *d_function = d_funcs.at(i); | 2316 AbstractMetaFunction *d_function = d_funcs.at(i); |
2329 uint included_attributes = 0; | 2317 uint included_attributes = 0; |
2330 uint excluded_attributes = 0; | 2318 uint excluded_attributes = 0; |
2331 setupForFunction(d_function, &included_attributes, &excluded_attributes); | 2319 setupForFunction(d_function, &included_attributes, &excluded_attributes); |
2385 } | 2373 } |
2386 */ | 2374 */ |
2387 | 2375 |
2388 /* qtd writeJavaLangObjectOverrideFunctions(s, d_class); | 2376 /* qtd writeJavaLangObjectOverrideFunctions(s, d_class); |
2389 */ | 2377 */ |
2390 writeOwnershipMethods(s, d_class); | 2378 writeFlagsSetter(s, d_class); |
2391 s << "// Injected code in class" << endl; | 2379 s << "// Injected code in class" << endl; |
2392 writeExtraFunctions(s, d_class); | 2380 writeExtraFunctions(s, d_class); |
2393 // qtd2 writeToStringFunction(s, d_class); | 2381 // qtd2 writeToStringFunction(s, d_class); |
2394 /* qtd | 2382 /* qtd |
2395 if (d_class->hasCloneOperator()) { | 2383 if (d_class->hasCloneOperator()) { |
2426 | 2414 |
2427 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl; | 2415 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl; |
2428 | 2416 |
2429 { | 2417 { |
2430 Indentation indent(INDENT); | 2418 Indentation indent(INDENT); |
2431 s << INDENT << "public this(void* native_id, bool no_real_delete = true) {" << endl | 2419 s << INDENT << "public this(void* native_id, QtdObjectFlags flags = QtdObjectFlags.nativeOwnership) {" << endl |
2432 << INDENT << " super(native_id, no_real_delete);" << endl; | 2420 << INDENT << " super(native_id, flags);" << endl << endl; |
2433 | 2421 |
2434 | 2422 /******************!!!DUPLICATE!!!*********************/ |
2435 | |
2436 | |
2437 /******************!!!DUBLICATE!!!*********************/ | |
2438 d_funcs = d_class->functionsInTargetLang(); | 2423 d_funcs = d_class->functionsInTargetLang(); |
2439 for (int i=0; i<d_funcs.size(); ++i) { | 2424 for (int i=0; i<d_funcs.size(); ++i) { |
2440 AbstractMetaFunction *d_function = d_funcs.at(i); | 2425 AbstractMetaFunction *d_function = d_funcs.at(i); |
2441 uint included_attributes = 0; | 2426 uint included_attributes = 0; |
2442 uint excluded_attributes = 0; | 2427 uint excluded_attributes = 0; |
2450 if(ctype->isAbstract()) | 2435 if(ctype->isAbstract()) |
2451 type_name = type_name + "_ConcreteWrapper"; | 2436 type_name = type_name + "_ConcreteWrapper"; |
2452 s << INDENT << " __m_" << d_function->name() << " = new " | 2437 s << INDENT << " __m_" << d_function->name() << " = new " |
2453 << type_name << "(cast(void*)null);" << endl; | 2438 << type_name << "(cast(void*)null);" << endl; |
2454 if (d_function->type()->isQObject()) | 2439 if (d_function->type()->isQObject()) |
2455 s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl; | 2440 s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; |
2456 } | 2441 } |
2457 } | 2442 } |
2458 | 2443 |
2459 s << INDENT << "}" << endl << endl; | 2444 s << INDENT << "}" << endl << endl; |
2460 | 2445 |
2507 s << INDENT << "}" << endl << endl; | 2492 s << INDENT << "}" << endl << endl; |
2508 } | 2493 } |
2509 | 2494 |
2510 if (d_class->generateShellClass()) { // qtd2 | 2495 if (d_class->generateShellClass()) { // qtd2 |
2511 if (d_class->hasVirtualFunctions() | 2496 if (d_class->hasVirtualFunctions() |
2512 && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) ) | 2497 && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) ) |
2513 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; | 2498 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; |
2514 } | 2499 } |
2515 | |
2516 if (d_class->isQObject()) | |
2517 writeQObjectFunctions(s, d_class); | |
2518 | 2500 |
2519 | 2501 |
2520 // if (d_class->needsConversionFunc) | 2502 // if (d_class->needsConversionFunc) |
2521 writeConversionFunction(s, d_class); | 2503 writeConversionFunction(s, d_class); |
2522 | 2504 |
2523 if (d_class->hasConstructors()) | 2505 if (d_class->hasConstructors() && !d_class->isQObject()) |
2524 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; | 2506 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; |
2525 | 2507 |
2526 // qtd | 2508 // qtd |
2527 s << endl << "// C wrappers" << endl; | 2509 s << endl << "// C wrappers" << endl; |
2528 d_funcs = d_class->functionsInTargetLang(); | 2510 d_funcs = d_class->functionsInTargetLang(); |
2562 const AbstractMetaFunction *function = virtualFunctions.at(pos); | 2544 const AbstractMetaFunction *function = virtualFunctions.at(pos); |
2563 if (!notWrappedYet(function)) // qtd2 | 2545 if (!notWrappedYet(function)) // qtd2 |
2564 writeShellVirtualFunction(s, function, d_class, pos); | 2546 writeShellVirtualFunction(s, function, d_class, pos); |
2565 } | 2547 } |
2566 | 2548 |
2567 //init callbacks from dll to D side | 2549 // write static constructor |
2568 if (cpp_shared) { | 2550 if (staticInit) { |
2569 bool shellClass = d_class->generateShellClass(); | 2551 QString initArgs; |
2570 if (shellClass && !d_class->isInterface()) { | 2552 if (cpp_shared) |
2571 QString initArgs = "void* virtuals"; | 2553 { |
2554 initArgs = "void* virtuals"; | |
2572 if (d_class->isQObject()) | 2555 if (d_class->isQObject()) |
2573 initArgs += ", void* signals, void* qobj_del"; | 2556 initArgs += ", void* signals"; |
2574 | 2557 |
2575 s << "private extern (C) void qtd_" << d_class->name() | 2558 s << "private extern (C) void qtd_" << d_class->name() |
2576 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl | 2559 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; |
2577 << "private bool init_flag_" << d_class->name() << " = false;" << endl | 2560 } |
2578 << "void static_init_" << d_class->name() << "() {" << endl | 2561 |
2579 << INDENT << "init_flag_" << d_class->name() << " = true;" << endl << endl | 2562 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; |
2580 | 2563 |
2581 // virtual functions | 2564 if (d_class->isQObject()) { |
2582 << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; | 2565 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl |
2566 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; | |
2567 } | |
2568 | |
2569 if (cpp_shared) { | |
2570 // virtual functions | |
2571 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; | |
2583 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { | 2572 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { |
2584 const AbstractMetaFunction *function = virtualFunctions.at(pos); | 2573 const AbstractMetaFunction *function = virtualFunctions.at(pos); |
2585 if (!notWrappedYet(function)) // qtd2 | 2574 if (!notWrappedYet(function)) // qtd2 |
2586 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName() << "_dispatch;" <<endl; | 2575 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName() << "_dispatch;" <<endl; |
2587 } | 2576 } |
2588 if (virtualFunctions.size() == 0) | 2577 if (virtualFunctions.size() == 0) |
2589 initArgs = "null"; | 2578 initArgs = "null"; |
2590 else | 2579 else |
2591 initArgs = "virt_arr.ptr"; | 2580 initArgs = "virt_arr.ptr"; |
2592 | 2581 |
2593 // signals | |
2594 if (d_class->isQObject()) { | 2582 if (d_class->isQObject()) { |
2583 | |
2584 // signals | |
2595 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); | 2585 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); |
2596 s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl; | 2586 s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl; |
2597 for(int i = 0; i < signal_funcs.size(); i++) { | 2587 for(int i = 0; i < signal_funcs.size(); i++) { |
2598 AbstractMetaFunction *signal = signal_funcs.at(i); | 2588 AbstractMetaFunction *signal = signal_funcs.at(i); |
2599 s << INDENT << "sign_arr[" << i << "] = &" << signalExternName(d_class, signal) << "_handle;" << endl; | 2589 s << INDENT << "sign_arr[" << i << "] = &" << signalExternName(d_class, signal) << "_handle;" << endl; |
2600 } | 2590 } |
2601 if(signal_funcs.size() == 0) | 2591 if(signal_funcs.size() == 0) |
2602 initArgs += ", null"; | 2592 initArgs += ", null"; |
2603 else | 2593 else |
2604 initArgs += ", sign_arr.ptr"; | 2594 initArgs += ", sign_arr.ptr"; |
2605 | 2595 } |
2606 // QObject_delete | 2596 |
2607 s << endl << INDENT << "void *qobj_del;" << endl | 2597 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl; |
2608 << INDENT << "qobj_del = &qtd_D_" << d_class->name() << "_delete;" << endl; | 2598 } |
2609 initArgs += ", qobj_del"; | 2599 |
2610 } | 2600 s << "}" << endl << endl; |
2611 | |
2612 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl | |
2613 << "}" << endl << endl; | |
2614 } | |
2615 } | 2601 } |
2616 | 2602 |
2617 writeSignalHandlers(s, d_class); | 2603 writeSignalHandlers(s, d_class); |
2618 s << endl; | 2604 s << endl; |
2619 | 2605 |
2626 foreach (AbstractMetaClass *cls, includedClassesList) { | 2612 foreach (AbstractMetaClass *cls, includedClassesList) { |
2627 m_isRecursive = true; | 2613 m_isRecursive = true; |
2628 write(s, cls); | 2614 write(s, cls); |
2629 m_isRecursive = false; | 2615 m_isRecursive = false; |
2630 } | 2616 } |
2617 | |
2618 // qtd static metaobject | |
2619 if (d_class->isQObject()) | |
2620 s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();"; | |
2631 } | 2621 } |
2632 | 2622 |
2633 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) | 2623 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) |
2634 { | 2624 { |
2635 const ComplexTypeEntry *ctype = d_class->typeEntry(); | 2625 const ComplexTypeEntry *ctype = d_class->typeEntry(); |
2636 if(!ctype->isQObject() && !ctype->isObject()) | 2626 if(ctype->isQObject() || !ctype->isObject()) |
2637 return; | 2627 return; |
2638 QString class_name = ctype->name(); | 2628 QString class_name = ctype->name(); |
2639 QString return_type_name = class_name; | 2629 QString return_type_name = class_name; |
2640 if(ctype->designatedInterface()) | 2630 if(ctype->designatedInterface()) |
2641 return_type_name = ctype->designatedInterface()->name(); | 2631 return_type_name = ctype->designatedInterface()->name(); |
2642 s << return_type_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl; | 2632 |
2643 | 2633 s << return_type_name << " qtd_" << class_name << "_from_ptr(void* ret) {" << endl; |
2644 if(ctype->isQObject()) { | 2634 |
2645 QString type_name = class_name; | 2635 |
2646 if(ctype->isAbstract()) | 2636 QString type_name = class_name; |
2647 type_name = type_name + "_ConcreteWrapper"; | 2637 if(ctype->isAbstract()) |
2648 | 2638 type_name = ctype->targetLangName() + "_ConcreteWrapper"; |
2649 s << INDENT << "if (__qt_return_value is null)" << endl | 2639 |
2650 << INDENT << " return null;" << endl | 2640 // if class has virtual functions then it has classname_entity function so |
2651 << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl | 2641 // we can look for D Object pointer. otherwise create new wrapper |
2652 << INDENT << "if (d_obj is null) {" << endl | 2642 if (d_class->hasVirtualFunctions()) { |
2653 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, false);" << endl | 2643 s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(ret);" << endl |
2654 << INDENT << " qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl | 2644 << INDENT << "if (d_obj !is null) {" << endl |
2655 << INDENT << " new_obj.__no_real_delete = true;" << endl | 2645 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl |
2656 << INDENT << " return new_obj;" << endl | 2646 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl |
2657 << INDENT << "} else" << endl | 2647 << INDENT << "} else {" << endl |
2658 << INDENT << " return cast(" << class_name << ") d_obj;" << endl; | 2648 << INDENT << " auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl |
2659 } else if (ctype->isObject()) { | 2649 << INDENT << " return return_value;" << endl |
2660 QString type_name = class_name; | 2650 << INDENT << "}" << endl; |
2661 if(ctype->isAbstract()) | 2651 } else { |
2662 type_name = ctype->targetLangName() + "_ConcreteWrapper"; | 2652 s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl |
2663 | 2653 << INDENT << "return return_value;" << endl; |
2664 // if class has virtual functions then it has classname_entity function so | |
2665 // we can look for D Object pointer. otherwise create new wrapper | |
2666 if (d_class->hasVirtualFunctions()) { | |
2667 s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(__qt_return_value);" << endl | |
2668 << INDENT << "if (d_obj !is null) {" << endl | |
2669 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl | |
2670 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl | |
2671 << INDENT << "} else {" << endl | |
2672 << INDENT << " auto return_value = new " << type_name << "(__qt_return_value, true);" << endl | |
2673 << INDENT << " return_value.__no_real_delete = true;" << endl | |
2674 << INDENT << " return return_value;" << endl | |
2675 << INDENT << "}" << endl; | |
2676 } else { | |
2677 s << INDENT << "auto return_value = new " << type_name << "(__qt_return_value, true);" << endl | |
2678 << INDENT << "return_value.__no_real_delete = true;" << endl | |
2679 << INDENT << "return return_value;" << endl; | |
2680 } | |
2681 } | 2654 } |
2682 s << "}" << endl << endl; | 2655 s << "}" << endl << endl; |
2683 } | 2656 } |
2684 | 2657 |
2685 | 2658 |
2686 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) | 2659 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) |
2687 { | 2660 { |
2688 s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl | 2661 QString concreteArg; |
2689 << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl; | 2662 if (d_class->isAbstract()) |
2690 s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl | 2663 concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; |
2691 << " auto d_ref = cast(QObject) d_ptr;" << endl | 2664 |
2692 << " d_ref.__no_real_delete = true;" << endl | 2665 s << " private static QMetaObject _staticMetaObject;" << endl |
2693 << " if(!d_ref.__qobject_is_deleting)" | 2666 << " protected static void createStaticMetaObject() {" << endl |
2694 << " delete d_ref;" << endl | 2667 << " assert(!_staticMetaObject);" << endl |
2695 << "}" << endl << endl; | 2668 << " QMetaObject base;" << endl |
2669 | |
2670 << " static if (!is(typeof(this) == QObject)) {" << endl | |
2671 << " alias BaseTypeTuple!(typeof(this))[0] B;" << endl | |
2672 << " if (!B._staticMetaObject)" << endl | |
2673 << " B.createStaticMetaObject;" << endl | |
2674 << " base = B._staticMetaObject;" << endl | |
2675 << " }" << endl | |
2676 << " _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);" << endl | |
2677 << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl | |
2678 << " }" << endl << endl | |
2679 | |
2680 << " QMetaObject metaObject() {" << endl | |
2681 << " return _staticMetaObject;" << endl | |
2682 << " }" << endl << endl | |
2683 | |
2684 << " static QMetaObject staticMetaObject() {" << endl | |
2685 << " return _staticMetaObject;" << endl | |
2686 << " }" << endl << endl | |
2687 | |
2688 << " static " << d_class->name() << " getObject(void* nativeId) {" << endl | |
2689 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl | |
2690 << " }" << endl << endl; | |
2696 } | 2691 } |
2697 | 2692 |
2698 /* | 2693 /* |
2699 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) | 2694 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) |
2700 { | 2695 { |
2703 */ | 2698 */ |
2704 void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype) | 2699 void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype) |
2705 { | 2700 { |
2706 if(ctype->isQObject()) { | 2701 if(ctype->isQObject()) { |
2707 QString type_name = ctype->name(); | 2702 QString type_name = ctype->name(); |
2708 s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl; | 2703 if (ctype->isAbstract()) |
2704 type_name += "_ConcreteWrapper"; | |
2705 s << "return " << type_name << ".getObject(ret);" << endl; | |
2709 } else if (ctype->isValue() && !ctype->isStructInD()) { | 2706 } else if (ctype->isValue() && !ctype->isStructInD()) { |
2710 s << INDENT << "return new " << ctype->name() << "(__qt_return_value, false);" << endl; | 2707 s << INDENT << "return new " << ctype->name() << "(ret);" << endl; |
2711 } else if (ctype->isVariant()) { | 2708 } else if (ctype->isVariant()) { |
2712 s << INDENT << "return new QVariant(__qt_return_value, false);" << endl; | 2709 s << INDENT << "return new QVariant(ret);" << endl; |
2713 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { | 2710 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { |
2714 s << INDENT << "return __qt_return_value;" << endl; | 2711 s << INDENT << "return ret;" << endl; |
2715 } else if (ctype->isObject()) { | 2712 } else if (ctype->isObject()) { |
2716 QString type_name = ctype->name(); | 2713 QString type_name = ctype->name(); |
2717 s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl; | 2714 s << "return qtd_" << type_name << "_from_ptr(ret);" << endl; |
2718 } | 2715 } |
2719 } | 2716 } |
2720 | 2717 |
2721 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) | 2718 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) |
2722 { | 2719 { |
2777 | 2774 |
2778 s << INDENT << "private final void onFirstSlot(int signalId) {" << endl; | 2775 s << INDENT << "private final void onFirstSlot(int signalId) {" << endl; |
2779 { | 2776 { |
2780 Indentation indent(INDENT); | 2777 Indentation indent(INDENT); |
2781 s << INDENT << "if (signalId < __slotConnectors.length) {" << endl; | 2778 s << INDENT << "if (signalId < __slotConnectors.length) {" << endl; |
2782 s << INDENT << " __slotConnectors[signalId](nativeId);" << endl; | 2779 s << INDENT << " __slotConnectors[signalId](__nativeId);" << endl; |
2783 s << INDENT << "}" << endl; | 2780 s << INDENT << "}" << endl; |
2784 } | 2781 } |
2785 s << INDENT << "}" << endl; | 2782 s << INDENT << "}" << endl; |
2786 | 2783 |
2787 s << INDENT << "private final void onLastSlot(int signalId) {" << endl; | 2784 s << INDENT << "private final void onLastSlot(int signalId) {" << endl; |
2788 { | 2785 { |
2789 Indentation indent(INDENT); | 2786 Indentation indent(INDENT); |
2790 s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl; | 2787 s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl; |
2791 s << INDENT << " __slotDisconnectors[signalId](nativeId);" << endl; | 2788 s << INDENT << " __slotDisconnectors[signalId](__nativeId);" << endl; |
2792 s << INDENT << "}" << endl; | 2789 s << INDENT << "}" << endl; |
2793 } | 2790 } |
2794 s << INDENT << "}" << endl; | 2791 s << INDENT << "}" << endl; |
2795 } | 2792 } |
2796 | 2793 |
2852 << arg_name << "[0.." << arg_name << "_size]);"; | 2849 << arg_name << "[0.." << arg_name << "_size]);"; |
2853 else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") { | 2850 else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") { |
2854 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl | 2851 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl |
2855 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; | 2852 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; |
2856 } else if(type->isVariant()) | 2853 } else if(type->isVariant()) |
2857 s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", true);"; | 2854 s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; |
2858 else if (type->typeEntry()->isStructInD()) | 2855 else if (type->typeEntry()->isStructInD()) |
2859 continue; | 2856 continue; |
2860 else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer())) | 2857 else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer())) |
2861 continue; | 2858 continue; |
2862 else if(type->isObject() | 2859 else if(type->isObject() |
2864 || type->isValue() || type->isVariant()) { | 2861 || type->isValue() || type->isVariant()) { |
2865 QString type_name = type->typeEntry()->name(); | 2862 QString type_name = type->typeEntry()->name(); |
2866 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); | 2863 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); |
2867 if(ctype->isAbstract()) | 2864 if(ctype->isAbstract()) |
2868 type_name = type_name + "_ConcreteWrapper"; | 2865 type_name = type_name + "_ConcreteWrapper"; |
2869 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", true);"; | 2866 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; |
2870 } | 2867 } |
2871 else if (type->isQObject()) { | 2868 else if (type->isQObject()) { |
2872 QString type_name = type->name(); | 2869 QString type_name = type->name(); |
2873 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); | 2870 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); |
2874 if(ctype->isAbstract()) | 2871 if(ctype->isAbstract()) |
2875 type_name = type_name + "_ConcreteWrapper"; | 2872 type_name = type_name + "_ConcreteWrapper"; |
2876 | 2873 |
2877 s << INDENT << "scope " << arg_name << "_so = new StackObject!(" << type_name << ");" << endl | 2874 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);" << endl; |
2878 << INDENT << "auto " << arg_name << "_d_ref = " << arg_name << "_so(" << arg_name <<", true);" << endl | |
2879 << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; | |
2880 /* | |
2881 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name <<", true);" << endl | |
2882 << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; | |
2883 */ | |
2884 } | 2875 } |
2885 s << endl; | 2876 s << endl; |
2886 } | 2877 } |
2887 } | 2878 } |
2888 | 2879 |
2957 if(has_return_type) { | 2948 if(has_return_type) { |
2958 AbstractMetaType *f_type = d_function->type(); | 2949 AbstractMetaType *f_type = d_function->type(); |
2959 if(f_type) { | 2950 if(f_type) { |
2960 if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() || | 2951 if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() || |
2961 (f_type->isValue() && !f_type->typeEntry()->isStructInD())) { | 2952 (f_type->isValue() && !f_type->typeEntry()->isStructInD())) { |
2962 QString native_id = "nativeId"; | 2953 QString native_id = "__nativeId"; |
2963 if (f_type->typeEntry()->designatedInterface()) | 2954 if (f_type->typeEntry()->designatedInterface()) |
2964 native_id = "__ptr_" + f_type->typeEntry()->designatedInterface()->name(); | 2955 native_id = "__ptr_" + f_type->typeEntry()->designatedInterface()->name(); |
2965 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl; | 2956 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl; |
2966 } else if (f_type->isTargetLangString()) | 2957 } else if (f_type->isTargetLangString()) |
2967 s << INDENT << "*ret_str = _d_str;" << endl; | 2958 s << INDENT << "*ret_str = _d_str;" << endl; |
3253 if (snip.language == TypeSystem::Constructors) { | 3244 if (snip.language == TypeSystem::Constructors) { |
3254 snip.formattedCode(s, INDENT); | 3245 snip.formattedCode(s, INDENT); |
3255 } | 3246 } |
3256 } | 3247 } |
3257 | 3248 |
3258 if(d_function->implementingClass()->isQObject()) | 3249 s << INDENT << "this(ret);" << endl; |
3259 { | |
3260 bool hasParentArg = false; | |
3261 AbstractMetaArgumentList arguments = d_function->arguments(); | |
3262 int arg_index = 0; | |
3263 for (int i=0; i<arguments.count(); ++i) { | |
3264 const AbstractMetaArgument *arg = arguments.at(i); | |
3265 if (arg->argumentName().contains("parent", Qt::CaseInsensitive)) { | |
3266 arg_index = i; | |
3267 hasParentArg = true; | |
3268 } | |
3269 } | |
3270 | |
3271 const AbstractMetaArgument *arg = arguments.at(arg_index); | |
3272 // QString ctor_call = d_function->implementingClass()->name() == "QObject"? "this" : "super"; | |
3273 QString ctor_call = "this"; | |
3274 if (hasParentArg) { | |
3275 s << INDENT << "bool gc_managed = " << arg->argumentName() << " is null ? true : false;" << endl | |
3276 << INDENT << ctor_call << "(__qt_return_value, gc_managed);" << endl; | |
3277 } else { | |
3278 s << INDENT << ctor_call << "(__qt_return_value, true);" << endl; | |
3279 } | |
3280 | |
3281 // creating a link object associated with the current QObject for signal handling and metadata | |
3282 s << INDENT << "qtd_" << d_function->ownerClass()->name() << "_create_link(this.nativeId, cast(void*) this);" << endl; | |
3283 } | |
3284 else | |
3285 s << INDENT << "this(__qt_return_value);" << endl; | |
3286 } | 3250 } |
3287 s << INDENT << "}" << endl << endl; | 3251 s << INDENT << "}" << endl << endl; |
3288 | 3252 |
3289 /* qtd // Write native constructor | 3253 /* qtd // Write native constructor |
3290 if (d_function->jumpTableId() == -1) | 3254 if (d_function->jumpTableId() == -1) |
3351 << " }" << endl; | 3315 << " }" << endl; |
3352 } else { | 3316 } else { |
3353 s << endl | 3317 s << endl |
3354 << " @Override" << endl | 3318 << " @Override" << endl |
3355 << " public String toString() {" << endl | 3319 << " public String toString() {" << endl |
3356 << " if (nativeId() == 0)" << endl | 3320 << " if (__nativeId == 0)" << endl |
3357 << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl | 3321 << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl |
3358 << " return __qt_toString(nativeId());" << endl | 3322 << " return __qt_toString(nativeId());" << endl |
3359 << " }" << endl | 3323 << " }" << endl |
3360 << " native String __qt_toString(long __this_nativeId);" << endl; | 3324 << " native String __qt_toString(long __this_nativeId);" << endl; |
3361 } | 3325 } |