aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljscompiler.cpp9
-rw-r--r--src/qmlcompiler/qqmljsfunctioninitializer.cpp103
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp15
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h3
-rw-r--r--src/qmlcompiler/qqmljslintercodegen.cpp12
5 files changed, 76 insertions, 66 deletions
diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp
index 8143f588ae..30c869c439 100644
--- a/src/qmlcompiler/qqmljscompiler.cpp
+++ b/src/qmlcompiler/qqmljscompiler.cpp
@@ -674,8 +674,13 @@ std::variant<QQmlJSAotFunction, QList<QQmlJS::DiagnosticMessage>> QQmlJSAotCompi
const QString name = m_document->stringAt(irBinding.propertyNameIndex);
QQmlJSCompilePass::Function function = initializer.run(
context, name, astNode, irBinding, &errors);
- const QQmlJSAotFunction aotFunction = doCompileAndRecordAotStats(
- context, &function, &errors, name, astNode->firstSourceLocation());
+
+ QQmlJSAotFunction aotFunction;
+ if (errors.isEmpty()) {
+ aotFunction = doCompileAndRecordAotStats(
+ context, &function, &errors, name, astNode->firstSourceLocation());
+ }
+
if (!errors.isEmpty()) {
for (auto &error : errors) {
diff --git a/src/qmlcompiler/qqmljsfunctioninitializer.cpp b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
index ffd6bf7308..95bd243f0b 100644
--- a/src/qmlcompiler/qqmljsfunctioninitializer.cpp
+++ b/src/qmlcompiler/qqmljsfunctioninitializer.cpp
@@ -168,71 +168,64 @@ QQmlJSCompilePass::Function QQmlJSFunctionInitializer::run(
}
function.isProperty = m_objectType->hasProperty(propertyName);
- if (!function.isProperty) {
- if (QQmlSignalNames::isHandlerName(propertyName)) {
- if (auto actualPropertyName =
- QQmlSignalNames::changedHandlerNameToPropertyName(propertyName);
- actualPropertyName && m_objectType->hasProperty(*actualPropertyName)) {
- function.isSignalHandler = true;
- } else {
- auto signalName = QQmlSignalNames::handlerNameToSignalName(propertyName);
- const auto methods = m_objectType->methods(*signalName);
- for (const auto &method : methods) {
- if (method.isCloned())
- continue;
- if (method.methodType() == QQmlJSMetaMethodType::Signal) {
- function.isSignalHandler = true;
- const auto arguments = method.parameters();
- for (qsizetype i = 0, end = arguments.size(); i < end; ++i) {
- const auto &type = arguments[i].type();
- if (type.isNull()) {
- diagnose(u"Cannot resolve the argument type %1."_s.arg(
- arguments[i].typeName()),
- QtDebugMsg, bindingLocation, errors);
- function.argumentTypes.append(
- m_typeResolver->namedType(m_typeResolver->varType()));
- } else {
- function.argumentTypes.append(m_typeResolver->namedType(type));
- }
- }
- break;
- }
- }
- if (!function.isSignalHandler) {
- diagnose(u"Could not compile signal handler for %1: The signal does not exist"_s.arg(
- *signalName),
- QtWarningMsg, bindingLocation, errors);
- }
- }
- }
- }
-
- if (!function.isSignalHandler) {
- if (!function.isProperty) {
- diagnose(u"Could not compile binding for %1: The property does not exist"_s.arg(
- propertyName),
- QtWarningMsg, bindingLocation, errors);
- }
-
+ if (function.isProperty) {
const auto property = m_objectType->property(propertyName);
if (const QQmlJSScope::ConstPtr propertyType = property.type()) {
function.returnType = m_typeResolver->namedType(propertyType->isListProperty()
? m_typeResolver->qObjectListType()
: QQmlJSScope::ConstPtr(property.type()));
} else {
- QString message = u"Cannot resolve property type %1 for binding on %2."_s
- .arg(property.typeName(), propertyName);
- if (m_objectType->isNameDeferred(propertyName)) {
- // If the property doesn't exist but the name is deferred, then
- // it's deferred via the presence of immediate names. Those are
- // most commonly used to enable generalized grouped properties.
- message += u" You may want use ID-based grouped properties here.";
- }
- diagnose(message, QtWarningMsg, bindingLocation, errors);
+ diagnose(u"Cannot resolve property type %1 for binding on %2."_s
+ .arg(property.typeName(), propertyName),
+ QtWarningMsg, bindingLocation, errors);
}
if (!property.bindable().isEmpty() && !property.isPrivate())
function.isQPropertyBinding = true;
+ } else if (QQmlSignalNames::isHandlerName(propertyName)) {
+ if (auto actualPropertyName =
+ QQmlSignalNames::changedHandlerNameToPropertyName(propertyName);
+ actualPropertyName && m_objectType->hasProperty(*actualPropertyName)) {
+ function.isSignalHandler = true;
+ } else {
+ auto signalName = QQmlSignalNames::handlerNameToSignalName(propertyName);
+ const auto methods = m_objectType->methods(*signalName);
+ for (const auto &method : methods) {
+ if (method.isCloned())
+ continue;
+ if (method.methodType() == QQmlJSMetaMethodType::Signal) {
+ function.isSignalHandler = true;
+ const auto arguments = method.parameters();
+ for (qsizetype i = 0, end = arguments.size(); i < end; ++i) {
+ const auto &type = arguments[i].type();
+ if (type.isNull()) {
+ diagnose(u"Cannot resolve the argument type %1."_s.arg(
+ arguments[i].typeName()),
+ QtDebugMsg, bindingLocation, errors);
+ function.argumentTypes.append(
+ m_typeResolver->namedType(m_typeResolver->varType()));
+ } else {
+ function.argumentTypes.append(m_typeResolver->namedType(type));
+ }
+ }
+ break;
+ }
+ }
+ if (!function.isSignalHandler) {
+ diagnose(u"Could not find signal \"%1\"."_s.arg(*signalName),
+ QtWarningMsg, bindingLocation, errors);
+ }
+ }
+ } else {
+ QString message = u"Could not find property \"%1\"."_s.arg(propertyName);
+ if (m_objectType->isNameDeferred(propertyName)) {
+ // If the property doesn't exist but the name is deferred, then
+ // it's deferred via the presence of immediate names. Those are
+ // most commonly used to enable generalized grouped properties.
+ message += u" You may want use ID-based grouped properties here.";
+ }
+
+ diagnose(message, QtWarningMsg, bindingLocation, errors);
}
QQmlJS::MemoryPool pool;
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 62c08d2bfb..9db0e9af69 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -222,6 +222,14 @@ void QQmlJSImportVisitor::warnUnresolvedType(const QQmlJSScope::ConstPtr &type)
qmlUnresolvedType, type->sourceLocation());
}
+void QQmlJSImportVisitor::warnMissingPropertyForBinding(
+ const QString &property, const QQmlJS::SourceLocation &location,
+ const std::optional<QQmlJSFixSuggestion> &fixSuggestion)
+{
+ m_logger->log(QStringLiteral("Could not find property \"%1\".").arg(property),
+ qmlMissingProperty, location, true, true, fixSuggestion);
+}
+
static bool mayBeUnresolvedGroupedProperty(const QQmlJSScope::ConstPtr &scope)
{
return scope->scopeType() == QQmlSA::ScopeType::GroupedPropertyScope && !scope->baseType();
@@ -753,8 +761,7 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
QQmlJSMetaProperty property = objectBinding.scope->property(propertyName);
if (!property.isValid()) {
- m_logger->log(QStringLiteral("Property \"%1\" does not exist").arg(propertyName),
- qmlMissingProperty, objectBinding.location);
+ warnMissingPropertyForBinding(propertyName, objectBinding.location);
continue;
}
const auto handleUnresolvedProperty = [&](const QQmlJSScope::ConstPtr &) {
@@ -976,9 +983,7 @@ void QQmlJSImportVisitor::processPropertyBindings()
}
}
- m_logger->log(QStringLiteral("Property \"%1\" does not exist.")
- .arg(name),
- qmlMissingProperty, location, true, true, fixSuggestion);
+ warnMissingPropertyForBinding(name, location, fixSuggestion);
continue;
}
diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h
index 02c8109d75..b9abf6ce7a 100644
--- a/src/qmlcompiler/qqmljsimportvisitor_p.h
+++ b/src/qmlcompiler/qqmljsimportvisitor_p.h
@@ -259,6 +259,9 @@ protected:
}
void warnUnresolvedType(const QQmlJSScope::ConstPtr &type) const;
+ void warnMissingPropertyForBinding(
+ const QString &property, const QQmlJS::SourceLocation &location,
+ const std::optional<QQmlJSFixSuggestion> &fixSuggestion = {});
QVector<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
void setAllBindings();
diff --git a/src/qmlcompiler/qqmljslintercodegen.cpp b/src/qmlcompiler/qqmljslintercodegen.cpp
index e33fe7139b..0717769a91 100644
--- a/src/qmlcompiler/qqmljslintercodegen.cpp
+++ b/src/qmlcompiler/qqmljslintercodegen.cpp
@@ -41,8 +41,10 @@ QQmlJSLinterCodegen::compileBinding(const QV4::Compiler::Context *context,
const QString name = m_document->stringAt(irBinding.propertyNameIndex);
QQmlJSCompilePass::Function function =
initializer.run(context, name, astNode, irBinding, &initializationErrors);
- for (const auto &error : initializationErrors)
- diagnose(error.message, error.type, error.loc);
+ for (const auto &error : initializationErrors) {
+ diagnose(u"Could not determine signature of binding for %1: %2"_s.arg(name, error.message),
+ error.type, error.loc);
+ }
QList<QQmlJS::DiagnosticMessage> analyzeErrors;
if (!analyzeFunction(context, &function, &analyzeErrors)) {
@@ -70,8 +72,10 @@ QQmlJSLinterCodegen::compileFunction(const QV4::Compiler::Context *context,
&m_typeResolver, m_currentObject->location, m_currentScope->location);
QQmlJSCompilePass::Function function =
initializer.run(context, name, astNode, &initializationErrors);
- for (const auto &error : initializationErrors)
- diagnose(error.message, error.type, error.loc);
+ for (const auto &error : initializationErrors) {
+ diagnose(u"Could not determine signature of function %1: %2"_s.arg(name, error.message),
+ error.type, error.loc);
+ }
QList<QQmlJS::DiagnosticMessage> analyzeErrors;
if (!analyzeFunction(context, &function, &analyzeErrors)) {