comparison generator/dgenerator.cpp @ 260:b5773ccab07d lifetime

closer
author maxter
date Fri, 18 Sep 2009 18:52:03 +0000
parents 515d6e1c7b10
children 90131f64c9c9
comparison
equal deleted inserted replaced
259:515d6e1c7b10 260:b5773ccab07d
772 else 772 else
773 s << "__nativeId"; 773 s << "__nativeId";
774 } 774 }
775 775
776 if (d_function->isConstructor() && 776 if (d_function->isConstructor() &&
777 ( d_function->implementingClass()->hasVirtualFunctions() 777 ( d_function->implementingClass()->isPolymorphic()
778 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd 778 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd
779 s << "cast(void*) this"; 779 s << "cast(void*) this";
780 if (arguments.count() > 0) 780 if (arguments.count() > 0)
781 s << ", "; 781 s << ", ";
782 } 782 }
896 } 896 }
897 897
898 if(return_type->isQObject()) 898 if(return_type->isQObject())
899 s << return_type->name() << ".__wrap(ret);" << endl; 899 s << return_type->name() << ".__wrap(ret);" << endl;
900 900
901 901 if ((return_type->isValue() && !return_type->typeEntry()->isStructInD()) || return_type->isVariant())
902 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) 902 s << "new " << return_type->name() << "(ret);" << endl;
903 s << "new " << return_type->name() << "(ret);" << endl; 903 else if (return_type->typeEntry()->isValue() && return_type->isNativePointer())
904 s << "new " << return_type->name() << "(ret, QtdObjectFlags.skipNativeDelete);" << endl;
904 905
905 if (return_type->isObject()) { 906 if (return_type->isObject()) {
906 if(d_function->storeResult()) 907 if(d_function->storeResult())
907 { 908 {
908 QString fieldName = QString("__m_%1;").arg(d_function->name()); 909 QString fieldName = QString("__m_%1;").arg(d_function->name());
1695 {// COMPILER BUG: 1696 {// COMPILER BUG:
1696 s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }"; 1697 s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }";
1697 } 1698 }
1698 } 1699 }
1699 1700
1701
1700 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) 1702 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class)
1701 { 1703 {
1702 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); 1704 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class);
1703 1705
1704 QString attr; 1706 QString attr;
1726 s << "private extern(C) void " << sigExternName << "_handle(void* d_entity, void** args) {" << endl; 1728 s << "private extern(C) void " << sigExternName << "_handle(void* d_entity, void** args) {" << endl;
1727 { 1729 {
1728 Indentation indent(INDENT); 1730 Indentation indent(INDENT);
1729 s << INDENT << "auto d_object = cast(" << d_class->name() << ") d_entity;" << endl; 1731 s << INDENT << "auto d_object = cast(" << d_class->name() << ") d_entity;" << endl;
1730 int sz = arguments.count(); 1732 int sz = arguments.count();
1731 1733
1734 //TODO: This mostly duplicates virtual function argument generation. Should be merged
1732 for (int j=0; j<sz; ++j) { 1735 for (int j=0; j<sz; ++j) {
1733 AbstractMetaArgument *argument = arguments.at(j); 1736 AbstractMetaArgument *argument = arguments.at(j);
1734 QString arg_name = argument->indexedName(); 1737 QString arg_name = argument->indexedName();
1735 AbstractMetaType *type = argument->type(); 1738 AbstractMetaType *type = argument->type();
1736 // if has QString argument we have to pass char* and str.length to QString constructor 1739 // if has QString argument we have to pass char* and str.length to QString constructor
1746 } else if(type->isPrimitive() || type->isEnum() || type->isFlags() || type->typeEntry()->isStructInD()) { 1749 } else if(type->isPrimitive() || type->isEnum() || type->isFlags() || type->typeEntry()->isStructInD()) {
1747 QString type_name = argument->type()->typeEntry()->qualifiedTargetLangName(); 1750 QString type_name = argument->type()->typeEntry()->qualifiedTargetLangName();
1748 if (type->isFlags()) 1751 if (type->isFlags())
1749 type_name = "int"; 1752 type_name = "int";
1750 s << INDENT << "auto " << arg_name << " = *(cast(" << type_name << "*)" << arg_ptr << ");"; 1753 s << INDENT << "auto " << arg_name << " = *(cast(" << type_name << "*)" << arg_ptr << ");";
1751 } else if(type->isObject() || type->isQObject() 1754 } else if (type->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())) {
1752 || (type->typeEntry()->isValue() && type->isNativePointer()) 1755 s << INDENT << "scope " << arg_name << " = new " << argument->type()->typeEntry()->name()
1753 || type->isValue()) {
1754 QString type_name = type->name();
1755 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
1756 if(ctype->isAbstract())
1757 type_name = type_name + "_ConcreteWrapper";
1758 s << INDENT << "scope " << arg_name << " = new " << type_name
1759 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl; 1756 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl;
1760 } 1757 }
1758 else if (type->isObject() || type->isQObject())
1759 {
1760 bool resetAfterUse = !type->isQObject() && signal->resetObjectAfterUse(argument->argumentIndex() + 1);
1761
1762 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
1763 {
1764 QString flags;
1765 if (resetAfterUse)
1766 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
1767 else if (type->isQObject())
1768 flags = "QtdObjectFlags.none";
1769 else
1770 flags = "QtdObjectFlags.skipNativeDelete";
1771
1772 s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name
1773 << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
1774
1775 if (resetAfterUse)
1776 {
1777 s << INDENT << "scope(exit) {" << endl
1778 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
1779 << INDENT << " delete " << arg_name << ";" << endl
1780 << INDENT << "}" << endl;
1781 }
1782 }
1783 else
1784 {
1785 s << INDENT << (resetAfterUse ? "scope " : "auto ")
1786 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);";
1787 }
1788 }
1789
1761 s << endl; 1790 s << endl;
1762 } 1791 }
1763 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl; 1792 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl;
1764 s << INDENT << "d_object." << signal->name() << ".emit("; 1793 s << INDENT << "d_object." << signal->name() << ".emit(";
1765 for (int j = 0; j<sz; ++j) { 1794 for (int j = 0; j<sz; ++j) {
1786 QString auxModName = d_class->package() + "." + d_class->name() + "_aux"; 1815 QString auxModName = d_class->package() + "." + d_class->name() + "_aux";
1787 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d"); 1816 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d");
1788 auxFile.isDone = true; 1817 auxFile.isDone = true;
1789 auxFile.stream << "module " << auxModName << ";" << endl << endl; 1818 auxFile.stream << "module " << auxModName << ";" << endl << endl;
1790 1819
1791 bool staticInit = (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); 1820 bool staticInit = (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
1792 if (staticInit) 1821 if (staticInit)
1793 { 1822 {
1794 auxFile.isDone = false; 1823 auxFile.isDone = false;
1795 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl; 1824 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl;
1796 auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl; 1825 auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl;
1896 << "public import qt.core.Qt;" << endl 1925 << "public import qt.core.Qt;" << endl
1897 << "public import qt.QtdObject;" << endl 1926 << "public import qt.QtdObject;" << endl
1898 << "private import qt.core.QString;" << endl 1927 << "private import qt.core.QString;" << endl
1899 << "private import qt.qtd.Array;" << endl; 1928 << "private import qt.qtd.Array;" << endl;
1900 if (d_class->isQObject()) { 1929 if (d_class->isQObject()) {
1930 s << "public import qt.core.QMetaObject;" << endl;
1901 s << "public import qt.Signal;" << endl; 1931 s << "public import qt.Signal;" << endl;
1902 if (d_class->name() != "QObject") 1932 if (d_class->name() != "QObject")
1903 s << "public import qt.core.QObject;" << endl; 1933 s << "public import qt.core.QObject;" << endl;
1904 } 1934 }
1905
1906 if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions())
1907 s << "public import qt.core.QMetaObject;" << endl;
1908 1935
1909 // qtd2 hack! 1936 // qtd2 hack!
1910 if (d_class->name() == "QCoreApplication") 1937 if (d_class->name() == "QCoreApplication")
1911 s << "private import qt.core.ArrayOps;" << endl; 1938 s << "private import qt.core.ArrayOps;" << endl;
1912 else if (d_class->name() == "QApplication") 1939 else if (d_class->name() == "QApplication")
2203 if (d_class->isQObject()) 2230 if (d_class->isQObject())
2204 writeQObjectFunctions(s, d_class); 2231 writeQObjectFunctions(s, d_class);
2205 else 2232 else
2206 writeObjectFunctions(s, d_class); 2233 writeObjectFunctions(s, d_class);
2207 2234
2208 if (d_class->hasVirtualDestructor()) 2235 if (d_class->isPolymorphic())
2209 { 2236 {
2210 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl 2237 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl;
2211 << " auto obj = new(flags) " << d_class->name() << "(nativeId, flags);" << endl; 2238
2239 QString className = d_class->name();
2240 if (d_class->isAbstract())
2241 className += "_ConcreteWrapper";
2242
2243 s << " auto obj = new(flags) " << className << "(nativeId, flags);" << endl;
2212 2244
2213 if (d_class->isQObject()) 2245 if (d_class->isQObject())
2214 s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl; 2246 s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl;
2215 2247
2216 s << " return obj;" << endl 2248 s << " return obj;" << endl
2217 << " }" << endl << endl; 2249 << " }" << endl << endl;
2218 } 2250 }
2219 } 2251 }
2220 2252
2221 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualDestructor())) 2253 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->isPolymorphic()))
2222 writeDestructor(s, d_class); 2254 writeDestructor(s, d_class);
2223 2255
2224 // Add dummy constructor for use when constructing subclasses 2256 // Add dummy constructor for use when constructing subclasses
2225 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { 2257 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
2226 s << endl 2258 s << endl
2456 } 2488 }
2457 } 2489 }
2458 s << INDENT << "}" << endl << endl; 2490 s << INDENT << "}" << endl << endl;
2459 } 2491 }
2460 2492
2461 if (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor()) 2493 if (d_class->typeEntry()->isObject() && d_class->isPolymorphic())
2462 { 2494 {
2463 if (!d_class->typeEntry()->isQObject()) 2495 if (!d_class->typeEntry()->isQObject())
2464 { 2496 {
2465 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl; 2497 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl;
2466 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; 2498 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
2529 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; 2561 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl;
2530 } 2562 }
2531 2563
2532 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2564 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
2533 2565
2534 if (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor()) { 2566 if (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) {
2535 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl 2567 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
2536 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; 2568 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
2537 } 2569 }
2538 2570
2539 if (cpp_shared) { 2571 if (cpp_shared) {
2631 */ 2663 */
2632 2664
2633 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2665 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2634 { 2666 {
2635 // polymorphic 2667 // polymorphic
2636 if (d_class->hasVirtualDestructor()) 2668 if (d_class->isPolymorphic())
2637 { 2669 {
2638 QString rootClassName = d_class->rootClass()->name(); 2670 QString rootClassName = d_class->rootClass()->name();
2639 QString concreteArg; 2671 QString concreteArg;
2640 if (d_class->isAbstract()) 2672 if (d_class->isAbstract())
2641 concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; 2673 concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
2668 << " }" << endl << endl 2700 << " }" << endl << endl
2669 2701
2670 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl 2702 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl
2671 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl 2703 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl
2672 << " if (!obj)" << endl 2704 << " if (!obj)" << endl
2673 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId," 2705 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, "
2674 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl 2706 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl
2675 << " return obj;" << endl 2707 << " return obj;" << endl
2676 << " }" << endl << endl; 2708 << " }" << endl << endl;
2677 } 2709 }
2678 else 2710 else
2726 } 2758 }
2727 */ 2759 */
2728 2760
2729 void DGenerator::marshalToD(QTextStream &s, const ComplexTypeEntry *ctype) 2761 void DGenerator::marshalToD(QTextStream &s, const ComplexTypeEntry *ctype)
2730 { 2762 {
2731 if(ctype->isQObject()) { 2763 if(ctype->isObject()) {
2732 QString type_name = ctype->name(); 2764 if (ctype->isPolymorphic())
2733 if (ctype->isAbstract()) 2765 s << "return " << ctype->name() << ".__wrap(ret);" << endl;
2734 type_name += "_ConcreteWrapper"; 2766 else
2735 s << "return " << type_name << ".__getObject(ret);" << endl; 2767 s << "return new " << ctype->name() << "(ret, QtdObjectFlags.skipNativeDelete);" << endl;
2736 } else if (ctype->isValue() && !ctype->isStructInD()) { 2768 } else if (ctype->isValue() && !ctype->isStructInD()) {
2737 s << INDENT << "return new " << ctype->name() << "(ret);" << endl; 2769 s << INDENT << "return new " << ctype->name() << "(ret);" << endl;
2738 } else if (ctype->isVariant()) { 2770 } else if (ctype->isVariant()) {
2739 s << INDENT << "return new QVariant(ret);" << endl; 2771 s << INDENT << "return new QVariant(ret);" << endl;
2740 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { 2772 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
2741 s << INDENT << "return ret;" << endl; 2773 s << INDENT << "return ret;" << endl;
2742 } else if (ctype->isObject()) {
2743 QString type_name = ctype->name();
2744 s << "return qtd_" << type_name << "_from_ptr(ret);" << endl;
2745 } 2774 }
2746 } 2775 }
2747 2776
2748 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) 2777 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field)
2749 { 2778 {
2876 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl 2905 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl
2877 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; 2906 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();";
2878 } 2907 }
2879 else if (type->typeEntry()->isStructInD()) 2908 else if (type->typeEntry()->isStructInD())
2880 continue; 2909 continue;
2881 else if (type->typeEntry()->isValue()){ 2910 else if (type->typeEntry()->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())){
2882 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);" << endl; 2911 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);" << endl;
2883 } 2912 }
2884 else if (!type->hasNativeId()) 2913 else if (!type->hasNativeId())
2885 continue; 2914 continue;
2886 else if (type->isObject() || type->isQObject()) 2915 else if (type->isObject() || type->isQObject())
2887 { 2916 {
2888 bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1); 2917 bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1);
2889 2918
2890 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->hasVirtualDestructor()) 2919 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
2891 { 2920 {
2892 QString flags; 2921 QString flags;
2893 if (resetAfterUse) 2922 if (resetAfterUse)
2894 flags += "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete"; 2923 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
2895 else if (type->isQObject()) 2924 else if (type->isQObject())
2896 flags += "QtdObjectFlags.none"; 2925 flags = "QtdObjectFlags.none";
2897 else 2926 else
2898 flags = "QtdObjectFlags.skipNativeDelete"; 2927 flags = "QtdObjectFlags.skipNativeDelete";
2899 2928
2900 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name 2929 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name
2901 << ", " << flags << ");" << endl; 2930 << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
2902 2931
2903 if (resetAfterUse) 2932 if (resetAfterUse)
2904 { 2933 {
2905 s << INDENT << "scope(exit) {" << endl 2934 s << INDENT << "scope(exit) {" << endl
2906 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl 2935 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
2926 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.'); 2955 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.');
2927 bool has_return_type = new_return_type != "void" 2956 bool has_return_type = new_return_type != "void"
2928 && (!new_return_type.isEmpty() || return_type != 0); 2957 && (!new_return_type.isEmpty() || return_type != 0);
2929 if(has_return_type) { 2958 if(has_return_type) {
2930 AbstractMetaType *f_type = d_function->type(); 2959 AbstractMetaType *f_type = d_function->type();
2960
2931 if(f_type && (f_type->isObject() || f_type->isQObject() || f_type->isVariant() || 2961 if(f_type && (f_type->isObject() || f_type->isQObject() || f_type->isVariant() ||
2932 (f_type->isValue() && !f_type->typeEntry()->isStructInD()))) 2962 (f_type->isValue() && !f_type->typeEntry()->isStructInD())))
2933 { 2963 {
2934 QString f_type_name = f_type->name(); 2964 QString f_type_name = f_type->name();
2935 if(f_type->typeEntry()->designatedInterface()) 2965 if(f_type->typeEntry()->designatedInterface())