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
462462 int parameterConversionFailureId = 0;
463463 int parameterConversionFailureCount = 0;
464464
465− for (auto iter = _metas.cbegin(); iter != _metas.end(); ++iter) {
466− const QMetaMethod& meta = *iter;
465+ int num_metas = _metas.size();
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;
467478 int methodNumArgs = meta.parameterCount();
468479 if (methodNumArgs != numArgs) {
480+ isMetaRejected[i] = true;
469481 continue;
470482 }
471483
472− QList<ScriptValue> qScriptArgList;
473− QList<QVariant> qVarArgList;
474− QGenericArgument qGenArgs[10];
484+ qGenArgsVectors[i].resize(10);
485+ conversionPenaltyScore[i] = 0;
475486 int conversionFailures = 0;
487+
476488 for (int arg = 0; arg < numArgs; ++arg) {
477489 int methodArgTypeId = meta.parameterType(arg);
478490 Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
479491 QScriptValue argVal = context->argument(arg);
480492 if (methodArgTypeId == scriptValueTypeId) {
481− qScriptArgList.append(ScriptValue(new ScriptValueQtWrapper(_engine, argVal)));
482− qGenArgs[arg] = Q_ARG(ScriptValue, qScriptArgList.back());
493+ qScriptArgLists[i].append(ScriptValue(new ScriptValueQtWrapper(_engine, argVal)));
494+ qGenArgsVectors[i][arg] = Q_ARG(ScriptValue, qScriptArgLists[i].back());
483495 } else if (methodArgTypeId == QMetaType::QVariant) {
484− qVarArgList.append(argVal.toVariant());
485− qGenArgs[arg] = Q_ARG(QVariant, qVarArgList.back());
496+ qVarArgLists[i].append(argVal.toVariant());
497+ qGenArgsVectors[i][arg] = Q_ARG(QVariant, qVarArgLists[i].back());
486498 } else {
487499 QVariant varArgVal;
488500 if (!_engine->castValueToVariant(argVal, varArgVal, methodArgTypeId)) {
489501 conversionFailures++;
490502 } else {
491− qVarArgList.append(varArgVal);
492− const QVariant& converted = qVarArgList.back();
503+ qVarArgLists[i].append(varArgVal);
504+ const QVariant& converted = qVarArgLists[i].back();
505+ conversionPenaltyScore[i] = _engine->computeCastPenalty(argVal, methodArgTypeId);
493506
494507 // a lot of type conversion assistance thanks to https://stackoverflow.com/questions/28457819/qt-invoke-method-with-qvariant
495508 // A const_cast is needed because calling data() would detach the QVariant.
496− qGenArgs[arg] =
509+ qGenArgsVectors[i][arg] =
497510 QGenericArgument(QMetaType::typeName(converted.userType()), const_cast<void*>(converted.constData()));
498511 }
499512 }
@@ -503,13 +516,30 @@ QVariant ScriptMethodQtProxy::extension(Extension extension, const QVariant& arg · 3 unmodified lines
503516 parameterConversionFailureCount = conversionFailures;
504517 parameterConversionFailureId = meta.methodIndex();
505518 }
519+ isMetaRejected[i] = true;
506520 continue;
507521 }
508522
509523 ScriptContextQtWrapper ourContext(_engine, context);
510524 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+ }
511538
539+ if (isValidMetaSelected) {
540+ const QMetaMethod& meta = _metas[bestMeta];
512541 int returnTypeId = meta.returnType();
542+ QVector <QGenericArgument> &qGenArgs = qGenArgsVectors[bestMeta];
513543
514544 // The Qt MOC engine will automatically call qRegisterMetaType on invokable parameters and properties, but there's
515545 // 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
579609 }
580610 }
581611
612+ context->throwError(QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName()));
582613 Q_ASSERT(false); // really shouldn't have gotten here -- it didn't work before and it's working now?
583614 return QVariant();
584− context->throwError(QString("Native call of %1 failed: could not locate an overload with the requested arguments").arg(fullName()));
585615 }
586616
587617 QString 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