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 }