aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4function.cpp')
-rw-r--r--src/qml/jsruntime/qv4function.cpp66
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 &param) {
+ 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 &param,
+ 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()