diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-09-12 17:20:47 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-09-12 19:50:16 +0000 |
commit | fa00f0a0206f87b43cd1ee5448efe20cb6ff8e44 (patch) | |
tree | 12176fd8b51e7393462e3bc049e2cf0dab2e7a09 /tools/qmlcachegen/qmlcachegen.cpp | |
parent | 98358715930739ca8de172d88c5ce6941c275ff3 (diff) |
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 <lars.knoll@qt.io>
Diffstat (limited to 'tools/qmlcachegen/qmlcachegen.cpp')
-rw-r--r-- | tools/qmlcachegen/qmlcachegen.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
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; { |