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