History

Added scoring system for determining overloaded function to call

ksuprynowicz committed 4 years ago

Commit 979e9ff1 parent 8304a0c3 files · +125 −13Browse files

Showing the changes to libraries/script-engine/src/qtscript/ScriptObjectQtProxy.cpp (1 of 3 files). Show all

Unified · Split

libraries/script-engine/src/qtscript/ScriptObjectQtProxy.cpp+43−13
@@ -462,38 +462,51 @@ QVariant ScriptMethodQtProxy::extension(Extension extension, const QVariant& arg · 461 unmodified lines
462 int parameterConversionFailureId = 0;462 int parameterConversionFailureId = 0;
463 int parameterConversionFailureCount = 0;463 int parameterConversionFailureCount = 0;
464 464
465 for (auto iter = _metas.cbegin(); iter != _metas.end(); ++iter) {465 int num_metas = _metas.size();
466 const QMetaMethod& meta = *iter;466 QVector< QList<ScriptValue> > qScriptArgLists;
467 QVector< QVector <QGenericArgument> > qGenArgsVectors;
468 QVector< QList<QVariant> > qVarArgLists;
469 int conversionPenaltyScore[num_metas];
470 bool isMetaRejected[num_metas];
471 qScriptArgLists.resize(num_metas);
472 qGenArgsVectors.resize(num_metas);
473 qVarArgLists.resize(num_metas);
474
475 for (int i = 0; i < num_metas; i++) {
476 const QMetaMethod& meta = _metas[i];
477 isMetaRejected[i] = false;
467 int methodNumArgs = meta.parameterCount();478 int methodNumArgs = meta.parameterCount();
468 if (methodNumArgs != numArgs) {479 if (methodNumArgs != numArgs) {
480 isMetaRejected[i] = true;
469 continue;481 continue;
470 }482 }
471 483
472 QList<ScriptValue> qScriptArgList;484 qGenArgsVectors[i].resize(10);
473 QList<QVariant> qVarArgList;485 conversionPenaltyScore[i] = 0;
474 QGenericArgument qGenArgs[10];
475 int conversionFailures = 0;486 int conversionFailures = 0;
487
476 for (int arg = 0; arg < numArgs; ++arg) {488 for (int arg = 0; arg < numArgs; ++arg) {
477 int methodArgTypeId = meta.parameterType(arg);489 int methodArgTypeId = meta.parameterType(arg);
478 Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);490 Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
479 QScriptValue argVal = context->argument(arg);491 QScriptValue argVal = context->argument(arg);
480 if (methodArgTypeId == scriptValueTypeId) {492 if (methodArgTypeId == scriptValueTypeId) {
481 qScriptArgList.append(ScriptValue(new ScriptValueQtWrapper(_engine, argVal)));493 qScriptArgLists[i].append(ScriptValue(new ScriptValueQtWrapper(_engine, argVal)));
482 qGenArgs[arg] = Q_ARG(ScriptValue, qScriptArgList.back());494 qGenArgsVectors[i][arg] = Q_ARG(ScriptValue, qScriptArgLists[i].back());
483 } else if (methodArgTypeId == QMetaType::QVariant) {495 } else if (methodArgTypeId == QMetaType::QVariant) {
484 qVarArgList.append(argVal.toVariant());496 qVarArgLists[i].append(argVal.toVariant());
485 qGenArgs[arg] = Q_ARG(QVariant, qVarArgList.back());497 qGenArgsVectors[i][arg] = Q_ARG(QVariant, qVarArgLists[i].back());
486 } else {498 } else {
487 QVariant varArgVal;499 QVariant varArgVal;
488 if (!_engine->castValueToVariant(argVal, varArgVal, methodArgTypeId)) {500 if (!_engine->castValueToVariant(argVal, varArgVal, methodArgTypeId)) {
489 conversionFailures++;501 conversionFailures++;
490 } else {502 } else {
491 qVarArgList.append(varArgVal);503 qVarArgLists[i].append(varArgVal);
492 const QVariant& converted = qVarArgList.back();504 const QVariant& converted = qVarArgLists[i].back();
505 conversionPenaltyScore[i] = _engine->computeCastPenalty(argVal, methodArgTypeId);
493 506
494 // a lot of type conversion assistance thanks to https://stackoverflow.com/questions/28457819/qt-invoke-method-with-qvariant507 // a lot of type conversion assistance thanks to https://stackoverflow.com/questions/28457819/qt-invoke-method-with-qvariant
495 // A const_cast is needed because calling data() would detach the QVariant.508 // A const_cast is needed because calling data() would detach the QVariant.
496 qGenArgs[arg] =509 qGenArgsVectors[i][arg] =
497 QGenericArgument(QMetaType::typeName(converted.userType()), const_cast<void*>(converted.constData()));510 QGenericArgument(QMetaType::typeName(converted.userType()), const_cast<void*>(converted.constData()));
498 }511 }
499 }512 }
@@ -503,13 +516,30 @@ QVariant ScriptMethodQtProxy::extension(Extension extension, const QVariant& arg · 3 unmodified lines
503 parameterConversionFailureCount = conversionFailures;516 parameterConversionFailureCount = conversionFailures;
504 parameterConversionFailureId = meta.methodIndex();517 parameterConversionFailureId = meta.methodIndex();
505 }518 }
519 isMetaRejected[i] = true;
506 continue;520 continue;
507 }521 }
508 522
509 ScriptContextQtWrapper ourContext(_engine, context);523 ScriptContextQtWrapper ourContext(_engine, context);
510 ScriptContextGuard guard(&ourContext);524 ScriptContextGuard guard(&ourContext);
525 }
526
527 bool isValidMetaSelected = false;
528 int bestMeta = 0;
529 for (int i = 0; i < num_metas; i++) {
530 if (!isValidMetaSelected && !isMetaRejected[i]) {
531 isValidMetaSelected = true;
532 bestMeta = i;
533 }
534 if (isValidMetaSelected && !isMetaRejected[i] && conversionPenaltyScore[bestMeta] > conversionPenaltyScore[i]) {
535 bestMeta = i;
536 }
537 }
511 538
539 if (isValidMetaSelected) {
540 const QMetaMethod& meta = _metas[bestMeta];
512 int returnTypeId = meta.returnType();541 int returnTypeId = meta.returnType();
542 QVector <QGenericArgument> &qGenArgs = qGenArgsVectors[bestMeta];
513 543
514 // The Qt MOC engine will automatically call qRegisterMetaType on invokable parameters and properties, but there's544 // The Qt MOC engine will automatically call qRegisterMetaType on invokable parameters and properties, but there's
515 // nothing in there for return values so these need to be explicitly runtime-registered!545 // nothing in there for return values so these need to be explicitly runtime-registered!
@@ -579,9 +609,9 @@ QVariant ScriptMethodQtProxy::extension(Extension extension, const QVariant& arg · 63 unmodified lines
579 }609 }
580 }610 }
581 611
612 context->throwError(QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName()));
582 Q_ASSERT(false); // really shouldn't have gotten here -- it didn't work before and it's working now?613 Q_ASSERT(false); // really shouldn't have gotten here -- it didn't work before and it's working now?
583 return QVariant();614 return QVariant();
584 context->throwError(QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName()));
585}615}
586 616
587QString ScriptSignalQtProxy::fullName() const {617QString ScriptSignalQtProxy::fullName() const {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t