diff options
Diffstat (limited to 'src/qml/jsruntime/qv4function.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 02c17d5de3..20dbff4cea 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -148,7 +148,66 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, QQmlTypeLoader *typeLoader = engine->typeLoader(); - auto findQmlType = [&](const CompiledData::ParameterType ¶m) { + const auto isEnumUsedAsType = [&](const QV4::ExecutableCompilationUnit *unit, + int elementNameId, QQmlTypeLoader *typeLoader, + const quint16 *parameter = nullptr) { + const QStringView name = unit->baseCompilationUnit()->stringAt(elementNameId); + const auto split = name.tokenize(u'.').toContainer<QVarLengthArray<QStringView, 4>>(); + if (split.size() != 2) + return false; + + const QStringView scopeName = split[0]; + const QStringView enumName = split[1]; + + auto *pengine = QQmlEnginePrivate::get(engine); + const auto warn = [&] { + QQmlError error; + auto where = parameter ? QStringLiteral("parameter ") + QString::number(*parameter) + : QStringLiteral("return type"); + auto msg = QStringLiteral("Type annotation for %1 of function %2: Enumerations are " + "not types. Use underlying type (int or double) instead.") + .arg(where, this->name()->toQString()); + error.setDescription(msg); + error.setUrl(QUrl(sourceFile())); + error.setLine(this->sourceLocation().line); + error.setColumn(this->sourceLocation().column); + error.setMessageType(QtWarningMsg); + pengine->warning(error); + }; + + bool ok; + if (scopeName == QStringLiteral("Qt")) { + const QMetaObject *mo = &Qt::staticMetaObject; + for (int i = 0; i < mo->enumeratorCount(); ++i) { + if (mo->enumerator(i).name() == enumName.toLatin1()) { + warn(); + return true; + } + } + return false; + } + + const QQmlType scope = unit->typeNameCache()->query<QQmlImport::AllowRecursion>( + scopeName, typeLoader).type; + if (!scope.isValid()) + return false; + + scope.scopedEnumIndex(typeLoader, enumName.toString(), &ok); + if (ok) { + warn(); + return true; + } + scope.unscopedEnumIndex(typeLoader, enumName.toString(), &ok); + if (ok) { + warn(); + return true; + } + + return false; + }; + + auto findQmlType = [&](const CompiledData::ParameterType ¶m, + const quint16 *parameter = nullptr) { const quint32 type = param.typeNameIndexOrCommonType(); if (param.indexIsCommonType()) { return QQmlMetaType::qmlType(QQmlPropertyCacheCreatorBase::metaTypeForPropertyType( @@ -158,6 +217,9 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, if (type == 0 || !typeLoader) return QQmlType(); + if (isEnumUsedAsType(unit, type, typeLoader, parameter)) + return QQmlType(); + const QQmlType qmltype = QQmlTypePrivate::visibleQmlTypeByName(unit, type, typeLoader); return qmltype.typeId().isValid() ? qmltype : QQmlType(); }; @@ -167,7 +229,7 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, jsTypedFunction.types.reserve(nFormals + 1); jsTypedFunction.types.append(findQmlType(compiledFunction->returnType)); for (quint16 i = 0; i < nFormals; ++i) - jsTypedFunction.types.append(findQmlType(formalsIndices[i].type)); + jsTypedFunction.types.append(findQmlType(formalsIndices[i].type, &i)); } Function::~Function() |
