Mercurial > projects > qtd
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 } |