comparison generator/dgenerator.cpp @ 259:515d6e1c7b10 lifetime

another iteration
author maxter
date Thu, 17 Sep 2009 16:28:41 +0000
parents 17b5e13364b7
children b5773ccab07d
comparison
equal deleted inserted replaced
258:1da8870e9a62 259:515d6e1c7b10
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
902 if (return_type->isValue() && !return_type->typeEntry()->isStructInD() 902 if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
903 || return_type->isNativePointer() && return_type->typeEntry()->isValue()
904 || return_type->name() == "QVariant")
905 s << "new " << return_type->name() << "(ret);" << endl; 903 s << "new " << return_type->name() << "(ret);" << endl;
906 904
907 if (return_type->isObject()) { 905 if (return_type->isObject()) {
908 if(d_function->storeResult()) 906 if(d_function->storeResult())
909 { 907 {
1788 QString auxModName = d_class->package() + "." + d_class->name() + "_aux"; 1786 QString auxModName = d_class->package() + "." + d_class->name() + "_aux";
1789 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d"); 1787 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d");
1790 auxFile.isDone = true; 1788 auxFile.isDone = true;
1791 auxFile.stream << "module " << auxModName << ";" << endl << endl; 1789 auxFile.stream << "module " << auxModName << ";" << endl << endl;
1792 1790
1793 bool staticInit = (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); 1791 bool staticInit = (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
1794 if (staticInit) 1792 if (staticInit)
1795 { 1793 {
1796 auxFile.isDone = false; 1794 auxFile.isDone = false;
1797 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl; 1795 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl;
1798 auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl; 1796 auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl;
2198 foreach (const AbstractMetaField *field, fields) { 2196 foreach (const AbstractMetaField *field, fields) {
2199 if (field->wasPublic() || (field->wasProtected() && !d_class->isFinal())) 2197 if (field->wasPublic() || (field->wasProtected() && !d_class->isFinal()))
2200 writeFieldAccessors(s, field); 2198 writeFieldAccessors(s, field);
2201 } 2199 }
2202 2200
2203 if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) 2201 if (d_class->typeEntry()->isObject())
2204 { 2202 {
2205 if (d_class->isQObject()) 2203 if (d_class->isQObject())
2206 writeQObjectFunctions(s, d_class); 2204 writeQObjectFunctions(s, d_class);
2207 else 2205 else
2208 writeObjectFunctions(s, d_class); 2206 writeObjectFunctions(s, d_class);
2207
2208 if (d_class->hasVirtualDestructor())
2209 {
2210 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl
2211 << " auto obj = new(flags) " << d_class->name() << "(nativeId, flags);" << endl;
2212
2213 if (d_class->isQObject())
2214 s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl;
2215
2216 s << " return obj;" << endl
2217 << " }" << endl << endl;
2218 }
2219 }
2209 2220
2210 s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl 2221 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualDestructor()))
2211 << " return new(flags) " << d_class->name() << "(nativeId, flags);" << endl
2212 << " }" << endl << endl;
2213 }
2214
2215 if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions()))
2216 writeDestructor(s, d_class); 2222 writeDestructor(s, d_class);
2217 2223
2218 // Add dummy constructor for use when constructing subclasses 2224 // Add dummy constructor for use when constructing subclasses
2219 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { 2225 if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
2220 s << endl 2226 s << endl
2222 << "this"; 2228 << "this";
2223 2229
2224 2230
2225 Indentation indent(INDENT); 2231 Indentation indent(INDENT);
2226 2232
2227
2228 QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none"; 2233 QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none";
2229 s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl 2234 s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl
2230 << INDENT << "super(nativeId, flags);" << endl; 2235 << INDENT << "super(nativeId, flags);" << endl;
2231
2232 if (d_class->name() == "QObject")
2233 {
2234 s << INDENT << "if (!(__flags & QtdObjectFlags.hasDId))" << endl
2235 << INDENT << " __createEntity;" << endl;
2236 }
2237
2238 2236
2239 /* 2237 /*
2240 if (cpp_shared) { 2238 if (cpp_shared) {
2241 if (d_class->generateShellClass() && !d_class->isInterface()) 2239 if (d_class->generateShellClass() && !d_class->isInterface())
2242 s << INDENT << "if (!static_inited)" << endl 2240 s << INDENT << "if (!static_inited)" << endl
2458 } 2456 }
2459 } 2457 }
2460 s << INDENT << "}" << endl << endl; 2458 s << INDENT << "}" << endl << endl;
2461 } 2459 }
2462 2460
2463 if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) 2461 if (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor())
2464 { 2462 {
2465 if (!d_class->typeEntry()->isQObject()) 2463 if (!d_class->typeEntry()->isQObject())
2466 { 2464 {
2467 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl; 2465 s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl;
2468 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; 2466 s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
2531 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; 2529 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl;
2532 } 2530 }
2533 2531
2534 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2532 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
2535 2533
2536 if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) { 2534 if (d_class->typeEntry()->isObject() && d_class->hasVirtualDestructor()) {
2537 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl 2535 s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
2538 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; 2536 << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
2539 } 2537 }
2540 2538
2541 if (cpp_shared) { 2539 if (cpp_shared) {
2630 } 2628 }
2631 s << "}" << endl << endl; 2629 s << "}" << endl << endl;
2632 } 2630 }
2633 */ 2631 */
2634 2632
2635 // Polymorphic non-QObject
2636 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2633 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2637 { 2634 {
2638 QString rootClassName = d_class->rootClass()->name(); 2635 // polymorphic
2639 QString concreteArg; 2636 if (d_class->hasVirtualDestructor())
2640 if (d_class->isAbstract())
2641 concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
2642
2643 s << " private static QtdMetaObject _staticMetaObject;" << endl
2644 //<< " private static QtdMetaObject[void*] _nativeToTargetMap;" << endl
2645
2646 << " protected static void createStaticMetaObject() {" << endl
2647 << " assert(!_staticMetaObject);" << endl
2648 << " QtdMetaObject base;" << endl;
2649
2650 if (d_class->baseClass())
2651 { 2637 {
2652 QString baseName = d_class->baseClassName(); 2638 QString rootClassName = d_class->rootClass()->name();
2653 s << " if (!" << baseName << "._staticMetaObject)" << endl 2639 QString concreteArg;
2654 << " " << baseName << ".createStaticMetaObject;" << endl 2640 if (d_class->isAbstract())
2655 << " base = " << baseName << "._staticMetaObject;" << endl; 2641 concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
2656 } 2642
2657 2643 s << " private static QtdMetaObject _staticMetaObject;" << endl
2658 s << " _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);" << endl 2644 //<< " private static QtdMetaObject[void*] _nativeToTargetMap;" << endl
2659 << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl 2645
2660 << " }" << endl << endl 2646 << " protected static void createStaticMetaObject() {" << endl
2661 2647 << " assert(!_staticMetaObject);" << endl
2662 << " QtdMetaObject metaObject() {" << endl 2648 << " QtdMetaObject base;" << endl;
2663 << " return _staticMetaObject;" << endl 2649
2664 << " }" << endl << endl 2650 if (d_class->baseClass())
2665 2651 {
2666 << " static QtdMetaObject staticMetaObject() {" << endl 2652 QString baseName = d_class->baseClassName();
2667 << " return _staticMetaObject;" << endl 2653 s << " if (!" << baseName << "._staticMetaObject)" << endl
2668 << " }" << endl << endl 2654 << " " << baseName << ".createStaticMetaObject;" << endl
2669 2655 << " base = " << baseName << "._staticMetaObject;" << endl;
2670 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl 2656 }
2671 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl 2657
2672 << " if (!obj)" << endl 2658 s << " _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);" << endl
2673 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId," 2659 << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl
2674 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl 2660 << " }" << endl << endl
2675 << " return obj;" << endl 2661
2676 << " }" << endl << endl; 2662 << " QtdMetaObject metaObject() {" << endl
2677 /* 2663 << " return _staticMetaObject;" << endl
2678 << " overrive protected void __addMapping() {" << endl 2664 << " }" << endl << endl
2679 << " _nativeToTargetMap[__nativeId] = this;" << endl 2665
2680 << " }" << endl << endl 2666 << " static QtdMetaObject staticMetaObject() {" << endl
2681 2667 << " return _staticMetaObject;" << endl
2682 << " override protected void __removeMapping() {" << endl 2668 << " }" << endl << endl
2683 << " _nativeToTargetMap.remove(__nativeId);" << endl 2669
2684 << " }" << endl << endl 2670 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl
2685 */ 2671 << " auto obj = cast(" << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl
2672 << " if (!obj)" << endl
2673 << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId,"
2674 "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl
2675 << " return obj;" << endl
2676 << " }" << endl << endl;
2677 }
2678 else
2679 {
2680 s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl
2681 << " return new " << d_class->name() << "(nativeId, flags);"
2682 << " }" << endl << endl;
2683 }
2686 } 2684 }
2687 2685
2688 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2686 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2689 { 2687 {
2690 QString concreteArg; 2688 QString concreteArg;
2716 << " return _staticMetaObject;" << endl 2714 << " return _staticMetaObject;" << endl
2717 << " }" << endl << endl 2715 << " }" << endl << endl
2718 2716
2719 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl 2717 << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
2720 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl 2718 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl
2721 << " }" << endl << endl 2719 << " }" << endl << endl;
2722
2723 << " void __createEntity() {" << endl
2724 << " return qtd_" << d_class->name() << "_createEntity(__nativeId, cast(void*)this);" << endl
2725 << " }" << endl << endl;
2726 } 2720 }
2727 2721
2728 /* 2722 /*
2729 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) 2723 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class)
2730 { 2724 {
2731 2725
2732 } 2726 }
2733 */ 2727 */
2734 2728
2735 // Returns the name of the resulting variable 2729 void DGenerator::marshalToD(QTextStream &s, const ComplexTypeEntry *ctype)
2736 QString DGenerator::marshalToD(QTextStream &s, QString argName, const TypeEntry* type, MarshalFlags flags) 2730 {
2737 { 2731 if(ctype->isQObject()) {
2738 if (type->isBasicValue()) 2732 QString type_name = ctype->name();
2739 return argName; 2733 if (ctype->isAbstract())
2740 2734 type_name += "_ConcreteWrapper";
2741 QString qtdObjFlags = "QtdObjectFlags.none"; 2735 s << "return " << type_name << ".__getObject(ret);" << endl;
2742 const ObjectTypeEntry *ctype = 0; 2736 } else if (ctype->isValue() && !ctype->isStructInD()) {
2743 bool stackObject = false; 2737 s << INDENT << "return new " << ctype->name() << "(ret);" << endl;
2744 2738 } else if (ctype->isVariant()) {
2745 if (type->isObject()) 2739 s << INDENT << "return new QVariant(ret);" << endl;
2746 ctype = static_cast<const ObjectTypeEntry *>(ctype);
2747
2748 if (type->isValue())
2749 flags |= MarshalScope;
2750
2751 if (flags & MarshalScope)
2752 {
2753 if (type->isObject() && type->hasVirtualDestructor())
2754 {
2755 qtdObjectFlags += " | QtdObjectFlags.stackAllocated";
2756 bool stackObject = true;
2757 }
2758 else
2759 s << INDENT << "scope ";
2760
2761 qtdObjectFlags += "| QtdObjectFlags.skipNativeDelete";
2762 }
2763 else
2764 s << INDENT << "auto ";
2765
2766 s << resultName << " = ";
2767
2768
2769 if (ctype->isObject() && type->hasVirtualDestructor()) {
2770 exp = type->name() + ".__wrap(ret);" + endl;
2771 }
2772 else if (type->isValue())
2773 {
2774 if (type->actualIndirections() == 0)
2775 s << "new " << type->name() << "(" << argName << ");" << endl;
2776 else if (type->actualIndirections() == 1)
2777 s << "new "
2778 }
2779
2780
2781 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { 2740 } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
2782 s << INDENT << "return ret;" << endl; 2741 s << INDENT << "return ret;" << endl;
2783 } 2742 } else if (ctype->isObject()) {
2784 2743 QString type_name = ctype->name();
2785 if (stackObject) 2744 s << "return qtd_" << type_name << "_from_ptr(ret);" << endl;
2786 { 2745 }
2787 s << ""
2788 }
2789
2790 } 2746 }
2791 2747
2792 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field) 2748 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field)
2793 { 2749 {
2794 Q_ASSERT(field->isPublic() || field->isProtected()); 2750 Q_ASSERT(field->isPublic() || field->isProtected());
2920 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl 2876 s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl
2921 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; 2877 << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();";
2922 } 2878 }
2923 else if (type->typeEntry()->isStructInD()) 2879 else if (type->typeEntry()->isStructInD())
2924 continue; 2880 continue;
2925 else if ((type->typeEntry()->isValue() && type->isNativePointer()) 2881 else if (type->typeEntry()->isValue()){
2926 || type->isValue() || type->isVariant()){ 2882 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);" << endl;
2927 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ");" << endl;
2928
2929 (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", "
2930 << implementor->name() << "::" << d_function->name();
2931
2932 if (type->typeEntry()->isValue())
2933 (*logstream) << ", type entry value";
2934
2935 if (type->typeEntry()->isValue())
2936 (*logstream) << ", value";
2937
2938 if (type->isNativePointer())
2939 (*logstream) << ", native pointer";
2940
2941 const ComplexTypeEntry* ctype = dynamic_cast<const ComplexTypeEntry*>(type->typeEntry());
2942 if (ctype && ctype->hasVirtualFunctions())
2943 (*logstream) << ", polymorphic";
2944
2945 (*logstream) << endl;
2946 } 2883 }
2947 else if (!type->hasNativeId()) 2884 else if (!type->hasNativeId())
2948 continue; 2885 continue;
2949 else if (type->isObject() || type->isQObject()) 2886 else if (type->isObject() || type->isQObject())
2950 { 2887 {
2951 if (!type->isQObject()) 2888 bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1);
2889
2890 if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->hasVirtualDestructor())
2891 {
2892 QString flags;
2893 if (resetAfterUse)
2894 flags += "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
2895 else if (type->isQObject())
2896 flags += "QtdObjectFlags.none";
2897 else
2898 flags = "QtdObjectFlags.skipNativeDelete";
2899
2900 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name
2901 << ", " << flags << ");" << endl;
2902
2903 if (resetAfterUse)
2904 {
2905 s << INDENT << "scope(exit) {" << endl
2906 << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
2907 << INDENT << " delete " << arg_name << ";" << endl
2908 << INDENT << "}" << endl;
2909 }
2910 }
2911 else
2952 { 2912 {
2953 (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", " 2913 s << INDENT << (resetAfterUse ? "scope " : "auto ")
2954 << implementor->name() << "::" << d_function->name(); 2914 << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);";
2955
2956 (*logstream) << ", object";
2957
2958 const ComplexTypeEntry* ctype = dynamic_cast<const ComplexTypeEntry*>(type->typeEntry());
2959 if (ctype && ctype->hasVirtualFunctions())
2960 (*logstream) << ", polymorphic";
2961
2962 (*logstream) << endl;
2963 } 2915 }
2964
2965 if (((ComplexTypeEntry*)type->typeEntry())->hasVirtualFunctions() || !d_function->resetObjectAfterUse(argument->argumentIndex() + 1))
2966 s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name << ");";
2967 else
2968 s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);";
2969 } 2916 }
2970 else 2917 else
2971 qFatal(qPrintable(type->typeEntry()->name())); 2918 qFatal(qPrintable(type->typeEntry()->name()));
2972 2919
2973 s << endl; 2920 s << endl;
3071 void DGenerator::generate() 3018 void DGenerator::generate()
3072 { 3019 {
3073 log = new QFile("arglog.txt"); 3020 log = new QFile("arglog.txt");
3074 log->open(QFile::ReadWrite); 3021 log->open(QFile::ReadWrite);
3075 logstream = new QTextStream(log); 3022 logstream = new QTextStream(log);
3076 // qtd
3077 // code for including classses in 1 module for avoiding circular imports
3078 foreach (AbstractMetaClass *cls, m_classes) {
3079 ComplexTypeEntry *ctype = const_cast<ComplexTypeEntry *>(cls->typeEntry());
3080
3081 if (!cls->isInterface() && cls->isAbstract())
3082 ctype->setAbstract(true);
3083
3084 ctype->setHasVirtualFunctions(cls->hasVirtualFunctions());
3085
3086 foreach(QString child, ctype->includedClasses) {
3087 ComplexTypeEntry *ctype_child = TypeDatabase::instance()->findComplexType(child);
3088 ctype_child->addedTo = cls->name();
3089 }
3090
3091 foreach (AbstractMetaFunction *function, cls->functions())
3092 function->checkStoreResult();
3093 }
3094 3023
3095 Generator::generate(); 3024 Generator::generate();
3096 3025
3097 { 3026 {
3098 const AbstractMetaClass *last_class = 0; 3027 const AbstractMetaClass *last_class = 0;