diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2021-12-14 11:09:17 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-17 22:48:16 +0000 |
commit | 177d0c57fc511a0c775147c6581095caafac0c25 (patch) | |
tree | 9d4fb5cb523f87185c44f8ddf92040b2634e0b8a /tools/qmltc/prototype/codegenerator.cpp | |
parent | c1fa37662459c72a9efe3126b81a5f25596020cf (diff) |
qmltc: Make special functions protected
Special functions are only invoked internally by the qmltc-generated
code. There is no reason in making them public as the compiler should
know which exact type would use another type (and so can generate
meaningful friend declarations)
Task-number: QTBUG-84368
Change-Id: I887ca8db7f916dba042f0ccbf19085aa438bf82d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 9cf864654f9154be52a7279a341948eabacfb397)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tools/qmltc/prototype/codegenerator.cpp')
-rw-r--r-- | tools/qmltc/prototype/codegenerator.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/tools/qmltc/prototype/codegenerator.cpp b/tools/qmltc/prototype/codegenerator.cpp index d02c98f04b..abb99ab401 100644 --- a/tools/qmltc/prototype/codegenerator.cpp +++ b/tools/qmltc/prototype/codegenerator.cpp @@ -247,8 +247,8 @@ void CodeGenerator::constructObjects(QSet<QString> &requiredCppIncludes) m_objects.emplaceBack(CodeGenObject { irObject, object }); } - // objects are constructed, now we can run compiler passes to make sure they - // are in good state + // objects are constructed, now we can run compiler passes to make sure the + // objects are in good state Qml2CppCompilerPassExecutor executor(m_doc, m_localTypeResolver, m_url, m_objects, m_typeToObjectIndex); executor.addPass(&verifyTypes); @@ -276,6 +276,11 @@ void CodeGenerator::constructObjects(QSet<QString> &requiredCppIncludes) }; executor.addPass(resolveImplicitComponents); executor.addPass(&setObjectIds); + const auto setImmediateParents = [&](const Qml2CppContext &context, + QList<Qml2CppObject> &objects) { + m_immediateParents = findImmediateParents(context, objects); + }; + executor.addPass(setImmediateParents); // run all passes: executor.run(m_logger); } @@ -373,14 +378,16 @@ void CodeGenerator::compileObject(QQmlJSAotObject &compiled, const CodeGenObject // add ctors code compiled.baselineCtor.access = QQmlJSMetaMethod::Protected; - compiled.externalCtor.access = QQmlJSMetaMethod::Public; + if (documentRoot) { + compiled.externalCtor.access = QQmlJSMetaMethod::Public; + } else { + compiled.externalCtor.access = QQmlJSMetaMethod::Protected; + } compiled.init.access = QQmlJSMetaMethod::Protected; - // TODO: all below could actually be hidden? (but need to befriend the - // document root, etc.) - compiled.endInit.access = QQmlJSMetaMethod::Public; - compiled.completeComponent.access = QQmlJSMetaMethod::Public; - compiled.finalizeComponent.access = QQmlJSMetaMethod::Public; - compiled.handleOnCompleted.access = QQmlJSMetaMethod::Public; + compiled.endInit.access = QQmlJSMetaMethod::Protected; + compiled.completeComponent.access = QQmlJSMetaMethod::Protected; + compiled.finalizeComponent.access = QQmlJSMetaMethod::Protected; + compiled.handleOnCompleted.access = QQmlJSMetaMethod::Protected; compiled.baselineCtor.name = compiled.cppType; compiled.externalCtor.name = compiled.cppType; @@ -413,6 +420,17 @@ void CodeGenerator::compileObject(QQmlJSAotObject &compiled, const CodeGenObject compiled.endInit.parameterList = { engine, CodeGeneratorUtility::compilationUnitVariable }; } + if (!documentRoot) { + // make document root a friend to allow protected member function access + Q_ASSERT(m_objects[0].type); + compiled.otherCode << u"friend class %1;"_qs.arg(m_objects[0].type->internalName()); + // additionally, befriend the immediate parent of this type + if (auto parent = m_immediateParents.value(object.type); + parent && parent != m_objects[0].type) { + compiled.otherCode << u"friend class %1;"_qs.arg(parent->internalName()); + } + } + if (baseTypeIsCompiledQml) { // call baseline ctor of the QML-originated base class. it also takes // care of QObject::setParent() call |