comparison generator/dgenerator.cpp @ 252:37eed70de029

More things broken than fixed. Rolling back to 263
author maxter
date Sat, 22 Aug 2009 12:50:58 +0000
parents 7664de4a55e5
children 073b9153ed8a
comparison
equal deleted inserted replaced
251:739d0ee5bd91 252:37eed70de029
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 "__setFlags(QtdObjectFlags.nativeOwnership, true)"; 482 return "__set_native_ownership(true)";
483 } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { 483 } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ {
484 return "__setFlags(QtdObjectFlags.nativeOwnership, false)"; 484 return "__set_native_ownership(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 *ret = "; 699 s << "void *__qt_return_value = ";
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* ret = "; 703 s << "void* __qt_return_value = ";
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* ret = "; 705 s << "void* __qt_return_value = ";
706 } else if (return_type && return_type->isVariant()) { 706 } else if (return_type && return_type->isVariant()) {
707 s << "void* ret = "; 707 s << "void* __qt_return_value = ";
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* ret = "; 711 s << "void* __qt_return_value = ";
712 } else if (return_type && return_type->isArray()) { 712 } else if (return_type && return_type->isArray()) {
713 s << return_type->arrayElementType()->name() + "* ret = "; 713 s << return_type->arrayElementType()->name() + "* __qt_return_value = ";
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 (ret != null) {" << endl; 867 s << INDENT << "if (__qt_return_value != null) {" << endl;
868 if (return_type->isContainer()) 868 if (return_type->isContainer())
869 writeOwnershipForContainer(s, owner, return_type, "ret"); 869 writeOwnershipForContainer(s, owner, return_type, "__qt_return_value");
870 else 870 else
871 s << INDENT << " ret." << function_call_for_ownership(owner) << ";" << endl; 871 s << INDENT << " __qt_return_value." << function_call_for_ownership(owner) << ";" << endl;
872 s << INDENT << "}" << endl; 872 s << INDENT << "}" << endl;
873 } 873 }
874 s << INDENT << "return ret;" << endl; 874 s << INDENT << "return __qt_return_value;" << 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 {
897 if(return_type->isQObject()) 896 if(return_type->isQObject())
898 s << return_type->name() << ".getObject(ret);" << endl; 897 s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
899 }
900 898
901 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) 899 if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
902 s << "new " << return_type->name() << "(ret);" << endl; 900 s << "new " << return_type->name() << "(__qt_return_value, false);" << endl;
903 901
904 if (return_type->isVariant()) 902 if (return_type->isVariant())
905 s << "new QVariant(ret);" << endl; 903 s << "new QVariant(__qt_return_value, false);" << endl;
906 904
907 if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) 905 if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
908 s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl; 906 s << "new " << return_type->name() << "(__qt_return_value, true);" << endl;
909 907
910 if (return_type->isObject()) { 908 if (return_type->isObject()) {
911 if(d_function->storeResult()) 909 if(d_function->storeResult())
912 s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl 910 s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl
913 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; 911 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl;
914 else 912 else
915 s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl; 913 s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
916 s << endl; 914 s << endl;
917 } 915 }
918 916
919 if (return_type->isArray()) { 917 if (return_type->isArray()) {
920 s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl; 918 s << "__qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl;
921 } 919 }
922 920
923 foreach (ReferenceCount referenceCount, referenceCounts) { 921 foreach (ReferenceCount referenceCount, referenceCounts) {
924 writeReferenceCount(s, referenceCount, "__d_return_value"); 922 writeReferenceCount(s, referenceCount, "__d_return_value");
925 } 923 }
1680 void DGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *d_class) 1678 void DGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *d_class)
1681 { 1679 {
1682 if (!d_class->hasConstructors()) 1680 if (!d_class->hasConstructors())
1683 return; 1681 return;
1684 1682
1685 bool isTheQObject = d_class->name() == "QObject"; 1683 s << endl;
1686 if (isTheQObject || !d_class->isQObject()) 1684 if (d_class->baseClassName().isEmpty()) {
1685 s << INDENT << "~this() { " << endl;
1686 {
1687 Indentation indent(INDENT);
1688
1689 /*
1690 if(d_class->name() == "QObject")
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 }
1709 s << INDENT << "}" << endl << endl;
1710 }
1711
1712 s << INDENT << "protected void __free_native_resources() {" << endl;
1687 { 1713 {
1688 s << INDENT << "protected override void __deleteNative() {" << endl; 1714 Indentation indent(INDENT);
1689 { 1715 s << INDENT << "qtd_" << d_class->name() << "_destructor(nativeId());" << endl;
1690 if (isTheQObject) 1716 }
1691 s << INDENT << "qtd_delete_qobject(__nativeId);" << endl; 1717 s << INDENT << "}" << endl << endl;
1692 else if (!d_class->isQObject()) 1718 }
1693 s << INDENT << "qtd_" << d_class->name() << "_destructor(__nativeId);" << endl; 1719
1694 } 1720 void DGenerator::writeOwnershipMethods(QTextStream &s, const AbstractMetaClass *d_class)
1695 s << INDENT << "}" << endl << endl; 1721 {
1696 } 1722 s << INDENT << "void __set_native_ownership(bool ownership_)";
1697 }
1698
1699 void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class)
1700 {
1701 if (d_class->isInterface() || d_class->isNamespace()) 1723 if (d_class->isInterface() || d_class->isNamespace())
1702 s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);"; 1724 s << ";";
1703 else // COMPILER BUG: 1725 else {
1704 s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }"; 1726 s << " {" << endl
1727 << INDENT << " __no_real_delete = ownership_;" << endl
1728 << INDENT << "}" << endl << endl;
1729 }
1705 } 1730 }
1706 1731
1707 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) 1732 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class)
1708 { 1733 {
1709 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); 1734 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class);
1710 1735
1736 //TODO: linkage trivia should be abstracted away
1711 QString attr; 1737 QString attr;
1712 1738
1713 s << "// signal handlers" << endl; 1739 s << "// signal handlers" << endl;
1714 foreach(AbstractMetaFunction *signal, signal_funcs) { 1740 foreach(AbstractMetaFunction *signal, signal_funcs) {
1715 QString sigExternName = signalExternName(d_class, signal); 1741 QString sigExternName = signalExternName(d_class, signal);
1761 QString type_name = type->name(); 1787 QString type_name = type->name();
1762 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); 1788 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
1763 if(ctype->isAbstract()) 1789 if(ctype->isAbstract())
1764 type_name = type_name + "_ConcreteWrapper"; 1790 type_name = type_name + "_ConcreteWrapper";
1765 s << INDENT << "scope " << arg_name << " = new " << type_name 1791 s << INDENT << "scope " << arg_name << " = new " << type_name
1766 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl; 1792 << "(cast(void*)(" << arg_ptr << "), true);" << endl
1793 << INDENT << arg_name << ".__no_real_delete = true;";
1767 } 1794 }
1768 s << endl; 1795 s << endl;
1769 } 1796 }
1770 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl; 1797 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl;
1771 s << INDENT << "d_object." << signal->name() << ".emit("; 1798 s << INDENT << "d_object." << signal->name() << ".emit(";
1786 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class) 1813 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class)
1787 { 1814 {
1788 ReportHandler::debugSparse("Generating class: " + d_class->fullName()); 1815 ReportHandler::debugSparse("Generating class: " + d_class->fullName());
1789 1816
1790 bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; 1817 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 }
1805 1818
1806 if (m_docs_enabled) { 1819 if (m_docs_enabled) {
1807 m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc"); 1820 m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc");
1808 } 1821 }
1809 if (!m_isRecursive) 1822 if (!m_isRecursive)
1882 if (inc.type == Include::TargetLangImport) { 1895 if (inc.type == Include::TargetLangImport) {
1883 s << inc.toString() << endl; 1896 s << inc.toString() << endl;
1884 } 1897 }
1885 } 1898 }
1886 1899
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
1901 if (!m_isRecursive) { 1900 if (!m_isRecursive) {
1902 s << "public import qt.QGlobal;" << endl 1901 s << "public import qt.QGlobal;" << endl
1903 << "public import qt.core.Qt;" << endl 1902 << "public import qt.core.Qt;" << endl
1904 << "private import qt.QtdObject;" << endl 1903 << "private import qt.QtDObject;" << endl
1905 << "private import qt.core.QString;" << endl 1904 << "private import qt.core.QString;" << endl
1906 << "private import qt.qtd.Array;" << endl; 1905 << "private import qt.qtd.Array;" << endl;
1907 if (d_class->isQObject()) { 1906 if (d_class->isQObject()) {
1908 s << "public import qt.Signal;" << endl 1907 s << "public import qt.Signal;" << endl;
1909 << "public import qt.core.QMetaObject;" << endl
1910 << "public import qt.qtd.Traits;" << endl;
1911
1912 if (d_class->name() != "QObject") 1908 if (d_class->name() != "QObject")
1913 s << "public import qt.core.QObject;" << endl; 1909 s << "public import qt.core.QObject;" << endl;
1914 } 1910 }
1915 1911
1916 // qtd2 hack! 1912 // qtd2 hack!
1926 for other usages - then restrict it just for namespaces/interfaces 1922 for other usages - then restrict it just for namespaces/interfaces
1927 */ 1923 */
1928 if(d_class->isQObject()) 1924 if(d_class->isQObject())
1929 s << "private import " << d_class->package() << ".ArrayOps2;" << endl; 1925 s << "private import " << d_class->package() << ".ArrayOps2;" << endl;
1930 1926
1927 if (!d_class->enums().isEmpty())
1928 s << "public import " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl;
1929
1931 s << "// automatic imports-------------" << endl; 1930 s << "// automatic imports-------------" << endl;
1932 writeRequiredImports(s, d_class); 1931 writeRequiredImports(s, d_class);
1933 s << endl; 1932 s << endl;
1934 if (dPhobos) 1933 if (dPhobos)
1935 { 1934 {
1936 s << "import std.stdio;" << endl 1935 s << "import std.stdio;" << endl
1937 << "import std.string;" << endl 1936 << "import std.string;" << endl
1938 << "import std.utf;" << endl 1937 << "import std.utf;" << endl
1939 << "import core.memory;" << endl; 1938 << "import core.memory;";
1940 } 1939 }
1941 else 1940 else
1942 { 1941 {
1943 s << "import tango.io.Stdout;" << endl 1942 s << "import tango.io.Stdout;" << endl
1944 << "import tango.stdc.stringz;" << endl 1943 << "import tango.stdc.stringz;" << endl
1945 << "import tango.text.convert.Utf;" << endl 1944 << "import tango.text.convert.Utf;" << endl
1946 << "import tango.core.Memory;" << endl; 1945 << "import tango.core.Memory;";
1947 } 1946 }
1948 1947 s << endl << endl << endl;
1949 s << endl << endl;
1950 } 1948 }
1951 1949
1952 if (m_doc_parser) { 1950 if (m_doc_parser) {
1953 s << m_doc_parser->documentation(d_class) << endl << endl; 1951 s << m_doc_parser->documentation(d_class) << endl << endl;
1954 } 1952 }
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;
1955 1966
1956 /* qtd s << "@QtJambiGeneratedClass" << endl; 1967 /* qtd s << "@QtJambiGeneratedClass" << endl;
1957 1968
1958 if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) { 1969 if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) {
1959 s << "@Deprecated" << endl; 1970 s << "@Deprecated" << endl;
2142 */ 2153 */
2143 2154
2144 // Enums aliaases 2155 // Enums aliaases
2145 foreach (AbstractMetaEnum *d_enum, d_class->enums()) 2156 foreach (AbstractMetaEnum *d_enum, d_class->enums())
2146 writeEnumAlias(s, d_enum); 2157 writeEnumAlias(s, d_enum);
2158
2159 if (!d_class->enums().isEmpty() && !d_class->functions().isEmpty())
2160 s << endl;
2147 2161
2148 // Signals 2162 // Signals
2149 AbstractMetaFunctionList signal_funcs; 2163 AbstractMetaFunctionList signal_funcs;
2150 2164
2151 signal_funcs = signalFunctions(d_class); 2165 signal_funcs = signalFunctions(d_class);
2235 << endl 2249 << endl
2236 << INDENT << "@QtBlockedSlot" << endl 2250 << INDENT << "@QtBlockedSlot" << endl
2237 << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl; 2251 << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl;
2238 } 2252 }
2239 */ 2253 */
2240 if (d_class->isQObject())
2241 writeQObjectFunctions(s, d_class);
2242
2243 // Add dummy constructor for use when constructing subclasses 2254 // Add dummy constructor for use when constructing subclasses
2244 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { 2255 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
2245 s << endl 2256 s << endl
2246 << INDENT << "public " 2257 << INDENT << "public "
2247 << "this"; 2258 << "this";
2248 2259
2249 2260 if(d_class->name() == "QObject")
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")
2256 { 2261 {
2257 // To prevent GC from collecting the object, add it to the statically rooted linked list 2262 {
2258 s << INDENT << " __next = __root;" << endl 2263 Indentation indent(INDENT);
2259 << INDENT << " __root = this;" << endl 2264 s << "(void* native_id, bool gc_managed) {" << endl
2260 << INDENT << " if (__next) {" << endl 2265 /* << INDENT << "if(!gc_managed)" << endl
2261 << INDENT << " __next.__prev = this;" << endl 2266 << INDENT << " __gc_ref_list ~= this;" << endl
2262 << INDENT << " }" << endl << endl; 2267 << INDENT << "__gc_managed = gc_managed;" << endl */
2263 } 2268 << INDENT << "super(native_id);" << endl;
2264 2269 }
2265 /* 2270 }
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 }
2266 if (cpp_shared) { 2280 if (cpp_shared) {
2267 if (d_class->generateShellClass() && !d_class->isInterface()) 2281 if (d_class->generateShellClass() && !d_class->isInterface())
2268 s << INDENT << "if (!static_inited)" << endl 2282 s << INDENT << "if (!init_flag_" << d_class->name() << ")" << endl
2269 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl; 2283 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl;
2270 } 2284 }
2271 */
2272
2273 // customized store-result instances 2285 // customized store-result instances
2274 d_funcs = d_class->functionsInTargetLang(); 2286 d_funcs = d_class->functionsInTargetLang();
2275 for (int i=0; i<d_funcs.size(); ++i) { 2287 for (int i=0; i<d_funcs.size(); ++i) {
2276 AbstractMetaFunction *d_function = d_funcs.at(i); 2288 AbstractMetaFunction *d_function = d_funcs.at(i);
2277 uint included_attributes = 0; 2289 uint included_attributes = 0;
2290 type_name = type_name + "_ConcreteWrapper"; 2302 type_name = type_name + "_ConcreteWrapper";
2291 2303
2292 s << INDENT << " __m_" << d_function->name() << " = new " 2304 s << INDENT << " __m_" << d_function->name() << " = new "
2293 << type_name << "(cast(void*)null);" << endl; 2305 << type_name << "(cast(void*)null);" << endl;
2294 if (d_function->type()->isQObject()) 2306 if (d_function->type()->isQObject())
2295 s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; 2307 s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl;
2296 } 2308 }
2297 } 2309 }
2298 2310
2299 // pointers to native interface objects for classes that implement interfaces 2311 // pointers to native interface objects for classes that implement interfaces
2300 // initializing 2312 // initializing
2302 if (!interfaces.isEmpty()) { 2314 if (!interfaces.isEmpty()) {
2303 for (int i=0; i<interfaces.size(); ++i) { 2315 for (int i=0; i<interfaces.size(); ++i) {
2304 AbstractMetaClass *iface = interfaces.at(i); 2316 AbstractMetaClass *iface = interfaces.at(i);
2305 2317
2306 s << INDENT << " __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName() 2318 s << INDENT << " __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName()
2307 << "(__nativeId);" << endl; 2319 << "(nativeId);" << endl;
2308 } 2320 }
2309 } 2321 }
2310 2322
2311 2323
2312 s << INDENT << "}" << endl << endl; 2324 s << INDENT << "}" << endl << endl;
2313 2325
2314 /******************!!!DUPLICATE OF ABOVE!!!*********************/ 2326 /******************!!!DUBLICATE OF ABOVE!!!*********************/
2315 for (int i=0; i<d_funcs.size(); ++i) { 2327 for (int i=0; i<d_funcs.size(); ++i) {
2316 AbstractMetaFunction *d_function = d_funcs.at(i); 2328 AbstractMetaFunction *d_function = d_funcs.at(i);
2317 uint included_attributes = 0; 2329 uint included_attributes = 0;
2318 uint excluded_attributes = 0; 2330 uint excluded_attributes = 0;
2319 setupForFunction(d_function, &included_attributes, &excluded_attributes); 2331 setupForFunction(d_function, &included_attributes, &excluded_attributes);
2373 } 2385 }
2374 */ 2386 */
2375 2387
2376 /* qtd writeJavaLangObjectOverrideFunctions(s, d_class); 2388 /* qtd writeJavaLangObjectOverrideFunctions(s, d_class);
2377 */ 2389 */
2378 writeFlagsSetter(s, d_class); 2390 writeOwnershipMethods(s, d_class);
2379 s << "// Injected code in class" << endl; 2391 s << "// Injected code in class" << endl;
2380 writeExtraFunctions(s, d_class); 2392 writeExtraFunctions(s, d_class);
2381 // qtd2 writeToStringFunction(s, d_class); 2393 // qtd2 writeToStringFunction(s, d_class);
2382 /* qtd 2394 /* qtd
2383 if (d_class->hasCloneOperator()) { 2395 if (d_class->hasCloneOperator()) {
2414 2426
2415 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl; 2427 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl;
2416 2428
2417 { 2429 {
2418 Indentation indent(INDENT); 2430 Indentation indent(INDENT);
2419 s << INDENT << "public this(void* native_id, QtdObjectFlags flags = QtdObjectFlags.nativeOwnership) {" << endl 2431 s << INDENT << "public this(void* native_id, bool no_real_delete = true) {" << endl
2420 << INDENT << " super(native_id, flags);" << endl << endl; 2432 << INDENT << " super(native_id, no_real_delete);" << endl;
2421 2433
2422 /******************!!!DUPLICATE!!!*********************/ 2434
2435
2436
2437 /******************!!!DUBLICATE!!!*********************/
2423 d_funcs = d_class->functionsInTargetLang(); 2438 d_funcs = d_class->functionsInTargetLang();
2424 for (int i=0; i<d_funcs.size(); ++i) { 2439 for (int i=0; i<d_funcs.size(); ++i) {
2425 AbstractMetaFunction *d_function = d_funcs.at(i); 2440 AbstractMetaFunction *d_function = d_funcs.at(i);
2426 uint included_attributes = 0; 2441 uint included_attributes = 0;
2427 uint excluded_attributes = 0; 2442 uint excluded_attributes = 0;
2435 if(ctype->isAbstract()) 2450 if(ctype->isAbstract())
2436 type_name = type_name + "_ConcreteWrapper"; 2451 type_name = type_name + "_ConcreteWrapper";
2437 s << INDENT << " __m_" << d_function->name() << " = new " 2452 s << INDENT << " __m_" << d_function->name() << " = new "
2438 << type_name << "(cast(void*)null);" << endl; 2453 << type_name << "(cast(void*)null);" << endl;
2439 if (d_function->type()->isQObject()) 2454 if (d_function->type()->isQObject())
2440 s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; 2455 s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl;
2441 } 2456 }
2442 } 2457 }
2443 2458
2444 s << INDENT << "}" << endl << endl; 2459 s << INDENT << "}" << endl << endl;
2445 2460
2492 s << INDENT << "}" << endl << endl; 2507 s << INDENT << "}" << endl << endl;
2493 } 2508 }
2494 2509
2495 if (d_class->generateShellClass()) { // qtd2 2510 if (d_class->generateShellClass()) { // qtd2
2496 if (d_class->hasVirtualFunctions() 2511 if (d_class->hasVirtualFunctions()
2497 && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) ) 2512 && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) )
2498 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; 2513 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl;
2499 } 2514 }
2515
2516 if (d_class->isQObject())
2517 writeQObjectFunctions(s, d_class);
2500 2518
2501 2519
2502 // if (d_class->needsConversionFunc) 2520 // if (d_class->needsConversionFunc)
2503 writeConversionFunction(s, d_class); 2521 writeConversionFunction(s, d_class);
2504 2522
2505 if (d_class->hasConstructors() && !d_class->isQObject()) 2523 if (d_class->hasConstructors())
2506 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; 2524 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl;
2507 2525
2508 // qtd 2526 // qtd
2509 s << endl << "// C wrappers" << endl; 2527 s << endl << "// C wrappers" << endl;
2510 d_funcs = d_class->functionsInTargetLang(); 2528 d_funcs = d_class->functionsInTargetLang();
2544 const AbstractMetaFunction *function = virtualFunctions.at(pos); 2562 const AbstractMetaFunction *function = virtualFunctions.at(pos);
2545 if (!notWrappedYet(function)) // qtd2 2563 if (!notWrappedYet(function)) // qtd2
2546 writeShellVirtualFunction(s, function, d_class, pos); 2564 writeShellVirtualFunction(s, function, d_class, pos);
2547 } 2565 }
2548 2566
2549 // write static constructor 2567 //init callbacks from dll to D side
2550 if (staticInit) { 2568 if (cpp_shared) {
2551 QString initArgs; 2569 bool shellClass = d_class->generateShellClass();
2552 if (cpp_shared) 2570 if (shellClass && !d_class->isInterface()) {
2553 { 2571 QString initArgs = "void* virtuals";
2554 initArgs = "void* virtuals";
2555 if (d_class->isQObject()) 2572 if (d_class->isQObject())
2556 initArgs += ", void* signals"; 2573 initArgs += ", void* signals, void* qobj_del";
2557 2574
2558 s << "private extern (C) void qtd_" << d_class->name() 2575 s << "private extern (C) void qtd_" << d_class->name()
2559 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; 2576 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl
2560 } 2577 << "private bool init_flag_" << d_class->name() << " = false;" << endl
2561 2578 << "void static_init_" << d_class->name() << "() {" << endl
2562 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2579 << INDENT << "init_flag_" << d_class->name() << " = true;" << endl << endl
2563 2580
2564 if (d_class->isQObject()) { 2581 // virtual functions
2565 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl 2582 << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << 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;
2572 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { 2583 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
2573 const AbstractMetaFunction *function = virtualFunctions.at(pos); 2584 const AbstractMetaFunction *function = virtualFunctions.at(pos);
2574 if (!notWrappedYet(function)) // qtd2 2585 if (!notWrappedYet(function)) // qtd2
2575 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName() << "_dispatch;" <<endl; 2586 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName() << "_dispatch;" <<endl;
2576 } 2587 }
2577 if (virtualFunctions.size() == 0) 2588 if (virtualFunctions.size() == 0)
2578 initArgs = "null"; 2589 initArgs = "null";
2579 else 2590 else
2580 initArgs = "virt_arr.ptr"; 2591 initArgs = "virt_arr.ptr";
2581 2592
2593 // signals
2582 if (d_class->isQObject()) { 2594 if (d_class->isQObject()) {
2583
2584 // signals
2585 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); 2595 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class);
2586 s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl; 2596 s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl;
2587 for(int i = 0; i < signal_funcs.size(); i++) { 2597 for(int i = 0; i < signal_funcs.size(); i++) {
2588 AbstractMetaFunction *signal = signal_funcs.at(i); 2598 AbstractMetaFunction *signal = signal_funcs.at(i);
2589 s << INDENT << "sign_arr[" << i << "] = &" << signalExternName(d_class, signal) << "_handle;" << endl; 2599 s << INDENT << "sign_arr[" << i << "] = &" << signalExternName(d_class, signal) << "_handle;" << endl;
2590 } 2600 }
2591 if(signal_funcs.size() == 0) 2601 if(signal_funcs.size() == 0)
2592 initArgs += ", null"; 2602 initArgs += ", null";
2593 else 2603 else
2594 initArgs += ", sign_arr.ptr"; 2604 initArgs += ", sign_arr.ptr";
2595 } 2605
2596 2606 // QObject_delete
2597 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl; 2607 s << endl << INDENT << "void *qobj_del;" << endl
2598 } 2608 << INDENT << "qobj_del = &qtd_D_" << d_class->name() << "_delete;" << endl;
2599 2609 initArgs += ", qobj_del";
2600 s << "}" << endl << endl; 2610 }
2611
2612 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl
2613 << "}" << endl << endl;
2614 }
2601 } 2615 }
2602 2616
2603 writeSignalHandlers(s, d_class); 2617 writeSignalHandlers(s, d_class);
2604 s << endl; 2618 s << endl;
2605 2619
2612 foreach (AbstractMetaClass *cls, includedClassesList) { 2626 foreach (AbstractMetaClass *cls, includedClassesList) {
2613 m_isRecursive = true; 2627 m_isRecursive = true;
2614 write(s, cls); 2628 write(s, cls);
2615 m_isRecursive = false; 2629 m_isRecursive = false;
2616 } 2630 }
2617
2618 // qtd static metaobject
2619 if (d_class->isQObject())
2620 s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();";
2621 } 2631 }
2622 2632
2623 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) 2633 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class)
2624 { 2634 {
2625 const ComplexTypeEntry *ctype = d_class->typeEntry(); 2635 const ComplexTypeEntry *ctype = d_class->typeEntry();
2626 if(ctype->isQObject() || !ctype->isObject()) 2636 if(!ctype->isQObject() && !ctype->isObject())
2627 return; 2637 return;
2628 QString class_name = ctype->name(); 2638 QString class_name = ctype->name();
2629 QString return_type_name = class_name; 2639 QString return_type_name = class_name;
2630 if(ctype->designatedInterface()) 2640 if(ctype->designatedInterface())
2631 return_type_name = ctype->designatedInterface()->name(); 2641 return_type_name = ctype->designatedInterface()->name();
2632 2642 s << return_type_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl;
2633 s << return_type_name << " qtd_" << class_name << "_from_ptr(void* ret) {" << endl; 2643
2634 2644 if(ctype->isQObject()) {
2635 2645 QString type_name = class_name;
2636 QString type_name = class_name; 2646 if(ctype->isAbstract())
2637 if(ctype->isAbstract()) 2647 type_name = type_name + "_ConcreteWrapper";
2638 type_name = ctype->targetLangName() + "_ConcreteWrapper"; 2648
2639 2649 s << INDENT << "if (__qt_return_value is null)" << endl
2640 // if class has virtual functions then it has classname_entity function so 2650 << INDENT << " return null;" << endl
2641 // we can look for D Object pointer. otherwise create new wrapper 2651 << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl
2642 if (d_class->hasVirtualFunctions()) { 2652 << INDENT << "if (d_obj is null) {" << endl
2643 s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(ret);" << endl 2653 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, false);" << endl
2644 << INDENT << "if (d_obj !is null) {" << endl 2654 << INDENT << " qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl
2645 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl 2655 << INDENT << " new_obj.__no_real_delete = true;" << endl
2646 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl 2656 << INDENT << " return new_obj;" << endl
2647 << INDENT << "} else {" << endl 2657 << INDENT << "} else" << endl
2648 << INDENT << " auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl 2658 << INDENT << " return cast(" << class_name << ") d_obj;" << endl;
2649 << INDENT << " return return_value;" << endl 2659 } else if (ctype->isObject()) {
2650 << INDENT << "}" << endl; 2660 QString type_name = class_name;
2651 } else { 2661 if(ctype->isAbstract())
2652 s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl 2662 type_name = ctype->targetLangName() + "_ConcreteWrapper";
2653 << INDENT << "return return_value;" << endl; 2663
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 }
2654 } 2681 }
2655 s << "}" << endl << endl; 2682 s << "}" << endl << endl;
2656 } 2683 }
2657 2684
2658 2685
2659 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2686 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2660 { 2687 {
2661 QString concreteArg; 2688 s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl
2662 if (d_class->isAbstract()) 2689 << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl;
2663 concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; 2690 s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl
2664 2691 << " auto d_ref = cast(QObject) d_ptr;" << endl
2665 s << " private static QMetaObject _staticMetaObject;" << endl 2692 << " d_ref.__no_real_delete = true;" << endl
2666 << " protected static void createStaticMetaObject() {" << endl 2693 << " if(!d_ref.__qobject_is_deleting)"
2667 << " assert(!_staticMetaObject);" << endl 2694 << " delete d_ref;" << endl
2668 << " QMetaObject base;" << endl 2695 << "}" << endl << 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;
2691 } 2696 }
2692 2697
2693 /* 2698 /*
2694 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) 2699 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class)
2695 { 2700 {
2698 */ 2703 */
2699 void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype) 2704 void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype)
2700 { 2705 {
2701 if(ctype->isQObject()) { 2706 if(ctype->isQObject()) {
2702 QString type_name = ctype->name(); 2707 QString type_name = ctype->name();
2703 if (ctype->isAbstract()) 2708 s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl;
2704 type_name += "_ConcreteWrapper";
2705 s << "return " << type_name << ".getObject(ret);" << endl;
2706 } else if (ctype->isValue() && !ctype->isStructInD()) { 2709 } else if (ctype->isValue() && !ctype->isStructInD()) {
2707 s << INDENT << "return new " << ctype->name() << "(ret);" << endl; 2710 s << INDENT << "return new " << ctype->name() << "(__qt_return_value, false);" << endl;
2708 } else if (ctype->isVariant()) { 2711 } else if (ctype->isVariant()) {
2709 s << INDENT << "return new QVariant(ret);" << endl; 2712 s << INDENT << "return new QVariant(__qt_return_value, false);" << endl;
2710 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { 2713 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
2711 s << INDENT << "return ret;" << endl; 2714 s << INDENT << "return __qt_return_value;" << endl;
2712 } else if (ctype->isObject()) { 2715 } else if (ctype->isObject()) {
2713 QString type_name = ctype->name(); 2716 QString type_name = ctype->name();
2714 s << "return qtd_" << type_name << "_from_ptr(ret);" << endl; 2717 s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl;
2715 } 2718 }
2716 } 2719 }
2717 2720
2718 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) 2721 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field)
2719 { 2722 {
2774 2777
2775 s << INDENT << "private final void onFirstSlot(int signalId) {" << endl; 2778 s << INDENT << "private final void onFirstSlot(int signalId) {" << endl;
2776 { 2779 {
2777 Indentation indent(INDENT); 2780 Indentation indent(INDENT);
2778 s << INDENT << "if (signalId < __slotConnectors.length) {" << endl; 2781 s << INDENT << "if (signalId < __slotConnectors.length) {" << endl;
2779 s << INDENT << " __slotConnectors[signalId](__nativeId);" << endl; 2782 s << INDENT << " __slotConnectors[signalId](nativeId);" << endl;
2780 s << INDENT << "}" << endl; 2783 s << INDENT << "}" << endl;
2781 } 2784 }
2782 s << INDENT << "}" << endl; 2785 s << INDENT << "}" << endl;
2783 2786
2784 s << INDENT << "private final void onLastSlot(int signalId) {" << endl; 2787 s << INDENT << "private final void onLastSlot(int signalId) {" << endl;
2785 { 2788 {
2786 Indentation indent(INDENT); 2789 Indentation indent(INDENT);
2787 s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl; 2790 s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl;
2788 s << INDENT << " __slotDisconnectors[signalId](__nativeId);" << endl; 2791 s << INDENT << " __slotDisconnectors[signalId](nativeId);" << endl;
2789 s << INDENT << "}" << endl; 2792 s << INDENT << "}" << endl;
2790 } 2793 }
2791 s << INDENT << "}" << endl; 2794 s << INDENT << "}" << endl;
2792 } 2795 }
2793 2796
2849 << arg_name << "[0.." << arg_name << "_size]);"; 2852 << arg_name << "[0.." << arg_name << "_size]);";
2850 else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") { 2853 else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") {
2851 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl 2854 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl
2852 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; 2855 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();";
2853 } else if(type->isVariant()) 2856 } else if(type->isVariant())
2854 s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; 2857 s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", true);";
2855 else if (type->typeEntry()->isStructInD()) 2858 else if (type->typeEntry()->isStructInD())
2856 continue; 2859 continue;
2857 else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer())) 2860 else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer()))
2858 continue; 2861 continue;
2859 else if(type->isObject() 2862 else if(type->isObject()
2861 || type->isValue() || type->isVariant()) { 2864 || type->isValue() || type->isVariant()) {
2862 QString type_name = type->typeEntry()->name(); 2865 QString type_name = type->typeEntry()->name();
2863 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); 2866 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
2864 if(ctype->isAbstract()) 2867 if(ctype->isAbstract())
2865 type_name = type_name + "_ConcreteWrapper"; 2868 type_name = type_name + "_ConcreteWrapper";
2866 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; 2869 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", true);";
2867 } 2870 }
2868 else if (type->isQObject()) { 2871 else if (type->isQObject()) {
2869 QString type_name = type->name(); 2872 QString type_name = type->name();
2870 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry()); 2873 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
2871 if(ctype->isAbstract()) 2874 if(ctype->isAbstract())
2872 type_name = type_name + "_ConcreteWrapper"; 2875 type_name = type_name + "_ConcreteWrapper";
2873 2876
2874 s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);" << endl; 2877 s << INDENT << "scope " << arg_name << "_so = new StackObject!(" << type_name << ");" << 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 */
2875 } 2884 }
2876 s << endl; 2885 s << endl;
2877 } 2886 }
2878 } 2887 }
2879 2888
2948 if(has_return_type) { 2957 if(has_return_type) {
2949 AbstractMetaType *f_type = d_function->type(); 2958 AbstractMetaType *f_type = d_function->type();
2950 if(f_type) { 2959 if(f_type) {
2951 if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() || 2960 if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() ||
2952 (f_type->isValue() && !f_type->typeEntry()->isStructInD())) { 2961 (f_type->isValue() && !f_type->typeEntry()->isStructInD())) {
2953 QString native_id = "__nativeId"; 2962 QString native_id = "nativeId";
2954 if (f_type->typeEntry()->designatedInterface()) 2963 if (f_type->typeEntry()->designatedInterface())
2955 native_id = "__ptr_" + f_type->typeEntry()->designatedInterface()->name(); 2964 native_id = "__ptr_" + f_type->typeEntry()->designatedInterface()->name();
2956 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl; 2965 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl;
2957 } else if (f_type->isTargetLangString()) 2966 } else if (f_type->isTargetLangString())
2958 s << INDENT << "*ret_str = _d_str;" << endl; 2967 s << INDENT << "*ret_str = _d_str;" << endl;
3244 if (snip.language == TypeSystem::Constructors) { 3253 if (snip.language == TypeSystem::Constructors) {
3245 snip.formattedCode(s, INDENT); 3254 snip.formattedCode(s, INDENT);
3246 } 3255 }
3247 } 3256 }
3248 3257
3249 s << INDENT << "this(ret);" << endl; 3258 if(d_function->implementingClass()->isQObject())
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;
3250 } 3286 }
3251 s << INDENT << "}" << endl << endl; 3287 s << INDENT << "}" << endl << endl;
3252 3288
3253 /* qtd // Write native constructor 3289 /* qtd // Write native constructor
3254 if (d_function->jumpTableId() == -1) 3290 if (d_function->jumpTableId() == -1)
3315 << " }" << endl; 3351 << " }" << endl;
3316 } else { 3352 } else {
3317 s << endl 3353 s << endl
3318 << " @Override" << endl 3354 << " @Override" << endl
3319 << " public String toString() {" << endl 3355 << " public String toString() {" << endl
3320 << " if (__nativeId == 0)" << endl 3356 << " if (nativeId() == 0)" << endl
3321 << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl 3357 << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl
3322 << " return __qt_toString(nativeId());" << endl 3358 << " return __qt_toString(nativeId());" << endl
3323 << " }" << endl 3359 << " }" << endl
3324 << " native String __qt_toString(long __this_nativeId);" << endl; 3360 << " native String __qt_toString(long __this_nativeId);" << endl;
3325 } 3361 }