comparison generator/dgenerator.cpp @ 262:90131f64c9c9 lifetime

looks like enabling/disabling GC is enough
author maxter
date Tue, 22 Sep 2009 15:19:04 +0000
parents b5773ccab07d
children a7b313b8b149
comparison
equal deleted inserted replaced
261:8f7bb7fc3123 262:90131f64c9c9
59 DGenerator::DGenerator() 59 DGenerator::DGenerator()
60 : m_doc_parser(0), 60 : m_doc_parser(0),
61 m_docs_enabled(false), 61 m_docs_enabled(false),
62 m_native_jump_table(false), 62 m_native_jump_table(false),
63 m_recursive(0), 63 m_recursive(0),
64 m_isRecursive(false) 64 m_isRecursive(false)
65 { 65 {
66 excludedTypes << "long long" << "bool" << "int" << "QString" << "char" << "WId" 66 excludedTypes << "long long" << "bool" << "int" << "QString" << "char" << "WId"
67 << "unsigned char" << "uint" << "double" << "short" << "float" 67 << "unsigned char" << "uint" << "double" << "short" << "float"
68 << "signed char" << "unsigned short" << "QBool" << "unsigned int" 68 << "signed char" << "unsigned short" << "QBool" << "unsigned int"
69 << "Qt::HANDLE" << "QChar" << "java.lang.JObjectWrapper" << "void" 69 << "Qt::HANDLE" << "QChar" << "java.lang.JObjectWrapper" << "void"
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 "__nativeOwnership = true"; 482 return "__pin";
483 } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { 483 } else if (owner == TypeSystem::TargetLangOwnership || owner == TypeSystem::TargetLangOwnership) {
484 return "__nativeOwnership = false"; 484 return "__unpin";
485 }/* else if (owner == TypeSystem::DefaultOwnership) {
486 return "__no_real_delete = false";
487
488 } else { 485 } else {
489 Q_ASSERT(false); 486 Q_ASSERT(false);
490 return "bogus()"; 487 return "bogus()";
491 }*/ 488 }
492 } 489 }
493 490
494 void DGenerator::writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership owner, 491 void DGenerator::writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership owner,
495 AbstractMetaType *type, const QString &arg_name) 492 AbstractMetaType *type, const QString &arg_name)
496 { 493 {
649 writeReferenceCount(s, refCount, i == 0 ? "this" : arguments.at(i-1)->argumentName()); 646 writeReferenceCount(s, refCount, i == 0 ? "this" : arguments.at(i-1)->argumentName());
650 } 647 }
651 648
652 referenceCounts = d_function->referenceCounts(d_function->implementingClass(), 0); 649 referenceCounts = d_function->referenceCounts(d_function->implementingClass(), 0);
653 */ 650 */
654 651
655 AbstractMetaType *return_type = d_function->type(); 652 AbstractMetaType *return_type = d_function->type();
656 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.'); 653 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.');
657 bool has_return_type = new_return_type != "void" 654 bool has_return_type = new_return_type != "void"
658 && (!new_return_type.isEmpty() || return_type != 0); 655 && (!new_return_type.isEmpty() || return_type != 0);
659 // qtd TypeSystem::Ownership owner = d_function->ownership(d_function->implementingClass(), TypeSystem::TargetLangCode, 0); 656 // qtd TypeSystem::Ownership owner = d_function->ownership(d_function->implementingClass(), TypeSystem::TargetLangCode, 0);
895 s << " __d_return_value = "; 892 s << " __d_return_value = ";
896 } 893 }
897 894
898 if(return_type->isQObject()) 895 if(return_type->isQObject())
899 s << return_type->name() << ".__wrap(ret);" << endl; 896 s << return_type->name() << ".__wrap(ret);" << endl;
900 897
901 if ((return_type->isValue() && !return_type->typeEntry()->isStructInD()) || return_type->isVariant()) 898 if ((return_type->isValue() && !return_type->typeEntry()->isStructInD()) || return_type->isVariant())
902 s << "new " << return_type->name() << "(ret);" << endl; 899 s << "new " << return_type->name() << "(ret);" << endl;
903 else if (return_type->typeEntry()->isValue() && return_type->isNativePointer()) 900 else if (return_type->typeEntry()->isValue() && return_type->isNativePointer())
904 s << "new " << return_type->name() << "(ret, QtdObjectFlags.skipNativeDelete);" << endl; 901 s << "new " << return_type->name() << "(ret, QtdObjectFlags.skipNativeDelete);" << endl;
905 902
906 if (return_type->isObject()) { 903 if (return_type->isObject()) {
907 if(d_function->storeResult()) 904 if(d_function->storeResult())
908 { 905 {
909 QString fieldName = QString("__m_%1;").arg(d_function->name()); 906 QString fieldName = QString("__m_%1;").arg(d_function->name());
910 s << INDENT << "if (!" << fieldName << " || " << fieldName << ".__nativeId != ret) {" << endl 907 s << INDENT << "if (!" << fieldName << " || " << fieldName << ".__nativeId != ret) {" << endl
1682 { 1679 {
1683 if (!d_class->hasConstructors()) 1680 if (!d_class->hasConstructors())
1684 return; 1681 return;
1685 1682
1686 s << " override void __deleteNative() {" << endl 1683 s << " override void __deleteNative() {" << endl
1687 << " qtd_" << d_class->name() << "_destructor(__nativeId);" << endl 1684 << " qtd_" << d_class->name() << "_destructor(__nativeId);" << endl
1688 << " }" << endl; 1685 << " }" << endl;
1689 } 1686 }
1690 1687
1691 void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class) 1688 void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class)
1692 { 1689 {
1728 s << "private extern(C) void " << sigExternName << "_handle(void* d_entity, void** args) {" << endl; 1725 s << "private extern(C) void " << sigExternName << "_handle(void* d_entity, void** args) {" << endl;
1729 { 1726 {
1730 Indentation indent(INDENT); 1727 Indentation indent(INDENT);
1731 s << INDENT << "auto d_object = cast(" << d_class->name() << ") d_entity;" << endl; 1728 s << INDENT << "auto d_object = cast(" << d_class->name() << ") d_entity;" << endl;
1732 int sz = arguments.count(); 1729 int sz = arguments.count();
1733 1730
1734 //TODO: This mostly duplicates virtual function argument generation. Should be merged 1731 //TODO: This mostly duplicates virtual function argument generation. Should be merged
1735 for (int j=0; j<sz; ++j) { 1732 for (int j=0; j<sz; ++j) {
1736 AbstractMetaArgument *argument = arguments.at(j); 1733 AbstractMetaArgument *argument = arguments.at(j);
1737 QString arg_name = argument->indexedName(); 1734 QString arg_name = argument->indexedName();
1738 AbstractMetaType *type = argument->type(); 1735 AbstractMetaType *type = argument->type();
1753 s << INDENT << "auto " << arg_name << " = *(cast(" << type_name << "*)" << arg_ptr << ");"; 1750 s << INDENT << "auto " << arg_name << " = *(cast(" << type_name << "*)" << arg_ptr << ");";
1754 } else if (type->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())) { 1751 } else if (type->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())) {
1755 s << INDENT << "scope " << arg_name << " = new " << argument->type()->typeEntry()->name() 1752 s << INDENT << "scope " << arg_name << " = new " << argument->type()->typeEntry()->name()
1756 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl; 1753 << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl;
1757 } 1754 }
1758 else if (type->isObject() || type->isQObject()) 1755 else if (type->typeEntry()->isObject())
1759 { 1756 {
1760 bool resetAfterUse = !type->isQObject() && signal->resetObjectAfterUse(argument->argumentIndex() + 1); 1757 bool resetAfterUse = !type->isQObject() && signal->resetObjectAfterUse(argument->argumentIndex() + 1);
1761 1758
1762 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic()) 1759 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
1763 { 1760 {
1764 QString flags; 1761 QString flags;
1765 if (resetAfterUse) 1762 if (resetAfterUse)
1766 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete"; 1763 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
1767 else if (type->isQObject()) 1764 else
1768 flags = "QtdObjectFlags.none"; 1765 flags = "QtdObjectFlags.none";
1769 else
1770 flags = "QtdObjectFlags.skipNativeDelete";
1771 1766
1772 s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name 1767 s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name
1773 << ", cast(QtdObjectFlags)(" << flags << "));" << endl; 1768 << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
1774 1769
1775 if (resetAfterUse) 1770 if (resetAfterUse)
1776 { 1771 {
1777 s << INDENT << "scope(exit) {" << endl 1772 s << INDENT << "scope(exit) {" << endl
1778 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl 1773 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
1779 << INDENT << " delete " << arg_name << ";" << endl 1774 << INDENT << " delete " << arg_name << ";" << endl
1780 << INDENT << "}" << endl; 1775 << INDENT << "}" << endl;
1781 } 1776 }
1782 } 1777 }
1783 else 1778 else
1784 { 1779 {
1785 s << INDENT << (resetAfterUse ? "scope " : "auto ") 1780 s << INDENT << (resetAfterUse ? "scope " : "auto ")
1786 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);"; 1781 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags."
1782 << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl;
1787 } 1783 }
1788 } 1784 }
1789 1785
1790 s << endl; 1786 s << endl;
1791 } 1787 }
1792 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl; 1788 // s << INDENT << "Stdout(\"" << d_class->name() << "\", \"" << signal->name() << "\").newline;" << endl;
1793 s << INDENT << "d_object." << signal->name() << ".emit("; 1789 s << INDENT << "d_object." << signal->name() << ".emit(";
1794 for (int j = 0; j<sz; ++j) { 1790 for (int j = 0; j<sz; ++j) {
1805 } 1801 }
1806 } 1802 }
1807 1803
1808 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class) 1804 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class)
1809 { 1805 {
1810 ReportHandler::debugSparse("Generating class: " + d_class->fullName()); 1806 ReportHandler::debugSparse("Generating class: " + d_class->fullName());
1811 1807
1812 bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; 1808 bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake;
1813 1809
1814 1810
1815 QString auxModName = d_class->package() + "." + d_class->name() + "_aux"; 1811 QString auxModName = d_class->package() + "." + d_class->name() + "_aux";
1929 if (d_class->isQObject()) { 1925 if (d_class->isQObject()) {
1930 s << "public import qt.core.QMetaObject;" << endl; 1926 s << "public import qt.core.QMetaObject;" << endl;
1931 s << "public import qt.Signal;" << endl; 1927 s << "public import qt.Signal;" << endl;
1932 if (d_class->name() != "QObject") 1928 if (d_class->name() != "QObject")
1933 s << "public import qt.core.QObject;" << endl; 1929 s << "public import qt.core.QObject;" << endl;
1934 } 1930 }
1935 1931
1936 // qtd2 hack! 1932 // qtd2 hack!
1937 if (d_class->name() == "QCoreApplication") 1933 if (d_class->name() == "QCoreApplication")
1938 s << "private import qt.core.ArrayOps;" << endl; 1934 s << "private import qt.core.ArrayOps;" << endl;
1939 else if (d_class->name() == "QApplication") 1935 else if (d_class->name() == "QApplication")
2022 s << ">"; 2018 s << ">";
2023 } 2019 }
2024 2020
2025 if (!d_class->isNamespace() && !d_class->isInterface()) { 2021 if (!d_class->isNamespace() && !d_class->isInterface()) {
2026 s << " : "; 2022 s << " : ";
2027 if (d_class->baseClass()) { 2023 if (d_class->baseClass()) {
2028 s << d_class->baseClass()->name(); 2024 s << d_class->baseClass()->name();
2029 } else { 2025 } else {
2030 if (d_class->typeEntry()->isValue()) 2026 if (d_class->typeEntry()->isValue())
2031 s << "QtdObjectBase"; 2027 s << "QtdObjectBase";
2032 else if (d_class->typeEntry()->isObject()) 2028 else if (d_class->typeEntry()->isObject())
2033 s << "QtdObject"; 2029 s << "QtdObject";
2034 2030
2035 } 2031 }
2036 }/* qtd else if (d_class->isInterface()) { 2032 }/* qtd else if (d_class->isInterface()) {
2037 s << " extends QtJambiInterface"; 2033 s << " extends QtJambiInterface";
2038 }*/ 2034 }*/
2039 2035
2043 if (!interfaces.isEmpty()) { 2039 if (!interfaces.isEmpty()) {
2044 if (!d_class->isInterface()) 2040 if (!d_class->isInterface())
2045 s << ", "; 2041 s << ", ";
2046 else { 2042 else {
2047 implements = true; 2043 implements = true;
2048 s << ": "; 2044 s << " : ";
2049 } 2045 }
2050 for (int i=0; i<interfaces.size(); ++i) { 2046 for (int i=0; i<interfaces.size(); ++i) {
2051 AbstractMetaClass *iface = interfaces.at(i); 2047 AbstractMetaClass *iface = interfaces.at(i);
2052 if (i) s << ", "; 2048 if (i) s << ", ";
2053 s << iface->name(); 2049 s << iface->name();
2092 } 2088 }
2093 } 2089 }
2094 2090
2095 foreach (QString variableName, variables.keys()) { 2091 foreach (QString variableName, variables.keys()) {
2096 int actions = variables.value(variableName) & ReferenceCount::ActionsMask; 2092 int actions = variables.value(variableName) & ReferenceCount::ActionsMask;
2097 // bool threadSafe = variables.value(variableName) & ReferenceCount::ThreadSafe; 2093 bool threadSafe = variables.value(variableName) & ReferenceCount::ThreadSafe;
2098 bool isStatic = variables.value(variableName) & ReferenceCount::Static; 2094 bool isStatic = variables.value(variableName) & ReferenceCount::Static;
2099 bool declareVariable = variables.value(variableName) & ReferenceCount::DeclareVariable; 2095 bool declareVariable = variables.value(variableName) & ReferenceCount::DeclareVariable;
2100 int access = variables.value(variableName) & ReferenceCount::AccessMask; 2096 int access = variables.value(variableName) & ReferenceCount::AccessMask;
2101 2097
2102 if (actions == ReferenceCount::Ignore || !declareVariable) 2098 if (actions == ReferenceCount::Ignore || !declareVariable)
2120 s << "package "; break; // qtd 2116 s << "package "; break; // qtd
2121 case ReferenceCount::Protected: 2117 case ReferenceCount::Protected:
2122 s << "protected "; break; 2118 s << "protected "; break;
2123 case ReferenceCount::Public: 2119 case ReferenceCount::Public:
2124 s << "public "; break; 2120 s << "public "; break;
2125 default: 2121 default: // friendly
2126 s << "protected"; // friendly
2127 } 2122 }
2128 2123
2129 } // qtd2 2124 } // qtd2
2130 2125
2131 if (isStatic) 2126 if (isStatic)
2166 2161
2167 // Enums aliaases 2162 // Enums aliaases
2168 foreach (AbstractMetaEnum *d_enum, d_class->enums()) 2163 foreach (AbstractMetaEnum *d_enum, d_class->enums())
2169 writeEnumAlias(s, d_enum); 2164 writeEnumAlias(s, d_enum);
2170 2165
2171 // Signals 2166 // Signals
2172 if (d_class->isQObject()) 2167 if (d_class->isQObject())
2173 { 2168 {
2174 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false); 2169 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false);
2175 writeSignalSignatures(s, d_class, signal_funcs); 2170 writeSignalSignatures(s, d_class, signal_funcs);
2176 2171
2177 foreach (AbstractMetaFunction *signal, signal_funcs) 2172 foreach (AbstractMetaFunction *signal, signal_funcs)
2178 writeSignal(s, signal); 2173 writeSignal(s, signal);
2179 } 2174 }
2180 2175
2181 // Class has subclasses but also only private constructors 2176 // Class has subclasses but also only private constructors
2229 { 2224 {
2230 if (d_class->isQObject()) 2225 if (d_class->isQObject())
2231 writeQObjectFunctions(s, d_class); 2226 writeQObjectFunctions(s, d_class);
2232 else 2227 else
2233 writeObjectFunctions(s, d_class); 2228 writeObjectFunctions(s, d_class);
2234 2229
2235 if (d_class->isPolymorphic()) 2230 if (d_class->isPolymorphic())
2236 { 2231 {
2237 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl; 2232 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl;
2238 2233
2239 QString className = d_class->name(); 2234 QString className = d_class->name();
2240 if (d_class->isAbstract()) 2235 if (d_class->isAbstract())
2241 className += "_ConcreteWrapper"; 2236 className += "_ConcreteWrapper";
2242 2237
2243 s << " auto obj = new(flags) " << className << "(nativeId, flags);" << endl; 2238 s << " auto obj = new(flags) " << className << "(nativeId, flags);" << endl;
2244 2239
2245 if (d_class->isQObject()) 2240 if (d_class->isQObject())
2246 s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl; 2241 s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl;
2247 2242
2248 s << " return obj;" << endl 2243 s << " return obj;" << endl
2249 << " }" << endl << endl; 2244 << " }" << endl << endl;
2250 } 2245 }
2251 } 2246 }
2252 2247
2253 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->isPolymorphic())) 2248 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions()))
2254 writeDestructor(s, d_class); 2249 writeDestructor(s, d_class);
2255 2250
2256 // Add dummy constructor for use when constructing subclasses 2251 // Add dummy constructor for use when constructing subclasses
2257 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { 2252 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
2258 s << endl 2253 s << endl
2259 << INDENT << "public " 2254 << INDENT << "public "
2260 << "this"; 2255 << "this";
2261 2256
2262 2257
2263 Indentation indent(INDENT); 2258 Indentation indent(INDENT);
2264 2259
2265 QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none"; 2260 QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none";
2266 s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl 2261 s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl
2267 << INDENT << "super(nativeId, flags);" << endl; 2262 << INDENT << "super(nativeId, flags);" << endl;
2268 2263
2269 /* 2264 /*
2270 if (cpp_shared) { 2265 if (cpp_shared) {
2271 if (d_class->generateShellClass() && !d_class->isInterface()) 2266 if (d_class->generateShellClass() && !d_class->isInterface())
2272 s << INDENT << "if (!static_inited)" << endl 2267 s << INDENT << "if (!static_inited)" << endl
2273 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl; 2268 << INDENT << " static_init_" << d_class->name() << "();" << endl << endl;
2274 } 2269 }
2275 */ 2270 */
2276 2271
2277 2272
2278 // customized store-result instances 2273 // customized store-result instances
2279 d_funcs = d_class->functionsInTargetLang(); 2274 d_funcs = d_class->functionsInTargetLang();
2280 for (int i=0; i<d_funcs.size(); ++i) { 2275 for (int i=0; i<d_funcs.size(); ++i) {
2281 AbstractMetaFunction *d_function = d_funcs.at(i); 2276 AbstractMetaFunction *d_function = d_funcs.at(i);
2282 uint included_attributes = 0; 2277 uint included_attributes = 0;
2292 QString type_name = d_function->type()->name(); 2287 QString type_name = d_function->type()->name();
2293 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry()); 2288 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry());
2294 if(ctype->isAbstract()) 2289 if(ctype->isAbstract())
2295 type_name = type_name + "_ConcreteWrapper"; 2290 type_name = type_name + "_ConcreteWrapper";
2296 2291
2297 s << INDENT << " __m_" << d_function->name() << ";" << endl; 2292 s << INDENT << " __m_" << d_function->name() << ";" << endl;
2298 } 2293 }
2299 } 2294 }
2300 2295
2301 // pointers to native interface objects for classes that implement interfaces 2296 // pointers to native interface objects for classes that implement interfaces
2302 // initializing 2297 // initializing
2344 AbstractMetaClass *iface = interfaces.at(i); 2339 AbstractMetaClass *iface = interfaces.at(i);
2345 2340
2346 s << INDENT << "private void* __m_ptr_" << iface->name() << ";" << endl 2341 s << INDENT << "private void* __m_ptr_" << iface->name() << ";" << endl
2347 << INDENT << "public void* __ptr_" << iface->name() << "() { return __m_ptr_" << iface->name() << "; }" << endl << endl; 2342 << INDENT << "public void* __ptr_" << iface->name() << "() { return __m_ptr_" << iface->name() << "; }" << endl << endl;
2348 } 2343 }
2349 } 2344 }
2350 } 2345 }
2351 2346
2352 /* qtd 2347 /* qtd
2353 // Add a function that converts an array of the value type to a QNativePointer 2348 // Add a function that converts an array of the value type to a QNativePointer
2354 if (d_class->typeEntry()->isValue() && !fakeClass) { 2349 if (d_class->typeEntry()->isValue() && !fakeClass) {
2384 writeCloneFunction(s, d_class); 2379 writeCloneFunction(s, d_class);
2385 } 2380 }
2386 */ 2381 */
2387 s << "}" << endl; 2382 s << "}" << endl;
2388 2383
2389 /* ---------------- injected free code ----------------*/ 2384 /* ---------------- injected free code ----------------*/
2390 const ComplexTypeEntry *class_type = d_class->typeEntry(); 2385 const ComplexTypeEntry *class_type = d_class->typeEntry();
2391 Q_ASSERT(class_type); 2386 Q_ASSERT(class_type);
2392 2387
2393 CodeSnipList code_snips = class_type->codeSnips(); 2388 CodeSnipList code_snips = class_type->codeSnips();
2394 foreach (const CodeSnip &snip, code_snips) { 2389 foreach (const CodeSnip &snip, code_snips) {
2395 if (!d_class->isInterface() && snip.language == TypeSystem::TargetLangFreeCode) { 2390 if (!d_class->isInterface() && snip.language == TypeSystem::TargetLangFreeCode) {
2396 s << endl; 2391 s << endl;
2397 snip.formattedCode(s, INDENT); 2392 snip.formattedCode(s, INDENT);
2398 } 2393 }
2399 } 2394 }
2400 /* --------------------------------------------------- */ 2395 /* --------------------------------------------------- */
2401 2396
2402 interfaces = d_class->interfaces(); 2397 interfaces = d_class->interfaces();
2403 if (!interfaces.isEmpty()) { 2398 if (!interfaces.isEmpty()) {
2404 for (int i=0; i<interfaces.size(); ++i) { 2399 for (int i=0; i<interfaces.size(); ++i) {
2413 s << endl; 2408 s << endl;
2414 2409
2415 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl; 2410 s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl;
2416 2411
2417 { 2412 {
2418 Indentation indent(INDENT); 2413 Indentation indent(INDENT);
2419 s << INDENT << "public this(void* native_id, QtdObjectFlags flags) {" << endl 2414 s << INDENT << "public this(void* native_id, QtdObjectFlags flags) {" << endl
2420 << INDENT << " super(native_id, flags);" << endl << endl; 2415 << INDENT << " super(native_id, flags);" << endl << endl;
2421 2416
2422 /******************!!!DUPLICATE!!!*********************/ 2417 /******************!!!DUPLICATE!!!*********************/
2423 d_funcs = d_class->functionsInTargetLang(); 2418 d_funcs = d_class->functionsInTargetLang();
2424 for (int i=0; i<d_funcs.size(); ++i) { 2419 for (int i=0; i<d_funcs.size(); ++i) {
2425 AbstractMetaFunction *d_function = d_funcs.at(i); 2420 AbstractMetaFunction *d_function = d_funcs.at(i);
2426 uint included_attributes = 0; 2421 uint included_attributes = 0;
2433 QString type_name = d_function->type()->name(); 2428 QString type_name = d_function->type()->name();
2434 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry()); 2429 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry());
2435 if(ctype->isAbstract()) 2430 if(ctype->isAbstract())
2436 type_name = type_name + "_ConcreteWrapper"; 2431 type_name = type_name + "_ConcreteWrapper";
2437 s << INDENT << " __m_" << d_function->name() << " = new " 2432 s << INDENT << " __m_" << d_function->name() << " = new "
2438 << type_name << "(cast(void*)null);" << endl; 2433 << type_name << "(cast(void*)null);" << endl;
2439 } 2434 }
2440 } 2435 }
2441 2436
2442 s << INDENT << "}" << endl << endl; 2437 s << INDENT << "}" << endl << endl;
2443 2438
2488 } 2483 }
2489 } 2484 }
2490 s << INDENT << "}" << endl << endl; 2485 s << INDENT << "}" << endl << endl;
2491 } 2486 }
2492 2487
2493 if (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) 2488 if (d_class->isPolymorphic())
2494 { 2489 {
2495 if (!d_class->typeEntry()->isQObject()) 2490 if (!d_class->typeEntry()->isQObject())
2496 { 2491 {
2497 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl; 2492 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl;
2498 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; 2493 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
2499 } 2494 }
2500 2495
2501 s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl; 2496 s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl;
2502 } 2497 }
2503 2498
2504 // if (d_class->needsConversionFunc) 2499 // if (d_class->needsConversionFunc)
2505 // writeConversionFunction(s, d_class); 2500 // writeConversionFunction(s, d_class);
2561 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; 2556 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl;
2562 } 2557 }
2563 2558
2564 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2559 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
2565 2560
2566 if (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) { 2561 if (d_class->isPolymorphic()) {
2567 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl 2562 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
2568 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; 2563 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
2569 } 2564 }
2570 2565
2571 if (cpp_shared) { 2566 if (cpp_shared) {
2661 s << "}" << endl << endl; 2656 s << "}" << endl << endl;
2662 } 2657 }
2663 */ 2658 */
2664 2659
2665 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2660 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2666 { 2661 {
2667 // polymorphic 2662 // polymorphic
2668 if (d_class->isPolymorphic()) 2663 if (d_class->isPolymorphic())
2669 { 2664 {
2670 QString rootClassName = d_class->rootClass()->name(); 2665 QString rootClassName = d_class->rootClass()->name();
2671 QString concreteArg; 2666 QString concreteArg;
2672 if (d_class->isAbstract()) 2667 if (d_class->isAbstract())
2673 concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; 2668 concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
2674 2669
2675 s << " private static QtdMetaObject _staticMetaObject;" << endl 2670 s << " private static QtdMetaObject _staticMetaObject;" << endl
2676 //<< " private static QtdMetaObject[void*] _nativeToTargetMap;" << endl 2671 //<< " private static QtdMetaObject[void*] _nativeToTargetMap;" << endl
2677 2672
2678 << " protected static void createStaticMetaObject() {" << endl 2673 << " protected static void createStaticMetaObject() {" << endl
2679 << " assert(!_staticMetaObject);" << endl 2674 << " assert(!_staticMetaObject);" << endl
2680 << " QtdMetaObject base;" << endl; 2675 << " QtdMetaObject base;" << endl;
2681 2676
2682 if (d_class->baseClass()) 2677 if (d_class->baseClass())
2684 QString baseName = d_class->baseClassName(); 2679 QString baseName = d_class->baseClassName();
2685 s << " if (!" << baseName << "._staticMetaObject)" << endl 2680 s << " if (!" << baseName << "._staticMetaObject)" << endl
2686 << " " << baseName << ".createStaticMetaObject;" << endl 2681 << " " << baseName << ".createStaticMetaObject;" << endl
2687 << " base = " << baseName << "._staticMetaObject;" << endl; 2682 << " base = " << baseName << "._staticMetaObject;" << endl;
2688 } 2683 }
2689 2684
2690 s << " _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);" << endl 2685 s << " _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);" << endl
2691 << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl 2686 << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl
2692 << " }" << endl << endl 2687 << " }" << endl << endl
2693 2688
2694 << " QtdMetaObject metaObject() {" << endl 2689 << " QtdMetaObject metaObject() {" << endl
2695 << " return _staticMetaObject;" << endl 2690 << " return _staticMetaObject;" << endl
2696 << " }" << endl << endl 2691 << " }" << endl << endl
2697 2692
2698 << " static QtdMetaObject staticMetaObject() {" << endl 2693 << " static QtdMetaObject staticMetaObject() {" << endl
2699 << " return _staticMetaObject;" << endl 2694 << " return _staticMetaObject;" << endl
2700 << " }" << endl << endl 2695 << " }" << endl << endl
2701 2696
2702 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl 2697 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
2703 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl 2698 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl
2704 << " if (!obj)" << endl 2699 << " if (!obj)" << endl
2705 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, " 2700 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, "
2706 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl 2701 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl
2707 << " return obj;" << endl 2702 << " return obj;" << endl
2708 << " }" << endl << endl; 2703 << " }" << endl << endl;
2709 } 2704 }
2710 else 2705 else
2711 { 2706 {
2712 s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl 2707 s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
2713 << " return new " << d_class->name() << "(nativeId, flags);" 2708 << " return new " << d_class->name() << "(nativeId, flags);"
2714 << " }" << endl << endl; 2709 << " }" << endl << endl;
2715 } 2710 }
2716 } 2711 }
2717 2712
2746 << " return _staticMetaObject;" << endl 2741 << " return _staticMetaObject;" << endl
2747 << " }" << endl << endl 2742 << " }" << endl << endl
2748 2743
2749 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl 2744 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
2750 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl 2745 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl
2751 << " }" << endl << endl; 2746 << " }" << endl << endl;
2752 } 2747 }
2753 2748
2754 /* 2749 /*
2755 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) 2750 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class)
2756 { 2751 {
2759 */ 2754 */
2760 2755
2761 void DGenerator::marshalToD(QTextStream &s, const ComplexTypeEntry *ctype) 2756 void DGenerator::marshalToD(QTextStream &s, const ComplexTypeEntry *ctype)
2762 { 2757 {
2763 if(ctype->isObject()) { 2758 if(ctype->isObject()) {
2764 if (ctype->isPolymorphic()) 2759 s << "return " << ctype->name() << ".__wrap(ret);" << endl;
2765 s << "return " << ctype->name() << ".__wrap(ret);" << endl;
2766 else
2767 s << "return new " << ctype->name() << "(ret, QtdObjectFlags.skipNativeDelete);" << endl;
2768 } else if (ctype->isValue() && !ctype->isStructInD()) { 2760 } else if (ctype->isValue() && !ctype->isStructInD()) {
2769 s << INDENT << "return new " << ctype->name() << "(ret);" << endl; 2761 s << INDENT << "return new " << ctype->name() << "(ret);" << endl;
2770 } else if (ctype->isVariant()) { 2762 } else if (ctype->isVariant()) {
2771 s << INDENT << "return new QVariant(ret);" << endl; 2763 s << INDENT << "return new QVariant(ret);" << endl;
2772 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { 2764 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
2815 { 2807 {
2816 s << INDENT << "private const string[" << signal_funcs.size() << "] __signalSignatures = ["; 2808 s << INDENT << "private const string[" << signal_funcs.size() << "] __signalSignatures = [";
2817 { 2809 {
2818 Indentation indent(INDENT); 2810 Indentation indent(INDENT);
2819 for (int i = 0; i < signal_funcs.size(); ++i) 2811 for (int i = 0; i < signal_funcs.size(); ++i)
2820 { 2812 {
2821 if (i) 2813 if (i)
2822 s << ", "; 2814 s << ", ";
2823 s << endl << INDENT << " \"" << signal_funcs.at(i)->minimalSignature() << "\""; 2815 s << endl << INDENT << " \"" << signal_funcs.at(i)->minimalSignature() << "\"";
2824 } 2816 }
2825 } 2817 }
2826 s << INDENT << "];" << endl << endl; 2818 s << INDENT << "];" << endl << endl;
2827 2819
2828 s << INDENT << "int signalSignature(int signalId, ref stringz signature) {" << endl; 2820 s << INDENT << "int signalSignature(int signalId, ref stringz signature) {" << endl;
2829 { 2821 {
2830 Indentation indent(INDENT); 2822 Indentation indent(INDENT);
2831 2823
2832 if (d_class->name() != "QObject") 2824 if (d_class->name() != "QObject")
2833 { 2825 {
2834 s << INDENT << "signalId = super.signalSignature(signalId, signature);" << endl 2826 s << INDENT << "signalId = super.signalSignature(signalId, signature);" << endl
2835 << INDENT << "if (signature)" << endl 2827 << INDENT << "if (signature)" << endl
2836 << INDENT << " return signalId;" << endl; 2828 << INDENT << " return signalId;" << endl;
2837 } 2829 }
2838 2830
2839 s << INDENT << "if (signalId < __signalSignatures.length)" << endl 2831 s << INDENT << "if (signalId < __signalSignatures.length)" << endl
2840 << INDENT << " signature = __signalSignatures[signalId].ptr;" << endl 2832 << INDENT << " signature = __signalSignatures[signalId].ptr;" << endl
2841 << INDENT << "else" << endl 2833 << INDENT << "else" << endl
2842 << INDENT << " signalId -= __signalSignatures.length;" << endl 2834 << INDENT << " signalId -= __signalSignatures.length;" << endl
2843 << INDENT << "return signalId;" << endl; 2835 << INDENT << "return signalId;" << endl;
2884 2876
2885 s << INDENT << "auto d_object = cast(" << own_class->name() << ") d_entity;" << endl; 2877 s << INDENT << "auto d_object = cast(" << own_class->name() << ") d_entity;" << endl;
2886 2878
2887 // the function arguments 2879 // the function arguments
2888 AbstractMetaArgumentList arguments = d_function->arguments(); 2880 AbstractMetaArgumentList arguments = d_function->arguments();
2889 foreach (const AbstractMetaArgument *argument, arguments) 2881 foreach (const AbstractMetaArgument *argument, arguments) {
2890 if (!d_function->argumentRemoved(argument->argumentIndex() + 1)) { 2882 if (!d_function->argumentRemoved(argument->argumentIndex() + 1)) {
2891 QString arg_name = argument->indexedName(); 2883 QString arg_name = argument->indexedName();
2892 AbstractMetaType *type = argument->type(); 2884 AbstractMetaType *type = argument->type();
2893 // if has QString argument we have to pass char* and str.length to QString constructor 2885 // if has QString argument we have to pass char* and str.length to QString constructor
2894 { 2886 {
2907 } 2899 }
2908 else if (type->typeEntry()->isStructInD()) 2900 else if (type->typeEntry()->isStructInD())
2909 continue; 2901 continue;
2910 else if (type->typeEntry()->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())){ 2902 else if (type->typeEntry()->isValue() || (type->typeEntry()->isValue() && type->isNativePointer())){
2911 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);" << endl; 2903 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);" << endl;
2912 } 2904 }
2913 else if (!type->hasNativeId()) 2905 else if (!type->hasNativeId())
2914 continue; 2906 continue;
2915 else if (type->isObject() || type->isQObject()) 2907 else if (type->typeEntry()->isObject())
2916 { 2908 {
2917 bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1); 2909 bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1);
2918 2910
2919 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic()) 2911 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
2920 { 2912 {
2921 QString flags; 2913 QString flags;
2922 if (resetAfterUse) 2914 if (resetAfterUse)
2923 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete"; 2915 flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
2924 else if (type->isQObject()) 2916 else
2925 flags = "QtdObjectFlags.none"; 2917 flags = "QtdObjectFlags.none";
2926 else
2927 flags = "QtdObjectFlags.skipNativeDelete";
2928 2918
2929 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name 2919 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name
2930 << ", cast(QtdObjectFlags)(" << flags << "));" << endl; 2920 << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
2931 2921
2932 if (resetAfterUse) 2922 if (resetAfterUse)
2933 { 2923 {
2934 s << INDENT << "scope(exit) {" << endl 2924 s << INDENT << "scope(exit) {" << endl
2935 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl 2925 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
2936 << INDENT << " delete " << arg_name << ";" << endl 2926 << INDENT << " delete " << arg_name << ";" << endl
2937 << INDENT << "}" << endl; 2927 << INDENT << "}" << endl;
2938 } 2928 }
2939 } 2929 }
2940 else 2930 else
2941 { 2931 {
2942 s << INDENT << (resetAfterUse ? "scope " : "auto ") 2932 s << INDENT << (resetAfterUse ? "scope " : "auto ")
2943 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);"; 2933 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags."
2934 << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl;
2944 } 2935 }
2945 } 2936 }
2946 else 2937 else
2947 qFatal(qPrintable(type->typeEntry()->name())); 2938 qFatal(qPrintable(type->typeEntry()->name()));
2948 2939
2949 s << endl; 2940 s << endl;
2950 } 2941 }
2942 }
2951 } 2943 }
2952 2944
2953 s << INDENT; 2945 s << INDENT;
2954 AbstractMetaType *return_type = d_function->type(); 2946 AbstractMetaType *return_type = d_function->type();
2955 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.'); 2947 QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.');
2956 bool has_return_type = new_return_type != "void" 2948 bool has_return_type = new_return_type != "void"
2957 && (!new_return_type.isEmpty() || return_type != 0); 2949 && (!new_return_type.isEmpty() || return_type != 0);
2958 if(has_return_type) { 2950 if(has_return_type) {
2959 AbstractMetaType *f_type = d_function->type(); 2951 AbstractMetaType *f_type = d_function->type();
2960 2952
2961 if(f_type && (f_type->isObject() || f_type->isQObject() || f_type->isVariant() || 2953 if(f_type && (f_type->isObject() || f_type->isQObject() || f_type->isVariant() ||
2962 (f_type->isValue() && !f_type->typeEntry()->isStructInD()))) 2954 (f_type->isValue() && !f_type->typeEntry()->isStructInD())))
2963 { 2955 {
2964 QString f_type_name = f_type->name(); 2956 QString f_type_name = f_type->name();
2965 if(f_type->typeEntry()->designatedInterface()) 2957 if(f_type->typeEntry()->designatedInterface())
3122 s << f->implementingClass()->fullName() << " : " << f->minimalSignature() << endl; 3114 s << f->implementingClass()->fullName() << " : " << f->minimalSignature() << endl;
3123 } 3115 }
3124 } 3116 }
3125 file.close(); 3117 file.close();
3126 } 3118 }
3127 3119
3128 delete logstream; 3120 delete logstream;
3129 delete log; 3121 delete log;
3130 } 3122 }
3131 3123
3132 void DGenerator::writeFunctionAttributes(QTextStream &s, const AbstractMetaFunction *d_function, 3124 void DGenerator::writeFunctionAttributes(QTextStream &s, const AbstractMetaFunction *d_function,