aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-09-12 17:20:47 +0200
committerLars Knoll <lars.knoll@qt.io>2017-09-12 19:50:16 +0000
commitfa00f0a0206f87b43cd1ee5448efe20cb6ff8e44 (patch)
tree12176fd8b51e7393462e3bc049e2cf0dab2e7a09 /tools
parent98358715930739ca8de172d88c5ce6941c275ff3 (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')
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp36
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;
{