Mercurial > projects > qtd
comparison generator/dgenerator.cpp @ 110:136c9ee83ee5
put conversion code in separate functions
author | eldar |
---|---|
date | Mon, 01 Jun 2009 23:32:57 +0000 |
parents | 3aa118a9ae71 |
children | 2a85b786fa3a |
comparison
equal
deleted
inserted
replaced
109:08135aa00cc9 | 110:136c9ee83ee5 |
---|---|
846 | 846 |
847 s << ";" << endl; | 847 s << ";" << endl; |
848 | 848 |
849 // return value marschalling | 849 // return value marschalling |
850 if(return_type) { | 850 if(return_type) { |
851 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )/* || d_function->isConstructor()*/) // qtd | 851 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd |
852 if(return_type->isQObject()) { | 852 if(return_type->isQObject()) |
853 | 853 s << INDENT << "return qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl; |
854 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(return_type->typeEntry()); | |
855 QString type_name = return_type->name(); | |
856 QString class_name = ctype->name(); | |
857 if(ctype->isAbstract()) | |
858 type_name = type_name + "_ConcreteWrapper"; | |
859 /* | |
860 s << INDENT << "if (__qt_return_value is null)" << endl | |
861 << INDENT << " return null;" << endl | |
862 << INDENT << "void* d_obj = __QObject_entity(__qt_return_value);" << endl | |
863 << INDENT << "if (d_obj is null) {" << endl | |
864 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl | |
865 << INDENT << " new_obj.__no_real_delete = true;" << endl | |
866 << INDENT << " return new_obj;" << endl | |
867 << INDENT << "} else" << endl | |
868 << INDENT << " return cast(" << return_type->name() << ") d_obj;" << endl; | |
869 */ | |
870 s << INDENT << "if (__qt_return_value is null)" << endl | |
871 << INDENT << " return null;" << endl | |
872 << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl | |
873 << INDENT << "if (d_obj is null) {" << endl | |
874 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl | |
875 << INDENT << " qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl | |
876 << INDENT << " new_obj.__no_real_delete = true;" << endl | |
877 << INDENT << " return new_obj;" << endl | |
878 << INDENT << "} else" << endl | |
879 << INDENT << " return cast(" << class_name << ") d_obj;" << endl; | |
880 | |
881 } | |
882 | |
883 | 854 |
884 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) | 855 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) |
885 s << INDENT << "return new " << return_type->name() << "(__qt_return_value, false);" << endl; | 856 s << INDENT << "return new " << return_type->name() << "(__qt_return_value, false);" << endl; |
886 | 857 |
887 if (return_type->isVariant()) | 858 if (return_type->isVariant()) |
903 QString return_type_name = return_type->name(); | 874 QString return_type_name = return_type->name(); |
904 if(return_type->typeEntry()->designatedInterface()) | 875 if(return_type->typeEntry()->designatedInterface()) |
905 return_type_name = return_type->typeEntry()->designatedInterface()->name(); | 876 return_type_name = return_type->typeEntry()->designatedInterface()->name(); |
906 | 877 |
907 AbstractMetaClass *classForTypeEntry = NULL; | 878 AbstractMetaClass *classForTypeEntry = NULL; |
908 // search in AbstractMetaClass list for return type | |
909 // find a better way to perform TypeEntry -> AbstractMetaClass lookup, maybe create hash before generation | |
910 // qtd2 | |
911 /*foreach (AbstractMetaClass *cls, m_classes) { | |
912 if ( cls->name() == d_function->type()->name() ) | |
913 classForTypeEntry = cls; | |
914 }*/ | |
915 | |
916 classForTypeEntry = ClassFromEntry::get(return_type->typeEntry()); | 879 classForTypeEntry = ClassFromEntry::get(return_type->typeEntry()); |
917 | 880 |
918 // if class has virtual functions then it has classname_entity function so | 881 // if class has virtual functions then it has classname_entity function so |
919 // we can look for D Object pointer. otherwise create new wrapper | 882 // we can look for D Object pointer. otherwise create new wrapper |
920 if (classForTypeEntry != NULL && classForTypeEntry->hasVirtualFunctions()) { | 883 if (classForTypeEntry != NULL && classForTypeEntry->hasVirtualFunctions()) { |
2514 if (d_class->hasVirtualFunctions() | 2477 if (d_class->hasVirtualFunctions() |
2515 && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) ) | 2478 && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) ) |
2516 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; | 2479 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; |
2517 } | 2480 } |
2518 | 2481 |
2519 if (d_class->isQObject()) { | 2482 if (d_class->isQObject()) |
2520 writeQObjectFunctions(s, d_class); | 2483 writeQObjectFunctions(s, d_class); |
2521 | 2484 |
2522 s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl | 2485 |
2523 << " auto d_ref = cast(QObject) d_ptr;" << endl | 2486 if (d_class->needsConversionFunc) |
2524 << " d_ref.__no_real_delete = true;" << endl | 2487 writeConversionFunction(s, d_class); |
2525 << " delete d_ref;" << endl | |
2526 << "}" << endl; | |
2527 } | |
2528 | 2488 |
2529 if (d_class->hasConstructors()) | 2489 if (d_class->hasConstructors()) |
2530 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; | 2490 s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; |
2531 | 2491 |
2532 // qtd | 2492 // qtd |
2634 write(s, cls); | 2594 write(s, cls); |
2635 m_isRecursive = false; | 2595 m_isRecursive = false; |
2636 } | 2596 } |
2637 } | 2597 } |
2638 | 2598 |
2599 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) | |
2600 { | |
2601 const ComplexTypeEntry *ctype = d_class->typeEntry(); | |
2602 QString class_name = ctype->name(); | |
2603 | |
2604 if(ctype->isQObject()) { | |
2605 s << class_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl; | |
2606 QString type_name = class_name; | |
2607 if(ctype->isAbstract()) | |
2608 type_name = type_name + "_ConcreteWrapper"; | |
2609 | |
2610 s << INDENT << "if (__qt_return_value is null)" << endl | |
2611 << INDENT << " return null;" << endl | |
2612 << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl | |
2613 << INDENT << "if (d_obj is null) {" << endl | |
2614 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl | |
2615 << INDENT << " qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl | |
2616 << INDENT << " new_obj.__no_real_delete = true;" << endl | |
2617 << INDENT << " return new_obj;" << endl | |
2618 << INDENT << "} else" << endl | |
2619 << INDENT << " return cast(" << class_name << ") d_obj;" << endl; | |
2620 s << "}" << endl << endl; | |
2621 | |
2622 } /* else if (ctype->isObject()) { | |
2623 QString type_name = class_name; | |
2624 if(ctype->isAbstract()) | |
2625 type_name = type_name + "_ConcreteWrapper"; | |
2626 | |
2627 QString return_type_name = ctype->name(); | |
2628 if(ctype->designatedInterface()) | |
2629 return_type_name = ctype->designatedInterface()->name(); | |
2630 | |
2631 // if class has virtual functions then it has classname_entity function so | |
2632 // we can look for D Object pointer. otherwise create new wrapper | |
2633 if (d_class->hasVirtualFunctions()) { | |
2634 s << INDENT << "void* d_obj = __" << ctype->name() << "_entity(__qt_return_value);" << endl | |
2635 << INDENT << "if (d_obj !is null) {" << endl | |
2636 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl | |
2637 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl | |
2638 << INDENT << "} else {" << endl | |
2639 << INDENT << " auto return_value = new " << type_name << "(__qt_return_value, true);" << endl | |
2640 << INDENT << " return_value.__no_real_delete = true;" << endl | |
2641 << INDENT << " return return_value;" << endl | |
2642 << INDENT << "}"; | |
2643 } else { | |
2644 s << INDENT << "auto return_value = new " << type_name << "(__qt_return_value, true);" << endl | |
2645 << INDENT << "return_value.__no_real_delete = true;" << endl | |
2646 << INDENT << "return return_value;" << endl; | |
2647 } | |
2648 }*/ | |
2649 } | |
2650 | |
2651 | |
2639 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) | 2652 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) |
2640 { | 2653 { |
2641 s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl | 2654 s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl |
2642 << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl; | 2655 << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl; |
2656 s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl | |
2657 << " auto d_ref = cast(QObject) d_ptr;" << endl | |
2658 << " d_ref.__no_real_delete = true;" << endl | |
2659 << " delete d_ref;" << endl | |
2660 << "}" << endl << endl; | |
2643 } | 2661 } |
2644 | 2662 |
2645 /* | 2663 /* |
2646 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) | 2664 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class) |
2647 { | 2665 { |
2970 foreach (AbstractMetaClass *cls, m_classes) { | 2988 foreach (AbstractMetaClass *cls, m_classes) { |
2971 const ComplexTypeEntry *ctype = cls->typeEntry(); | 2989 const ComplexTypeEntry *ctype = cls->typeEntry(); |
2972 | 2990 |
2973 if (!cls->isInterface() && cls->isAbstract()) { | 2991 if (!cls->isInterface() && cls->isAbstract()) { |
2974 ComplexTypeEntry *ctype_m = (ComplexTypeEntry *)ctype; | 2992 ComplexTypeEntry *ctype_m = (ComplexTypeEntry *)ctype; |
2975 | |
2976 ctype_m->setAbstract(true); | 2993 ctype_m->setAbstract(true); |
2977 } | 2994 } |
2978 | 2995 |
2979 foreach(QString child, ctype->includedClasses) { | 2996 foreach(QString child, ctype->includedClasses) { |
2980 ComplexTypeEntry *ctype_child = TypeDatabase::instance()->findComplexType(child); | 2997 ComplexTypeEntry *ctype_child = TypeDatabase::instance()->findComplexType(child); |
2981 ctype_child->addedTo = cls->name(); | 2998 ctype_child->addedTo = cls->name(); |
2982 } | 2999 } |
2983 | 3000 |
2984 foreach (AbstractMetaFunction *function, cls->functions()) | 3001 foreach (AbstractMetaFunction *function, cls->functions()) |
2985 function->checkStoreResult(); | 3002 function->checkStoreResult(); |
2986 } | 3003 |
2987 | 3004 // generate QObject conversion functions only those that are required |
3005 AbstractMetaFunctionList d_funcs = cls->functionsInTargetLang(); | |
3006 for (int i=0; i<d_funcs.size(); ++i) { | |
3007 AbstractMetaType *f_type = d_funcs.at(i)->type(); | |
3008 if (!f_type) | |
3009 continue; | |
3010 if (f_type->isQObject() || f_type->isObject()) { | |
3011 const ComplexTypeEntry* cte = static_cast<const ComplexTypeEntry *>(f_type->typeEntry()); | |
3012 AbstractMetaClass* d_class = ClassFromEntry::get(cte); | |
3013 if (d_class) | |
3014 d_class->needsConversionFunc = true; | |
3015 } | |
3016 } | |
3017 } | |
2988 | 3018 |
2989 Generator::generate(); | 3019 Generator::generate(); |
2990 | 3020 |
2991 { | 3021 { |
2992 const AbstractMetaClass *last_class = 0; | 3022 const AbstractMetaClass *last_class = 0; |
3351 | 3381 |
3352 ClassFromEntry* ClassFromEntry::m_instance = NULL; | 3382 ClassFromEntry* ClassFromEntry::m_instance = NULL; |
3353 | 3383 |
3354 ClassFromEntry::ClassFromEntry() | 3384 ClassFromEntry::ClassFromEntry() |
3355 { | 3385 { |
3386 } | |
3387 | |
3388 AbstractMetaClass* ClassFromEntry::get(const TypeEntry *ctype) | |
3389 { | |
3390 if(!m_instance) | |
3391 return NULL; | |
3392 | |
3393 return m_instance->classFromEntry[ctype]; | |
3394 } | |
3395 | |
3396 void ClassFromEntry::construct(const AbstractMetaClassList &classes) | |
3397 { | |
3398 if(!m_instance) { | |
3399 m_instance = new ClassFromEntry; | |
3400 m_instance->setClasses(classes); | |
3401 m_instance->buildHash(); | |
3402 } | |
3403 } | |
3404 | |
3405 void ClassFromEntry::buildHash() | |
3406 { | |
3356 foreach (AbstractMetaClass *cls, m_classes) { | 3407 foreach (AbstractMetaClass *cls, m_classes) { |
3357 const ComplexTypeEntry *ctype = cls->typeEntry(); | 3408 const ComplexTypeEntry *ctype = cls->typeEntry(); |
3358 classFromEntry[ctype] = cls; | 3409 classFromEntry[ctype] = cls; |
3359 } | 3410 } |
3360 } | 3411 } |
3361 | 3412 |
3362 AbstractMetaClass* ClassFromEntry::get(const TypeEntry *ctype) | 3413 void ClassFromEntry::print(QTextStream &s) |
3363 { | 3414 { |
3364 if(!m_instance) | 3415 s << "_fuck_" << m_instance->m_classes.size(); |
3365 m_instance = new ClassFromEntry; | 3416 foreach (AbstractMetaClass *cls, m_instance->m_classes) { |
3366 | 3417 s << cls->name() << endl; |
3367 return m_instance->classFromEntry[ctype]; | 3418 } |
3368 } | 3419 } |
3420 |