aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsfunctioninitializer.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-06-15 14:16:11 +0200
committerUlf Hermann <ulf.hermann@qt.io>2022-07-07 19:33:39 +0200
commit38fdf2717d9c2432a9cd7de605f2e1c1517ff744 (patch)
treea24150dae1eb8715750048e0d605c88e16e1caab /src/qmlcompiler/qqmljsfunctioninitializer.cpp
parent3f3e961a5afe2e62f436f946c521ea4afab76dde (diff)
QmlCompiler: Handle trivial signal handler constructions
If the signal handler does nothing but return a closure, we have to compile the closure using the same signature as the outer signal handler. In order for this to work, we also have to detect unresolved argument types for signal handlers. Those are just as bad as unresolved argument types for other functions. Fixes: QTBUG-101531 Change-Id: Idb5b3994809d91a4b4ce936282685435eb75e670 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsfunctioninitializer.cpp')
-rw-r--r--src/qmlcompiler/qqmljsfunctioninitializer.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/qmlcompiler/qqmljsfunctioninitializer.cpp b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
index 56d1d25124..30aada368e 100644
--- a/src/qmlcompiler/qqmljsfunctioninitializer.cpp
+++ b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
@@ -86,6 +86,20 @@ void QQmlJSFunctionInitializer::populateSignature(
signatureError(u"Functions without type annotations won't be compiled"_s);
}
}
+ } else {
+ for (qsizetype i = 0, end = arguments.length(); i != end; ++i) {
+ const QQmlJS::AST::BoundName &argument = arguments[i];
+ if (argument.typeAnnotation) {
+ if (const auto type = m_typeResolver->typeFromAST(argument.typeAnnotation->type)) {
+ if (!m_typeResolver->registerContains(function->argumentTypes[i], type)) {
+ signatureError(u"Type annotation %1 on signal handler "
+ "contradicts signal argument type %2"_s
+ .arg(argument.typeAnnotation->type->toString(),
+ function->argumentTypes[i].descriptiveName()));
+ }
+ }
+ }
+ }
}
if (!function->returnType) {
@@ -121,7 +135,9 @@ static void diagnose(
QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
const QV4::Compiler::Context *context,
- const QString &propertyName, const QmlIR::Binding &irBinding,
+ const QString &propertyName,
+ QQmlJS::AST::Node *astNode,
+ const QmlIR::Binding &irBinding,
QQmlJS::DiagnosticMessage *error)
{
QQmlJS::SourceLocation bindingLocation;
@@ -149,6 +165,21 @@ QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
for (const auto &method : methods) {
if (method.methodType() == QQmlJSMetaMethod::Signal) {
function.isSignalHandler = true;
+ const auto argumentTypes = method.parameterTypes();
+ for (qsizetype i = 0, end = argumentTypes.length(); i < end; ++i) {
+ const auto &type = argumentTypes[i];
+ if (type.isNull()) {
+ diagnose(u"Cannot resolve the argument type %1."_s
+ .arg(method.parameterTypeNames()[i]),
+ QtDebugMsg, bindingLocation, error);
+ function.argumentTypes.append(
+ m_typeResolver->tracked(
+ m_typeResolver->globalType(m_typeResolver->varType())));
+ } else {
+ function.argumentTypes.append(m_typeResolver->tracked(
+ m_typeResolver->globalType(type)));
+ }
+ }
break;
}
}
@@ -185,8 +216,6 @@ QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
}
QQmlJS::MemoryPool pool;
- auto astNode = m_currentObject->functionsAndExpressions->slowAt(
- irBinding.value.compiledScriptIndex)->node;
auto ast = astNode->asFunctionDefinition();
if (!ast) {
QQmlJS::AST::Statement *stmt = astNode->statementCast();
@@ -212,7 +241,7 @@ QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
const QV4::Compiler::Context *context,
- const QString &functionName, const QmlIR::Function &irFunction,
+ const QString &functionName, QQmlJS::AST::Node *astNode,
QQmlJS::DiagnosticMessage *error)
{
Q_UNUSED(functionName);
@@ -220,7 +249,6 @@ QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
QQmlJSCompilePass::Function function;
function.qmlScope = m_scopeType;
- auto astNode = m_currentObject->functionsAndExpressions->slowAt(irFunction.index)->node;
auto ast = astNode->asFunctionDefinition();
Q_ASSERT(ast);