From fa00f0a0206f87b43cd1ee5448efe20cb6ff8e44 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 12 Sep 2017 17:20:47 +0200 Subject: Error out when compiling signal handlers with arguments in qml files Ahead of time we cannot tell whether the use of "arguments" in a signal hander refers to the JS arguments object or a potential arguments signal parameter. Resolving that requires access to information we currently don't have. The QML engine has it at run-time (in SignalHandlerConverter) and that's why it works there accordingly. However when generating caches ahead of time, let's rather produce an error message with a hint how to work around it instead of producing differing behavior at run-time. Task-number: QTBUG-60011 Change-Id: I9e460bd467dbb5998f12a44c439223ea44e7bbad Reviewed-by: Lars Knoll --- tools/qmlcachegen/qmlcachegen.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'tools') diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index b201176d5e..a62adc82f4 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -114,6 +114,37 @@ static void annotateListElements(QmlIR::Document *document) } } +static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc, Error *error) +{ + for (QmlIR::Object *object: qAsConst(doc.objects)) { + for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) { + if (binding->type != QV4::CompiledData::Binding::Type_Script) + continue; + const QString propName = doc.stringAt(binding->propertyNameIndex); + if (!propName.startsWith(QLatin1String("on")) + || propName.length() < 3 + || !propName.at(2).isUpper()) + continue; + auto compiledFunction = doc.jsModule.functions.value(object->runtimeFunctionIndices.at(binding->value.compiledScriptIndex)); + if (!compiledFunction) + continue; + if (compiledFunction->usesArgumentsObject) { + error->message = QLatin1Char(':') + QString::number(compiledFunction->line) + QLatin1Char(':'); + if (compiledFunction->column > 0) + error->message += QString::number(compiledFunction->column) + QLatin1Char(':'); + + error->message += QLatin1String(" error: The use of the arguments object in signal handlers is\n" + "not supported when compiling qml files ahead of time, because it may be ambiguous if\n" + "any signal parameter is called \"arguments\". Unfortunately we cannot distinguish\n" + "between it being a parameter or the JavaScript arguments object at this point.\n" + "Consider renaming the parameter of the signal if applicable."); + return false; + } + } + } + return true; +} + static bool compileQmlFile(const QString &inputFileName, const QString &outputFileName, QV4::EvalISelFactory *iselFactory, const QString &targetABI, Error *error) { QmlIR::Document irDocument(/*debugMode*/false); @@ -173,6 +204,11 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi object->runtimeFunctionIndices.allocate(pool, runtimeFunctionIndices); } + if (!checkArgumentsObjectUseInSignalHandlers(irDocument, error)) { + *error = error->augment(inputFileName); + return false; + } + QmlIR::QmlUnitGenerator generator; { -- cgit v1.2.3