aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmltc/prototype/qml2cppdefaultpasses.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmltc/prototype/qml2cppdefaultpasses.cpp')
-rw-r--r--tools/qmltc/prototype/qml2cppdefaultpasses.cpp56
1 files changed, 50 insertions, 6 deletions
diff --git a/tools/qmltc/prototype/qml2cppdefaultpasses.cpp b/tools/qmltc/prototype/qml2cppdefaultpasses.cpp
index 586cc85754..8372d397d0 100644
--- a/tools/qmltc/prototype/qml2cppdefaultpasses.cpp
+++ b/tools/qmltc/prototype/qml2cppdefaultpasses.cpp
@@ -35,6 +35,8 @@
#include <algorithm>
+QT_BEGIN_NAMESPACE
+
static QString const cppKeywords[] = {
u"alignas"_qs,
u"alignof"_qs,
@@ -534,7 +536,7 @@ static void setupQmlCppType(const Qml2CppContext &context, const QQmlJSScope::Pt
context.recordError(type->sourceLocation(), u"QML type has unknown file path"_qs);
return;
}
- if (!type->fileName().isEmpty()) // consider this one to be already set up
+ if (type->filePath().endsWith(u".h")) // consider this one to be already set up
return;
if (!filePath.endsWith(u".qml"_qs)) {
context.recordError(type->sourceLocation(),
@@ -545,7 +547,7 @@ static void setupQmlCppType(const Qml2CppContext &context, const QQmlJSScope::Pt
// TODO: this does not cover QT_QMLTC_FILE_BASENAME renaming
if (filePath != context.documentUrl) {
// this file name will be discovered during findCppIncludes
- type->setFileName(QFileInfo(filePath).baseName().toLower() + u".h"_qs);
+ type->setFilePath(QFileInfo(filePath).baseName().toLower() + u".h"_qs);
}
const auto properties = type->ownProperties();
@@ -786,7 +788,7 @@ static void addFirstCppIncludeFromType(QSet<QString> &cppIncludes,
auto t = QQmlJSScope::nonCompositeBaseType(type);
if (!t)
return;
- if (QString includeFile = t->fileName(); !includeFile.isEmpty())
+ if (QString includeFile = t->filePath(); includeFile.endsWith(u".h"))
cppIncludes.insert(includeFile);
}
@@ -816,7 +818,7 @@ static void populateCppIncludes(QSet<QString> &cppIncludes, const QQmlJSScope::C
for (auto t = type; t; t = t->baseType()) {
// NB: Composite types might have include files - this is custom qmltc
// logic for local imports
- if (QString includeFile = t->fileName(); !includeFile.isEmpty())
+ if (QString includeFile = t->filePath(); includeFile.endsWith(u".h"))
cppIncludes.insert(includeFile);
// look in property types
@@ -824,8 +826,10 @@ static void populateCppIncludes(QSet<QString> &cppIncludes, const QQmlJSScope::C
for (const QQmlJSMetaProperty &p : properties) {
addFirstCppIncludeFromType(cppIncludes, p.type());
- if (p.isPrivate()) {
- const QString ownersInclude = QQmlJSScope::nonCompositeBaseType(t)->fileName();
+ const auto baseType = QQmlJSScope::nonCompositeBaseType(t);
+
+ if (p.isPrivate() && baseType->filePath().endsWith(u".h")) {
+ const QString ownersInclude = baseType->filePath();
QString privateInclude = constructPrivateInclude(ownersInclude);
if (!privateInclude.isEmpty())
cppIncludes.insert(std::move(privateInclude));
@@ -1079,3 +1083,43 @@ QSet<QQmlJSScope::ConstPtr> collectIgnoredTypes(const Qml2CppContext &context,
return ignored;
}
+
+static void setDeferred(const Qml2CppContext &context, qsizetype objectIndex,
+ QList<Qml2CppObject> &objects)
+{
+ Q_UNUSED(objects);
+
+ Qml2CppObject &o = objects[objectIndex];
+
+ // c.f. QQmlDeferredAndCustomParserBindingScanner::scanObject()
+ if (o.irObject->flags & QV4::CompiledData::Object::IsComponent) {
+ // unlike QmlIR compiler, qmltc should not care about anything within a
+ // component (let the QQmlComponent wrapper - at runtime anyway - take
+ // care of this type instead)
+ return;
+ }
+
+ const auto setRecursive = [&](QmlIR::Binding &binding) {
+ if (binding.type >= QmlIR::Binding::Type_Object)
+ setDeferred(context, binding.value.objectIndex, objects); // Note: recursive call here!
+
+ const QString propName = findPropertyName(context, o.type, binding);
+ Q_ASSERT(!propName.isEmpty());
+
+ if (o.type->isNameDeferred(propName)) {
+ binding.flags |= QV4::CompiledData::Binding::IsDeferredBinding;
+ o.irObject->flags |= QV4::CompiledData::Object::HasDeferredBindings;
+ }
+ };
+
+ std::for_each(o.irObject->bindingsBegin(), o.irObject->bindingsEnd(), setRecursive);
+}
+
+void setDeferredBindings(const Qml2CppContext &context, QList<Qml2CppObject> &objects)
+{
+ // as we do not support InlineComponents just yet, we can shortcut the logic
+ // here to only work with root object
+ setDeferred(context, 0, objects);
+}
+
+QT_END_NAMESPACE