annotate generator/cppimplgenerator.cpp @ 382:1d56b2a2e10c

Fixes to debugging stuff. Added size_t as primitive type to workaround Qwt build failure in debug
author Max Samukha <maxter@spambox.com>
date Mon, 12 Jul 2010 20:36:07 +0300
parents 7341c47790d4
children d2f48c4cb3e3
rev   line source
mandel@1 1 /****************************************************************************
mandel@1 2 **
mandel@1 3 ** Copyright (C) 1992-2008 Nokia. All rights reserved.
mandel@1 4 **
mandel@1 5 ** This file is part of Qt Jambi.
mandel@1 6 **
mandel@1 7 ** * Commercial Usage
mandel@1 8 * Licensees holding valid Qt Commercial licenses may use this file in
mandel@1 9 * accordance with the Qt Commercial License Agreement provided with the
mandel@1 10 * Software or, alternatively, in accordance with the terms contained in
mandel@1 11 * a written agreement between you and Nokia.
mandel@1 12 *
mandel@1 13 *
mandel@1 14 * GNU General Public License Usage
mandel@1 15 * Alternatively, this file may be used under the terms of the GNU
mandel@1 16 * General Public License versions 2.0 or 3.0 as published by the Free
mandel@1 17 * Software Foundation and appearing in the file LICENSE.GPL included in
mandel@1 18 * the packaging of this file. Please review the following information
mandel@1 19 * to ensure GNU General Public Licensing requirements will be met:
mandel@1 20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and
mandel@1 21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special
mandel@1 22 * exception, Nokia gives you certain additional rights. These rights
mandel@1 23 * are described in the Nokia Qt GPL Exception version 1.2, included in
mandel@1 24 * the file GPL_EXCEPTION.txt in this package.
mandel@1 25 *
mandel@1 26 * Qt for Windows(R) Licensees
mandel@1 27 * As a special exception, Nokia, as the sole copyright holder for Qt
mandel@1 28 * Designer, grants users of the Qt/Eclipse Integration plug-in the
mandel@1 29 * right for the Qt/Eclipse Integration to link to functionality
mandel@1 30 * provided by Qt Designer and its related libraries.
mandel@1 31 *
mandel@1 32 *
mandel@1 33 * If you are unsure which license is appropriate for your use, please
mandel@1 34 * contact the sales department at qt-sales@nokia.com.
mandel@1 35
mandel@1 36 **
mandel@1 37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
mandel@1 38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
mandel@1 39 **
mandel@1 40 ****************************************************************************/
mandel@1 41
mandel@1 42 #include "cppimplgenerator.h"
mandel@1 43 #include "dgenerator.h"
mandel@1 44 #include "reporthandler.h"
mandel@1 45
mandel@1 46 #include <QDir>
mandel@1 47 #include <QtDebug>
mandel@1 48 #include <QVariant>
mandel@1 49 #include <iostream>
mandel@1 50 #define VOID_POINTER_ORDINAL 8
mandel@1 51
mandel@1 52 static Indentor INDENT;
mandel@1 53
mandel@1 54 QString jni_signature(const AbstractMetaFunction *function, JNISignatureFormat format)
mandel@1 55 {
mandel@1 56 QString returned = "(";
mandel@1 57 AbstractMetaArgumentList arguments = function->arguments();
mandel@1 58 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 59 if (!function->argumentRemoved(argument->argumentIndex() + 1)) {
mandel@1 60 QString modified_type = function->typeReplaced(argument->argumentIndex()+1);
mandel@1 61
mandel@1 62 if (modified_type.isEmpty())
mandel@1 63 returned += jni_signature(argument->type(), format);
mandel@1 64 else
mandel@1 65 returned += jni_signature(modified_type, format);
mandel@1 66 }
mandel@1 67 }
mandel@1 68
mandel@1 69 returned += ")";
mandel@1 70
mandel@1 71 QString modified_type = function->typeReplaced(0);
mandel@1 72 if (modified_type.isEmpty())
mandel@1 73 returned += jni_signature(function->type(), format);
mandel@1 74 else
mandel@1 75 returned += jni_signature(modified_type, format);
mandel@1 76
mandel@1 77 return returned;
mandel@1 78 }
mandel@1 79
mandel@1 80 QString jni_signature(const QString &_full_name, JNISignatureFormat format)
mandel@1 81 {
mandel@1 82 QString signature;
mandel@1 83 QString full_name = _full_name;
mandel@1 84
mandel@1 85 if (full_name.endsWith("[]")) {
mandel@1 86 full_name.chop(2);
mandel@1 87 signature = "[";
mandel@1 88 }
mandel@1 89
mandel@1 90 int start = 0, end = -1;
mandel@1 91 while ( (start = full_name.indexOf("<")) >= 0 && (end = full_name.indexOf(">")) >= 0 ) {
mandel@1 92 full_name.remove(start, end - start + 1);
mandel@1 93 }
mandel@1 94
mandel@1 95 static QHash<QString, QString> table;
mandel@1 96 if (table.isEmpty()) {
mandel@1 97 table["boolean"] = "Z";
mandel@1 98 table["byte"] = "B";
mandel@1 99 table["char"] = "C";
mandel@1 100 table["short"] = "S";
mandel@1 101 table["int"] = "I";
mandel@1 102 table["long"] = "J";
mandel@1 103 table["float"] = "F";
mandel@1 104 table["double"] = "D";
mandel@1 105 }
mandel@1 106
mandel@1 107 if (format == Underscores)
mandel@1 108 signature.replace("[", "_3");
mandel@1 109
mandel@1 110 if (table.contains(full_name)) {
mandel@1 111 signature += table[full_name];
mandel@1 112 } else if (format == Underscores) {
mandel@1 113 signature.replace("[", "_3");
mandel@1 114 signature += "L";
mandel@1 115 signature += QString(full_name).replace("_", "_1").replace('.', '_').replace("$", "_00024");
mandel@1 116 signature += "_2";
mandel@1 117 } else {
mandel@1 118 signature += "L";
mandel@1 119 signature += QString(full_name).replace('.', '/');
mandel@1 120 signature += ";";
mandel@1 121 }
mandel@1 122
mandel@1 123 return signature;
mandel@1 124 }
mandel@1 125
mandel@1 126 QString jni_signature(const AbstractMetaType *java_type, JNISignatureFormat format)
mandel@1 127 {
mandel@1 128 if (!java_type)
mandel@1 129 return "V";
mandel@1 130
mandel@1 131 if (java_type->isArray()) {
mandel@1 132 return "_3" + jni_signature(java_type->arrayElementType(), format);
mandel@1 133 } else if (java_type->isNativePointer()) {
mandel@1 134 if (format == Underscores)
mandel@1 135 return "Lcom_trolltech_qt_QNativePointer_2";
mandel@1 136 else
mandel@1 137 return "Lcom/trolltech/qt/QNativePointer;";
mandel@1 138 } else if (java_type->isIntegerEnum() || java_type->isIntegerFlags()
mandel@1 139 || (format == Underscores && (java_type->isEnum() || java_type->isFlags()))) {
mandel@1 140 return "I";
mandel@1 141 } else if (java_type->isThread()) {
mandel@1 142 if (format == Underscores)
mandel@1 143 return "Ljava_lang_Thread_2";
mandel@1 144 else
mandel@1 145 return "Ljava/lang/Thread;";
mandel@1 146 }
mandel@1 147
mandel@1 148
mandel@1 149
mandel@1 150 QString name = java_type->name();
mandel@1 151 if (java_type->isObject()) {
mandel@1 152 if (const InterfaceTypeEntry *ie
mandel@1 153 = static_cast<const ObjectTypeEntry *>(java_type->typeEntry())->designatedInterface())
mandel@1 154 name = ie->targetLangName();
mandel@1 155 } else if (java_type->isTargetLangEnum()) {
mandel@1 156 const EnumTypeEntry *et = static_cast<const EnumTypeEntry *>(java_type->typeEntry());
mandel@1 157 name = et->javaQualifier() + "$" + et->targetLangName();
mandel@1 158
mandel@1 159 } else if (java_type->isTargetLangFlags()) {
mandel@1 160 const FlagsTypeEntry *ft = static_cast<const FlagsTypeEntry *>(java_type->typeEntry());
mandel@1 161 name = ft->originator()->javaQualifier() + "$" + ft->targetLangName();
mandel@1 162 }
mandel@1 163
mandel@1 164 return jni_signature( (java_type->package().isEmpty() ? QString() : java_type->package() + ".") + name, format);
mandel@1 165 }
mandel@1 166
mandel@1 167 static QHash<QString, QString> table;
mandel@1 168 QString default_return_statement_qt(const AbstractMetaType *java_type, Generator::Option options = Generator::NoOption)
mandel@1 169 {
mandel@1 170 QString returnStr = ((options & Generator::NoReturnStatement) == 0 ? "return" : "");
mandel@1 171 if (!java_type)
mandel@1 172 return returnStr;
mandel@1 173
mandel@1 174 if (table.isEmpty()) {
mandel@1 175 table["bool"] = "false";
mandel@1 176 table["byte"] = "0";
mandel@1 177 table["char"] = "0";
mandel@1 178 table["short"] = "0";
mandel@1 179 table["int"] = "0";
mandel@1 180 table["long"] = "0";
mandel@1 181 table["float"] = "0f";
mandel@1 182 table["double"] = "0.0";
maxter@382 183 table["size_t"] = "0";
mandel@1 184 table["java.lang.Object"] = "0";
mandel@1 185 }
mandel@1 186
mandel@1 187 QString signature = table.value(java_type->typeEntry()->targetLangName());
mandel@1 188
mandel@1 189 if (!signature.isEmpty())
mandel@1 190 return returnStr + " " + signature;
mandel@1 191
mandel@1 192 Q_ASSERT(!java_type->isPrimitive());
maxter@382 193
mandel@1 194 if (java_type->isJObjectWrapper())
mandel@1 195 return returnStr + " JObjectWrapper()";
mandel@1 196 if (java_type->isVariant())
mandel@1 197 return returnStr + " QVariant()";
mandel@1 198 if (java_type->isTargetLangString())
mandel@1 199 return returnStr + " QString()";
mandel@1 200 if (java_type->isTargetLangChar())
mandel@1 201 return returnStr + " QChar()";
mandel@1 202 else if (java_type->isEnum())
mandel@1 203 return returnStr + " " + java_type->typeEntry()->name() + "(0)";
mandel@1 204 else if (java_type->isContainer() && ((ContainerTypeEntry *)java_type->typeEntry())->type() == ContainerTypeEntry::StringListContainer)
mandel@1 205 return returnStr + " " + java_type->typeEntry()->name() + "()";
mandel@1 206 else if (java_type->isValue() || java_type->isContainer())
mandel@1 207 return returnStr + " " + java_type->cppSignature() + "()";
mandel@1 208 else
mandel@1 209 return returnStr + " 0";
mandel@1 210 }
mandel@1 211
mandel@1 212 QString default_return_statement_java(const AbstractMetaType *java_type)
mandel@1 213 {
mandel@1 214 if (!java_type)
mandel@1 215 return "return";
mandel@1 216 if (java_type->isArray())
mandel@1 217 return "return null";
mandel@1 218
mandel@1 219 if (table.isEmpty()) {
mandel@1 220 table["boolean"] = "false";
mandel@1 221 table["byte"] = "0";
mandel@1 222 table["char"] = "0";
mandel@1 223 table["short"] = "0";
mandel@1 224 table["int"] = "0";
mandel@1 225 table["long"] = "0";
mandel@1 226 table["float"] = "0f";
mandel@1 227 table["double"] = "0.0";
mandel@1 228 table["java.lang.Object"] = "0";
mandel@1 229 }
mandel@1 230
mandel@1 231 QString signature = table.value(java_type->typeEntry()->targetLangName());
mandel@1 232 if (!signature.isEmpty())
mandel@1 233 return "return " + signature;
mandel@1 234
mandel@1 235 Q_ASSERT(!java_type->isPrimitive());
mandel@1 236 return "return 0";
mandel@1 237 }
mandel@1 238
mandel@1 239 /* Used to decide how which of the Call[Xxx]Method functions to call
mandel@1 240 */
mandel@1 241 QByteArray jniTypeName(const QString &name) {
mandel@1 242 static QHash<QString, const char *> table;
mandel@1 243 if (table.isEmpty()) {
mandel@1 244 table["jboolean"] = "Boolean";
mandel@1 245 table["jbyte"] = "Byte";
mandel@1 246 table["jchar"] = "Char";
mandel@1 247 table["jshort"] = "Short";
mandel@1 248 table["jint"] = "Int";
mandel@1 249 table["jlong"] = "Long";
mandel@1 250 table["jfloat"] = "Float";
mandel@1 251 table["jdouble"] = "Double";
mandel@1 252 table["jobject"] = "Object";
mandel@1 253 }
mandel@1 254
mandel@1 255 return table[name];
mandel@1 256 }
mandel@1 257
mandel@1 258 QByteArray jniName(const QString &name) {
mandel@1 259 TypeEntry *entry = TypeDatabase::instance()->findType(name);
mandel@1 260 if (entry)
mandel@1 261 return entry->name().toLatin1();
mandel@1 262 else
mandel@1 263 return "void *";
mandel@1 264 }
mandel@1 265
mandel@1 266 QString CppImplGenerator::jniReturnName(const AbstractMetaFunction *java_function, uint options, bool d_export)
mandel@1 267 {
eldar@20 268 AbstractMetaType *f_type = java_function->type();
eldar@20 269
eldar@20 270 QString return_type = translateType(f_type, EnumAsInts, d_export);
mandel@1 271 QString new_return_type = java_function->typeReplaced(0);
mandel@1 272 if (!new_return_type.isEmpty()) {
eldar@20 273 if(f_type && f_type->isPrimitive()) {
eldar@20 274 if (d_export)
eldar@20 275 return_type = new_return_type;
eldar@20 276 } else
eldar@20 277 return_type = jniName(new_return_type);
mandel@1 278 }
mandel@1 279
mandel@1 280 // qtd
mandel@1 281 if (f_type) {
eldar@81 282 if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
mandel@1 283 return_type = "void";
mandel@1 284 else if (f_type->isObject() || f_type->isReference() || f_type->isValue() || f_type->isQObject())
mandel@1 285 return_type = "void*";
mandel@1 286 if (f_type->isVariant())
mandel@1 287 return_type = "void*";
mandel@1 288 }
mandel@1 289
mandel@1 290 if (options & CppImplGenerator::ExternC && java_function->isConstructor())
mandel@1 291 return_type = "void*";
mandel@1 292 if (options & CppImplGenerator::ExternC && f_type)
mandel@1 293 if (f_type->isTargetLangString() || f_type->typeEntry()->isContainer())
mandel@1 294 return_type = "void";
mandel@1 295 // qtd end
mandel@1 296
mandel@1 297 return return_type;
mandel@1 298 }
mandel@1 299
mandel@1 300 QString CppImplGenerator::jniReturnType(const AbstractMetaType *f_type, uint options)
mandel@1 301 {
mandel@1 302 QString return_type = translateType(f_type, EnumAsInts);
mandel@1 303
mandel@1 304 // qtd
mandel@1 305 if (f_type) {
mandel@1 306 if (f_type->typeEntry()->isStructInD())
mandel@1 307 return_type = f_type->typeEntry()->qualifiedCppName();
mandel@1 308 else if (f_type->isObject() || f_type->isReference() || f_type->isValue() || f_type->isQObject())
mandel@1 309 return_type = "void*";
mandel@1 310 if (f_type->isVariant())
mandel@1 311 return_type = "void*";
mandel@1 312 }
mandel@1 313
mandel@1 314 if (options & CppImplGenerator::ExternC && f_type)
mandel@1 315 if (f_type->isTargetLangString())
mandel@1 316 return_type = "void";
mandel@1 317 // qtd end
mandel@1 318 return return_type;
mandel@1 319 }
mandel@1 320
mandel@1 321 QByteArray jniTypeName(const AbstractMetaType *java_type)
mandel@1 322 {
mandel@1 323 if (!java_type) {
mandel@1 324 return "Void";
mandel@1 325 } else if (java_type->isTargetLangChar()) {
mandel@1 326 return "Char";
mandel@1 327 } else if (java_type->isPrimitive()) {
mandel@1 328 return jniTypeName(java_type->typeEntry()->jniName());
mandel@1 329 } else if (java_type->isIntegerEnum() || java_type->isIntegerFlags()) {
mandel@1 330 return "Int";
mandel@1 331 } else {
mandel@1 332 return "Object";
mandel@1 333 }
mandel@1 334 }
mandel@1 335
mandel@1 336 QByteArray newXxxArray(const AbstractMetaType *java_type)
mandel@1 337 {
mandel@1 338 return "New" + jniTypeName(java_type) + "Array";
mandel@1 339 }
mandel@1 340
mandel@1 341 QByteArray setXxxArrayElement(const AbstractMetaType *java_type)
mandel@1 342 {
mandel@1 343 Q_ASSERT(java_type);
mandel@1 344 return "Set" + jniTypeName(java_type) + "ArrayElement";
mandel@1 345 }
mandel@1 346
mandel@1 347 QByteArray getXxxArrayElement(const AbstractMetaType *java_type)
mandel@1 348 {
mandel@1 349 Q_ASSERT(java_type);
mandel@1 350 return "Get" + jniTypeName(java_type) + "ArrayElement";
mandel@1 351 }
mandel@1 352
mandel@1 353 QByteArray getXxxArrayRegion(const AbstractMetaType *java_type)
mandel@1 354 {
mandel@1 355 Q_ASSERT(java_type);
mandel@1 356 return "Get" + jniTypeName(java_type) + "ArrayRegion";
mandel@1 357 }
mandel@1 358
mandel@1 359 QByteArray setXxxArrayRegion(const AbstractMetaType *java_type)
mandel@1 360 {
mandel@1 361 Q_ASSERT(java_type);
mandel@1 362 return "Set" + jniTypeName(java_type) + "ArrayRegion";
mandel@1 363 }
mandel@1 364
mandel@1 365 QByteArray callXxxMethod(const AbstractMetaType *java_type)
mandel@1 366 {
mandel@1 367 return "Call" + jniTypeName(java_type) + "Method";
mandel@1 368 }
mandel@1 369
mandel@1 370 QByteArray callXxxMethod(const QString &name) {
mandel@1 371 TypeEntry *entry = TypeDatabase::instance()->findType(name);
mandel@1 372 if (entry && entry->isPrimitive())
mandel@1 373 return "Call" + jniTypeName(entry->jniName()) + "Method";
mandel@1 374 else
mandel@1 375 return "CallObjectMethod";
mandel@1 376 }
mandel@1 377
mandel@1 378 QString jni_function_signature(QString package, QString class_name,
mandel@1 379 const QString &function_name,
mandel@1 380 const QString &return_type,
mandel@1 381 const QString &mangled_arguments = QString(),
mandel@1 382 uint options = CppImplGenerator::StandardJNISignature)
mandel@1 383 {
mandel@1 384 QString s;
mandel@1 385
mandel@1 386 if (options & CppImplGenerator::ExternC)
maxter@357 387 s += "QTD_EXTERN QTD_DLL_PUBLIC ";
mandel@1 388 /* qtd
mandel@1 389 if (options & CppImplGenerator::JNIExport)
mandel@1 390 s += "Q_DECL_EXPORT ";
mandel@1 391 */
eldar@270 392 if (options & CppImplGenerator::ReturnType)
eldar@270 393 s += return_type + " ";
eldar@270 394 else
eldar@270 395 s += "void ";
mandel@1 396 /* qtd
mandel@1 397 if (options & CppImplGenerator::JNIExport)
mandel@1 398 s += "JNICALL QTJAMBI_FUNCTION_PREFIX(";
mandel@1 399
mandel@1 400 s += "Java_";
mandel@1 401
mandel@1 402 s += package.replace(".", "_"); // qtd .replace("_", "_1")
mandel@1 403 s += '_';
mandel@1 404 s += class_name; // qtd .replace("_", "_1");
mandel@1 405 s += '_';
mandel@1 406 */
mandel@1 407 s += QString(function_name); //.replace("_", "_1");
mandel@1 408 // s += mangled_arguments;
mandel@1 409
mandel@1 410 /* qtd
mandel@1 411 if (options & CppImplGenerator::JNIExport)
mandel@1 412 s += ")";
mandel@1 413 */
mandel@1 414 return s;
mandel@1 415 }
mandel@1 416
mandel@1 417 QString CppImplGenerator::fileNameForClass(const AbstractMetaClass *java_class) const
mandel@1 418 {
mandel@1 419 return QString("%1_shell.cpp").arg(java_class->name());
mandel@1 420 }
mandel@1 421
mandel@1 422 void CppImplGenerator::writeSignalFunction(QTextStream &s, const AbstractMetaFunction *signal, const AbstractMetaClass *cls,
mandel@1 423 int pos)
mandel@1 424 {
mandel@1 425 writeFunctionSignature(s, signal, cls, signalWrapperPrefix(),
mandel@1 426 Option(OriginalName | OriginalTypeDescription),
mandel@1 427 "QtJambi_SignalWrapper_");
mandel@1 428 s << endl << "{" << endl;
mandel@1 429 {
mandel@1 430 AbstractMetaArgumentList arguments = signal->arguments();
mandel@1 431 Indentation indent(INDENT);
mandel@1 432
mandel@1 433 if (arguments.size() > 0)
mandel@1 434 s << INDENT << "jvalue arguments[" << arguments.size() << "];" << endl;
mandel@1 435 else
mandel@1 436 s << INDENT << "jvalue *arguments = 0;" << endl;
mandel@1 437 s << INDENT << "JNIEnv *__jni_env = qtjambi_current_environment();" << endl
mandel@1 438 << INDENT << "__jni_env->PushLocalFrame(100);" << endl;
mandel@1 439
mandel@1 440 for (int i=0; i<arguments.size(); ++i) {
mandel@1 441 const AbstractMetaArgument *argument = arguments.at(i);
mandel@1 442 writeQtToJava(s,
mandel@1 443 argument->type(),
mandel@1 444 argument->indexedName(),
mandel@1 445 "__java_" + argument->indexedName(),
mandel@1 446 signal,
mandel@1 447 argument->argumentIndex() + 1,
mandel@1 448 BoxedPrimitive);
mandel@1 449 s << INDENT << "arguments[" << i << "].l = __java_" << argument->indexedName() << ";" << endl;
mandel@1 450 }
mandel@1 451 s << INDENT << "qtjambi_call_java_signal(__jni_env, m_signals[" << pos << "], arguments);"
mandel@1 452 << endl;
mandel@1 453
mandel@1 454 s << INDENT << "__jni_env->PopLocalFrame(0);" << endl;
mandel@1 455
mandel@1 456 if (signal->type() != 0)
mandel@1 457 s << INDENT << default_return_statement_qt(signal->type()) << ";" << endl;
mandel@1 458 }
mandel@1 459 s << "}" << endl << endl;
mandel@1 460
mandel@1 461 if (signal->implementingClass() == signal->ownerClass())
mandel@1 462 writeFinalFunction(s, signal, cls);
mandel@1 463 }
mandel@1 464
mandel@1 465 bool CppImplGenerator::hasCustomDestructor(const AbstractMetaClass *java_class) const
mandel@1 466 {
mandel@1 467 return !java_class->isQObject() && !java_class->typeEntry()->isValue();
mandel@1 468 }
mandel@1 469
mandel@1 470 void CppImplGenerator::writeInterfaceCasts(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 471 {
mandel@1 472 // pointers to native interface objects for classes that implement interfaces
mandel@1 473 // initializing
mandel@1 474 AbstractMetaClassList interfaces = java_class->interfaces();
mandel@1 475 if (!interfaces.isEmpty()) {
mandel@1 476 for (int i=0; i<interfaces.size(); ++i) {
mandel@1 477 AbstractMetaClass *iface = interfaces.at(i);
eldar@33 478
eldar@33 479 // in case of renamed class
eldar@33 480 InterfaceTypeEntry *ite = static_cast<InterfaceTypeEntry*>(iface->typeEntry());
eldar@33 481 QString real_name = ite->origin()->qualifiedCppName();
eldar@33 482
maxter@357 483 s << "QTD_EXTERN QTD_DLL_PUBLIC " << real_name << "* qtd_" << java_class->name() << "_cast_to_" << iface->qualifiedCppName()
eldar@33 484 << "(" << java_class->qualifiedCppName() << " *ptr)" << endl << "{" << endl;
mandel@1 485 Indentation indent(INDENT);
eldar@33 486 s << INDENT << "return dynamic_cast<" << real_name << "*>(ptr);" << endl;
mandel@1 487 s << "}" << endl << endl;
mandel@1 488 }
mandel@1 489 }
mandel@1 490 }
mandel@1 491
mandel@1 492 void CppImplGenerator::write(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 493 {
mandel@1 494
mandel@1 495 bool shellClass = java_class->generateShellClass();
mandel@1 496
mandel@1 497 // Includes
mandel@1 498 writeExtraIncludes(s, java_class);
mandel@1 499 bool shellInclude = (java_class->generateShellClass()
mandel@1 500 || java_class->queryFunctions(AbstractMetaClass::Signals | AbstractMetaClass::Visible | AbstractMetaClass::NotRemovedFromShell).size() > 0);
mandel@1 501
mandel@1 502 // need to include QPainter for all widgets...
mandel@1 503 {
mandel@1 504 const AbstractMetaClass *qwidget = java_class;
mandel@1 505 while (qwidget && qwidget->name() != "QWidget") {
mandel@1 506 qwidget = qwidget->baseClass();
mandel@1 507 }
mandel@1 508 if (qwidget)
mandel@1 509 s << "#include <QPainter>" << endl << endl;
mandel@1 510 }
mandel@1 511 /*
mandel@1 512 #if defined(QTJAMBI_DEBUG_TOOLS)
mandel@1 513 s << "#include <qtjambidebugtools_p.h>" << endl << endl;
mandel@1 514 #endif
mandel@1 515 */
mandel@1 516 if (shellInclude)
mandel@1 517 s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl;
mandel@1 518 /* qtd
mandel@1 519 if (java_class->isQObject())
mandel@1 520 s << "#include <qtdynamicmetaobject.h>" << endl;
mandel@1 521 */
maxter@253 522
mandel@1 523 s << "#include <iostream>" << endl;
maxter@253 524
maxter@355 525 writeInclude(s, java_class->typeEntry()->include());
maxter@355 526
mandel@1 527 s << endl; // qtd
mandel@1 528 s << "#include \"qtd_core.h\"" << endl
mandel@1 529 << "#include \"ArrayOpsPrimitive.h\"" << endl
mandel@1 530 << "#include \"ArrayOps_qt_core.h\"" << endl;
mandel@1 531
mandel@1 532 // qtd2 hack!!
eldar@37 533 if (java_class->package() == "qt.svg")
mandel@1 534 s << "#include \"ArrayOps_qt_gui.h\"" << endl;
mandel@1 535
eldar@35 536 QString pkg_name = QString(java_class->package()).replace(".", "_");
eldar@35 537 s << QString("#include \"ArrayOps_%1.h\"").arg(pkg_name) << endl;
eldar@35 538
mandel@1 539 s << endl;
mandel@1 540
mandel@1 541 writeInterfaceCasts(s, java_class);
mandel@1 542
mandel@1 543 /* qtd2
mandel@1 544 writeShellSignatures(s, java_class);
mandel@1 545
mandel@1 546 writeDefaultConstructedValues(s, java_class);
mandel@1 547
mandel@1 548 if (hasCustomDestructor(java_class)) */
maxter@354 549
maxter@354 550 writeFinalDestructor(s, java_class);
eldar@105 551
eldar@288 552 if (java_class->isQObject()) {
maxter@357 553 writeQObjectEntity(s, java_class);
eldar@288 554 }
eldar@105 555 if (shellClass) {
mandel@1 556 foreach (AbstractMetaFunction *function, java_class->functions()) {
mandel@1 557 if (function->isConstructor() && !function->isPrivate())
mandel@1 558 writeShellConstructor(s, function);
mandel@1 559 }
maxter@355 560
mandel@1 561 writeShellDestructor(s, java_class);
mandel@1 562
maxter@253 563 if (!java_class->isQObject() && java_class->hasVirtualFunctions())
maxter@253 564 writeQtdEntityFunction(s, java_class);
mandel@1 565
mandel@1 566 if (java_class->isQObject())
mandel@1 567 writeQObjectFunctions(s, java_class);
mandel@1 568
mandel@1 569 // Virtual overrides
mandel@1 570 s << "// Virtual overrides" << endl;
mandel@1 571 AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions();
mandel@1 572 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
mandel@1 573 const AbstractMetaFunction *function = virtualFunctions.at(pos);
eldar@105 574 // qtd writeShellFunction(s, function, java_class, pos);
mandel@1 575 writeShellVirtualFunction(s, function, java_class, pos);
mandel@1 576 }
mandel@1 577
mandel@1 578 if (cpp_shared)
mandel@1 579 writeInitCallbacks(s, java_class);
mandel@1 580
mandel@1 581 // Functions in shell class
mandel@1 582 s << "// Functions in shell class" << endl;
mandel@1 583 AbstractMetaFunctionList shellFunctions = java_class->nonVirtualShellFunctions();
mandel@1 584 for (int i=0; i<shellFunctions.size(); ++i) {
mandel@1 585 const AbstractMetaFunction *function = shellFunctions.at(i);
eldar@105 586 writeShellFunction(s, function, java_class, -1);
mandel@1 587 }
mandel@1 588
mandel@1 589 // Write public overrides for functions that are protected in the base class
mandel@1 590 // so they can be accessed from the native callback
mandel@1 591 s << "// public overrides for functions that are protected in the base class" << endl;
mandel@1 592 AbstractMetaFunctionList public_override_functions = java_class->publicOverrideFunctions();
mandel@1 593 foreach (AbstractMetaFunction *function, public_override_functions) {
mandel@1 594 if(notWrappedYet(function))
mandel@1 595 continue;
mandel@1 596 writePublicFunctionOverride(s, function, java_class);
mandel@1 597 }
mandel@1 598
mandel@1 599 // Write virtual function overries used to decide on static/virtual calls
mandel@1 600 s << "// Write virtual function overries used to decide on static/virtual calls" << endl;
mandel@1 601 AbstractMetaFunctionList virtual_functions = java_class->virtualOverrideFunctions();
mandel@1 602 foreach (const AbstractMetaFunction *function, virtual_functions) {
mandel@1 603 if(notWrappedYet(function))
mandel@1 604 continue;
mandel@1 605 writeVirtualFunctionOverride(s, function, java_class);
mandel@1 606 }
mandel@1 607 }
mandel@1 608
mandel@1 609 writeExtraFunctions(s, java_class);
mandel@1 610 /* qtd2
mandel@1 611 writeToStringFunction(s, java_class);
mandel@1 612
mandel@1 613 if (java_class->hasCloneOperator()) {
mandel@1 614 writeCloneFunction(s, java_class);
mandel@1 615 }
eldar@270 616 */
eldar@270 617 // Signals emitters
eldar@272 618 AbstractMetaFunctionList signal_functions = signalFunctions(java_class, false);
mandel@1 619 for (int i=0; i<signal_functions.size(); ++i)
eldar@270 620 {
eldar@270 621 const AbstractMetaFunction *function = signal_functions.at(i);
eldar@270 622 if(!function->isPrivate())
eldar@270 623 writeFinalFunction(s, signal_functions.at(i), java_class);
eldar@270 624 }
mandel@1 625 s << "// ---externC---" << endl;
mandel@1 626
mandel@1 627 // Native callbacks (all java functions require native callbacks)
mandel@1 628 AbstractMetaFunctionList class_funcs = java_class->functionsInTargetLang();
mandel@1 629 foreach (AbstractMetaFunction *function, class_funcs) {
mandel@1 630 if (!function->isEmptyFunction())
mandel@1 631 writeFinalFunction(s, function, java_class);
mandel@1 632 }
mandel@1 633 s << "// ---externC---end" << endl;
mandel@1 634
mandel@1 635
mandel@1 636 class_funcs = java_class->queryFunctions(AbstractMetaClass::NormalFunctions | AbstractMetaClass::AbstractFunctions | AbstractMetaClass::NotRemovedFromTargetLang);
mandel@1 637 foreach (AbstractMetaFunction *function, class_funcs) {
mandel@1 638 if (function->implementingClass() != java_class) {
mandel@1 639 writeFinalFunction(s, function, java_class);
mandel@1 640 }
mandel@1 641 }
mandel@1 642
mandel@1 643 // Field accessors
mandel@1 644 s << "// Field accessors" << endl;
mandel@1 645 foreach (AbstractMetaField *field, java_class->fields()) {
mandel@1 646 if (field->wasPublic() || (field->wasProtected() && !java_class->isFinal()))
mandel@1 647 writeFieldAccessors(s, field);
mandel@1 648 }
mandel@1 649 /*
mandel@1 650 s << "// writeFromNativeFunction" << endl;
mandel@1 651 writeFromNativeFunction(s, java_class);
mandel@1 652
mandel@1 653 if (java_class->isQObject())
mandel@1 654 writeOriginalMetaObjectFunction(s, java_class);
mandel@1 655
mandel@1 656 if (java_class->typeEntry()->isValue())
mandel@1 657 writeFromArrayFunction(s, java_class);
mandel@1 658
mandel@1 659 // generate the __qt_cast_to_Xxx functions
mandel@1 660 if (!java_class->isNamespace() && !java_class->isInterface()) {
mandel@1 661 AbstractMetaClassList interfaces = java_class->interfaces();
mandel@1 662 foreach (AbstractMetaClass *iface, interfaces)
mandel@1 663 writeInterfaceCastFunction(s, java_class, iface);
mandel@1 664 }
mandel@1 665
mandel@1 666 writeSignalInitialization(s, java_class);
mandel@1 667 */
mandel@1 668 // qtd writeJavaLangObjectOverrideFunctions(s, java_class);
mandel@1 669
eldar@292 670 if (java_class->typeEntry()->isValue())
eldar@292 671 writeValueFunctions(s, java_class);
eldar@292 672
maxter@253 673 if (java_class->isQObject())
maxter@253 674 {
maxter@253 675 s << endl << endl
maxter@357 676 << "QTD_EXTERN QTD_DLL_PUBLIC void* qtd_" << java_class->name() << "_staticMetaObject() {" << endl
maxter@253 677 << " return (void*)&" << java_class->name() << "::staticMetaObject;" << endl
maxter@253 678 << "}" << endl;
maxter@253 679 }
maxter@253 680
eldar@298 681 if (java_class->typeEntry()->isValue())
eldar@293 682 {
eldar_ins@304 683 if (!java_class->typeEntry()->hasPrivateCopyConstructor()) // can do a copy if we have a public ctor or don't have any
eldar@293 684 {
eldar@298 685 QString argName = "orig";
eldar@293 686 s << endl << endl
maxter@357 687 << "QTD_EXTERN QTD_DLL_PUBLIC void qtd_" << java_class->name() << "_placed_copy(void* "
eldar@298 688 << argName << ", void* place) {" << endl
eldar@298 689 << QString(" const %1& __qt_%2 = (const %1& ) *(%1 *)%2;").arg(shellClassName(java_class)).arg(argName) << endl
eldar@298 690 << QString(" %1 *result = new (place) %1 (__qt_%2);").arg(java_class->qualifiedCppName()).arg(argName) << endl;
eldar@298 691 // writeFinalConstructor(s, ctor, "result", "original", "(place)");
eldar@298 692 s << "}";
eldar@298 693
eldar@298 694 s << endl << endl
maxter@357 695 << "QTD_EXTERN QTD_DLL_PUBLIC void* qtd_" << java_class->name() << "_native_copy(void* " << argName << ") {" << endl
eldar@298 696 << QString(" const %1& __qt_%2 = (const %1& ) *(%1 *)%2;").arg(shellClassName(java_class)).arg(argName) << endl
eldar@298 697 << QString(" %1 *result = new %1 (__qt_%2);").arg(java_class->qualifiedCppName()).arg(argName) << endl
eldar@298 698 << " return result;" << endl;
eldar@293 699 s << "}";
eldar@293 700 }
eldar@293 701 }
eldar@293 702
mandel@1 703 s << endl << endl;
mandel@1 704
SokoL_SD@238 705 priGenerator->addSource(java_class->package(), fileNameForClass(java_class));
mandel@1 706 }
mandel@1 707
eldar@292 708 void CppImplGenerator::writeValueFunctions(QTextStream &s, const AbstractMetaClass *java_class)
eldar@292 709 {
maxter@357 710 s << QString("QTD_EXTERN QTD_DLL_PUBLIC bool qtd_%1_QTypeInfo_isComplex() { return (bool) QTypeInfo<%2>::isComplex; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
maxter@357 711 s << QString("QTD_EXTERN QTD_DLL_PUBLIC bool qtd_%1_QTypeInfo_isStatic() { return (bool) QTypeInfo<%2>::isStatic; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
maxter@357 712 s << QString("QTD_EXTERN QTD_DLL_PUBLIC bool qtd_%1_QTypeInfo_isLarge() { return (bool) QTypeInfo<%2>::isLarge; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
maxter@357 713 s << QString("QTD_EXTERN QTD_DLL_PUBLIC bool qtd_%1_QTypeInfo_isPointer() { return (bool) QTypeInfo<%2>::isPointer; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
maxter@357 714 s << QString("QTD_EXTERN QTD_DLL_PUBLIC bool qtd_%1_QTypeInfo_isDummy() { return (bool) QTypeInfo<%2>::isDummy; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
eldar@292 715 }
eldar@292 716
maxter@355 717 void CppImplGenerator::writeVirtualDispatchFunction(QTextStream &s, const AbstractMetaFunction *function, const AbstractMetaClass *java_class, bool d_export)
mandel@1 718 {
maxter@357 719 uint options2 = ReturnType | ExternC;
maxter@357 720 QString return_type = jniReturnName(function, options2);
maxter@357 721
maxter@357 722 AbstractMetaFunction::Options opts(AbstractMetaFunction::NoExternNamespace | AbstractMetaFunction::DeclaringClass);
maxter@357 723 QString f_name = function->marshalledName(opts) + "_dispatch";
maxter@357 724
maxter@357 725 if (d_export) {
maxter@357 726 QString qtdExtern = "extern(C)"; // TODO: should be settable via a generator switch
maxter@357 727 if (cpp_shared) {
maxter@357 728
maxter@357 729 s << qtdExtern << "{ extern export " << return_type << " function";
maxter@357 730 writeVirtualDispatchArguments(s, function, d_export);
maxter@357 731 s << " qtd_" << f_name << "; }" << endl;
maxter@357 732
maxter@357 733 s << qtdExtern << " " << return_type << " qtd_export_" << f_name;
maxter@357 734 writeVirtualDispatchArguments(s, function, d_export);
maxter@357 735
maxter@357 736 } else {
maxter@357 737 s << qtdExtern << " " << return_type << " qtd_" << f_name;
maxter@357 738 writeVirtualDispatchArguments(s, function, d_export);
maxter@357 739 }
maxter@357 740 } else {
maxter@357 741 QString module = packageToQtModule(java_class->package());
maxter@357 742 s << "QTD_EXPORT_DECL(" << module << ", " << return_type << ", " << f_name << ", ";
maxter@357 743 writeVirtualDispatchArguments(s, function, d_export);
maxter@357 744 s << ")" << endl;
maxter@357 745
maxter@357 746 if (function->declaringClass() == java_class) {
maxter@357 747 s << "QTD_EXPORT(" << module << ", " << f_name << ")" << endl;
maxter@357 748 }
maxter@357 749 }
mandel@1 750 }
mandel@1 751
mandel@1 752 void CppImplGenerator::writeShellVirtualFunction(QTextStream &s, const AbstractMetaFunction *function,
mandel@1 753 const AbstractMetaClass *implementor, int id)
mandel@1 754 {
mandel@1 755 // ----------------------------
mandel@1 756 if(notWrappedYet(function))
mandel@1 757 return;
mandel@1 758
mandel@1 759 AbstractMetaType *f_type = function->type();
mandel@1 760 QString new_return_type = function->typeReplaced(0);
mandel@1 761 bool has_function_type = ((f_type != 0
mandel@1 762 || !new_return_type.isEmpty())
mandel@1 763 && new_return_type != "void");
mandel@1 764
maxter@355 765 writeVirtualDispatchFunction(s, function, implementor);
mandel@1 766
mandel@1 767 writeFunctionSignature(s, function, implementor, QString(), OriginalName);
mandel@1 768
mandel@1 769 s << endl
mandel@1 770 << "{" << endl;
mandel@1 771
mandel@1 772 Option options = NoOption;
mandel@1 773
mandel@1 774 Indentation indent(INDENT);
mandel@1 775 //bool static_call = !(options & VirtualCall);
mandel@1 776 //s << "std::cout << \"entering " << function->marshalledName() << " \\n\"; " << endl;
mandel@1 777
mandel@1 778 if (f_type) {
mandel@1 779 if (f_type->isTargetLangString())
eldar@104 780 s << INDENT << "DArray ret_str;" << endl;
eldar@81 781
mandel@1 782 if (f_type->name() == "QModelIndex")
mandel@1 783 s << INDENT << "QModelIndexAccessor __d_return_value;" << endl;
eldar@81 784 else if (f_type->typeEntry()->isStructInD())
eldar@81 785 s << INDENT << f_type->typeEntry()->qualifiedCppName() << " __d_return_value;" << endl;
eldar@81 786
mandel@1 787 if (f_type->isContainer())
eldar@298 788 {
eldar@298 789 if (isNativeContainer(f_type))
eldar@298 790 {
eldar@298 791 s << INDENT;
eldar@298 792 writeTypeInfo(s, f_type, ForceValueType);
eldar@298 793 s << "__d_return_value;" << endl;
eldar@298 794 }
eldar@298 795 else
eldar@298 796 s << INDENT << "void* __d_return_value;" << endl
eldar@298 797 << INDENT << "size_t __d_return_value_size;" << endl;
eldar@298 798 }
mandel@1 799 }
mandel@1 800
mandel@1 801 AbstractMetaArgumentList arguments = function->arguments();
mandel@1 802 foreach (AbstractMetaArgument *argument, arguments) {
mandel@1 803 if (!function->argumentRemoved(argument->argumentIndex()+1)) {
eldar@298 804 AbstractMetaType *atype = argument->type();
eldar@298 805 if (!atype->isPrimitive()
mandel@1 806 || !function->conversionRule(TypeSystem::NativeCode, argument->argumentIndex()+1).isEmpty()) {
eldar@298 807 if(atype->isContainer()) {
mandel@1 808 QString arg_name = argument->indexedName();
eldar@298 809 if(!isNativeContainer(atype))
eldar@298 810 writeQtToJava(s,
eldar@298 811 argument->type(),
eldar@298 812 arg_name,
eldar@298 813 "__d_" + arg_name,
eldar@298 814 function,
eldar@298 815 argument->argumentIndex() + 1,
eldar@298 816 Option(VirtualDispatch));
mandel@1 817 }
mandel@1 818 }
mandel@1 819 }
mandel@1 820 }
mandel@1 821
mandel@1 822 if ((options & NoReturnStatement) == 0)
mandel@1 823 s << INDENT;
mandel@1 824 /* qtd if (function->isAbstract() && static_call) {
mandel@1 825 s << default_return_statement_qt(function->type(), options) << ";" << endl;
mandel@1 826 } else */
mandel@1 827 {
mandel@1 828 if (f_type) {
mandel@1 829 if (f_type->isTargetLangString() || f_type->isContainer())
mandel@1 830 ;
mandel@1 831 else if ((f_type->isValue() && !f_type->typeEntry()->isStructInD()) ||
mandel@1 832 f_type->isVariant() )
mandel@1 833 s << f_type->name() << " *__qt_return_value = (" << f_type->name() << "*) ";
mandel@1 834 else if (f_type->isObject() || f_type->isQObject())
mandel@1 835 s << "return (" << f_type->name() <<"*) ";
eldar@81 836 else if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
mandel@1 837 ;
mandel@1 838 else if ((options & NoReturnStatement) == 0)
mandel@1 839 s << "return ";
mandel@1 840
mandel@1 841 if (f_type->isEnum() || f_type->isFlags())
mandel@1 842 s << "(" << f_type->typeEntry()->qualifiedCppName() <<") ";
mandel@1 843 }
mandel@1 844
maxter@357 845 s << function->marshalledName(AbstractMetaFunction::DeclaringClass) << "_dispatch(";
maxter@355 846 if (implementor->isQObject())
maxter@355 847 s << "QObjectLink::getLink(this)->dId";
maxter@355 848 else
maxter@355 849 s << "this->dId";
mandel@1 850
mandel@1 851 if (f_type) {
mandel@1 852 if (f_type->isTargetLangString())
eldar@104 853 s << ", &ret_str";
eldar@81 854 if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
eldar@298 855 s << ", &__d_return_value"; // TODO should both be refactored into isNativeType function
eldar@298 856 if (f_type->isContainer()) {
eldar@298 857 if ( ((const ContainerTypeEntry *)f_type->typeEntry())->isQList() )
eldar@298 858 s << ", &__d_return_value";
eldar@298 859 else
eldar@298 860 s << ", &__d_return_value, &__d_return_value_size";
eldar@298 861 }
mandel@1 862 }
mandel@1 863
mandel@1 864 if (function->arguments().size() > 0)
mandel@1 865 s << ", ";
mandel@1 866 writeFunctionCallArguments(s, function, QString(), Option(options | ForceEnumCast | SkipRemovedArguments | ExcludeConst | VirtualDispatch));
mandel@1 867
mandel@1 868 s << ");" << endl;
mandel@1 869
mandel@1 870 //s << "std::cout << \"leaving " << function->marshalledName() << " \\n\"; " << endl;
mandel@1 871
mandel@1 872 if (f_type) {
mandel@1 873 if (f_type->name() == "QModelIndex") {
mandel@1 874 s << INDENT << "QModelIndex __qt_return_value = qtd_to_QModelIndex( __d_return_value );" << endl;
mandel@1 875 s << INDENT << "return __qt_return_value;" << endl;
eldar@81 876 } else if (f_type->typeEntry()->isStructInD())
eldar@81 877 s << INDENT << "return __d_return_value;" << endl;
mandel@1 878
mandel@1 879 if (f_type->isContainer()) {
eldar@298 880 if (isNativeContainer(f_type))
eldar@298 881 s << INDENT << "return __d_return_value;" << endl;
eldar@298 882 else
eldar@298 883 {
eldar@298 884 writeJavaToQt(s, f_type, "__qt_return_value", "__d_return_value",
eldar@298 885 function, 0, GlobalRefJObject);
eldar@298 886 s << INDENT << "return __qt_return_value;" << endl;
eldar@298 887 }
mandel@1 888 }
mandel@1 889
mandel@1 890 if (f_type->isTargetLangString())
eldar@104 891 s << INDENT << "return " << "QString::fromUtf8((const char*) ret_str.ptr, ret_str.length);" << endl;
mandel@1 892
mandel@1 893 if ( ( f_type->isValue() && !f_type->typeEntry()->isStructInD() ) || f_type->isVariant() )
mandel@1 894 s << INDENT << "return " << f_type->name() << "(*__qt_return_value);" << endl; //" __qt_return_value = ";
mandel@1 895 }
mandel@1 896 }
mandel@1 897
mandel@1 898 s << "}" << endl << endl;
mandel@1 899 // ----------------------------
mandel@1 900 }
mandel@1 901
maxter@357 902 void CppImplGenerator::writeInitCallbacks(QTextStream &s, const AbstractMetaClass *java_class)
maxter@357 903 {
maxter@361 904 QString initArgs = "VoidFunc *virts";
maxter@357 905 if (java_class->name() == "QObject")
maxter@361 906 initArgs += ", VoidFunc *sigs";
maxter@357 907
maxter@357 908 s << "QTD_EXTERN QTD_DLL_EXPORT void qtd_" << java_class->name()
maxter@357 909 << QString("_initCallBacks(%1) {").arg(initArgs) << endl;
maxter@357 910
maxter@357 911 // virtual functions handlers
maxter@357 912 AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions();
maxter@357 913 AbstractMetaFunction::Options opts(AbstractMetaFunction::DeclaringClass | AbstractMetaFunction::NoExternNamespace);
maxter@357 914 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
maxter@357 915 const AbstractMetaFunction *function = virtualFunctions.at(pos);
maxter@357 916 if (!notWrappedYet(function) && java_class == function->declaringClass()) { // qtd2
maxter@357 917 QString mName = function->marshalledName(opts);
maxter@357 918 s << " qtd_" << mName << "_dispatch = "
maxter@357 919 "(qtd_" << mName << "_dispatch_t) virts[" << pos << "];" << endl;
maxter@357 920 }
maxter@357 921 }
maxter@357 922 // D-side signal callbacks
maxter@357 923 if (java_class->name() == "QObject") {
maxter@357 924 s << " qtd_QObject_qt_metacall_dispatch = (QtMetacallCallback)sigs[0];" << endl
maxter@357 925 << " qtd_QObject_metaObject_dispatch = (MetaObjectCallback)sigs[1];" << endl;
maxter@357 926 }
maxter@357 927 s << "}" << endl;
maxter@357 928 }
maxter@357 929
mandel@1 930 void CppImplGenerator::writeVirtualDispatchArguments(QTextStream &s, const AbstractMetaFunction *d_function, bool d_export)
mandel@1 931 {
mandel@1 932 uint nativeArgCount = 0;
mandel@1 933 AbstractMetaType *ret_type = d_function->type();
mandel@1 934
maxter@355 935 s << "(void *dId";
mandel@1 936
mandel@1 937 if (ret_type) {
eldar@104 938 if (ret_type->isTargetLangString()) {
eldar@104 939 if (d_export)
eldar@104 940 s << ", string* ret_str";
eldar@104 941 else
eldar@104 942 s << ", DArray* ret_str";
eldar@104 943 }
mandel@1 944 if (ret_type->name() == "QModelIndex")
mandel@1 945 s << ", QModelIndexAccessor *__d_return_value";
eldar@81 946 else if(ret_type->typeEntry()->isStructInD())
eldar@81 947 s << ", " << ret_type->typeEntry()->qualifiedCppName() << " *__d_return_value";
eldar@81 948
eldar@298 949 if (ret_type->isContainer()) {
eldar@298 950 if(isNativeContainer(ret_type)) {
eldar@298 951 if(d_export)
eldar@298 952 s << ", " << DGenerator::translateType(ret_type, d_function->ownerClass(), NoOption) << "* __d_arr";
eldar@298 953 else
eldar@298 954 s << ", void * __d_arr";
eldar@298 955 }
eldar@298 956 else
eldar@298 957 s << ", void** __d_arr_ptr, size_t* __d_arr_size";
eldar@298 958 }
mandel@1 959 }
mandel@1 960
mandel@1 961 if (d_function->arguments().size() > 0)
mandel@1 962 s << ", ";
mandel@1 963
mandel@1 964
mandel@1 965 // the function arguments
mandel@1 966 AbstractMetaArgumentList arguments = d_function->arguments();
mandel@1 967 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 968 if (!d_function->argumentRemoved(argument->argumentIndex() + 1)) {
mandel@1 969 if (nativeArgCount > 0)
mandel@1 970 s << "," << " ";
mandel@1 971
mandel@1 972 AbstractMetaType *d_type = argument->type();
mandel@1 973 QString arg_name = argument->indexedName();
mandel@1 974
mandel@1 975 if (d_type->name() == "QModelIndex")
mandel@1 976 s << "QModelIndexAccessor" << QString(d_type->actualIndirections(), '*') << " " << arg_name;
mandel@1 977 else if (d_type->isContainer()) {
eldar@298 978 if ( isNativeContainer(d_type) )
eldar@298 979 s << "void* ";
eldar@298 980 else if (d_export)
mandel@1 981 s << DGenerator::translateType(d_type, d_function->ownerClass(), NoOption) << "* ";
eldar@298 982 else
mandel@1 983 s << "DArray* ";
mandel@1 984 s << arg_name;
mandel@1 985 } else if (d_type->typeEntry()->isStructInD())
mandel@1 986 s << d_type->typeEntry()->qualifiedCppName() << QString(d_type->actualIndirections(), '*')
mandel@1 987 << " " << arg_name;
mandel@1 988 else if (d_type->isTargetLangString()) {
mandel@1 989 if (d_export)
mandel@1 990 s << "wchar* ";
mandel@1 991 else
mandel@1 992 s << "const unsigned short* ";
mandel@1 993 s << QString("%1, int %1_size").arg(arg_name);
mandel@1 994 } else {
mandel@1 995 if(d_type->isVariant())
mandel@1 996 s << "void*";
mandel@1 997 else if (!d_type->hasNativeId())
mandel@1 998 {
mandel@1 999 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_type->typeEntry());
mandel@1 1000 if(d_type->typeEntry()->isObject() && ctype->isAbstract() && d_export)
mandel@1 1001 {
mandel@1 1002 QString d_name = d_type->typeEntry()->qualifiedCppName();
mandel@1 1003 s << d_name + "_ConcreteWrapper" + QString(d_type->indirections(),'*');
mandel@1 1004 }
mandel@1 1005 else
eldar@39 1006 s << translateType(d_type, EnumAsInts, d_export);
mandel@1 1007 }
mandel@1 1008 else
mandel@1 1009 s << "void*";
mandel@1 1010 s << " " << argument->indexedName();
mandel@1 1011 }
mandel@1 1012 nativeArgCount++;
mandel@1 1013 }
mandel@1 1014 }
mandel@1 1015 s << ")";
mandel@1 1016 }
mandel@1 1017
mandel@1 1018 void CppImplGenerator::writeJavaLangObjectOverrideFunctions(QTextStream &s, const AbstractMetaClass *cls)
mandel@1 1019 {
mandel@1 1020 if (cls->hasHashFunction()) {
mandel@1 1021 AbstractMetaFunctionList hashcode_functions = cls->queryFunctionsByName("hashCode");
mandel@1 1022 bool found = false;
mandel@1 1023 foreach (const AbstractMetaFunction *function, hashcode_functions) {
mandel@1 1024 if (function->actualMinimumArgumentCount() == 0) {
mandel@1 1025 found = true;
mandel@1 1026 break;
mandel@1 1027 }
mandel@1 1028 }
mandel@1 1029
mandel@1 1030 if (!found) {
mandel@1 1031 s << endl
mandel@1 1032 << INDENT << jni_function_signature(cls->package(), cls->name(), "__qt_hashCode", "jint")
mandel@1 1033 << "(JNIEnv *__jni_env, jobject, jlong __this_nativeId)" << endl
mandel@1 1034 << INDENT << "{" << endl;
mandel@1 1035 {
mandel@1 1036 Indentation indent(INDENT);
mandel@1 1037 s << INDENT << "Q_UNUSED(__jni_env);" << endl
mandel@1 1038 << INDENT << cls->qualifiedCppName() << " *__qt_this = ("
mandel@1 1039 << cls->qualifiedCppName() << " *) qtjambi_from_jlong(__this_nativeId);" << endl
mandel@1 1040 << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl
mandel@1 1041 << INDENT << "Q_ASSERT(__qt_this);" << endl
mandel@1 1042 << INDENT << "return qHash(*__qt_this);" << endl;
mandel@1 1043 }
mandel@1 1044 s << INDENT << "}" << endl;
mandel@1 1045 }
mandel@1 1046 }
mandel@1 1047
mandel@1 1048 // Qt has a standard toString() conversion in QVariant?
mandel@1 1049 QVariant::Type type = QVariant::nameToType(cls->qualifiedCppName().toLatin1());
mandel@1 1050 if (QVariant(type).canConvert(QVariant::String) && !cls->hasToStringCapability()) {
mandel@1 1051 AbstractMetaFunctionList tostring_functions = cls->queryFunctionsByName("toString");
mandel@1 1052 bool found = false;
mandel@1 1053 foreach (const AbstractMetaFunction *function, tostring_functions) {
mandel@1 1054 if (function->actualMinimumArgumentCount() == 0) {
mandel@1 1055 found = true;
mandel@1 1056 break;
mandel@1 1057 }
mandel@1 1058 }
mandel@1 1059
mandel@1 1060 if (!found) {
mandel@1 1061 s << endl
mandel@1 1062 << INDENT << jni_function_signature(cls->package(), cls->name(), "__qt_toString", "jstring")
mandel@1 1063 << "(JNIEnv *__jni_env, jobject, jlong __this_nativeId)" << endl
mandel@1 1064 << INDENT << "{" << endl;
mandel@1 1065 {
mandel@1 1066 Indentation indent(INDENT);
mandel@1 1067 s << INDENT << cls->qualifiedCppName() << " *__qt_this = ("
mandel@1 1068 << cls->qualifiedCppName() << " *) qtjambi_from_jlong(__this_nativeId);" << endl
mandel@1 1069 << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl
mandel@1 1070 << INDENT << "Q_ASSERT(__qt_this);" << endl
mandel@1 1071 << INDENT << "return qtjambi_from_qstring(__jni_env, QVariant(*__qt_this).toString());" << endl;
mandel@1 1072 }
mandel@1 1073 s << INDENT << "}" << endl;
mandel@1 1074 }
mandel@1 1075 }
mandel@1 1076 }
mandel@1 1077
mandel@1 1078 void CppImplGenerator::writeExtraFunctions(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1079 {
mandel@1 1080 const ComplexTypeEntry *class_type = java_class->typeEntry();
mandel@1 1081 Q_ASSERT(class_type);
mandel@1 1082
mandel@1 1083 CodeSnipList code_snips = class_type->codeSnips();
mandel@1 1084 foreach (const CodeSnip &snip, code_snips) {
mandel@1 1085 if (snip.language == TypeSystem::ShellCode || snip.language == TypeSystem::NativeCode) {
mandel@1 1086 snip.formattedCode(s, INDENT) << endl;
mandel@1 1087 }
mandel@1 1088 }
mandel@1 1089 }
mandel@1 1090
mandel@1 1091 void CppImplGenerator::writeToStringFunction(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1092 {
mandel@1 1093 FunctionModelItem fun = java_class->hasToStringCapability();
mandel@1 1094 bool core = java_class->package() == QLatin1String("qt.core");
mandel@1 1095 bool qevent = false;
mandel@1 1096
mandel@1 1097 const AbstractMetaClass *cls = java_class;
mandel@1 1098 while (cls) {
mandel@1 1099 if (cls->name() == "QEvent") {
mandel@1 1100 qevent = true;
mandel@1 1101 fun = cls->hasToStringCapability();
mandel@1 1102 break;
mandel@1 1103 }
mandel@1 1104 cls = cls->baseClass();
mandel@1 1105 }
mandel@1 1106
mandel@1 1107 if (!java_class->hasDefaultToStringFunction() && fun && !(qevent && core)) {
mandel@1 1108
mandel@1 1109 int indirections = fun->arguments().at(1)->type().indirections();
mandel@1 1110 QString deref = QLatin1String(indirections == 0 ? "*" : "");
mandel@1 1111
mandel@1 1112 s << endl;
mandel@1 1113 s << "#include <QDebug>" << endl;
mandel@1 1114 s << jni_function_signature(java_class->package(), java_class->name(), "__qt_toString", "jstring")
mandel@1 1115 << "(JNIEnv *__jni_env, jobject, jlong __this_nativeId)" << endl
mandel@1 1116 << INDENT << "{" << endl;
mandel@1 1117 {
mandel@1 1118 Indentation indent(INDENT);
mandel@1 1119 s << INDENT << java_class->qualifiedCppName() << " *__qt_this = ("
mandel@1 1120 << java_class->qualifiedCppName() << " *) qtjambi_from_jlong(__this_nativeId);" << endl
mandel@1 1121 << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl
mandel@1 1122 << INDENT << "Q_ASSERT(__qt_this);" << endl
mandel@1 1123
mandel@1 1124 << INDENT << "QString res;" << endl
mandel@1 1125 << INDENT << "QDebug d(&res);" << endl
mandel@1 1126 << INDENT << "d << " << deref << "__qt_this;" << endl;
mandel@1 1127 s << INDENT << "return qtjambi_from_qstring(__jni_env, res);" << endl;
mandel@1 1128 }
mandel@1 1129 s << INDENT << "}" << endl << endl;
mandel@1 1130 }
mandel@1 1131 }
mandel@1 1132
mandel@1 1133 void CppImplGenerator::writeCloneFunction(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1134 {
mandel@1 1135 s << endl
mandel@1 1136 << jni_function_signature(java_class->package(), java_class->name(), "__qt_clone", "jobject") << endl
mandel@1 1137 << "(JNIEnv *__jni_env, jobject, jlong __this_nativeId)" << endl
mandel@1 1138 << INDENT << "{" << endl;
mandel@1 1139 {
mandel@1 1140 Indentation indent(INDENT);
mandel@1 1141 s << INDENT << java_class->qualifiedCppName() << " *__qt_this = ("
mandel@1 1142
mandel@1 1143 << java_class->qualifiedCppName() << " *) qtjambi_from_jlong(__this_nativeId);" << endl
mandel@1 1144 << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl
mandel@1 1145 << INDENT << "Q_ASSERT(__qt_this);" << endl
mandel@1 1146 << INDENT << java_class->qualifiedCppName() << " *res = __qt_this;" << endl
mandel@1 1147 << INDENT << "return qtjambi_from_object(__jni_env, res, \"" << java_class->name() << "\", \"" << java_class->package().replace(".", "/") << "/\", true);" << endl;
mandel@1 1148 }
mandel@1 1149 s << INDENT << "}" << endl << endl;
mandel@1 1150 }
mandel@1 1151
mandel@1 1152 void CppImplGenerator::writeShellSignatures(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1153 {
mandel@1 1154 bool has_constructors = java_class->hasConstructors();
mandel@1 1155
mandel@1 1156 // Write the function names...
mandel@1 1157 if (has_constructors && java_class->hasVirtualFunctions()) {
mandel@1 1158 AbstractMetaFunctionList virtual_functions = java_class->virtualFunctions();
mandel@1 1159 {
mandel@1 1160 Indentation indent(INDENT);
mandel@1 1161
mandel@1 1162 int pos = -1;
mandel@1 1163 foreach (AbstractMetaFunction *function, virtual_functions) {
mandel@1 1164 ++pos;
mandel@1 1165
mandel@1 1166 if (pos == 0)
mandel@1 1167 s << "static const char *qtjambi_method_names[] = {";
mandel@1 1168 else
mandel@1 1169 s << ",";
mandel@1 1170 s << endl
mandel@1 1171 << "/* " << QString("%1").arg(QString::number(pos), 3) << " */ "
mandel@1 1172 << "\"" << function->name() << "\"";
mandel@1 1173 }
mandel@1 1174 if (pos >= 0)
mandel@1 1175 s << endl << "};" << endl << endl;
mandel@1 1176 else
mandel@1 1177 s << "static const char **qtjambi_method_names = 0;" << endl;
mandel@1 1178 }
mandel@1 1179
mandel@1 1180 // Write the function signatures
mandel@1 1181 {
mandel@1 1182 Indentation indent(INDENT);
mandel@1 1183
mandel@1 1184 int pos = -1;
mandel@1 1185 foreach (AbstractMetaFunction *function, virtual_functions) {
mandel@1 1186 ++pos;
mandel@1 1187
mandel@1 1188 if (pos == 0)
mandel@1 1189 s << "static const char *qtjambi_method_signatures[] = {";
mandel@1 1190 else
mandel@1 1191 s << ",";
mandel@1 1192 s << endl
mandel@1 1193 << "/* " << QString("%1").arg(QString::number(pos), 3) << " */ "
mandel@1 1194 << "\""
mandel@1 1195 << jni_signature(function, SlashesAndStuff)
mandel@1 1196 << "\"";
mandel@1 1197 }
mandel@1 1198 if (pos >= 0)
mandel@1 1199 s << endl << "};" << endl;
mandel@1 1200 else
mandel@1 1201 s << "static const char **qtjambi_method_signatures = 0;" << endl;
mandel@1 1202 s << "static const int qtjambi_method_count = " << QString::number(pos + 1) << ";" << endl
mandel@1 1203 << endl;
mandel@1 1204 }
mandel@1 1205 }
mandel@1 1206
mandel@1 1207 if (has_constructors && java_class->hasInconsistentFunctions()) {
mandel@1 1208 AbstractMetaFunctionList inconsistents = java_class->cppInconsistentFunctions();
mandel@1 1209 // Write the inconsistent function names...
mandel@1 1210 {
mandel@1 1211 Indentation indent(INDENT);
mandel@1 1212 s << "static const char *qtjambi_inconsistent_names[] = {";
mandel@1 1213 for (int i=0; i<inconsistents.size(); ++i) {
mandel@1 1214 if (i != 0)
mandel@1 1215 s << ",";
mandel@1 1216 s << endl << INDENT << "\"" << inconsistents.at(i)->name() << "\"";
mandel@1 1217 }
mandel@1 1218 s << endl << "};" << endl << endl;
mandel@1 1219 }
mandel@1 1220
mandel@1 1221 // Write the function signatures
mandel@1 1222 {
mandel@1 1223 Indentation indent(INDENT);
mandel@1 1224 s << "static const char *qtjambi_inconsistent_signatures[] = {";
mandel@1 1225 for (int i=0; i<inconsistents.size(); ++i) {
mandel@1 1226 const AbstractMetaFunction *function = inconsistents.at(i);
mandel@1 1227
mandel@1 1228 if (i != 0)
mandel@1 1229 s << ",";
mandel@1 1230 s << endl << INDENT << "\""
mandel@1 1231 << jni_signature(function, SlashesAndStuff)
mandel@1 1232 << "\"";
mandel@1 1233 }
mandel@1 1234 s << endl << "};" << endl << endl;
mandel@1 1235 }
mandel@1 1236 s << "static const int qtjambi_inconsistent_count = " << inconsistents.size() << ";" << endl
mandel@1 1237 << endl;
mandel@1 1238 }
mandel@1 1239
mandel@1 1240
mandel@1 1241 AbstractMetaFunctionList signal_functions = java_class->cppSignalFunctions();
mandel@1 1242 if (signal_functions.size()) {
mandel@1 1243 Indentation indent(INDENT);
mandel@1 1244 s << "static const char *qtjambi_signal_names[] = {";
mandel@1 1245 for (int i=0; i<signal_functions.size(); ++i) {
mandel@1 1246 if (i != 0)
mandel@1 1247 s << ",";
mandel@1 1248
mandel@1 1249 const AbstractMetaFunction *f = signal_functions.at(i);
mandel@1 1250
mandel@1 1251 QString signalName = f->name();
mandel@1 1252
mandel@1 1253 s << endl << INDENT << "\"" << signalName << "\"";
mandel@1 1254 }
mandel@1 1255 s << endl << "};" << endl << endl;
mandel@1 1256
mandel@1 1257 s << "static const int qtjambi_signal_argumentcounts[] = {";
mandel@1 1258 for (int i=0; i<signal_functions.size(); ++i) {
mandel@1 1259 if (i != 0)
mandel@1 1260 s << ",";
mandel@1 1261 s << endl << INDENT << signal_functions.at(i)->arguments().count();
mandel@1 1262 }
mandel@1 1263 s << endl << "};" << endl << endl;
mandel@1 1264 s << "static const int qtjambi_signal_count = " << signal_functions.size() << ";" << endl
mandel@1 1265 << endl;
mandel@1 1266 }
mandel@1 1267 }
mandel@1 1268
maxter@253 1269 void CppImplGenerator::writeQObjectEntity(QTextStream &s, const AbstractMetaClass *java_class)
maxter@253 1270 {
maxter@253 1271 QString entityName = java_class->name() + "Entity";
maxter@253 1272 QString className = java_class->name();
maxter@253 1273
maxter@355 1274 s << "class " << entityName << " : public QObject, public QObjectLink" << endl
maxter@253 1275 << "{" << endl
maxter@253 1276 << "public:" << endl
maxter@253 1277 << " Q_OBJECT_CHECK" << endl
eldar@288 1278 << "// virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl << endl
maxter@253 1279
maxter@355 1280 << " " << entityName << "(QObject *qObject, void *dId) : QObject(), QObjectLink(qObject, dId) {}" << endl
maxter@253 1281 << "};" << endl << endl;
maxter@253 1282
eldar@288 1283 /* // QObject_Link::qt_metacall()
maxter@253 1284 s << "int " << entityName << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
maxter@253 1285 << "{" << endl
maxter@253 1286 << " _id = QObject::qt_metacall(_c, _id, _a);" << endl
maxter@253 1287 << " if (_id < 0 || _c != QMetaObject::InvokeMetaMethod)" << endl
maxter@253 1288 << " return _id;" << endl
maxter@253 1289 << " emit_callbacks_" << java_class->name() << "[_id](dId, _a);" << endl
maxter@253 1290 << " return -1;" << endl
maxter@253 1291 << "}" << endl << endl;
eldar@288 1292 */
maxter@357 1293 s << "QTD_EXTERN QTD_DLL_PUBLIC void qtd_" << className << "_createEntity(void *nativeId, void* dId)" << endl
maxter@253 1294 << "{" << endl
maxter@253 1295 << " new " << entityName << "((QObject*)nativeId, dId);" << endl
maxter@253 1296 << "}" << endl << endl;
maxter@253 1297 }
maxter@253 1298
mandel@1 1299 void CppImplGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1300 {
mandel@1 1301 // QObject::metaObject()
mandel@1 1302 /* s << "const QMetaObject *" << shellClassName(java_class) << "::metaObject() const" << endl
mandel@1 1303 << "{" << endl
mandel@1 1304 << " if (m_meta_object == 0) {" << endl
mandel@1 1305 << " JNIEnv *__jni_env = qtjambi_current_environment();" << endl
mandel@1 1306 << " jobject __obj = m_link != 0 ? m_link->javaObject(__jni_env) : 0;" << endl
mandel@1 1307 << " if (__obj == 0) return " << java_class->qualifiedCppName() << "::metaObject();" << endl
mandel@1 1308 << " else m_meta_object = qtjambi_metaobject_for_class(__jni_env, __jni_env->GetObjectClass(__obj), " << java_class->qualifiedCppName() << "::metaObject());" << endl;
mandel@1 1309
mandel@1 1310
mandel@1 1311 AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions();
mandel@1 1312 for (int pos=0; pos<virtualFunctions.size(); ++pos) {
mandel@1 1313 const AbstractMetaFunction *virtualFunction = virtualFunctions.at(pos);
mandel@1 1314 if (virtualFunction->isVirtualSlot()) {
mandel@1 1315 QStringList introspectionCompatibleSignatures = virtualFunction->introspectionCompatibleSignatures();
mandel@1 1316 foreach (QString introspectionCompatibleSignature, introspectionCompatibleSignatures) {
mandel@1 1317 s << " {" << endl
mandel@1 1318 << " int idx = "
mandel@1 1319 << java_class->qualifiedCppName() << "::metaObject()->indexOfMethod(\""
mandel@1 1320 << introspectionCompatibleSignature << "\");" << endl;
mandel@1 1321
mandel@1 1322 s << " if (idx >= 0) m_map.insert(idx, " << pos << ");" << endl
mandel@1 1323 << " }" << endl;
mandel@1 1324 }
mandel@1 1325 }
mandel@1 1326
mandel@1 1327 }
mandel@1 1328
mandel@1 1329 s << " }" << endl
mandel@1 1330 << " return m_meta_object;" << endl
mandel@1 1331 << "}" << endl << endl;
mandel@1 1332
mandel@1 1333 // QObject::qt_metacast()
mandel@1 1334 s << "void *" << shellClassName(java_class) << "::qt_metacast(const char *_clname)" << endl
mandel@1 1335 << "{" << endl
mandel@1 1336 << " if (!_clname) return 0;" << endl
mandel@1 1337 << " if (!strcmp(_clname, \"" << shellClassName(java_class) << "\"))" << endl
mandel@1 1338 << " return static_cast<void*>(const_cast<" << shellClassName(java_class) << "*>(this));" << endl
mandel@1 1339 << " return " << java_class->qualifiedCppName() << "::qt_metacast(_clname);" << endl
mandel@1 1340 << "}" << endl << endl;
mandel@1 1341 */
eldar@288 1342 /*
mandel@1 1343 s << "int " << shellClassName(java_class) << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
eldar@288 1344 << "{" << endl
eldar@288 1345 << " _id = " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" << endl
eldar@105 1346 << " if (_id < 0 || _c != QMetaObject::InvokeMetaMethod)" << endl
maxter@253 1347 << " return _id;" << endl
maxter@253 1348 << " emit_callbacks_" << java_class->name() << "[_id](this->dId, _a);" << endl
eldar@105 1349 << " return -1;" << endl
mandel@1 1350 << "}" << endl << endl;
eldar@288 1351 */
eldar@288 1352
maxter@357 1353 QString module = packageToQtModule(java_class->package());
maxter@357 1354
maxter@357 1355 s << "QTD_EXPORT_DECL(" << module << ", const QMetaObject*, QObject_metaObject_dispatch, (void *dId))" << endl
maxter@357 1356 << "QTD_EXPORT_DECL(" << module << ", int, QObject_qt_metacall_dispatch, (void *dId, QMetaObject::Call _c, int _id, void **_a))" << endl;
maxter@357 1357
maxter@357 1358 if (java_class->name() == "QObject") {
maxter@357 1359 s << "QTD_EXPORT(" << module << ", QObject_metaObject_dispatch)" << endl
maxter@357 1360 << "QTD_EXPORT(" << module << ", QObject_qt_metacall_dispatch)" << endl;
maxter@355 1361 }
maxter@355 1362
maxter@355 1363 // TODO: QMetaObject should be included in the typesystem
eldar_ins@303 1364 s << endl
eldar_ins@303 1365 << "const QMetaObject * " << shellClassName(java_class) << "::metaObject() const" << endl
eldar_ins@303 1366 << "{" << endl
maxter@355 1367 << " void* dId = QObjectLink::getDId(this);" << endl
maxter@355 1368 << " if (dId)" << endl
maxter@355 1369 << " return qtd_QObject_metaObject_dispatch(dId);" << endl
maxter@355 1370 << " else" << endl
maxter@355 1371 << " return " << java_class->qualifiedCppName() << "::metaObject();" << endl
eldar_ins@303 1372 << "}" << endl << endl
eldar_ins@303 1373 << "int " << shellClassName(java_class) << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
eldar@288 1374 << "{" << endl
maxter@355 1375 << " void* dId = QObjectLink::getDId(this);" << endl
maxter@355 1376 << " if (dId)" << endl
maxter@355 1377 << " return qtd_QObject_qt_metacall_dispatch(dId, _c, _id, _a);" << endl
maxter@355 1378 << " else" << endl
maxter@355 1379 << " return " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" << endl
eldar@288 1380 << "}" << endl << endl
eldar@288 1381
eldar@288 1382 << "int " << shellClassName(java_class) << "::__override_qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
eldar@288 1383 << "{" << endl
eldar@288 1384 << " return " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);"
eldar@288 1385 << "}" << endl << endl
eldar@288 1386
maxter@357 1387 << "QTD_EXTERN QTD_DLL_PUBLIC int qtd_" << java_class->name() << "_qt_metacall(void* __this_nativeId, QMetaObject::Call _c, int _id, void **_a)"
eldar@288 1388 << "{" << endl
eldar@288 1389 << " " << shellClassName(java_class) << " *__qt_this = (" << shellClassName(java_class) << " *) __this_nativeId;" << endl
eldar@288 1390 << " return __qt_this->__override_qt_metacall(_c, _id, _a);" << endl
eldar@288 1391 << "}" << endl << endl;
mandel@1 1392 }
mandel@1 1393
eldar@270 1394 void CppImplGenerator::writeSignalEmitter(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunction *function)
mandel@1 1395 {
eldar@270 1396 Q_ASSERT(d_class);
eldar@270 1397
eldar@270 1398 if (function->isModifiedRemoved(TypeSystem::NativeCode))
eldar@270 1399 return;
eldar@270 1400
eldar@270 1401 const AbstractMetaClass *cls = d_class ? d_class : function->ownerClass();
eldar@270 1402
eldar@270 1403 QString function_signature = cls->name() + "::" + function->signature();
eldar@270 1404
eldar@270 1405 s << "// " << function_signature << endl;
eldar@270 1406
eldar@270 1407 const QString qt_object_name = function->isStatic() ? shellClassName(cls) : "__qt_this";
eldar@270 1408
eldar@270 1409 // we are not wrapping some functions depending on arguments because API is not yet full
eldar@270 1410 if (notWrappedYet(function))
eldar@270 1411 return;
eldar@270 1412
eldar@270 1413 // function signature...
eldar@270 1414 bool callThrough = function->needsCallThrough();
eldar@270 1415 // uint options = m_native_jump_table ? ReturnType | ExternC : StandardJNISignature;
eldar@270 1416 writeFunctionName(s, function, cls, ExternC);
eldar@270 1417 s << endl;
eldar@270 1418 writeFinalFunctionArguments(s, function);
eldar@270 1419 s << endl << "{" << endl;
mandel@1 1420 Indentation indent(INDENT);
mandel@1 1421
eldar@270 1422 writeFinalFunctionSetup(s, function, qt_object_name, cls);
eldar@270 1423
eldar@270 1424 s << "void *args[] = {NULL";
eldar@270 1425 // create an array of pointers to args
eldar@270 1426 /* AbstractMetaArgumentList arguments = java_function->arguments();
eldar@270 1427 foreach (const AbstractMetaArgument *argument, arguments) {
eldar@270 1428 s << ", ";
eldar@270 1429 if (!argument->type()->isPrimitive()
eldar@270 1430 || !java_function->conversionRule(TypeSystem::NativeCode, argument->argumentIndex() + 1).isEmpty()) {
eldar@270 1431 // s << &qt_arg + n
mandel@1 1432 }
mandel@1 1433 }
eldar@270 1434 */
eldar@270 1435 s << endl << "}";
eldar@270 1436 s << endl << endl;
mandel@1 1437 }
mandel@1 1438
mandel@1 1439 void CppImplGenerator::writeShellConstructor(QTextStream &s, const AbstractMetaFunction *java_function)
mandel@1 1440 {
mandel@1 1441 if (java_function->isModifiedRemoved(TypeSystem::ShellCode))
mandel@1 1442 return;
mandel@1 1443
mandel@1 1444 const AbstractMetaClass *cls = java_function->ownerClass();
mandel@1 1445 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 1446
mandel@1 1447 writeFunctionSignature(s, java_function, cls);
mandel@1 1448
mandel@1 1449 s << endl;
mandel@1 1450 s << " : " << cls->qualifiedCppName() << "(";
mandel@1 1451 for (int i=0; i<arguments.size(); ++i) {
mandel@1 1452 s << arguments.at(i)->indexedName();
mandel@1 1453 if (i != arguments.size() - 1)
mandel@1 1454 s << ", ";
mandel@1 1455 }
mandel@1 1456 s << ")";
maxter@355 1457 if (cls->isQObject()) {
maxter@355 1458 s << "," << endl << " QObjectLink(this, d_ptr)";
maxter@355 1459 }
maxter@355 1460 else if (cls->isPolymorphic())
maxter@355 1461 s << "," << endl << " QtdObjectLink(d_ptr)";
mandel@1 1462 /* qtd s << " m_meta_object(0)," << endl;
mandel@1 1463 s << " m_vtable(0)," << endl
mandel@1 1464 << " m_link(0)" << endl;
mandel@1 1465 */
mandel@1 1466 s << endl;
mandel@1 1467 s << "{" << endl;
mandel@1 1468 {
mandel@1 1469 Indentation indent(INDENT);
maxter@253 1470
mandel@1 1471 writeCodeInjections(s, java_function, cls, CodeSnip::Beginning, TypeSystem::ShellCode);
mandel@1 1472 writeCodeInjections(s, java_function, cls, CodeSnip::End, TypeSystem::ShellCode);
mandel@1 1473 }
mandel@1 1474 s << "}" << endl << endl;
mandel@1 1475 }
mandel@1 1476
mandel@1 1477 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 1478 {
maxter@354 1479 QString className = shellClassName(java_class);
maxter@354 1480 s << className << "::~" << className << "() {" << endl;
maxter@354 1481
maxter@355 1482 if (java_class->isQObject()) {
maxter@355 1483 s << " destroyLink(this);" << endl;
maxter@355 1484 }
maxter@355 1485 /*
maxter@355 1486 else if (java_class->isPolymorphic())
maxter@355 1487 s << " qtd_delete_d_object(dId);" << endl;
maxter@355 1488 */
maxter@354 1489
mandel@1 1490 s << "}" << endl << endl;
mandel@1 1491 }
mandel@1 1492
mandel@1 1493 void CppImplGenerator::writeCodeInjections(QTextStream &s, const AbstractMetaFunction *java_function,
mandel@1 1494 const AbstractMetaClass *implementor, CodeSnip::Position position,
mandel@1 1495 TypeSystem::Language language)
mandel@1 1496 {
mandel@1 1497
mandel@1 1498 FunctionModificationList mods;
mandel@1 1499 const AbstractMetaClass *cls = implementor;
mandel@1 1500 while (cls != 0) {
mandel@1 1501 mods += java_function->modifications(cls);
mandel@1 1502
mandel@1 1503 if (cls == cls->baseClass())
mandel@1 1504 break;
mandel@1 1505 cls = cls->baseClass();
mandel@1 1506 }
mandel@1 1507
mandel@1 1508 foreach (FunctionModification mod, mods) {
mandel@1 1509 if (mod.snips.count() <= 0)
mandel@1 1510 continue ;
mandel@1 1511
mandel@1 1512 foreach (CodeSnip snip, mod.snips) {
mandel@1 1513 if (snip.position != position)
mandel@1 1514 continue ;
mandel@1 1515
mandel@1 1516 if ((snip.language & language) == false)
mandel@1 1517 continue ;
mandel@1 1518
mandel@1 1519 if (position == CodeSnip::End)
mandel@1 1520 s << endl;
mandel@1 1521
mandel@1 1522 QString code;
mandel@1 1523 QTextStream tmpStream(&code);
mandel@1 1524 snip.formattedCode(tmpStream, INDENT);
mandel@1 1525 ArgumentMap map = snip.argumentMap;
mandel@1 1526 ArgumentMap::iterator it = map.begin();
mandel@1 1527 for (;it!=map.end();++it) {
mandel@1 1528 int pos = it.key() - 1;
mandel@1 1529 QString meta_name = it.value();
mandel@1 1530
mandel@1 1531 if (pos >= 0 && pos < java_function->arguments().count()) {
mandel@1 1532 code = code.replace(meta_name, java_function->arguments().at(pos)->indexedName());
mandel@1 1533 } else {
mandel@1 1534 QString debug = QString("argument map specifies invalid argument index %1"
mandel@1 1535 "for function '%2'")
mandel@1 1536 .arg(pos + 1).arg(java_function->name());
mandel@1 1537 ReportHandler::warning(debug);
mandel@1 1538 }
mandel@1 1539
mandel@1 1540 }
mandel@1 1541 s << code;
mandel@1 1542 if (position == CodeSnip::Beginning)
mandel@1 1543 s << endl;
mandel@1 1544 }
mandel@1 1545 }
mandel@1 1546 }
mandel@1 1547
mandel@1 1548 static QString function_call_for_ownership(TypeSystem::Ownership owner, const QString &var_name)
mandel@1 1549 {
mandel@1 1550 if (owner == TypeSystem::CppOwnership) {
mandel@1 1551 return "setCppOwnership(__jni_env, " + var_name + ")";
mandel@1 1552 } else if (owner == TypeSystem::TargetLangOwnership) {
mandel@1 1553 return "setJavaOwnership(__jni_env, " + var_name + ")";
mandel@1 1554 } else if (owner == TypeSystem::DefaultOwnership) {
mandel@1 1555 return "setDefaultOwnership(__jni_env, " + var_name + ")";
mandel@1 1556 } else {
mandel@1 1557 Q_ASSERT(false);
mandel@1 1558 return "bogus()";
mandel@1 1559 }
mandel@1 1560 }
mandel@1 1561
mandel@1 1562 void CppImplGenerator::writeOwnership(QTextStream &s,
mandel@1 1563 const AbstractMetaFunction *java_function,
mandel@1 1564 const QString &var_name,
mandel@1 1565 int var_index,
mandel@1 1566 const AbstractMetaClass *implementor)
mandel@1 1567 {
mandel@1 1568 TypeSystem::Ownership owner = TypeSystem::InvalidOwnership;
mandel@1 1569 const AbstractMetaClass *cls = implementor;
mandel@1 1570 while (cls != 0 && owner == TypeSystem::InvalidOwnership) {
mandel@1 1571 owner = java_function->ownership(cls, TypeSystem::ShellCode, var_index);
mandel@1 1572 cls = cls->baseClass();
mandel@1 1573 }
mandel@1 1574
mandel@1 1575 if (owner == TypeSystem::InvalidOwnership)
mandel@1 1576 return;
mandel@1 1577
mandel@1 1578 if (var_index != -1) {
mandel@1 1579 s << INDENT << "if (" << var_name << " != 0) {" << endl;
mandel@1 1580 {
mandel@1 1581 Indentation indent(INDENT);
mandel@1 1582 s << INDENT << "QtJambiLink *__link = QtJambiLink::findLink(__jni_env, "
mandel@1 1583 << var_name << ");" << endl
mandel@1 1584 << INDENT << "Q_ASSERT(__link != 0);" << endl;
mandel@1 1585
mandel@1 1586 s << INDENT << "__link->" << function_call_for_ownership(owner, var_name) << ";" << endl;
mandel@1 1587 }
mandel@1 1588 s << INDENT << "}" << endl;
mandel@1 1589 } else {
mandel@1 1590 s << INDENT << "if (m_link) {" << endl;
mandel@1 1591 {
mandel@1 1592 Indentation indent(INDENT);
mandel@1 1593 s << INDENT << "m_link->" << function_call_for_ownership(owner, "m_link->javaObject(__jni_env)") << ";" << endl;
mandel@1 1594 }
mandel@1 1595 s << INDENT << "}" << endl;
mandel@1 1596 }
mandel@1 1597
mandel@1 1598 }
mandel@1 1599
mandel@1 1600 void CppImplGenerator::writeShellFunction(QTextStream &s, const AbstractMetaFunction *java_function,
mandel@1 1601 const AbstractMetaClass *implementor, int id)
mandel@1 1602 {
mandel@1 1603 writeFunctionSignature(s, java_function, implementor, QString(), OriginalName);
mandel@1 1604
mandel@1 1605 s << endl
mandel@1 1606 << "{" << endl;
mandel@1 1607
mandel@1 1608 Indentation indent(INDENT);
mandel@1 1609
mandel@1 1610 QString java_function_signature = java_function->signature();
mandel@1 1611 /* s << INDENT << "QTJAMBI_DEBUG_TRACE(\"(shell) entering: " << implementor->name() << "::"
mandel@1 1612 << java_function_signature << "\");" << endl;
mandel@1 1613 */
mandel@1 1614 writeCodeInjections(s, java_function, implementor, CodeSnip::Beginning, TypeSystem::ShellCode);
mandel@1 1615
mandel@1 1616 // s << " printf(\"%s : %s\\n\", \"" << java_function->enclosingClass()->name() << "\""
mandel@1 1617 // << ", \"" << java_function->name() << "\");" << endl;
mandel@1 1618
mandel@1 1619 if (!java_function->isFinalInCpp() || java_function->isVirtualSlot()) {
mandel@1 1620 s << INDENT << "jmethodID method_id = m_vtable->method(" << id << ");" << endl;
mandel@1 1621 s << INDENT << "if (method_id) {" << endl;
mandel@1 1622
mandel@1 1623 {
mandel@1 1624 Indentation indent(INDENT);
mandel@1 1625 s << INDENT << "JNIEnv *__jni_env = qtjambi_current_environment();" << endl;
mandel@1 1626
mandel@1 1627 // This nasty case comes up when we're shutting down while receiving virtual
mandel@1 1628 // calls.. With these checks we safly abort...
mandel@1 1629 s << INDENT << "if (!__jni_env) {" << endl
mandel@1 1630 << " ";
mandel@1 1631 writeBaseClassFunctionCall(s, java_function, implementor);
mandel@1 1632 if (!java_function->type()) {
mandel@1 1633 s << INDENT << " return;" << endl;
mandel@1 1634 }
mandel@1 1635 s << INDENT << "}" << endl;
mandel@1 1636
mandel@1 1637 // otherwise, continue with the function call...
mandel@1 1638 s << INDENT << "__jni_env->PushLocalFrame(100);" << endl;
mandel@1 1639
mandel@1 1640 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 1641 AbstractMetaArgumentList argumentsToReset;
mandel@1 1642 foreach (AbstractMetaArgument *argument, arguments) {
mandel@1 1643 if (!java_function->argumentRemoved(argument->argumentIndex()+1)) {
mandel@1 1644 if (!argument->type()->isPrimitive()
mandel@1 1645 || !java_function->conversionRule(TypeSystem::NativeCode, argument->argumentIndex()+1).isEmpty()) {
mandel@1 1646 writeQtToJava(s,
mandel@1 1647 argument->type(),
mandel@1 1648 argument->indexedName(),
mandel@1 1649 "__java_" + argument->indexedName(),
mandel@1 1650 java_function,
mandel@1 1651 argument->argumentIndex() + 1);
mandel@1 1652 }
mandel@1 1653
mandel@1 1654 if (java_function->resetObjectAfterUse(argument->argumentIndex()+1))
mandel@1 1655 argumentsToReset.append(argument);
mandel@1 1656 }
mandel@1 1657 }
mandel@1 1658
mandel@1 1659 for (int i=0; i<arguments.size(); ++i)
mandel@1 1660 writeOwnership(s, java_function, "__java_" + arguments.at(i)->indexedName(), i+1, implementor);
mandel@1 1661
mandel@1 1662
mandel@1 1663 AbstractMetaType *function_type = java_function->type();
mandel@1 1664 QString new_return_type = java_function->typeReplaced(0);
mandel@1 1665 bool has_function_type = ((function_type != 0
mandel@1 1666 || !new_return_type.isEmpty())
mandel@1 1667 && new_return_type != "void");
mandel@1 1668
mandel@1 1669 s << INDENT;
mandel@1 1670 if (has_function_type) {
mandel@1 1671 if (new_return_type.isEmpty()) {
mandel@1 1672 s << translateType(function_type);
mandel@1 1673 } else {
mandel@1 1674 s << jniName(new_return_type);
mandel@1 1675 }
mandel@1 1676 s << " " << "__d_return_value = ";
mandel@1 1677 }
mandel@1 1678
mandel@1 1679 s << "__jni_env->";
mandel@1 1680 if (new_return_type.isEmpty()) {
mandel@1 1681 s << callXxxMethod(java_function->type());
mandel@1 1682 } else if (!has_function_type) {
mandel@1 1683 s << "CallVoidMethod";
mandel@1 1684 } else {
mandel@1 1685 s << callXxxMethod(new_return_type);
mandel@1 1686 }
mandel@1 1687
mandel@1 1688 s << "(m_link->javaObject(__jni_env), method_id";
mandel@1 1689 if (arguments.size() > 0)
mandel@1 1690 s << ", ";
mandel@1 1691 writeFunctionCallArguments(s, java_function, "__java_", Option(NoCasts | SkipRemovedArguments));
mandel@1 1692 s << ");" << endl
mandel@1 1693 << INDENT << "qtjambi_exception_check(__jni_env);" << endl;
mandel@1 1694
mandel@1 1695 if (has_function_type) {
mandel@1 1696 writeJavaToQt(s, function_type, "__qt_return_value", "__d_return_value",
mandel@1 1697 java_function, 0, GlobalRefJObject);
mandel@1 1698
mandel@1 1699 if (java_function->nullPointersDisabled()) {
mandel@1 1700 s << INDENT << "if (__d_return_value == 0) {" << endl;
mandel@1 1701 {
mandel@1 1702 Indentation indent(INDENT);
mandel@1 1703 s << INDENT << "fprintf(stderr, \"QtJambi: Unexpected null pointer returned from override of '" << java_function->name() << "' in class '%s'\\n\"," << endl
mandel@1 1704 << INDENT << " qPrintable(qtjambi_object_class_name(__jni_env, m_link->javaObject(__jni_env))));" << endl;
mandel@1 1705 s << INDENT << "__qt_return_value = ";
mandel@1 1706 QString defaultValue = java_function->nullPointerDefaultValue();
mandel@1 1707 if (!defaultValue.isEmpty())
mandel@1 1708 s << defaultValue << ";";
mandel@1 1709 else
mandel@1 1710 writeBaseClassFunctionCall(s, java_function, implementor, NoReturnStatement);
mandel@1 1711 s << endl;
mandel@1 1712 }
mandel@1 1713
mandel@1 1714 s << INDENT << "}" << endl;
mandel@1 1715 }
mandel@1 1716 } else if (!java_function->conversionRule(TypeSystem::ShellCode, 0).isEmpty()) {
mandel@1 1717 writeConversionRule(s, TypeSystem::ShellCode, java_function, 0, "<invalid>", "<invalid>");
mandel@1 1718 }
mandel@1 1719
mandel@1 1720 writeOwnership(s, java_function, "this", -1, implementor);
mandel@1 1721 writeOwnership(s, java_function, "__d_return_value", 0, implementor);
mandel@1 1722
mandel@1 1723 foreach (AbstractMetaArgument *argumentToReset, argumentsToReset) {
mandel@1 1724
mandel@1 1725 QString argumentName = "__java_" + argumentToReset->indexedName();
mandel@1 1726
mandel@1 1727 s << INDENT;
mandel@1 1728 if (argumentToReset->type()->isContainer())
mandel@1 1729 s << "qtjambi_invalidate_collection(";
mandel@1 1730 else
mandel@1 1731 s << "qtjambi_invalidate_object(";
mandel@1 1732
mandel@1 1733 s << "__jni_env, " << argumentName << ");" << endl;
mandel@1 1734 }
mandel@1 1735
mandel@1 1736 s << INDENT << "__jni_env->PopLocalFrame(0);" << endl;
mandel@1 1737
mandel@1 1738 s << INDENT << "QTJAMBI_DEBUG_TRACE(\"(shell) -> leaving: " << implementor->name()
mandel@1 1739 << "::" << java_function_signature << "\");" << endl;
mandel@1 1740
mandel@1 1741 if (function_type)
mandel@1 1742 s << INDENT << "return __qt_return_value;" << endl;
mandel@1 1743
mandel@1 1744 }
mandel@1 1745
mandel@1 1746 s << INDENT << "} else {" << endl;
mandel@1 1747
mandel@1 1748 {
mandel@1 1749 Indentation indent(INDENT);
mandel@1 1750 s << INDENT << "QTJAMBI_DEBUG_TRACE(\"(shell) -> super() and leaving: "
mandel@1 1751 << implementor->name() << "::" << java_function_signature << "\");" << endl;
mandel@1 1752 writeBaseClassFunctionCall(s, java_function, implementor);
mandel@1 1753 }
mandel@1 1754
mandel@1 1755
mandel@1 1756 s << INDENT << "}" << endl;
mandel@1 1757
mandel@1 1758 writeCodeInjections(s, java_function, implementor, CodeSnip::End, TypeSystem::ShellCode);
mandel@1 1759
mandel@1 1760 // A little trick to close open painters on a widget
mandel@1 1761 if (java_function->name() == "paintEvent") {
mandel@1 1762 s << INDENT << "JNIEnv *env = qtjambi_current_environment();" << endl
mandel@1 1763 << INDENT << "qtjambi_end_paint(env, m_link->javaObject(env));" << endl;
mandel@1 1764 }
mandel@1 1765
mandel@1 1766 } else {
mandel@1 1767 if(java_function->isRemovedFrom(implementor, TypeSystem::TargetLangCode)){
mandel@1 1768 // Avoid compiler warnings for unused parameters
mandel@1 1769 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 1770
mandel@1 1771 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 1772 s << INDENT << "Q_UNUSED(" << argument->indexedName() << ")" << endl;
mandel@1 1773 }
mandel@1 1774 }
mandel@1 1775 writeBaseClassFunctionCall(s, java_function, implementor);
mandel@1 1776 writeCodeInjections(s, java_function, implementor, CodeSnip::End, TypeSystem::ShellCode);
mandel@1 1777 }
mandel@1 1778
mandel@1 1779 s << "}" << endl << endl;
mandel@1 1780
mandel@1 1781 }
mandel@1 1782
mandel@1 1783 // ### kill implementor
mandel@1 1784
mandel@1 1785 void CppImplGenerator::writePublicFunctionOverride(QTextStream &s,
mandel@1 1786 const AbstractMetaFunction *java_function,
mandel@1 1787 const AbstractMetaClass *implementor)
mandel@1 1788 {
mandel@1 1789 Q_ASSERT(java_function->originalAttributes()
mandel@1 1790 & (AbstractMetaAttributes::Protected
mandel@1 1791 | AbstractMetaAttributes::Final));
mandel@1 1792
mandel@1 1793 // The write a public override version of this function to be used by native functions
mandel@1 1794 writeFunctionSignature(s, java_function, implementor, "__public_",
mandel@1 1795 Option(EnumAsInts | UnderscoreSpaces
mandel@1 1796 | (java_function->isAbstract() ? SkipName : NoOption)));
mandel@1 1797 s << endl
mandel@1 1798 << "{" << endl;
mandel@1 1799 Indentation indent(INDENT);
mandel@1 1800 writeBaseClassFunctionCall(s, java_function, implementor);
mandel@1 1801 s << "}" << endl << endl;
mandel@1 1802 }
mandel@1 1803
maxter@253 1804 void CppImplGenerator::writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class)
maxter@253 1805 {
maxter@357 1806 s << "QTD_EXTERN QTD_DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl;
maxter@253 1807 s << "{" << endl;
maxter@253 1808 {
maxter@253 1809 Indentation indent(INDENT);
maxter@355 1810 s << INDENT << "QtdObjectLink* a = dynamic_cast<QtdObjectLink*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl
maxter@253 1811 << INDENT << "if (a != NULL)" << endl
maxter@253 1812 << INDENT << " return a->dId;" << endl
maxter@253 1813 << INDENT << "else" << endl
maxter@253 1814 << INDENT << " return NULL;" << endl;
maxter@253 1815 }
maxter@253 1816 s << "}" << endl << endl;
maxter@253 1817 }
mandel@1 1818
mandel@1 1819 void CppImplGenerator::writeVirtualFunctionOverride(QTextStream &s,
mandel@1 1820 const AbstractMetaFunction *java_function,
mandel@1 1821 const AbstractMetaClass *implementor)
mandel@1 1822 {
mandel@1 1823 Q_ASSERT(!java_function->isFinalInCpp());
mandel@1 1824
mandel@1 1825 Option options = Option(EnumAsInts | UnderscoreSpaces);
mandel@1 1826
mandel@1 1827 // The write a public override version of this function to be used by native functions
mandel@1 1828 writeFunctionSignature(s, java_function, implementor, "__override_",
mandel@1 1829 options,
eldar@21 1830 QString(), // the class prefix
eldar@21 1831 QStringList() << "bool static_call");
mandel@1 1832 s << endl
mandel@1 1833 << "{" << endl;
mandel@1 1834 Indentation indent(INDENT);
eldar@21 1835 s << INDENT << "if (static_call) {" << endl;
mandel@1 1836 {
eldar@21 1837 Indentation indent(INDENT);
mandel@1 1838 writeBaseClassFunctionCall(s, java_function, implementor);
eldar@21 1839 }
mandel@1 1840 s << INDENT << "} else {" << endl;
mandel@1 1841 {
mandel@1 1842 Indentation indent(INDENT);
mandel@1 1843 writeBaseClassFunctionCall(s, java_function, implementor, VirtualCall);
mandel@1 1844 }
mandel@1 1845
eldar@21 1846 s << INDENT << "}" << endl;
mandel@1 1847 s << "}" << endl << endl;
mandel@1 1848 }
mandel@1 1849
mandel@1 1850
mandel@1 1851 void CppImplGenerator::writeBaseClassFunctionCall(QTextStream &s,
mandel@1 1852 const AbstractMetaFunction *java_function,
mandel@1 1853 const AbstractMetaClass *,
mandel@1 1854 Option options)
mandel@1 1855 {
mandel@1 1856 bool static_call = !(options & VirtualCall);
mandel@1 1857 if ((options & NoReturnStatement) == 0)
mandel@1 1858 s << INDENT;
mandel@1 1859 if (java_function->isAbstract() && static_call) {
mandel@1 1860 s << default_return_statement_qt(java_function->type(), options) << ";" << endl;
mandel@1 1861 } else {
mandel@1 1862 if (java_function->type() && (options & NoReturnStatement) == 0)
mandel@1 1863 s << "return ";
mandel@1 1864 if (static_call) {
mandel@1 1865 const AbstractMetaClass *implementor = java_function->implementingClass();
mandel@1 1866 if (java_function->isInterfaceFunction())
mandel@1 1867 implementor = java_function->interfaceClass()->primaryInterfaceImplementor();
mandel@1 1868 s << implementor->qualifiedCppName() << "::";
mandel@1 1869 }
mandel@1 1870 s << java_function->originalName() << "(";
mandel@1 1871 writeFunctionCallArguments(s, java_function, QString(), Option(options | ForceEnumCast));
mandel@1 1872 s << ");" << endl;
mandel@1 1873 }
mandel@1 1874 }
mandel@1 1875
mandel@1 1876
mandel@1 1877 void CppImplGenerator::writeFunctionName(QTextStream &s,
mandel@1 1878 const AbstractMetaFunction *java_function,
mandel@1 1879 const AbstractMetaClass *java_class,
mandel@1 1880 uint options)
mandel@1 1881 {
mandel@1 1882 const AbstractMetaClass *cls = java_class ? java_class : java_function->ownerClass();
mandel@1 1883 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 1884
mandel@1 1885 // Function signature
mandel@1 1886 QString return_type = jniReturnName(java_function, options);
mandel@1 1887
mandel@1 1888 QString function_name;
mandel@1 1889
mandel@1 1890 bool callThrough = java_function->needsCallThrough();
mandel@1 1891 /* qtd if (!callThrough)
mandel@1 1892 function_name = java_function->name();
mandel@1 1893 else */
mandel@1 1894 function_name = java_function->marshalledName();
mandel@1 1895
mandel@1 1896 QString args = "__";
mandel@1 1897
mandel@1 1898 if (callThrough && !java_function->isStatic() && !java_function->isConstructor())
mandel@1 1899 args += "J";
mandel@1 1900
mandel@1 1901 if (!arguments.isEmpty()) {
mandel@1 1902 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 1903 if (!java_function->argumentRemoved(argument->argumentIndex() + 1)) {
mandel@1 1904 if (!argument->type()->hasNativeId()) {
mandel@1 1905 QString modified_type = java_function->typeReplaced(argument->argumentIndex()+1);
mandel@1 1906 if (modified_type.isEmpty())
mandel@1 1907 args += jni_signature(argument->type(), Underscores);
mandel@1 1908 else
mandel@1 1909 args += jni_signature(modified_type, Underscores);
mandel@1 1910 } else {
mandel@1 1911 args += "J";
mandel@1 1912 }
mandel@1 1913 }
mandel@1 1914 }
mandel@1 1915 }
mandel@1 1916
mandel@1 1917 s << jni_function_signature(cls->package(), cls->name(), function_name,
mandel@1 1918 return_type, args, options);
mandel@1 1919
mandel@1 1920 }
mandel@1 1921
mandel@1 1922 void CppImplGenerator::writeFinalFunctionArguments(QTextStream &s, const AbstractMetaFunction *java_function, bool d_export)
mandel@1 1923 {
mandel@1 1924 bool callThrough = java_function->needsCallThrough();
mandel@1 1925 s << "(";
mandel@1 1926 /* qtd
mandel@1 1927 << "JNIEnv *__jni_env," << endl;
mandel@1 1928 if (!java_function->isConstructor()) {
mandel@1 1929 if (java_function->isStatic())
mandel@1 1930 s << " jclass";
mandel@1 1931 else
mandel@1 1932 s << " jobject";
mandel@1 1933 } else
mandel@1 1934 s << " jobject " << java_object_name;
mandel@1 1935 */
mandel@1 1936 uint nativeArgCount = 0;
mandel@1 1937 const AbstractMetaClass *cls = java_function->ownerClass();
mandel@1 1938 if (java_function->isConstructor() &&
maxter@355 1939 ( cls->isPolymorphic()
mandel@1 1940 || cls->typeEntry()->isObject() ) )
mandel@1 1941 {
mandel@1 1942 s << "void *d_ptr";
mandel@1 1943 nativeArgCount++;
mandel@1 1944 }
mandel@1 1945
mandel@1 1946 // passing pointer to C++ object
maxter@355 1947 bool hasNativeId = callThrough && !java_function->isStatic() && !java_function->isConstructor();
mandel@1 1948 if (hasNativeId) {
mandel@1 1949 if (nativeArgCount > 0)
mandel@1 1950 s << "," << endl << " ";
mandel@1 1951 /* qtd << "," << endl */ s << "void* __this_nativeId";
mandel@1 1952 nativeArgCount++;
mandel@1 1953 }
mandel@1 1954
mandel@1 1955 AbstractMetaType *f_type = java_function->type();
mandel@1 1956
mandel@1 1957 // return values as strings, arrays or QModelIndex'es we return as arguments
mandel@1 1958 bool return_arg = false;
mandel@1 1959 if (f_type) {
mandel@1 1960 if (f_type->isTargetLangString() ||
mandel@1 1961 f_type->isContainer() ||
eldar@81 1962 f_type->name() == "QModelIndex" ||
eldar@81 1963 f_type->typeEntry()->isStructInD())
mandel@1 1964 return_arg = true;
mandel@1 1965
mandel@1 1966 if (return_arg && nativeArgCount > 0)
mandel@1 1967 s << "," << endl << " ";
mandel@1 1968
mandel@1 1969 if (f_type->isTargetLangString() || f_type->isContainer())
mandel@1 1970 s << "void*";
mandel@1 1971 else if (f_type->name() == "QModelIndex")
mandel@1 1972 s << "QModelIndexAccessor*";
eldar@81 1973 else if (f_type->typeEntry()->isStructInD())
eldar@81 1974 s << f_type->typeEntry()->qualifiedCppName() << " *";
mandel@1 1975
mandel@1 1976 if(return_arg) {
mandel@1 1977 s << " __d_return_value";
mandel@1 1978 nativeArgCount++;
mandel@1 1979 }
mandel@1 1980 }
mandel@1 1981
mandel@1 1982 // the function arguments
mandel@1 1983 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 1984 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 1985 if (!java_function->argumentRemoved(argument->argumentIndex() + 1)) {
mandel@1 1986 AbstractMetaType *d_type = argument->type();
mandel@1 1987 const TypeEntry *te = d_type->typeEntry();
mandel@1 1988
mandel@1 1989 QString arg_name = argument->indexedName();
mandel@1 1990
mandel@1 1991 if (nativeArgCount > 0)
mandel@1 1992 s << "," << endl << " ";
eldar@81 1993
eldar@81 1994 // if QString argument we have to pass DArray
eldar@35 1995 if ((te && te->qualifiedCppName() == "QString") || d_type->isTargetLangString()) {
eldar@35 1996 if (d_export)
eldar@35 1997 s << "string " << arg_name;
eldar@35 1998 else
eldar@35 1999 s << "DArray " << arg_name;
eldar@35 2000 } else if (d_type->isContainer()) {
mandel@1 2001 const ContainerTypeEntry *cte =
mandel@1 2002 static_cast<const ContainerTypeEntry *>(te);
eldar@298 2003 if(cte->isQList())
eldar@298 2004 s << "void* " << arg_name;
eldar@298 2005 else if(isLinearContainer(cte))
eldar@298 2006 s << "DArray* " << arg_name;
mandel@1 2007 } else {
mandel@1 2008 if (!d_type->hasNativeId()) {
mandel@1 2009 if(d_type->isVariant()) {
mandel@1 2010 if (d_export) s << "void*";
mandel@1 2011 else s << "QVariant*";
mandel@1 2012 } else
mandel@1 2013 s << translateType(argument->type(), EnumAsInts, d_export);
mandel@1 2014 }
eldar@188 2015 else if (d_type->name() == "QModelIndex") {
eldar@188 2016 if(d_export && dVersion == 2 && d_type->isConstant())
eldar@188 2017 s << "const(QModelIndexAccessor)";
eldar@188 2018 else
eldar@188 2019 s << "QModelIndexAccessor";
eldar@188 2020 } else if (te->isStructInD())
mandel@1 2021 s << te->qualifiedCppName();
mandel@1 2022 else
mandel@1 2023 s << "void*";
mandel@1 2024
mandel@1 2025 s << " " << arg_name;
mandel@1 2026 }
mandel@1 2027 nativeArgCount++;
mandel@1 2028 }
mandel@1 2029 }
mandel@1 2030 s << ")";
mandel@1 2031 }
mandel@1 2032
mandel@1 2033
mandel@1 2034 /*!
mandel@1 2035 Generates type conversion from Java -> Qt for all the arguments
mandel@1 2036 that are to be to be passed to the function
mandel@1 2037 */
mandel@1 2038 void CppImplGenerator::writeFinalFunctionSetup(QTextStream &s, const AbstractMetaFunction *java_function,
mandel@1 2039 const QString &qt_object_name,
mandel@1 2040 const AbstractMetaClass *cls)
mandel@1 2041 {
mandel@1 2042
mandel@1 2043 // Translate each of the function arguments into qt types
mandel@1 2044 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 2045 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 2046 if (!argument->type()->isPrimitive()
mandel@1 2047 || !java_function->conversionRule(TypeSystem::NativeCode, argument->argumentIndex() + 1).isEmpty()) {
mandel@1 2048 writeJavaToQt(s,
mandel@1 2049 argument->type(),
mandel@1 2050 "__qt_" + argument->indexedName(),
mandel@1 2051 argument->indexedName(),
mandel@1 2052 java_function,
mandel@1 2053 argument->argumentIndex() + 1,
mandel@1 2054 Option(UseNativeIds | EnumAsInts));
mandel@1 2055 }
mandel@1 2056 }
mandel@1 2057
mandel@1 2058 // Extract the qt equivalent to the this pointer and name it "qt_object_name"
mandel@1 2059 if (!java_function->isStatic() && !java_function->isConstructor()) {
mandel@1 2060 // qtd2 QString className = java_function->isFinalOverload() ? cls->name() : shellClassName(cls);
mandel@1 2061 QString className = java_function->isFinalOverload() ? cls->name() : shellClassName(cls);
mandel@1 2062 s << INDENT
mandel@1 2063 << className << " *" << qt_object_name
mandel@1 2064 << " = (" << className << " *) __this_nativeId;"
mandel@1 2065 << endl;
mandel@1 2066 // << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl
mandel@1 2067 // qtd << INDENT << "Q_ASSERT(" << qt_object_name << ");" << endl;
mandel@1 2068 }
mandel@1 2069 }
mandel@1 2070
mandel@1 2071 void CppImplGenerator::writeFinalFunction(QTextStream &s, const AbstractMetaFunction *java_function,
mandel@1 2072 const AbstractMetaClass *java_class)
mandel@1 2073 {
mandel@1 2074 Q_ASSERT(java_class);
mandel@1 2075
mandel@1 2076 if (java_function->isModifiedRemoved(TypeSystem::NativeCode))
mandel@1 2077 return;
mandel@1 2078
mandel@1 2079 const AbstractMetaClass *cls = java_class ? java_class : java_function->ownerClass();
mandel@1 2080
mandel@1 2081 QString java_function_signature = cls->name() + "::" + java_function->signature();
mandel@1 2082
mandel@1 2083 s << "// " << java_function_signature << endl;
mandel@1 2084
mandel@1 2085 const AbstractMetaType *function_type = java_function->type();
mandel@1 2086 QString new_return_type = java_function->typeReplaced(0);
mandel@1 2087 bool has_function_type = new_return_type != "void"
mandel@1 2088 && (!new_return_type.isEmpty() || function_type != 0)
mandel@1 2089 && java_function->argumentReplaced(0).isEmpty();
mandel@1 2090
mandel@1 2091 const QString qt_object_name = java_function->isStatic() ? shellClassName(cls) : "__qt_this";
mandel@1 2092 const QString java_object_name = java_function->isStatic() ? "__jni_class" : "__jni_object";
mandel@1 2093
mandel@1 2094 // we are not wrapping some functions depending on arguments because API is not yet full
mandel@1 2095 if (notWrappedYet(java_function))
mandel@1 2096 return;
mandel@1 2097
mandel@1 2098 // function signature...
mandel@1 2099 bool callThrough = java_function->needsCallThrough();
mandel@1 2100 uint options = m_native_jump_table ? ReturnType | ExternC : StandardJNISignature;
mandel@1 2101 writeFunctionName(s, java_function, cls, options);
mandel@1 2102 s << endl;
mandel@1 2103 writeFinalFunctionArguments(s, java_function);
mandel@1 2104 s << endl << "{" << endl;
mandel@1 2105 Indentation indent(INDENT);
mandel@1 2106
mandel@1 2107 // qtd2 s << INDENT << "QTJAMBI_DEBUG_TRACE(\"(native) entering: " << java_function_signature << "\");" << endl;
mandel@1 2108 bool hasNativeId = (callThrough && !java_function->isStatic() && !java_function->isConstructor());
mandel@1 2109 /* if (hasNativeId)
mandel@1 2110 s << INDENT << "Q_UNUSED(__this_nativeId)" << endl;
mandel@1 2111 // Avoid compiler warnings when the variables are unused
mandel@1 2112 {
mandel@1 2113 s << INDENT << "Q_UNUSED(__jni_env)" << endl;
mandel@1 2114
mandel@1 2115 if (java_function->isConstructor())
mandel@1 2116 s << INDENT << "Q_UNUSED(" << java_object_name << ")" << endl;
mandel@1 2117
mandel@1 2118 bool hasNativeId = (callThrough && !java_function->isStatic() && !java_function->isConstructor());
mandel@1 2119 if (hasNativeId)
mandel@1 2120 s << INDENT << "Q_UNUSED(__this_nativeId)" << endl;
mandel@1 2121 }
mandel@1 2122 */
mandel@1 2123
mandel@1 2124 if (cls->isFinal() && (!java_function->isAbstract() || !java_function->isFinalInTargetLang()) && !java_function->wasPublic()) {
mandel@1 2125 QString debug = QString("protected function '%1' in final class '%2'")
mandel@1 2126 .arg(java_function->signature()).arg(java_class->name());
mandel@1 2127 ReportHandler::warning(debug);
mandel@1 2128 // Avoid compiler warnings for unused parameters
mandel@1 2129 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 2130
mandel@1 2131 foreach (const AbstractMetaArgument *argument, arguments) {
mandel@1 2132 s << INDENT << "Q_UNUSED(" << argument->indexedName() << ")" << endl;
mandel@1 2133 }
mandel@1 2134 s << INDENT << default_return_statement_qt(java_function->type()) << "";
mandel@1 2135 } else {
mandel@1 2136 writeFinalFunctionSetup(s, java_function, qt_object_name, cls);
mandel@1 2137
mandel@1 2138 writeCodeInjections(s, java_function, java_function->implementingClass(), CodeSnip::Beginning, TypeSystem::NativeCode);
mandel@1 2139
mandel@1 2140 if (java_function->isConstructor()) {
mandel@1 2141 writeFinalConstructor(s, java_function, qt_object_name, java_object_name);
mandel@1 2142 } else {
mandel@1 2143
mandel@1 2144 QString function_prefix = "";
mandel@1 2145 QStringList extra_param;
mandel@1 2146 Option option = NoOption;
mandel@1 2147
mandel@1 2148 bool hasShell = cls->generateShellClass();
mandel@1 2149
mandel@1 2150 if (java_function->isFinalOverload()) {
mandel@1 2151 // no prefix
mandel@1 2152 } else if (java_function->isFinalInCpp() && !java_function->wasPublic() && hasShell) {
mandel@1 2153 function_prefix = "__public_";
mandel@1 2154 } else if (!java_function->isFinalInCpp() && !java_function->isStatic() && hasShell) {
mandel@1 2155 function_prefix = "__override_";
eldar@21 2156 extra_param.append("__do_static_call");
mandel@1 2157 s << INDENT
maxter@355 2158 << "bool __do_static_call = "
maxter@355 2159 << "dynamic_cast<QtdObjectLink*>((" << java_class->polymorphicBase()->qualifiedCppName() << "*)__this_nativeId) != NULL;" << endl;
eldar@21 2160 } else {
mandel@1 2161 option = OriginalName;
mandel@1 2162 }
mandel@1 2163
mandel@1 2164 // Call the Qt function on the java object
mandel@1 2165 s << " ";
mandel@1 2166 if (has_function_type) {
mandel@1 2167 const QString qt_return_value = "__qt_return_value";
mandel@1 2168 const QString java_return_value = "__d_return_value";
mandel@1 2169 if (function_type) {
mandel@1 2170 writeTypeInfo(s, function_type, EnumAsInts);
mandel@1 2171 s << " " << qt_return_value
mandel@1 2172 << " = ";
mandel@1 2173 }
mandel@1 2174
mandel@1 2175 writeFunctionCall(s, qt_object_name, java_function, function_prefix, option,
mandel@1 2176 extra_param);
mandel@1 2177 s << endl;
mandel@1 2178
eldar@104 2179 writeRefArguments(s, java_function);
eldar@104 2180
mandel@1 2181 writeQtToJava(s, function_type, qt_return_value, java_return_value,
mandel@1 2182 java_function, 0, EnumAsInts);
mandel@1 2183
mandel@1 2184 // qtd s << INDENT << "QTJAMBI_DEBUG_TRACE(\"(native) -> leaving: "
mandel@1 2185 // << java_function_signature << "\");";
mandel@1 2186
mandel@1 2187 if (function_type && function_type->name() != "QModelIndex") {
mandel@1 2188 if(function_type->typeEntry()->isStructInD())
eldar@81 2189 ; //s << endl << INDENT << "return " << qt_return_value << ";";
mandel@1 2190 else if (!function_type->isTargetLangString() && !function_type->isContainer())
mandel@1 2191 s << endl << INDENT << "return " << java_return_value << ";";
mandel@1 2192 }
mandel@1 2193
mandel@1 2194 } else {
mandel@1 2195 writeFunctionCall(s, qt_object_name, java_function, function_prefix, option,
mandel@1 2196 extra_param);
eldar@104 2197 writeRefArguments(s, java_function);
mandel@1 2198 }
mandel@1 2199 }
mandel@1 2200 }
mandel@1 2201 if(!java_function->argumentReplaced(0).isEmpty()) {
mandel@1 2202 s << INDENT << "return 0;" << endl;
mandel@1 2203 }
mandel@1 2204
mandel@1 2205 s << endl << "}";
mandel@1 2206 s << endl << endl;
mandel@1 2207 }
mandel@1 2208
eldar@33 2209 void CppImplGenerator::writeRefArguments(QTextStream &s, const AbstractMetaFunction *java_function)
eldar@33 2210 {
eldar@33 2211 AbstractMetaArgumentList arguments = java_function->arguments();
eldar@33 2212 foreach (const AbstractMetaArgument *argument, arguments) {
eldar@33 2213 AbstractMetaType *d_type = argument->type();
eldar@33 2214 const TypeEntry *te = d_type->typeEntry();
eldar@33 2215 if ((te && d_type->isNativePointer() && te->name() == "QString"))
maxter@253 2216 s << QString(" qtd_toUtf8(__qt_%1.utf16(), __qt_%1.size(), &%1);").arg(argument->indexedName()) << endl;
eldar@33 2217 }
eldar@33 2218 }
eldar@33 2219
mandel@1 2220 void CppImplGenerator::writeAssignment(QTextStream &s, const QString &destName, const QString &srcName,
mandel@1 2221 const AbstractMetaType *java_type)
mandel@1 2222 {
mandel@1 2223 if (java_type->isArray()) {
mandel@1 2224 for (int i=0; i<java_type->arrayElementCount(); ++i) {
mandel@1 2225 writeAssignment(s, destName + "[" + QString::number(i) + "]",
mandel@1 2226 srcName + "[" + QString::number(i) + "]", java_type->arrayElementType());
mandel@1 2227 }
mandel@1 2228 } else {
mandel@1 2229 s << INDENT << destName << " = " << srcName << ";" << endl;
mandel@1 2230 }
mandel@1 2231 }
mandel@1 2232
mandel@1 2233 void CppImplGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *java_field)
mandel@1 2234 {
mandel@1 2235 Q_ASSERT(java_field);
mandel@1 2236 Q_ASSERT(java_field->isPublic() || java_field->isProtected());
mandel@1 2237
mandel@1 2238 const AbstractMetaFunction *setter = java_field->setter();
mandel@1 2239 const AbstractMetaFunction *getter = java_field->getter();
mandel@1 2240
mandel@1 2241 const AbstractMetaClass *cls = java_field->enclosingClass();
mandel@1 2242 FieldModification mod = cls->typeEntry()->fieldModification(java_field->name());
mandel@1 2243
mandel@1 2244 if(notWrappedYet(getter))
mandel@1 2245 return;
mandel@1 2246
mandel@1 2247 if (mod.isReadable()) {
mandel@1 2248 // Getter
mandel@1 2249 if (getter->wasProtected()) {
mandel@1 2250 writeFunctionSignature(s, getter, getter->ownerClass());
mandel@1 2251 s << endl
mandel@1 2252 << "{" << endl;
mandel@1 2253 {
mandel@1 2254 Indentation indent(INDENT);
mandel@1 2255 s << INDENT << "return " << java_field->name() << ";" << endl;
mandel@1 2256 }
mandel@1 2257 s << "}" << endl << endl;
mandel@1 2258 }
mandel@1 2259
mandel@1 2260
mandel@1 2261 writeFunctionName(s, getter, getter->ownerClass());
mandel@1 2262 s << endl;
mandel@1 2263 writeFinalFunctionArguments(s, getter);
mandel@1 2264 s << "{" << endl;
mandel@1 2265 {
mandel@1 2266 Indentation indent(INDENT);
mandel@1 2267
mandel@1 2268
mandel@1 2269 writeFinalFunctionSetup(s, getter, "__qt_object", getter->ownerClass());
mandel@1 2270
mandel@1 2271 const QString java_return_value = "__d_return_value";
mandel@1 2272 QString qt_return_value;
mandel@1 2273 if (setter->isStatic())
mandel@1 2274 qt_return_value = shellClassName(setter->ownerClass()) + "::";
mandel@1 2275 else
mandel@1 2276 qt_return_value = "__qt_object->";
mandel@1 2277
mandel@1 2278
mandel@1 2279 // To avoid "taking address of tmp"
mandel@1 2280 s << INDENT;
mandel@1 2281 writeTypeInfo(s, getter->type(), Option(ArrayAsPointer));
mandel@1 2282 QString tmp_name = "__tmp_" + getter->name();
mandel@1 2283 s << tmp_name << " = ";
mandel@1 2284
mandel@1 2285 if (getter->wasPublic())
mandel@1 2286 qt_return_value += java_field->name();
mandel@1 2287 else
mandel@1 2288 qt_return_value += getter->name() + "_getter()";
mandel@1 2289 s << qt_return_value << ";" << endl;
mandel@1 2290
mandel@1 2291 writeQtToJava(s, getter->type(), tmp_name, java_return_value, 0, -1, EnumAsInts);
eldar@33 2292 if (getter->type()->isTargetLangString() || getter->type()->name() == "QModelIndex")
mandel@1 2293 ;
mandel@1 2294 else if(getter->type()->typeEntry()->isStructInD())
eldar@81 2295 ; //s << INDENT << "return " << tmp_name << ";" << endl;
mandel@1 2296 else
mandel@1 2297 s << INDENT << "return " << java_return_value << ";" << endl;
mandel@1 2298 }
mandel@1 2299 s << "}" << endl << endl;
mandel@1 2300 }
mandel@1 2301
mandel@1 2302 if(notWrappedYet(setter))
mandel@1 2303 return;
mandel@1 2304
mandel@1 2305 // Setter
mandel@1 2306 if (mod.isWritable() && !java_field->type()->isConstant()) {
mandel@1 2307 // Write public override for protected fields
mandel@1 2308 if (setter->wasProtected()) {
mandel@1 2309 writeFunctionSignature(s, setter, setter->ownerClass());
mandel@1 2310 s << endl
mandel@1 2311 << "{" << endl;
mandel@1 2312 {
mandel@1 2313 Indentation indent(INDENT);
mandel@1 2314
mandel@1 2315 Q_ASSERT(setter->arguments().count() > 0);
mandel@1 2316 const AbstractMetaArgument *argument = setter->arguments().at(0);
mandel@1 2317
mandel@1 2318 QString thisRef = java_field->isStatic()
mandel@1 2319 ? setter->ownerClass()->qualifiedCppName() + QString("::")
mandel@1 2320 : QString("this->");
mandel@1 2321 writeAssignment(s, thisRef + java_field->name(), argument->indexedName(), argument->type());
mandel@1 2322 }
mandel@1 2323 s << "}" << endl << endl;
mandel@1 2324 }
mandel@1 2325
mandel@1 2326 writeFunctionName(s, setter, setter->ownerClass());
mandel@1 2327 s << endl;
mandel@1 2328 writeFinalFunctionArguments(s, setter);
mandel@1 2329 s << "{" << endl;
mandel@1 2330
mandel@1 2331 {
mandel@1 2332 Indentation indent(INDENT);
mandel@1 2333
mandel@1 2334 writeFinalFunctionSetup(s, setter, "__qt_object", setter->ownerClass());
mandel@1 2335
mandel@1 2336 Q_ASSERT(setter->arguments().count() == 1);
mandel@1 2337 const AbstractMetaArgument *argument = setter->arguments().at(0);
mandel@1 2338
mandel@1 2339 QString dest;
mandel@1 2340 if (setter->isStatic())
mandel@1 2341 dest = shellClassName(setter->ownerClass()) + "::";
mandel@1 2342 else
mandel@1 2343 dest = "__qt_object->";
mandel@1 2344
mandel@1 2345 QString src;
eldar@33 2346 if (!argument->type()->isPrimitive() && !argument->type()->typeEntry()->isStructInD()) {
mandel@1 2347 src = "__qt_" + argument->indexedName();
eldar@33 2348 } else if (argument->type()->name() == "QModelIndex") {
eldar@33 2349 src = "qtd_to_QModelIndex(" + argument->indexedName() + ")";
eldar@33 2350 } else
mandel@1 2351 src = argument->indexedName();
mandel@1 2352
mandel@1 2353 if (setter->wasPublic())
mandel@1 2354 writeAssignment(s, dest + java_field->name(), src, argument->type());
mandel@1 2355 else
mandel@1 2356 s << INDENT << dest << setter->name() << "_setter(" << src << ");" << endl;
mandel@1 2357 }
mandel@1 2358 s << "}" << endl << endl;
mandel@1 2359 }
mandel@1 2360 }
mandel@1 2361
mandel@1 2362 void CppImplGenerator::writeFinalDestructor(QTextStream &s, const AbstractMetaClass *cls)
mandel@1 2363 {
maxter@354 2364 if (cls->hasConstructors() && cls->isDestructorBase()) {
maxter@357 2365 s << INDENT << "QTD_EXTERN QTD_DLL_PUBLIC void qtd_" << cls->name() << "_delete(void* nativeId)" << endl
eldar@294 2366 << INDENT << "{" << endl
maxter@354 2367 << INDENT << " delete (" << shellClassName(cls) << "*)nativeId;" << endl
eldar@294 2368 << INDENT << "}" << endl << endl;
eldar@294 2369
maxter@357 2370 s << INDENT << "QTD_EXTERN QTD_DLL_PUBLIC void qtd_" << cls->name() << "_destroy(void* nativeId)" << endl
eldar@294 2371 << INDENT << "{" << endl
maxter@354 2372 << INDENT << " call_destructor((" << shellClassName(cls) << "*)nativeId);" << endl
eldar@294 2373 << INDENT << "}" << endl << endl;
mandel@1 2374 }
mandel@1 2375 }
mandel@1 2376
mandel@1 2377 void CppImplGenerator::writeFinalConstructor(QTextStream &s,
mandel@1 2378 const AbstractMetaFunction *java_function,
mandel@1 2379 const QString &qt_object_name,
eldar@293 2380 const QString &java_object_name,
eldar@293 2381 const QString &place)
mandel@1 2382 {
mandel@1 2383 const AbstractMetaClass *cls = java_function->ownerClass();
mandel@1 2384 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 2385 QString className = cls->typeEntry()->qualifiedCppName();
mandel@1 2386
mandel@1 2387 bool hasShellClass = cls->generateShellClass();
mandel@1 2388
mandel@1 2389 s << INDENT << shellClassName(cls) << " *" << qt_object_name
eldar@293 2390 << " = new " << place << shellClassName(cls)
mandel@1 2391 << "(";
mandel@1 2392 writeFunctionCallArguments(s, java_function, "__qt_");
mandel@1 2393 s << ");" << endl;
mandel@1 2394 s << INDENT << "return (void *) " << qt_object_name << ";" << endl; // qtd
mandel@1 2395
mandel@1 2396 /* qtd s << INDENT << "QtJambiLink *__qt_java_link = ";
mandel@1 2397 if (cls->isQObject()) {
mandel@1 2398 s << "qtjambi_construct_qobject(__jni_env, " << java_object_name << ", "
mandel@1 2399 << qt_object_name << ")";
mandel@1 2400 } else {
mandel@1 2401 s << "qtjambi_construct_object(__jni_env, " << java_object_name << ", " << qt_object_name;
mandel@1 2402 if (cls->typeEntry()->isValue())
mandel@1 2403 s << ", \"" << className << "\")";
mandel@1 2404 else // non-QObject, object type
mandel@1 2405 s << ", QMetaType::Void, QLatin1String(\"" << cls->fullName().replace(".", "/") << "\"), true)";
mandel@1 2406 }
mandel@1 2407 s << ";" << endl
mandel@1 2408 << INDENT << "if (!__qt_java_link) {" << endl;
mandel@1 2409 {
mandel@1 2410 Indentation indent(INDENT);
mandel@1 2411 s << INDENT << "qWarning(\"object construction failed for type: "
mandel@1 2412 << className << "\");" << endl
mandel@1 2413 << INDENT << "return;" << endl;
mandel@1 2414 }
mandel@1 2415 s << INDENT << "}" << endl;
mandel@1 2416
mandel@1 2417
mandel@1 2418 if (cls->isQObject()) {
mandel@1 2419 // Make sure all qobjects created by Java are owned by java only if
mandel@1 2420 // parent object has not been set.
mandel@1 2421 // All other objects will default to split ownership.
mandel@1 2422 s << INDENT << "if(!__qt_this->QObject::parent()){" << endl;
mandel@1 2423 s << INDENT << " __qt_java_link->setJavaOwnership(__jni_env, " << java_object_name << ");" << endl;
mandel@1 2424 s << INDENT << "}" << endl;
mandel@1 2425 } else {
mandel@1 2426 // All non-qobjects created by Java are owned by java
mandel@1 2427 s << INDENT << "__qt_java_link->setJavaOwnership(__jni_env, " << java_object_name << ");" << endl;
mandel@1 2428 }
mandel@1 2429
mandel@1 2430 if (hasCustomDestructor(cls)) {
mandel@1 2431 s << INDENT << "__qt_java_link->setDestructorFunction(qtjambi_destructor);" << endl;
mandel@1 2432 }
mandel@1 2433
mandel@1 2434 if (cls->typeEntry()->typeFlags() & ComplexTypeEntry::DeleteInMainThread)
mandel@1 2435 s << INDENT << "__qt_java_link->setDeleteInMainThread(true);" << endl;
mandel@1 2436
mandel@1 2437 if (!cls->hasVirtualFunctions() && !cls->hasInconsistentFunctions() && !cls->typeEntry()->isObject())
mandel@1 2438 return;
mandel@1 2439
mandel@1 2440 if (hasShellClass) {
mandel@1 2441 // Set up the link object
mandel@1 2442 s << INDENT << qt_object_name << "->m_link = __qt_java_link;" << endl;
mandel@1 2443
mandel@1 2444 // Make sure the user data in the QObject has bindings to the qobject's meta object
mandel@1 2445 // (this has to be done after the link is set, so that the fake meta object
mandel@1 2446 // can access the java object, for which it gets a reference in the link)
mandel@1 2447 if (cls->isQObject())
mandel@1 2448 s << INDENT << qt_object_name << "->m_link->setMetaObject(" << qt_object_name << "->metaObject());" << endl;
mandel@1 2449
mandel@1 2450 s << INDENT << qt_object_name << "->m_link->setCreatedByJava(true);" << endl;
mandel@1 2451
mandel@1 2452
mandel@1 2453
mandel@1 2454 AbstractMetaClassList interfaces = cls->interfaces();
mandel@1 2455 if (interfaces.size() + (cls->baseClass() != 0 ? 1 : 0) > 1) {
mandel@1 2456 if (cls->baseClass() != 0)
mandel@1 2457 interfaces += cls->baseClass();
mandel@1 2458 foreach (AbstractMetaClass *iface, interfaces) {
mandel@1 2459 AbstractMetaClass *impl = iface->isInterface() ? iface->primaryInterfaceImplementor() : iface;
mandel@1 2460 s << INDENT << qt_object_name << "->m_link->registerSubObject((" << impl->qualifiedCppName() << " *) " << qt_object_name << ");" << endl;
mandel@1 2461 }
mandel@1 2462 }
mandel@1 2463 }
mandel@1 2464
mandel@1 2465 if (!cls->hasVirtualFunctions() && !cls->hasInconsistentFunctions())
mandel@1 2466 return;
mandel@1 2467
mandel@1 2468 // Set up the vtable
mandel@1 2469 s << INDENT;
mandel@1 2470 QString space(24, ' ');
mandel@1 2471 if (hasShellClass)
mandel@1 2472 s << qt_object_name << "->m_vtable = ";
mandel@1 2473 s << "qtjambi_setup_vtable(__jni_env, " << endl << space << "__jni_object, " << endl;
mandel@1 2474
mandel@1 2475 if (cls->hasInconsistentFunctions()) {
mandel@1 2476 s << space << "qtjambi_inconsistent_count, " << endl
mandel@1 2477 << space << "qtjambi_inconsistent_names, " << endl
mandel@1 2478 << space << "qtjambi_inconsistent_signatures, " << endl;
mandel@1 2479 } else {
mandel@1 2480 s << space << "0, 0, 0, // no inconsistent functions" << endl;
mandel@1 2481 }
mandel@1 2482
mandel@1 2483 if (cls->hasVirtualFunctions()) {
mandel@1 2484 s << space << "qtjambi_method_count, " << endl
mandel@1 2485 << space << "qtjambi_method_names, " << endl
mandel@1 2486 << space << "qtjambi_method_signatures" << endl;
mandel@1 2487 } else {
mandel@1 2488 s << space << "0, 0, 0 // no virtual functions" << endl;
mandel@1 2489 }
mandel@1 2490
mandel@1 2491 s << space << ");" << endl; */
mandel@1 2492 }
mandel@1 2493
mandel@1 2494 void CppImplGenerator::writeSignalInitialization(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 2495 {
mandel@1 2496 if (!java_class->isQObject()
mandel@1 2497 || java_class->queryFunctions(AbstractMetaClass::Signals | AbstractMetaClass::Visible | AbstractMetaClass::NotRemovedFromTargetLang).size() == 0) {
mandel@1 2498 return ;
mandel@1 2499 }
mandel@1 2500
mandel@1 2501 s << jni_function_signature(java_class->package(), java_class->name(), "__qt_signalInitialization", "jboolean")
mandel@1 2502 << endl << "(JNIEnv *__jni_env, jobject java_object, jlong ptr, jstring java_signal_name)" << endl
mandel@1 2503 << "{" << endl
mandel@1 2504 << " QtJambiLink *link = (QtJambiLink *) ptr;" << endl
mandel@1 2505 << " if (link == 0)" << endl
mandel@1 2506 << " return true;" << endl << endl
mandel@1 2507 << " QObject *qt_this = link->qobject();" << endl
mandel@1 2508 << " Q_ASSERT(qt_this);" << endl << endl
mandel@1 2509 << " QtJambi_SignalWrapper_" << java_class->name() << " *qt_wrapper = "
mandel@1 2510 << " (QtJambi_SignalWrapper_" << java_class->name() << " *) link->signalWrapper();" << endl
mandel@1 2511 << " if (qt_wrapper == 0) {" << endl
mandel@1 2512 << " qt_wrapper = new QtJambi_SignalWrapper_" << java_class->name() << ";" << endl
mandel@1 2513 << " link->setSignalWrapper(qt_wrapper);" << endl
mandel@1 2514 << " qt_wrapper->link = link;" << endl << endl
mandel@1 2515 << " qtjambi_resolve_signals(__jni_env," << endl
mandel@1 2516 << " java_object," << endl
mandel@1 2517 << " qt_wrapper->m_signals," << endl
mandel@1 2518 << " qtjambi_signal_count," << endl
mandel@1 2519 << " (char **) qtjambi_signal_names," << endl
mandel@1 2520 << " (int *) qtjambi_signal_argumentcounts);" << endl
mandel@1 2521 << " }" << endl
mandel@1 2522 << " QString signal_name = qtjambi_to_qstring(__jni_env, java_signal_name);" << endl
mandel@1 2523 << " return qtjambi_connect_cpp_to_java(__jni_env," << endl
mandel@1 2524 << " signal_name," << endl
mandel@1 2525 << " qt_this," << endl
mandel@1 2526 << " qt_wrapper," << endl
mandel@1 2527 << " QLatin1String(\"" << java_class->fullName() << "\")," << endl
mandel@1 2528 << " QLatin1String(\"" << signalWrapperPrefix() << "\"));" << endl
mandel@1 2529 << "}";
mandel@1 2530 }
mandel@1 2531
mandel@1 2532 QString CppImplGenerator::fromObject(const TypeEntry *entry,
mandel@1 2533 const QString &var_name)
mandel@1 2534 {
mandel@1 2535 QString returned;
mandel@1 2536 QString package = entry->javaPackage();
mandel@1 2537 const ComplexTypeEntry *centry = entry->isComplex()
mandel@1 2538 ? static_cast<const ComplexTypeEntry *>(entry)
mandel@1 2539 : 0;
mandel@1 2540
mandel@1 2541 if (centry == 0 || centry->polymorphicIdValue().isEmpty()) {
mandel@1 2542 /* qtd returned = "qtjambi_from_object(__jni_env, " + var_name + ", \""
mandel@1 2543 + entry->lookupName()
mandel@1 2544 + "\", \"" + QString(package).replace(".", "/") + "/\", true);";
mandel@1 2545 */
mandel@1 2546 if(entry->isObject())
mandel@1 2547 returned = var_name + ";";
mandel@1 2548 else
mandel@1 2549 returned = "new " + entry->lookupName() + "(" + var_name +");";
mandel@1 2550 } else {
mandel@1 2551 AbstractMetaClass *cls = classes().findClass(centry->qualifiedCppName());
mandel@1 2552 if (!cls) {
mandel@1 2553 qFatal("CppImplGenerator::fromObject(): class '%s' could not be resolved...",
mandel@1 2554 qPrintable(centry->qualifiedCppName()));
mandel@1 2555 }
mandel@1 2556
mandel@1 2557 while (cls != 0 && !cls->typeEntry()->isPolymorphicBase())
mandel@1 2558 cls = cls->baseClass();
mandel@1 2559
mandel@1 2560 QString full_name;
mandel@1 2561 if (cls != 0) {
mandel@1 2562 full_name = cls->fullName();
mandel@1 2563 } else {
mandel@1 2564 ReportHandler::warning(QString("class '%1' has polymorphic id but does not inherit a polymorphic class")
mandel@1 2565 .arg(centry->qualifiedCppName()));
mandel@1 2566 }
mandel@1 2567 /* qtd
mandel@1 2568 returned = "qtjambi_from_object(__jni_env, " + var_name + ", \""
mandel@1 2569 + centry->lookupName()
mandel@1 2570 + "\", \"" + QString(package).replace(".", "/") + "/\","
mandel@1 2571 + "\"" + jni_signature(full_name, Underscores) + "\", true); // fucking complex";
mandel@1 2572 */
mandel@1 2573 if(entry->isObject())
mandel@1 2574 returned = var_name + "; // complex entry";
mandel@1 2575 else
mandel@1 2576 returned = "new " + centry->lookupName() + "(" + var_name +"); // complex entry";
mandel@1 2577 }
mandel@1 2578
mandel@1 2579 return returned;
mandel@1 2580 }
mandel@1 2581
mandel@1 2582 void CppImplGenerator::writeOriginalMetaObjectFunction(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 2583 {
mandel@1 2584 Q_ASSERT(java_class->isQObject());
mandel@1 2585
mandel@1 2586 s << jni_function_signature(java_class->package(),
mandel@1 2587 java_class->name(),
mandel@1 2588 "originalMetaObject",
mandel@1 2589 "jlong");
mandel@1 2590
mandel@1 2591 s << endl
mandel@1 2592 << "(JNIEnv *," << endl
mandel@1 2593 << " jclass)" << endl
mandel@1 2594 << "{" << endl;
mandel@1 2595 {
mandel@1 2596 Indentation indent(INDENT);
mandel@1 2597 s << INDENT << "return reinterpret_cast<jlong>(&" << java_class->qualifiedCppName() << "::staticMetaObject);" << endl;
mandel@1 2598 }
mandel@1 2599 s << "}" << endl << endl;
mandel@1 2600 }
mandel@1 2601
mandel@1 2602 void CppImplGenerator::writeFromNativeFunction(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 2603 {
mandel@1 2604 s << jni_function_signature(java_class->package(),
mandel@1 2605 java_class->name(),
mandel@1 2606 "fromNativePointer",
mandel@1 2607 "jobject");
mandel@1 2608 s << endl
mandel@1 2609 << "(JNIEnv *__jni_env," << endl
mandel@1 2610 << " jclass," << endl
mandel@1 2611 << " jobject nativePointer)" << endl
mandel@1 2612 << "{" << endl;
mandel@1 2613 {
mandel@1 2614 Indentation indent(INDENT);
mandel@1 2615 s << INDENT << "void *ptr = qtjambi_to_cpointer(__jni_env, nativePointer, 1);" << endl
mandel@1 2616 << INDENT << "return " << fromObject(java_class->typeEntry(), "ptr") << endl
mandel@1 2617 << "}" << endl;
mandel@1 2618 }
mandel@1 2619 }
mandel@1 2620
mandel@1 2621 void CppImplGenerator::writeFromArrayFunction(QTextStream &s, const AbstractMetaClass *java_class)
mandel@1 2622 {
mandel@1 2623 s << jni_function_signature(java_class->package(),
mandel@1 2624 java_class->name(),
mandel@1 2625 "nativePointerArray",
mandel@1 2626 "jobject");
mandel@1 2627 s << endl
mandel@1 2628 << "(JNIEnv *__jni_env," << endl
mandel@1 2629 << " jclass," << endl
mandel@1 2630 << " jobjectArray array)" << endl
mandel@1 2631 << "{" << endl;
mandel@1 2632 {
mandel@1 2633 Indentation indent(INDENT);
mandel@1 2634 s << INDENT << "return qtjambi_array_to_nativepointer(__jni_env, " << endl
mandel@1 2635 << INDENT << " array, " << endl
mandel@1 2636 << INDENT << " sizeof("
mandel@1 2637 << java_class->qualifiedCppName() << "));" << endl;
mandel@1 2638 }
mandel@1 2639 s << "}" << endl;
mandel@1 2640 }
mandel@1 2641
mandel@1 2642
mandel@1 2643 void CppImplGenerator::writeInterfaceCastFunction(QTextStream &s,
mandel@1 2644 const AbstractMetaClass *java_class,
mandel@1 2645 const AbstractMetaClass *interface)
mandel@1 2646 {
mandel@1 2647 Q_ASSERT(interface->isInterface());
mandel@1 2648 const InterfaceTypeEntry *ie = static_cast<const InterfaceTypeEntry *>(interface->typeEntry());
mandel@1 2649 QString interface_name = ie->origin()->targetLangName();
mandel@1 2650
mandel@1 2651 s << endl
mandel@1 2652 << jni_function_signature(java_class->package(),
mandel@1 2653 java_class->name(),
mandel@1 2654 QString("__qt_cast_to_%1").arg(interface_name),
mandel@1 2655 "jlong",
mandel@1 2656 "__J");
mandel@1 2657
mandel@1 2658 s << endl
mandel@1 2659 << "(JNIEnv *," << endl
mandel@1 2660 << " jobject," << endl
mandel@1 2661 << " jlong ptr)" << endl
mandel@1 2662 << "{" << endl
mandel@1 2663 << " return (jlong) (" << interface->primaryInterfaceImplementor()->qualifiedCppName() << " *) "
mandel@1 2664 << "(" << java_class->qualifiedCppName() << " *) ptr;" << endl
mandel@1 2665 << "}" << endl;
mandel@1 2666 }
mandel@1 2667
mandel@1 2668 bool CppImplGenerator::writeConversionRule(QTextStream &s,
mandel@1 2669 TypeSystem::Language target_language,
mandel@1 2670 const AbstractMetaFunction *java_function,
mandel@1 2671 int argument_index,
mandel@1 2672 const QString &qt_name,
mandel@1 2673 const QString &java_name)
mandel@1 2674 {
mandel@1 2675 if (argument_index < 0 || java_function == 0)
mandel@1 2676 return false;
mandel@1 2677
mandel@1 2678 QString conversion_rule = java_function->conversionRule(target_language, argument_index);
mandel@1 2679
mandel@1 2680 if (!conversion_rule.isEmpty()) {
mandel@1 2681 QString qt_name_var;
mandel@1 2682 QString java_name_var;
mandel@1 2683
mandel@1 2684 if ((argument_index == 0 && target_language == TypeSystem::NativeCode)
mandel@1 2685 || (argument_index != 0 && target_language == TypeSystem::ShellCode)) {
mandel@1 2686 qt_name_var = "%in";
mandel@1 2687 java_name_var = "%out";
mandel@1 2688 } else {
mandel@1 2689 qt_name_var = "%out";
mandel@1 2690 java_name_var = "%in";
mandel@1 2691 }
mandel@1 2692
mandel@1 2693 conversion_rule = conversion_rule.replace(qt_name_var, qt_name)
mandel@1 2694 .replace(java_name_var, java_name);
mandel@1 2695
mandel@1 2696 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 2697 for (int i=0; i<arguments.size(); ++i) {
mandel@1 2698 conversion_rule = conversion_rule.replace("%" + QString::number(i+1),
mandel@1 2699 arguments.at(i)->indexedName());
mandel@1 2700 }
mandel@1 2701
mandel@1 2702 QStringList lines = conversion_rule.split("\n");
mandel@1 2703 foreach (QString line, lines) {
mandel@1 2704 s << INDENT << line.trimmed() << endl;
mandel@1 2705 }
mandel@1 2706
mandel@1 2707 return true;
mandel@1 2708 } else {
mandel@1 2709 return false;
mandel@1 2710 }
mandel@1 2711 }
mandel@1 2712
mandel@1 2713
mandel@1 2714 void CppImplGenerator::writeJavaToQt(QTextStream &s,
mandel@1 2715 const AbstractMetaClass *java_class,
mandel@1 2716 const AbstractMetaType *function_return_type,
mandel@1 2717 const QString &qt_name,
mandel@1 2718 const QString &java_name,
mandel@1 2719 const AbstractMetaFunction *java_function,
mandel@1 2720 int argument_index)
mandel@1 2721 {
mandel@1 2722 // Conversion to C++: Shell code for return values, native code for arguments
mandel@1 2723 TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode;
mandel@1 2724 if (writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
mandel@1 2725 return;
mandel@1 2726
mandel@1 2727 s << INDENT << shellClassName(java_class) << " *" << qt_name << " = ("
mandel@1 2728 << shellClassName(java_class) << " *) ";
mandel@1 2729 if (java_class->isQObject())
mandel@1 2730 s << "qtjambi_to_qobject";
mandel@1 2731 else
mandel@1 2732 s << "qtjambi_to_object";
mandel@1 2733 s << "(__jni_env, " << java_name << ");" << endl;
mandel@1 2734 if (java_class->isQObject()) {
mandel@1 2735 // ### throw exceptions when objects are null...
mandel@1 2736 s << INDENT << "if (!" << qt_name << ") "
mandel@1 2737 << default_return_statement_java(function_return_type) << ";" << endl << endl;
mandel@1 2738 }
mandel@1 2739 }
mandel@1 2740
mandel@1 2741
mandel@1 2742 void CppImplGenerator::writeJavaToQt(QTextStream &s,
mandel@1 2743 const AbstractMetaType *java_type,
mandel@1 2744 const QString &qt_name,
mandel@1 2745 const QString &java_name,
mandel@1 2746 const AbstractMetaFunction *java_function,
mandel@1 2747 int argument_index,
mandel@1 2748 Option options)
mandel@1 2749 {
mandel@1 2750 // Conversion to C++: Shell code for return values, native code for arguments
mandel@1 2751 TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode;
mandel@1 2752 if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
mandel@1 2753 return;
mandel@1 2754
mandel@1 2755 if (java_type == 0) {
mandel@1 2756 QString warn = QString("no conversion possible for argument '%1' in function '%2::%3' for "
mandel@1 2757 "language '%4'")
mandel@1 2758 .arg(argument_index)
mandel@1 2759 .arg(java_function->implementingClass()->name())
mandel@1 2760 .arg(java_function->name())
mandel@1 2761 .arg(int(lang));
mandel@1 2762 ReportHandler::warning(warn);
mandel@1 2763 return;
mandel@1 2764 }
mandel@1 2765 if (java_type->name() == "QModelIndex") {
mandel@1 2766 s << INDENT << "QModelIndex " << qt_name << " = qtd_to_QModelIndex("
mandel@1 2767 << java_name << ");" << endl;
mandel@1 2768 } else if (java_type->typeEntry()->isStructInD()) {
mandel@1 2769 // empty
mandel@1 2770 } else if (java_type->typeEntry() && java_type->typeEntry()->qualifiedCppName() == "QString") {
mandel@1 2771 s << INDENT << "QString " << qt_name
eldar@33 2772 << " = " << QString("QString::fromUtf8((const char *)%1.ptr, %1.length);").arg(java_name) << endl;
mandel@1 2773 } else if (java_type->isJObjectWrapper()) {
mandel@1 2774 s << INDENT << "JObjectWrapper " << qt_name
mandel@1 2775 << " = qtjambi_to_jobjectwrapper(__jni_env, " << java_name << ");" << endl;
mandel@1 2776 } else if (java_type->isVariant()) {
mandel@1 2777 s << INDENT << "QVariant " << qt_name
mandel@1 2778 << " = " << java_name << " == NULL ? QVariant() : QVariant(*" << java_name << ");" << endl;
mandel@1 2779 } else if (java_type->isArray() && java_type->arrayElementType()->isPrimitive()) {
mandel@1 2780 AbstractMetaType *elementType = java_type->arrayElementType();
mandel@1 2781
mandel@1 2782 // ### Don't assert on wrong array lengths
eldar@33 2783 // s << INDENT << "Q_ASSERT(__jni_env->GetArrayLength((jarray) " << java_name << ") == " << java_type->arrayElementCount() << ");" << endl;
mandel@1 2784 s << INDENT;
mandel@1 2785 writeTypeInfo(s, elementType);
eldar@33 2786 s << " *" << qt_name << " = (";
eldar@33 2787 writeTypeInfo(s, elementType);
eldar@33 2788 s << "*) " << java_name << ";" << endl;
eldar@33 2789 /*
mandel@1 2790 s << INDENT << "__jni_env->" << getXxxArrayRegion(elementType) << "( (" << translateType(java_type, options)
mandel@1 2791 << ")" << java_name << ", 0, " << java_type->arrayElementCount() << ", "
mandel@1 2792 << "(" << translateType(elementType, options) << " *" << ")"
mandel@1 2793 << qt_name << ");" << endl;
eldar@33 2794 */
mandel@1 2795 } else if (java_type->isArray()) {
mandel@1 2796 AbstractMetaType *elementType = java_type->arrayElementType();
mandel@1 2797
mandel@1 2798 s << INDENT << "Q_ASSERT(__jni_env->GetArrayLength((jarray) " << java_name << ") == " << java_type->arrayElementCount() << ");" << endl;
mandel@1 2799 writeTypeInfo(s, elementType);
mandel@1 2800 s << "[" << java_type->arrayElementCount() << "]" << qt_name << ";" << endl;
mandel@1 2801
mandel@1 2802 for (int i=0; i<java_type->arrayElementCount(); ++i) {
mandel@1 2803 writeJavaToQt(s, elementType, qt_name + "[" + QString::number(i) + "]",
mandel@1 2804 "__jni_env->GetObjectArrayElement(" + java_name + ", " + QString::number(i) + ")", 0, -1, options);
mandel@1 2805 }
mandel@1 2806
mandel@1 2807 } else if (java_type->isTargetLangString()) {
mandel@1 2808 s << INDENT << "QString " << qt_name
mandel@1 2809 << " = " << "QString::fromUtf8(" << java_name << ", " << java_name << "_size);" << endl;
mandel@1 2810 // qtd << " = qtjambi_to_qstring(__jni_env, (jstring) " << java_name << ");" << endl;
mandel@1 2811
mandel@1 2812 } else if (java_type->isTargetLangChar()) {
mandel@1 2813 s << INDENT << "QChar " << qt_name
mandel@1 2814 << " = (ushort)" << java_name << ";" << endl;
mandel@1 2815
mandel@1 2816 } else if (java_type->isEnum() || java_type->isFlags()) {
mandel@1 2817
mandel@1 2818 bool written = false;
mandel@1 2819 if (java_type->isEnum()) {
mandel@1 2820 AbstractMetaEnum *java_enum =
mandel@1 2821 m_classes.findEnum(static_cast<const EnumTypeEntry *>(java_type->typeEntry()));
mandel@1 2822 if (java_enum && !java_enum->isPublic()) {
mandel@1 2823
mandel@1 2824 s << INDENT << "int " << qt_name << " = ";
mandel@1 2825 written = true;
mandel@1 2826 }
mandel@1 2827 }
mandel@1 2828
mandel@1 2829 if (!written) {
mandel@1 2830 QString qualified_name = java_type->typeEntry()->qualifiedCppName();
mandel@1 2831 s << INDENT << qualified_name << " " << qt_name
mandel@1 2832 << " = (" << qualified_name << ") ";
mandel@1 2833 }
mandel@1 2834
mandel@1 2835 if ((options & EnumAsInts) == 0 && (java_type->isTargetLangEnum() || java_type->isTargetLangFlags())) {
eldar@33 2836 s << java_name << ";" << endl;
mandel@1 2837
mandel@1 2838 } else if (options & BoxedPrimitive) {
mandel@1 2839 const PrimitiveTypeEntry *pentry = TypeDatabase::instance()->findTargetLangPrimitiveType("int");
mandel@1 2840 Q_ASSERT(pentry);
mandel@1 2841
mandel@1 2842 s << java_name << ";" << endl;
mandel@1 2843
mandel@1 2844 } else {
mandel@1 2845 s << java_name << ';' << endl;
mandel@1 2846 }
mandel@1 2847
mandel@1 2848 } else if (java_type->isContainer()) {
mandel@1 2849 writeJavaToQtContainer(s, java_type, qt_name, java_name, 0, -1);
mandel@1 2850
mandel@1 2851 } else if (java_type->isThread()) {
mandel@1 2852 s << INDENT << "QThread *" << qt_name << " = qtjambi_to_thread(__jni_env, " << java_name
mandel@1 2853 << ");" << endl;
mandel@1 2854
mandel@1 2855 } else if (java_type->typeEntry()->isCustom()) {
mandel@1 2856 const CustomTypeEntry *custom_type =
mandel@1 2857 static_cast<const CustomTypeEntry *>(java_type->typeEntry());
mandel@1 2858 s << INDENT;
mandel@1 2859 custom_type->generateCppJavaToQt(s, java_type, "__jni_env", qt_name, java_name);
mandel@1 2860 s << ";" << endl;
mandel@1 2861
mandel@1 2862 } else {
mandel@1 2863
mandel@1 2864 const TypeEntry *type = java_type->typeEntry();
mandel@1 2865 QString class_name = type->name();
mandel@1 2866 QString qualified_class_name = fixCppTypeName(type->qualifiedCppName());
mandel@1 2867
mandel@1 2868 // Declaration and the c-cast
mandel@1 2869 s << INDENT;
mandel@1 2870 writeTypeInfo(s, java_type);
mandel@1 2871 s << ' ' << qt_name << " = (";
mandel@1 2872 writeTypeInfo(s, java_type);
mandel@1 2873 s << ") ";
mandel@1 2874
mandel@1 2875 if (java_type->isPrimitive()) {
mandel@1 2876 if (options & BoxedPrimitive) {
mandel@1 2877 const PrimitiveTypeEntry *pentry = static_cast<const PrimitiveTypeEntry *>(type);
mandel@1 2878 //std::cout << "---error_here " << type->targetLangName().toStdString() << " \n";
mandel@1 2879 //std::cout << "----func_here " << java_function->marshalledName().toStdString() << " \n";
mandel@1 2880
mandel@1 2881 if (!pentry->preferredConversion())
mandel@1 2882 pentry = TypeDatabase::instance()->findTargetLangPrimitiveType(pentry->targetLangName());
mandel@1 2883 Q_ASSERT(pentry);
mandel@1 2884
mandel@1 2885 s << java_name << ";" << endl;
mandel@1 2886
mandel@1 2887 } else if ((options & GlobalRefJObject) && type->jniName() == QLatin1String("jobject")) {
mandel@1 2888 s << "__jni_env->NewGlobalRef(" << java_name << ");" << endl;
mandel@1 2889 } else {
mandel@1 2890 s << java_name << ';' << endl;
mandel@1 2891 }
mandel@1 2892
mandel@1 2893 #if 0
mandel@1 2894 } else if (java_type->isEnum()) {
mandel@1 2895 s << "qtjambi_to_enum(__jni_env, " << java_name << ");" << endl;
mandel@1 2896 #endif
mandel@1 2897
mandel@1 2898 } else if ((java_type->isQObject() || java_type->isObject())
mandel@1 2899 && static_cast<const ObjectTypeEntry *>(type)->designatedInterface()) {
mandel@1 2900 /* qtd const InterfaceTypeEntry *ie =
mandel@1 2901 static_cast<const ObjectTypeEntry *>(type)->designatedInterface();
mandel@1 2902 s << "qtjambi_to_interface(__jni_env, ";
mandel@1 2903
mandel@1 2904 // This cast is only valid if we're dealing with a native id
mandel@1 2905 if ((options & UseNativeIds) == UseNativeIds)
mandel@1 2906 s << "(QtJambiLink *)";
mandel@1 2907 */
mandel@1 2908 s << java_name << ";" << endl;
mandel@1 2909 /* qtd
mandel@1 2910 s << "\"" << ie->targetLangName() << "\", \""
mandel@1 2911 << ie->javaPackage().replace(".", "/") << "/\", "
mandel@1 2912 << "\"__qt_cast_to_" << type->targetLangName() << "\");" << endl;
mandel@1 2913 */
mandel@1 2914 } else if (java_type->isObject() || java_type->isQObject() || java_type->isNativePointer()) {
mandel@1 2915 if (java_type->isReference()) {
mandel@1 2916 s << "* (" << qualified_class_name << " "
mandel@1 2917 << QString(java_type->actualIndirections(), '*') << ") ";
mandel@1 2918 }
mandel@1 2919
mandel@1 2920 if (java_type->isNativePointer()) {
mandel@1 2921 /* qtd s << "qtjambi_to_cpointer("
mandel@1 2922 << "__jni_env, "
mandel@1 2923 << java_name << ", "
mandel@1 2924 << java_type->actualIndirections() << ");" << endl; */
mandel@1 2925 s << java_name << ";" << endl; // qtd
mandel@1 2926 }/* qtd else if (java_type->isQObject()) {
mandel@1 2927 if ((options & UseNativeIds) == 0)
mandel@1 2928 s << "qtjambi_to_qobject(__jni_env, ";
mandel@1 2929 else
mandel@1 2930 s << "qtjambi_from_jlong(";
mandel@1 2931 s << java_name;
mandel@1 2932 s << ");" << endl;
mandel@1 2933 }*/ else {
mandel@1 2934 /* qtd if ((options & UseNativeIds) == 0)
mandel@1 2935 s << "qtjambi_to_object(__jni_env, ";
mandel@1 2936 else
mandel@1 2937 s << "qtjambi_from_jlong(";
mandel@1 2938 */ s << java_name;
mandel@1 2939 s << ";" << endl; // +
mandel@1 2940 // qtd s << ");" << endl;
mandel@1 2941 }
mandel@1 2942
mandel@1 2943 } else {
mandel@1 2944 // Return values...
mandel@1 2945 if (argument_index == 0) {
mandel@1 2946 s << "(" << java_name << " != 0 ? *(" << qualified_class_name << " *)";
mandel@1 2947 /* qtd if ((options & UseNativeIds) == 0)
mandel@1 2948 s << "qtjambi_to_object(__jni_env, ";
mandel@1 2949 else
mandel@1 2950 s << "qtjambi_from_jlong(";
mandel@1 2951 */ s << java_name;
mandel@1 2952 s << " : " << qualified_class_name << "());" << endl;
mandel@1 2953 } else {
mandel@1 2954 s << "*"
mandel@1 2955 << "(" << qualified_class_name << " *)";
mandel@1 2956 bool null_check = false;
mandel@1 2957 /* qtd if ((options & UseNativeIds) == 0) {
mandel@1 2958 s << "qtjambi_to_object(__jni_env, ";
mandel@1 2959 } else if (hasDefaultConstructor(java_type)) {
mandel@1 2960 null_check = true;
mandel@1 2961 s << "(" << java_name << " != 0 ? qtjambi_from_jlong(";
mandel@1 2962 } else {
mandel@1 2963 s << "qtjambi_from_jlong(";
mandel@1 2964 }
mandel@1 2965 */ s << java_name;
mandel@1 2966 // qtd s << ")";
mandel@1 2967
mandel@1 2968 if (null_check)
mandel@1 2969 s << " : default_" << QString(qualified_class_name).replace("::", "_") << "())";
mandel@1 2970 s << ";" << endl;
mandel@1 2971 }
mandel@1 2972
mandel@1 2973 }
mandel@1 2974 }
mandel@1 2975 // qtd s << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl;
mandel@1 2976 }
mandel@1 2977
mandel@1 2978 void CppImplGenerator::writeQtToJava(QTextStream &s,
mandel@1 2979 const AbstractMetaType *java_type,
mandel@1 2980 const QString &qt_name,
mandel@1 2981 const QString &java_name,
mandel@1 2982 const AbstractMetaFunction *java_function,
mandel@1 2983 int argument_index,
mandel@1 2984 Option option)
mandel@1 2985 {
mandel@1 2986
mandel@1 2987 // Conversion to Java: Native code for return values, shell code for arguments
mandel@1 2988 TypeSystem::Language lang = argument_index == 0 ? TypeSystem::NativeCode : TypeSystem::ShellCode;
mandel@1 2989 /* qtd if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
mandel@1 2990 return;
mandel@1 2991 */
mandel@1 2992 if (java_type == 0) {
mandel@1 2993 QString warn = QString("no conversion possible for argument '%1' in function '%2::%3' for "
mandel@1 2994 "language '%4'")
mandel@1 2995 .arg(argument_index)
mandel@1 2996 .arg(java_function->implementingClass()->name())
mandel@1 2997 .arg(java_function->name())
mandel@1 2998 .arg(int(lang));
mandel@1 2999 ReportHandler::warning(warn);
mandel@1 3000 return;
mandel@1 3001 }
mandel@1 3002
mandel@1 3003 if (java_type->name() == "QModelIndex") {
mandel@1 3004 QString prefix = "*";
mandel@1 3005 if (option & BoxedPrimitive)
mandel@1 3006 s << INDENT << "QModelIndexAccessor tmp_index = qtd_from_QModelIndex(" << qt_name << ");" << endl
mandel@1 3007 << INDENT << "QModelIndexAccessor *" << java_name << " = &tmp_index;" << endl;
mandel@1 3008 else
mandel@1 3009 s << INDENT << "*" << java_name << " = qtd_from_QModelIndex(" << qt_name << ");" << endl;
mandel@1 3010
eldar@81 3011 } else if (java_type->typeEntry()->isStructInD()) {
eldar@81 3012 if (option & BoxedPrimitive) {
eldar@81 3013 s << INDENT << java_type->typeEntry()->name() << " *" << java_name << " = ("
eldar@81 3014 << java_type->typeEntry()->name() << " *) &" << qt_name << ";" << endl;
eldar@81 3015 } else {
eldar@81 3016 s << INDENT << "*" << java_name << " = " << qt_name << ";" << endl;
eldar@81 3017 }
mandel@1 3018 } else if (java_type->isArray() && java_type->arrayElementType()->isPrimitive()) {
mandel@1 3019 AbstractMetaType *elementType = java_type->arrayElementType();
eldar@33 3020 /* qtd
mandel@1 3021 s << INDENT << translateType(java_type, option) << " " << java_name << " = __jni_env->" << newXxxArray(elementType)
mandel@1 3022 << "(" << java_type->arrayElementCount() << ");" << endl;
mandel@1 3023
mandel@1 3024 s << INDENT << "__jni_env->" << setXxxArrayRegion(elementType) << "("
mandel@1 3025 << "(" << translateType(java_type, option) << ")" << java_name
mandel@1 3026 << ", 0, " << java_type->arrayElementCount() << ", "
mandel@1 3027 << "(" << translateType(elementType, option) << " *" << ")"
mandel@1 3028 << qt_name << ");" << endl;
eldar@33 3029 */
eldar@33 3030 s << INDENT << translateType(java_type, option) << " " << java_name << " = " << qt_name << ";" <<endl;
mandel@1 3031 } else if (java_type->isArray()) {
mandel@1 3032 AbstractMetaType *elementType = java_type->arrayElementType();
mandel@1 3033
mandel@1 3034 s << INDENT << "jobject " << java_name << " = __jni_env->NewObjectArray("
mandel@1 3035 << java_type->arrayElementCount() << ");" << endl;
mandel@1 3036
mandel@1 3037 s << "jobject __qt_element = 0;";
mandel@1 3038
mandel@1 3039 for (int i=0; i<java_type->arrayElementCount(); ++i) {
mandel@1 3040 writeQtToJava(s, elementType, qt_name + "[" + QString::number(i) + "]",
mandel@1 3041 "__qt_element", 0, -1, option);
mandel@1 3042 s << "__jni_env->SetObjectArrayElement((jobjectArray) " << java_name << ", "
mandel@1 3043 << i << ", __qt_element);" << endl;
mandel@1 3044 }
mandel@1 3045
mandel@1 3046 } else if (java_type->isPrimitive()) {
mandel@1 3047 const PrimitiveTypeEntry *type =
mandel@1 3048 static_cast<const PrimitiveTypeEntry *>(java_type->typeEntry());
mandel@1 3049
mandel@1 3050 Q_ASSERT(type);
mandel@1 3051 QString ret_val;
mandel@1 3052 if (java_function)
mandel@1 3053 ret_val = jniReturnName(java_function);
mandel@1 3054 else
mandel@1 3055 ret_val = fixCppTypeName(java_type->typeEntry()->qualifiedCppName());
mandel@1 3056 s << INDENT << ret_val << " " << java_name << " = " << qt_name << ";" << endl;
mandel@1 3057 } else if (java_type->isJObjectWrapper()) {
mandel@1 3058 s << INDENT << "jobject " << java_name << " = qtjambi_from_jobjectwrapper(__jni_env, "
mandel@1 3059 << qt_name << ");" << endl;
mandel@1 3060 } else if (java_type->isVariant()) {
mandel@1 3061 s << INDENT << "QVariant *" << java_name
mandel@1 3062 << " = new QVariant(" << qt_name << ");" << endl;
mandel@1 3063 } else if (java_type->isTargetLangString()) {
eldar@35 3064 if(java_type->typeEntry()->qualifiedCppName() == "QStringRef") {
eldar@35 3065 s << INDENT << "const QString *str_ref = " << qt_name << ".string();" << endl
eldar@35 3066 << INDENT << "if(str_ref)" << endl
maxter@253 3067 << INDENT << " qtd_toUtf8(str_ref->utf16(), str_ref->size(), " << java_name << ");" << endl
eldar@35 3068 << INDENT << "else {" << endl
eldar@35 3069 << INDENT << " QString empty_str;" << endl
maxter@253 3070 << INDENT << " qtd_toUtf8(empty_str.utf16(), empty_str.size(), " << java_name << ");" << endl
eldar@35 3071 << INDENT << "}" << endl;
eldar@35 3072 } else {
maxter@253 3073 s << INDENT << QString("qtd_toUtf8(%1.utf16(), %1.size(), %2);").arg(qt_name, java_name) << endl;
eldar@35 3074 }
mandel@1 3075 } else if (java_type->isTargetLangChar()) {
mandel@1 3076 s << INDENT << "jchar " << java_name << " = " << qt_name << ".unicode();" << endl;
mandel@1 3077
mandel@1 3078 } else if (java_type->isIntegerEnum() || java_type->isIntegerFlags()
mandel@1 3079 || ((option & EnumAsInts) && (java_type->isEnum() || java_type->isFlags()))) {
mandel@1 3080 // } else if (java_type->isEnum() || java_type->isFlags()) {
mandel@1 3081
mandel@1 3082 // if (option & EnumAsInts) {
mandel@1 3083 // qDebug() << java_type->name() << "should be int...";
mandel@1 3084 // }
mandel@1 3085
mandel@1 3086 /* if (option & BoxedPrimitive) {
mandel@1 3087 s << INDENT << "jobject " << java_name << " = qtjambi_from_int(__jni_env, "
mandel@1 3088 << qt_name << ");" << endl;
mandel@1 3089 } else */{
mandel@1 3090 s << INDENT << "int " << java_name << " = " << qt_name << ";" << endl;
mandel@1 3091 }
mandel@1 3092
mandel@1 3093 } else if (java_type->isTargetLangEnum()) {
mandel@1 3094 Q_ASSERT((option & EnumAsInts) == 0);
mandel@1 3095 const EnumTypeEntry *et = static_cast<const EnumTypeEntry *>(java_type->typeEntry());
mandel@1 3096 s << INDENT << "int " << java_name << " = " << qt_name << ";" << endl;
mandel@1 3097
mandel@1 3098 } else if (java_type->isTargetLangFlags()) {
mandel@1 3099 Q_ASSERT((option & EnumAsInts) == 0);
mandel@1 3100 const FlagsTypeEntry *ft = static_cast<const FlagsTypeEntry *>(java_type->typeEntry());
mandel@1 3101 s << INDENT << "jobject " << java_name << " = qtjambi_from_flags(__jni_env, "
mandel@1 3102 << qt_name << ", \"" << ft->javaPackage().replace('.', '/') << '/'
mandel@1 3103 << ft->originator()->javaQualifier() << '$' << ft->targetLangName() << "\");" << endl;
mandel@1 3104
mandel@1 3105 } else if (java_type->isContainer()) {
mandel@1 3106 writeQtToJavaContainer(s, java_type, qt_name, java_name, 0, -1);
mandel@1 3107
mandel@1 3108 } else if (java_type->isThread()) {
mandel@1 3109 s << INDENT << "jobject " << java_name << " = qtjambi_from_thread(__jni_env, " << qt_name
mandel@1 3110 << ");" << endl;
mandel@1 3111
mandel@1 3112 } else if (!java_type->isNativePointer() && java_type->typeEntry()->isCustom()) {
mandel@1 3113 s << INDENT;
mandel@1 3114 static_cast<const CustomTypeEntry *>(java_type->typeEntry())
mandel@1 3115 ->generateCppQtToJava(s, java_type, "__jni_env", qt_name, java_name);
mandel@1 3116 s << ";" << endl;
mandel@1 3117
mandel@1 3118 } else {
mandel@1 3119 QString return_type;
mandel@1 3120 if (java_function)
mandel@1 3121 return_type = jniReturnName(java_function);
mandel@1 3122 else {
mandel@1 3123 return_type = jniReturnType(java_type);
mandel@1 3124 return_type = fixCppTypeName(return_type);
mandel@1 3125 // return_type = fixCppTypeName(java_type->typeEntry()->qualifiedCppName());
mandel@1 3126 }
mandel@1 3127 /* if( (java_type->isValue() && !java_type->typeEntry()->isStructInD())
mandel@1 3128 || java_type->isObject() )
mandel@1 3129 s << INDENT << return_type << " *" << java_name << " = (" << return_type << "*) ";
mandel@1 3130 else*/
mandel@1 3131 s << INDENT << return_type << " " << java_name << " = (" << return_type << ") ";
mandel@1 3132
mandel@1 3133 if (java_type->isQObject()) {
mandel@1 3134 /* qtd s << "qtjambi_from_qobject(__jni_env, " << "(QObject *) ";
mandel@1 3135
mandel@1 3136 if (java_type->isReference() && java_type->indirections() == 0)
mandel@1 3137 s << "&";
mandel@1 3138
mandel@1 3139 s << qt_name
mandel@1 3140 << ", \"" << java_type->typeEntry()->lookupName() << "\""
mandel@1 3141 << ", \"" << java_type->package().replace(".", "/") << "/\""
mandel@1 3142 << ");" << endl;
mandel@1 3143 */
mandel@1 3144 s << qt_name << ";" << endl;
mandel@1 3145
mandel@1 3146 #if 0
mandel@1 3147 } else if (java_type->isEnum()) {
mandel@1 3148
mandel@1 3149 const EnumTypeEntry *et = static_cast<const EnumTypeEntry *>(java_type->typeEntry());
mandel@1 3150 s << "qtjambi_from_enum(__jni_env, " << qt_name << ", \""
mandel@1 3151 << et->javaQualifier() << "$" << et->targetLangName() << "\");" << endl;
mandel@1 3152 #endif
mandel@1 3153 } else if (java_type->isNativePointer()) {
mandel@1 3154 /* qtd s << "qtjambi_from_cpointer(__jni_env, ";
mandel@1 3155 if (java_type->isReference())
mandel@1 3156 s << "&";
mandel@1 3157 s << qt_name << ", " << nativePointerType(java_type) << ", "
mandel@1 3158 << java_type->actualIndirections() << ");" << endl;
mandel@1 3159 */
mandel@1 3160 if (java_type->isReference())
mandel@1 3161 s << "&";
mandel@1 3162 s << qt_name << ";" << "// qtjambi_from_cpointer" << endl;
mandel@1 3163 } else if (java_type->isValue()) {
mandel@1 3164 // qtd s << fromObject(java_type->typeEntry(), "&" + qt_name) << endl;
mandel@1 3165 s << "new " << java_type->typeEntry()->qualifiedCppName() << "(" << qt_name << ");" << endl;
mandel@1 3166 } else {
mandel@1 3167 // qtd s << fromObject(java_type->typeEntry(),
mandel@1 3168 // qtd (java_type->isReference() ? "&" : "") + qt_name) << endl;
Eldar@378 3169 if (java_type->isReference())
Eldar@378 3170 s << "&";
mandel@1 3171 s << qt_name << ";" << endl;
mandel@1 3172 }
mandel@1 3173 }
mandel@1 3174
mandel@1 3175 }
mandel@1 3176
mandel@1 3177 QString CppImplGenerator::getTypeName(const TypeEntry *entry, Option option)
mandel@1 3178 {
mandel@1 3179 if(entry->isEnum() && (option & EnumAsInts))
mandel@1 3180 return "int";
mandel@1 3181
mandel@1 3182 return entry->lookupName();
mandel@1 3183 }
mandel@1 3184
mandel@1 3185 void CppImplGenerator::writeQtToJavaContainer(QTextStream &s,
mandel@1 3186 const AbstractMetaType *java_type,
mandel@1 3187 const QString &qt_name,
mandel@1 3188 const QString &java_name,
mandel@1 3189 const AbstractMetaFunction *java_function,
mandel@1 3190 int argument_index)
mandel@1 3191 {
mandel@1 3192 // Language for conversion to Java: Native code for return values and Shell code for arguments
mandel@1 3193 TypeSystem::Language lang = argument_index == 0 ? TypeSystem::NativeCode : TypeSystem::ShellCode;
mandel@1 3194 if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
mandel@1 3195 return;
mandel@1 3196
mandel@1 3197 if (java_type == 0) {
mandel@1 3198 QString warn = QString("no conversion possible for argument '%1' in function '%2::%3' for "
mandel@1 3199 "language '%4'")
mandel@1 3200 .arg(argument_index)
mandel@1 3201 .arg(java_function->implementingClass()->name())
mandel@1 3202 .arg(java_function->name())
mandel@1 3203 .arg(int(lang));
mandel@1 3204 ReportHandler::warning(warn);
mandel@1 3205 return;
mandel@1 3206 }
mandel@1 3207
mandel@1 3208 Q_ASSERT(java_type->isContainer());
mandel@1 3209 const ContainerTypeEntry *type =
mandel@1 3210 static_cast<const ContainerTypeEntry *>(java_type->typeEntry());
mandel@1 3211
eldar@298 3212 if (type->type() == ContainerTypeEntry::VectorContainer
mandel@1 3213 || type->type() == ContainerTypeEntry::LinkedListContainer
mandel@1 3214 || type->type() == ContainerTypeEntry::StackContainer
mandel@1 3215 || type->type() == ContainerTypeEntry::SetContainer
mandel@1 3216 || type->type() == ContainerTypeEntry::QueueContainer) {
mandel@1 3217
mandel@1 3218 Q_ASSERT(java_type->instantiations().size() == 1);
mandel@1 3219 AbstractMetaType *targ = java_type->instantiations().first();
mandel@1 3220
mandel@1 3221 QString cls_name = getTypeName(targ->typeEntry(), EnumAsInts);
mandel@1 3222 cls_name.remove("_ConcreteWrapper");
mandel@1 3223
mandel@1 3224 s << endl
mandel@1 3225 << INDENT;
mandel@1 3226
mandel@1 3227 switch (type->type()) {
mandel@1 3228 case ContainerTypeEntry::LinkedListContainer:
mandel@1 3229 case ContainerTypeEntry::QueueContainer:
mandel@1 3230 s << "qtjambi_linkedlist_new(__jni_env)";
mandel@1 3231 break;
mandel@1 3232 case ContainerTypeEntry::StackContainer:
mandel@1 3233 s << "qtjambi_stack_new(__jni_env)";
mandel@1 3234 break;
mandel@1 3235 case ContainerTypeEntry::SetContainer:
mandel@1 3236 s << "qtjambi_hashset_new(__jni_env)";
mandel@1 3237 break;
mandel@1 3238 default:
mandel@1 3239 s << "qtd_allocate_" << cls_name
mandel@1 3240 << "_array(" << java_name << ", " << qt_name << ".size())";
mandel@1 3241 break;
mandel@1 3242 }
mandel@1 3243
mandel@1 3244 s << ";" << endl
mandel@1 3245 << INDENT;
mandel@1 3246
mandel@1 3247
mandel@1 3248 writeTypeInfo(s, java_type, ForceValueType);
eldar@167 3249 QString index = "i_" + qt_name;
mandel@1 3250 s << "::const_iterator " << qt_name << "_end_it = " << qt_name << ".constEnd();" << endl
eldar@167 3251 << INDENT << QString("int %0 = 0;").arg(index) << endl
mandel@1 3252 << INDENT;
mandel@1 3253 s << "for (";
mandel@1 3254 writeTypeInfo(s, java_type, ForceValueType);
mandel@1 3255 s << "::const_iterator " << qt_name << "_it = " << qt_name << ".constBegin(); "
mandel@1 3256 << qt_name << "_it != " << qt_name << "_end_it; ++" << qt_name << "_it) {" << endl;
mandel@1 3257 {
mandel@1 3258 Indentation indent(INDENT);
mandel@1 3259 s << INDENT;
mandel@1 3260 writeTypeInfo(s, targ);
mandel@1 3261 s << " __qt_tmp = *" << qt_name << "_it;" << endl;
mandel@1 3262
mandel@1 3263 if(targ->isTargetLangString())
eldar@167 3264 s << INDENT << "void *__java_tmp = qtd_string_from_array(" << java_name << ", " << index << ");" << endl;
mandel@1 3265
mandel@1 3266 writeQtToJava(s, targ, "__qt_tmp", "__java_tmp", 0, -1, BoxedPrimitive);
mandel@1 3267
eldar@167 3268 s << INDENT << "qtd_assign_" << cls_name << "_array_element(" << java_name << ", " << index << ", __java_tmp);" << endl;
eldar@167 3269 s << INDENT << "++" << index << ";" << endl;
mandel@1 3270 }
eldar@167 3271 s << INDENT << "}" << endl;
eldar@298 3272
eldar@298 3273 } else if (type->isQList()) {
eldar@298 3274 // QList<QObject*> & list2 = (*(QList<QObject*> *)nativeId);
eldar@298 3275 writeTypeInfo(s, java_type, ForceValueType);
eldar@298 3276 s << "&" << java_name << "_tmp = (*(";
eldar@298 3277 writeTypeInfo(s, java_type, ForceValueType);
eldar@298 3278 s << "*)" << java_name << ");" << endl
eldar@298 3279 << INDENT << java_name << "_tmp = " << qt_name << ";" << endl;
mandel@1 3280
mandel@1 3281 } else if (type->type() == ContainerTypeEntry::PairContainer) {
mandel@1 3282 QList<AbstractMetaType *> args = java_type->instantiations();
mandel@1 3283 Q_ASSERT(args.size() == 2);
mandel@1 3284
mandel@1 3285 s << INDENT << "jobject " << java_name << ";" << endl
mandel@1 3286 << INDENT << "{" << endl;
mandel@1 3287 {
mandel@1 3288 Indentation indent(INDENT);
mandel@1 3289 writeQtToJava(s, args.at(0), qt_name + ".first", "__java_tmp_first", 0, -1, BoxedPrimitive);
mandel@1 3290 writeQtToJava(s, args.at(1), qt_name + ".second", "__java_tmp_second", 0, -1, BoxedPrimitive);
mandel@1 3291 s << INDENT << java_name << " = qtjambi_pair_new(__jni_env, "
mandel@1 3292 << "__java_tmp_first, __java_tmp_second);" << endl;
mandel@1 3293 }
mandel@1 3294
mandel@1 3295 s << INDENT << "}" << endl;
mandel@1 3296
mandel@1 3297 } else if (type->type() == ContainerTypeEntry::MultiMapContainer) {
mandel@1 3298
mandel@1 3299 Q_ASSERT(java_type->instantiations().size() == 2);
mandel@1 3300 AbstractMetaType *targ_key = java_type->instantiations().at(0);
mandel@1 3301 AbstractMetaType *targ_val = java_type->instantiations().at(1);
mandel@1 3302
mandel@1 3303 s << endl
mandel@1 3304 << INDENT << "jobject " << java_name << " = qtjambi_treemap_new(__jni_env, " << qt_name << ".keys().size());" << endl
mandel@1 3305 << INDENT << "QList<";
mandel@1 3306 writeTypeInfo(s, targ_key);
mandel@1 3307 s << "> __qt_keys = " << qt_name << ".keys();" << endl
mandel@1 3308 << INDENT << "for (int i=0; i<__qt_keys.size(); ++i) {" << endl;
mandel@1 3309 {
mandel@1 3310 Indentation indent(INDENT);
mandel@1 3311
mandel@1 3312 s << INDENT;
mandel@1 3313 writeTypeInfo(s, targ_key);
mandel@1 3314 s << " __qt_tmp_key = __qt_keys.at(i);" << endl;
mandel@1 3315 writeQtToJava(s, targ_key, "__qt_tmp_key", "__java_tmp_key", 0, -1, BoxedPrimitive);
mandel@1 3316
mandel@1 3317 s << INDENT << "QList<";
mandel@1 3318 writeTypeInfo(s, targ_val);
mandel@1 3319 s << "> __qt_values = " << qt_name << ".values(__qt_tmp_key);" << endl
mandel@1 3320 << INDENT << "jobject __java_value_list = qtjambi_arraylist_new(__jni_env, __qt_values.size());" << endl
mandel@1 3321 << INDENT << "for (int j=0; j<__qt_values.size(); ++j) {" << endl;
mandel@1 3322 {
mandel@1 3323 Indentation indent(INDENT);
mandel@1 3324
mandel@1 3325 s << INDENT;
mandel@1 3326 writeTypeInfo(s, targ_val);
mandel@1 3327 s << " __qt_tmp_val = __qt_values.at(j);" << endl;
mandel@1 3328 writeQtToJava(s, targ_val, "__qt_tmp_val", "__java_tmp_val", 0, -1, BoxedPrimitive);
mandel@1 3329
mandel@1 3330 s << INDENT << "qtjambi_collection_add(__jni_env, __java_value_list, __java_tmp_val);" << endl;
mandel@1 3331 }
mandel@1 3332 s << INDENT << "}" << endl
mandel@1 3333 << INDENT << "qtjambi_map_put(__jni_env, " << java_name << ", __java_tmp_key, __java_value_list);" << endl;
mandel@1 3334 }
mandel@1 3335 s << INDENT << "}" << endl;
mandel@1 3336
mandel@1 3337 } else if (type->type() == ContainerTypeEntry::MapContainer
mandel@1 3338 || type->type() == ContainerTypeEntry::HashContainer) {
mandel@1 3339 QString constructor = type->type() == ContainerTypeEntry::MapContainer
mandel@1 3340 ? "qtjambi_treemap_new"
mandel@1 3341 : "qtjambi_hashmap_new";
mandel@1 3342
mandel@1 3343 Q_ASSERT(java_type->instantiations().size() == 2);
mandel@1 3344 AbstractMetaType *targ_key = java_type->instantiations().at(0);
mandel@1 3345 AbstractMetaType *targ_val = java_type->instantiations().at(1);
mandel@1 3346
mandel@1 3347 s << endl
mandel@1 3348 << INDENT << "jobject " << java_name << " = " << constructor << "(__jni_env, " << qt_name
mandel@1 3349 << ".size());" << endl
mandel@1 3350 << INDENT;
mandel@1 3351 writeTypeInfo(s, java_type, Option(ExcludeReference | ExcludeConst));
mandel@1 3352 s << "::const_iterator it;" << endl
mandel@1 3353 << INDENT << "for (it=" << qt_name << ".constBegin(); it!=" << qt_name << ".constEnd(); ++it) {" << endl;
mandel@1 3354 {
mandel@1 3355 Indentation indent(INDENT);
mandel@1 3356 s << INDENT;
mandel@1 3357 writeTypeInfo(s, targ_key);
mandel@1 3358 s << " __qt_tmp_key = it.key();" << endl
mandel@1 3359 << INDENT;
mandel@1 3360 writeTypeInfo(s, targ_val);
mandel@1 3361 s << " __qt_tmp_val = it.value();" << endl;
mandel@1 3362 writeQtToJava(s, targ_key, "__qt_tmp_key", "__java_tmp_key", 0, -1, BoxedPrimitive);
mandel@1 3363 writeQtToJava(s, targ_val, "__qt_tmp_val", "__java_tmp_val", 0, -1, BoxedPrimitive);
mandel@1 3364 s << INDENT << "qtjambi_map_put(__jni_env, " << java_name
mandel@1 3365 << ", __java_tmp_key, __java_tmp_val);" << endl;
mandel@1 3366 }
mandel@1 3367 s << INDENT << "}" << endl;
mandel@1 3368
mandel@1 3369 } else {
mandel@1 3370 ReportHandler::warning(QString("unable to generate container type %1, type=%2")
mandel@1 3371 .arg(java_type->name()).arg(type->type()));
mandel@1 3372 }
mandel@1 3373
mandel@1 3374 // qtd s << INDENT << "QTJAMBI_EXCEPTION_CHECK(__jni_env);" << endl;
mandel@1 3375 }
mandel@1 3376
mandel@1 3377
mandel@1 3378 void CppImplGenerator::writeJavaToQtContainer(QTextStream &s,
mandel@1 3379 const AbstractMetaType *java_type,
mandel@1 3380 const QString &qt_name,
mandel@1 3381 const QString &java_name,
mandel@1 3382 const AbstractMetaFunction *java_function,
mandel@1 3383 int argument_index)
mandel@1 3384 {
mandel@1 3385 // Conversion to C++: Shell code for return value, native code for arguments
mandel@1 3386 TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode;
mandel@1 3387 if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
mandel@1 3388 return;
mandel@1 3389
mandel@1 3390 if (java_type == 0) {
mandel@1 3391 QString warn = QString("no conversion possible for argument '%1' in function '%2::%3' for "
mandel@1 3392 "language '%4'")
mandel@1 3393 .arg(argument_index)
mandel@1 3394 .arg(java_function->implementingClass()->name())
mandel@1 3395 .arg(java_function->name())
mandel@1 3396 .arg(int(lang));
mandel@1 3397 ReportHandler::warning(warn);
mandel@1 3398 return;
mandel@1 3399 }
mandel@1 3400
mandel@1 3401
mandel@1 3402 Q_ASSERT(java_type->isContainer());
mandel@1 3403 const ContainerTypeEntry *type =
mandel@1 3404 static_cast<const ContainerTypeEntry *>(java_type->typeEntry());
mandel@1 3405
eldar@298 3406 if (type->type() == ContainerTypeEntry::VectorContainer
mandel@1 3407 || type->type() == ContainerTypeEntry::LinkedListContainer
mandel@1 3408 || type->type() == ContainerTypeEntry::StackContainer
mandel@1 3409 || type->type() == ContainerTypeEntry::SetContainer
mandel@1 3410 || type->type() == ContainerTypeEntry::QueueContainer) {
mandel@1 3411 Q_ASSERT(java_type->instantiations().size() == 1);
mandel@1 3412 AbstractMetaType *targ = java_type->instantiations().first();
mandel@1 3413 QString elem_type = getTypeName(targ->typeEntry(), EnumAsInts);
mandel@1 3414 elem_type.remove("_ConcreteWrapper");
mandel@1 3415
mandel@1 3416 s << INDENT;
mandel@1 3417 writeTypeInfo(s, java_type, ForceValueType);
mandel@1 3418 s << qt_name << ";" << endl;
mandel@1 3419
mandel@1 3420 {
mandel@1 3421 if (type->type() == ContainerTypeEntry::VectorContainer
mandel@1 3422 || type->type() == ContainerTypeEntry::StackContainer)
eldar@298 3423 s << INDENT << qt_name << ".reserve(" << java_name << "->length);" << endl;
eldar@298 3424
eldar@298 3425 s << INDENT << "for (int i=0; i<" << java_name << "->length; ++i) {" << endl;
mandel@1 3426 {
mandel@1 3427 Indentation indent(INDENT);
mandel@1 3428 if(targ->isTargetLangString())
eldar@35 3429 s << INDENT << "DArray __d_element;" << endl
eldar@298 3430 << INDENT << "qtd_get_string_from_array(" << java_name << "->ptr, i, &__d_element);" << endl;
mandel@1 3431 else {
mandel@1 3432 s << INDENT;
eldar@33 3433 writeTypeInfo(s, targ, Option(VirtualDispatch | ForcePointer | EnumAsInts));
mandel@1 3434 QString cast_string = "";
mandel@1 3435 const TypeEntry* centry = targ->typeEntry();
mandel@1 3436 if (centry->isComplex() && (centry->isObject() || centry->isValue() || centry->isInterface()))
mandel@1 3437 cast_string = "(void**)";
mandel@1 3438 s << "__d_element;" << endl
mandel@1 3439 << INDENT << "qtd_get_" << elem_type << "_from_array(" << java_name << ", i, &__d_element);" << endl;
mandel@1 3440 }
mandel@1 3441 writeJavaToQt(s, targ, "__qt_element", "__d_element", 0, -1, BoxedPrimitive);
mandel@1 3442 QString cont_element = "__qt_element";
mandel@1 3443 if(targ->typeEntry()->isStructInD() && targ->name() != "QModelIndex")
mandel@1 3444 cont_element = "__d_element";
mandel@1 3445 s << INDENT << qt_name << " << " << cont_element << ";" << endl;
mandel@1 3446 }
mandel@1 3447 // qtd s << INDENT << "}" << endl;
mandel@1 3448 }
mandel@1 3449 s << INDENT << "}" << endl;
eldar@298 3450 } else if (type->isQList()) {
eldar@298 3451 writeTypeInfo(s, java_type, ForceValueType);
eldar@298 3452 s << qt_name << " = (*(";
eldar@298 3453 writeTypeInfo(s, java_type, ForceValueType);
eldar@298 3454 s << "*)" << java_name << ");" << endl;
mandel@1 3455 } else if (type->type() == ContainerTypeEntry::PairContainer) {
mandel@1 3456 QList<AbstractMetaType *> targs = java_type->instantiations();
mandel@1 3457 Q_ASSERT(targs.size() == 2);
mandel@1 3458
mandel@1 3459 s << INDENT;
mandel@1 3460 writeTypeInfo(s, java_type, ForceValueType);
mandel@1 3461 s << " " << qt_name << ";" << endl
mandel@1 3462 << INDENT << "if (" << java_name << " != 0) {" << endl;
mandel@1 3463 {
mandel@1 3464 // separate scope required just in case function takes two QPair's.
mandel@1 3465 Indentation indent(INDENT);
mandel@1 3466 s << INDENT << "jobject __java_first = qtjambi_pair_get(__jni_env, "
mandel@1 3467 << java_name << ", 0);" << endl;
mandel@1 3468 writeJavaToQt(s, targs.at(0), "__qt_first", "__java_first", 0, -1, BoxedPrimitive);
mandel@1 3469
mandel@1 3470 s << INDENT << "jobject __java_second = qtjambi_pair_get(__jni_env, "
mandel@1 3471 << java_name << ", 1);" << endl;
mandel@1 3472 writeJavaToQt(s, targs.at(1), "__qt_second", "__java_second", 0, -1, BoxedPrimitive);
mandel@1 3473
mandel@1 3474 s << INDENT << qt_name << ".first = __qt_first;" << endl
mandel@1 3475 << INDENT << qt_name << ".second = __qt_second;" << endl;
mandel@1 3476 }
mandel@1 3477 s << INDENT << "}" << endl;
mandel@1 3478 } else if (type->type() == ContainerTypeEntry::MapContainer
mandel@1 3479 || type->type() == ContainerTypeEntry::HashContainer) {
mandel@1 3480 Q_ASSERT(java_type->instantiations().size() == 2);
mandel@1 3481 AbstractMetaType *targ_key = java_type->instantiations().at(0);
mandel@1 3482 AbstractMetaType *targ_val = java_type->instantiations().at(1);
mandel@1 3483
mandel@1 3484 s << INDENT;
mandel@1 3485 writeTypeInfo(s, java_type, ForceValueType);
mandel@1 3486 s << qt_name << ";" << endl;
mandel@1 3487 s << INDENT << "if (" << java_name << " != 0) {" << endl;
mandel@1 3488 {
mandel@1 3489 Indentation indent(INDENT);
mandel@1 3490 s << INDENT << "int __qt_list_size = qtjambi_map_size(__jni_env, " << java_name
mandel@1 3491 << ");" << endl
mandel@1 3492 << INDENT
mandel@1 3493 << "jobjectArray __java_entry_set = qtjambi_map_entryset_array(__jni_env, " << java_name
mandel@1 3494 << ");" << endl;
mandel@1 3495
mandel@1 3496 s << INDENT << "for (int i=0; i<__qt_list_size; ++i) {" << endl;
mandel@1 3497 {
mandel@1 3498 Indentation indent(INDENT);
mandel@1 3499 s << INDENT
mandel@1 3500 << "QPair<jobject, jobject> __java_entry = "
mandel@1 3501 << "qtjambi_entryset_array_get(__jni_env, __java_entry_set, i);"
mandel@1 3502 << endl
mandel@1 3503 << INDENT << "jobject __java_key = __java_entry.first;" << endl
mandel@1 3504 << INDENT << "jobject __java_val = __java_entry.second;" << endl;
mandel@1 3505 writeJavaToQt(s, targ_key, "__qt_key", "__java_key", 0, -1, BoxedPrimitive);
mandel@1 3506 writeJavaToQt(s, targ_val, "__qt_val", "__java_val", 0, -1, BoxedPrimitive);
mandel@1 3507 s << INDENT << qt_name << ".insert(__qt_key, __qt_val);" << endl;
mandel@1 3508 }
mandel@1 3509 s << INDENT << "}" << endl;
mandel@1 3510 }
mandel@1 3511 s << INDENT << "}" << endl;
mandel@1 3512
mandel@1 3513 } else {
mandel@1 3514 ReportHandler::warning(QString("unable to generate container type %1, %2")
mandel@1 3515 .arg(java_type->name()).arg(type->type()));
mandel@1 3516 }
mandel@1 3517
mandel@1 3518 }
mandel@1 3519
mandel@1 3520
mandel@1 3521 void CppImplGenerator::writeFunctionCall(QTextStream &s, const QString &object_name,
mandel@1 3522 const AbstractMetaFunction *java_function,
mandel@1 3523 const QString &prefix,
mandel@1 3524 Option option,
mandel@1 3525 const QStringList &extra_arguments)
mandel@1 3526 {
mandel@1 3527 QString function_name = option & OriginalName ? java_function->originalName() : java_function->name();
mandel@1 3528
mandel@1 3529 AbstractMetaClassList interfaces = java_function->implementingClass()->interfaces();
mandel@1 3530
mandel@1 3531 QString classPrefix;
mandel@1 3532 if (prefix.isEmpty()
mandel@1 3533 && !java_function->implementingClass()->interfaces().isEmpty()
mandel@1 3534 && !java_function->implementingClass()->inheritsFrom(java_function->declaringClass())) {
mandel@1 3535 classPrefix = java_function->declaringClass()->qualifiedCppName() + "::";
mandel@1 3536 }
mandel@1 3537
mandel@1 3538 if (java_function->isInGlobalScope()) {
mandel@1 3539
mandel@1 3540 // Global scope stream operators need the arguments to be reordered (this ref at end)
mandel@1 3541 // so we special case them in order to simplify this code
mandel@1 3542 bool stream_operator = java_function->originalName() == "operator<<"
mandel@1 3543 || java_function->originalName() == "operator>>";
mandel@1 3544
mandel@1 3545 if (java_function->type() == 0)
mandel@1 3546 s << "if (" << object_name << " != 0) ";
mandel@1 3547 else
mandel@1 3548 s << "(" << object_name << " != 0) ? ";
mandel@1 3549 s << "::" << prefix << function_name << "(";
mandel@1 3550 if (!stream_operator)
mandel@1 3551 s << "*" << object_name << ", ";
mandel@1 3552 writeFunctionCallArguments(s, java_function, "__qt_");
mandel@1 3553 if (stream_operator)
mandel@1 3554 s << ", *" << object_name;
mandel@1 3555 s << ")";
mandel@1 3556 if (java_function->type() != 0)
mandel@1 3557 s << " : " << default_return_statement_qt(java_function->type(), Generator::Option(option | Generator::NoReturnStatement));
mandel@1 3558 s << ";";
mandel@1 3559 } else {
mandel@1 3560 s << object_name << (java_function->isStatic() ? QLatin1String("::") : QLatin1String("->") + classPrefix)
mandel@1 3561 << prefix << function_name << "(";
mandel@1 3562 writeFunctionCallArguments(s, java_function, "__qt_");
mandel@1 3563
mandel@1 3564 // The extra arguments...
mandel@1 3565 for (int i=0; i<extra_arguments.size(); ++i) {
mandel@1 3566 if (i > 0 || java_function->arguments().size() != 0)
mandel@1 3567 s << ", ";
mandel@1 3568 s << extra_arguments.at(i);
mandel@1 3569 }
mandel@1 3570
mandel@1 3571 s << ");";
mandel@1 3572 }
mandel@1 3573
mandel@1 3574 s << endl;
mandel@1 3575
mandel@1 3576 }
mandel@1 3577
mandel@1 3578
mandel@1 3579 void CppImplGenerator::writeFunctionCallArguments(QTextStream &s,
mandel@1 3580 const AbstractMetaFunction *java_function,
mandel@1 3581 const QString &prefix,
mandel@1 3582 Option options)
mandel@1 3583 {
mandel@1 3584 AbstractMetaArgumentList arguments = java_function->arguments();
mandel@1 3585
mandel@1 3586 int written_arguments = 0;
mandel@1 3587 const AbstractMetaClass *cls = java_function->ownerClass();
maxter@355 3588 if (java_function->isConstructor() && cls->isPolymorphic()) {
mandel@1 3589 s << "d_ptr";
mandel@1 3590 written_arguments++;
mandel@1 3591 }
mandel@1 3592 for (int i=0; i<arguments.size(); ++i) {
mandel@1 </