diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-02-28 15:28:34 +0100 |
---|---|---|
committer | Andrei Golubev <andrei.golubev@qt.io> | 2022-03-08 18:35:19 +0100 |
commit | 3c680af4e9164b81548c1c633f3c0a2f0583aea4 (patch) | |
tree | 9dcb497af48f33ee11acb7ac9ab4c9550b78dce8 | |
parent | abee06cbabcd8df286d5c1d5d0079e3ece9e310a (diff) |
Remove qmltc prototype code (1/N)
- Wrap prototype code into Qt namespace
- Move inline component logic from prototype/visitor to qmltcvisitor
and erase (for now) property method setting (in favor of the
prototype logic which is more advanced)
- Move prototype/typeresolver.cpp into qmltctyperesolver.cpp
- Delete (now useless) prototype/{visitor, typeresolver}
- Start cleaning up prototype/qmlcompiler.h
- Adjust prototype/codegenerator accordingly
Change-Id: If49d6aa8bb97093b273915caa356278ca9bbdfe1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
21 files changed, 135 insertions, 254 deletions
diff --git a/tools/qmltc/CMakeLists.txt b/tools/qmltc/CMakeLists.txt index cf35319a3b..8408e4bd84 100644 --- a/tools/qmltc/CMakeLists.txt +++ b/tools/qmltc/CMakeLists.txt @@ -8,7 +8,7 @@ qt_internal_add_tool(${target_name} qmltcoutputprimitives.h qmltccodewriter.h qmltccodewriter.cpp qmltcoutputir.h - qmltctyperesolver.h + qmltctyperesolver.h qmltctyperesolver.cpp qmltcvisitor.h qmltcvisitor.cpp qmltccompiler.h qmltccompiler.cpp qmltccompilerpieces.h @@ -16,13 +16,11 @@ qt_internal_add_tool(${target_name} prototype/generatedcodeprimitives.h prototype/qml2cppcontext.h - prototype/visitor.cpp prototype/visitor.h prototype/qml2cppdefaultpasses.cpp prototype/qml2cppdefaultpasses.h prototype/codegenerator.cpp prototype/codegenerator.h prototype/codegeneratorutil.cpp prototype/codegeneratorutil.h prototype/codegeneratorwriter.cpp prototype/codegeneratorwriter.h prototype/qmlcompiler.h - prototype/typeresolver.cpp prototype/typeresolver.h DEFINES QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII diff --git a/tools/qmltc/main.cpp b/tools/qmltc/main.cpp index 7498622ee4..49e218f4fe 100644 --- a/tools/qmltc/main.cpp +++ b/tools/qmltc/main.cpp @@ -28,8 +28,10 @@ #include "qmltccommandlineutils.h" #include "prototype/codegenerator.h" -#include "prototype/visitor.h" -#include "prototype/typeresolver.h" +#include "qmltcvisitor.h" +#include "qmltctyperesolver.h" + +#include "qmltccompiler.h" #include <QtQml/private/qqmlirbuilder_p.h> #include <private/qqmljscompiler_p.h> @@ -185,11 +187,11 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - Options options; - options.outputCppFile = parser.value(outputCppOption); - options.outputHFile = parser.value(outputHOption); - options.resourcePath = paths.first(); - options.outNamespace = parser.value(namespaceOption); + QmltcCompilerInfo info; + info.outputCppFile = parser.value(outputCppOption); + info.outputHFile = parser.value(outputHOption); + info.resourcePath = paths.first(); + info.outputNamespace = parser.value(namespaceOption); QQmlJSImporter importer { importPaths, &mapper }; QQmlJSLogger logger; @@ -197,9 +199,9 @@ int main(int argc, char **argv) logger.setCode(sourceCode); setupLogger(logger); - Qmltc::Visitor visitor(&importer, &logger, - QQmlJSImportVisitor::implicitImportDirectory(url, &mapper), qmldirFiles); - Qmltc::TypeResolver typeResolver { &importer }; + QmltcVisitor visitor(&importer, &logger, + QQmlJSImportVisitor::implicitImportDirectory(url, &mapper), qmldirFiles); + QmltcTypeResolver typeResolver { &importer }; typeResolver.init(visitor, document.program); if (logger.hasErrors()) @@ -214,8 +216,8 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - CodeGenerator generator(url, &logger, &document, &typeResolver); - generator.generate(options); + CodeGenerator generator(url, &logger, &document, &typeResolver, &info); + generator.generate(); if (logger.hasErrors()) return EXIT_FAILURE; diff --git a/tools/qmltc/prototype/codegenerator.cpp b/tools/qmltc/prototype/codegenerator.cpp index 213b68b085..83c4b7d94b 100644 --- a/tools/qmltc/prototype/codegenerator.cpp +++ b/tools/qmltc/prototype/codegenerator.cpp @@ -32,6 +32,8 @@ #include "prototype/codegeneratorutil.h" #include "prototype/codegeneratorwriter.h" +#include "qmltccompiler.h" + #include <QtCore/qfileinfo.h> #include <QtCore/qhash.h> #include <QtCore/qset.h> @@ -45,12 +47,7 @@ #include <utility> #include <numeric> -static constexpr char newLineLatin1[] = -#ifdef Q_OS_WIN32 - "\r\n"; -#else - "\n"; -#endif +QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcCodeGenerator, "qml.qmltc.compiler", QtWarningMsg); @@ -216,13 +213,12 @@ toOrderedSequence(typename QmlIR::PoolList<QmlIR::Binding>::Iterator first, Q_LOGGING_CATEGORY(lcCodeGen, "qml.compiler.CodeGenerator", QtWarningMsg); CodeGenerator::CodeGenerator(const QString &url, QQmlJSLogger *logger, QmlIR::Document *doc, - const Qmltc::TypeResolver *localResolver) - : m_url(url), - m_logger(logger), - m_doc(doc), - m_localTypeResolver(localResolver), - m_qmlSource(doc->code.split(QLatin1String(newLineLatin1))) + const QmltcTypeResolver *localResolver, const QmltcCompilerInfo *info) + : m_url(url), m_logger(logger), m_doc(doc), m_localTypeResolver(localResolver), m_info(info) { + Q_ASSERT(m_info); + Q_ASSERT(!m_info->outputHFile.isEmpty()); + Q_ASSERT(!m_info->outputCppFile.isEmpty()); } void CodeGenerator::constructObjects(QSet<QString> &requiredCppIncludes) @@ -297,16 +293,13 @@ void CodeGenerator::constructObjects(QSet<QString> &requiredCppIncludes) executor.run(m_logger); } -void CodeGenerator::generate(const Options &options) +void CodeGenerator::generate() { - m_options = options; GeneratedCode code; const QString rootClassName = QFileInfo(m_url).baseName(); Q_ASSERT(!rootClassName.isEmpty()); - Q_ASSERT(!options.outputHFile.isEmpty()); - Q_ASSERT(!options.outputCppFile.isEmpty()); - const QString hPath = options.outputHFile; - const QString cppPath = options.outputCppFile; + const QString hPath = m_info->outputHFile; + const QString cppPath = m_info->outputCppFile; m_isAnonymous = rootClassName.at(0).isLower(); const QString url = QFileInfo(m_url).fileName(); @@ -366,8 +359,8 @@ void CodeGenerator::generate(const Options &options) if (m_logger->hasErrors()) return; - QQmlJSProgram program { compiledObjects, m_urlMethod, url, hPath, cppPath, - options.outNamespace, requiredCppIncludes }; + QQmlJSProgram program { compiledObjects, m_urlMethod, url, hPath, cppPath, + m_info->outputNamespace, requiredCppIncludes }; // write everything GeneratedCodeUtils codeUtils(code); @@ -1918,7 +1911,7 @@ void CodeGenerator::compileUrlMethod() m_urlMethod.returnType = u"const QUrl &"_qs; m_urlMethod.name = u"q_qmltc_docUrl"_qs; m_urlMethod.body << u"static QUrl docUrl = %1;"_qs.arg( - CodeGeneratorUtility::toResourcePath(m_options.resourcePath)); + CodeGeneratorUtility::toResourcePath(m_info->resourcePath)); m_urlMethod.body << u"return docUrl;"_qs; m_urlMethod.declPreambles << u"static"_qs; m_urlMethod.modifiers << u"noexcept"_qs; @@ -1933,3 +1926,5 @@ void CodeGenerator::recordError(const QV4::CompiledData::Location &location, con { recordError(QQmlJS::SourceLocation { 0, 0, location.line, location.column }, message); } + +QT_END_NAMESPACE diff --git a/tools/qmltc/prototype/codegenerator.h b/tools/qmltc/prototype/codegenerator.h index 63549ae76e..06cbb3b673 100644 --- a/tools/qmltc/prototype/codegenerator.h +++ b/tools/qmltc/prototype/codegenerator.h @@ -29,7 +29,7 @@ #ifndef CODEGENERATOR_H #define CODEGENERATOR_H -#include "prototype/typeresolver.h" +#include "qmltctyperesolver.h" #include "prototype/qmlcompiler.h" #include "prototype/generatedcodeprimitives.h" #include "prototype/qml2cppcontext.h" @@ -40,19 +40,21 @@ #include <QtQml/private/qqmlirbuilder_p.h> #include <private/qqmljscompiler_p.h> -#include <private/qqmljstyperesolver_p.h> #include <variant> #include <utility> +QT_BEGIN_NAMESPACE + +struct QmltcCompilerInfo; class CodeGenerator { public: CodeGenerator(const QString &url, QQmlJSLogger *logger, QmlIR::Document *doc, - const Qmltc::TypeResolver *localResolver); + const QmltcTypeResolver *localResolver, const QmltcCompilerInfo *info); // main function: given compilation options, generates C++ code (implicitly) - void generate(const Options &options); + void generate(); // TODO: this should really be just QQmlJSScope::ConstPtr (and maybe C++ // class name), but bindings are currently not represented in QQmlJSScope, @@ -63,10 +65,9 @@ private: QString m_url; // document url QQmlJSLogger *m_logger = nullptr; QmlIR::Document *m_doc = nullptr; - const Qmltc::TypeResolver *m_localTypeResolver = nullptr; - QStringList m_qmlSource; // QML source code split to lines + const QmltcTypeResolver *m_localTypeResolver = nullptr; - Options m_options = {}; // compilation options + const QmltcCompilerInfo *m_info = nullptr; // convenient object abstraction, laid out as QmlIR::Document.objects QList<CodeGenObject> m_objects; @@ -186,4 +187,6 @@ private: void recordError(const QV4::CompiledData::Location &location, const QString &message); }; +QT_END_NAMESPACE + #endif // CODEGENERATOR_H diff --git a/tools/qmltc/prototype/codegeneratorutil.cpp b/tools/qmltc/prototype/codegeneratorutil.cpp index 3d7300e0d8..f9473a4114 100644 --- a/tools/qmltc/prototype/codegeneratorutil.cpp +++ b/tools/qmltc/prototype/codegeneratorutil.cpp @@ -33,6 +33,8 @@ #include <tuple> +QT_BEGIN_NAMESPACE + // NB: this variable would behave correctly as long as QML init and QML finalize // are non-virtual functions const QQmlJSAotVariable CodeGeneratorUtility::childrenOffsetVariable = { u"qsizetype"_qs, @@ -245,3 +247,5 @@ QString CodeGeneratorUtility::generate_setIdValue(const QString &context, qsizet return context + u"->setIdValue(" + QString::number(index) + idComment + u", " + accessor + u")"; } + +QT_END_NAMESPACE diff --git a/tools/qmltc/prototype/codegeneratorutil.h b/tools/qmltc/prototype/codegeneratorutil.h index d8b8defac8..563896637d 100644 --- a/tools/qmltc/prototype/codegeneratorutil.h +++ b/tools/qmltc/prototype/codegeneratorutil.h @@ -39,6 +39,8 @@ #include <utility> +QT_BEGIN_NAMESPACE + struct CodeGeneratorUtility { // magic variable, necessary for correct handling of object bindings: since @@ -96,4 +98,6 @@ struct CodeGeneratorUtility const QString &accessor, const QString &idString); }; +QT_END_NAMESPACE + #endif // CODEGENERATORUTIL_H diff --git a/tools/qmltc/prototype/codegeneratorwriter.cpp b/tools/qmltc/prototype/codegeneratorwriter.cpp index d43a94084e..a932012b63 100644 --- a/tools/qmltc/prototype/codegeneratorwriter.cpp +++ b/tools/qmltc/prototype/codegeneratorwriter.cpp @@ -34,6 +34,8 @@ #include <utility> #include <functional> +QT_BEGIN_NAMESPACE + static constexpr char16_t newLine[] = #ifdef Q_OS_WIN32 u"\r\n"; @@ -474,3 +476,5 @@ void CodeGeneratorWriter::write(GeneratedCodeUtils &code, const QQmlJSProgram &c writeGlobalFooter(code, compiled.url, compiled.hPath, compiled.cppPath, compiled.outNamespace); } + +QT_END_NAMESPACE diff --git a/tools/qmltc/prototype/codegeneratorwriter.h b/tools/qmltc/prototype/codegeneratorwriter.h index e03a2123ac..d33a8affd4 100644 --- a/tools/qmltc/prototype/codegeneratorwriter.h +++ b/tools/qmltc/prototype/codegeneratorwriter.h @@ -32,6 +32,8 @@ #include "generatedcodeprimitives.h" #include "qmlcompiler.h" +QT_BEGIN_NAMESPACE + // writes compiled code into the GeneratedCode structure struct CodeGeneratorWriter { @@ -54,4 +56,6 @@ private: static void writeUrl(GeneratedCodeUtils &code, const QQmlJSAotMethod &urlMethod); }; +QT_END_NAMESPACE + #endif // CODEGENERATORWRITER_H diff --git a/tools/qmltc/prototype/generatedcodeprimitives.h b/tools/qmltc/prototype/generatedcodeprimitives.h index 46d7b1461f..72007caae3 100644 --- a/tools/qmltc/prototype/generatedcodeprimitives.h +++ b/tools/qmltc/prototype/generatedcodeprimitives.h @@ -32,6 +32,8 @@ #include <QtCore/qstring.h> #include <QtCore/qstack.h> +QT_BEGIN_NAMESPACE + // holds generated code for header and implementation files struct GeneratedCode { @@ -123,4 +125,6 @@ struct GeneratedCodeUtils } }; +QT_END_NAMESPACE + #endif // GENERATEDCODEPRIMITIVES_H diff --git a/tools/qmltc/prototype/qml2cppcontext.h b/tools/qmltc/prototype/qml2cppcontext.h index f80beaebfb..a8b6aa7c90 100644 --- a/tools/qmltc/prototype/qml2cppcontext.h +++ b/tools/qmltc/prototype/qml2cppcontext.h @@ -30,7 +30,7 @@ #define QML2CPPCONTEXT_H #include "prototype/qmlcompiler.h" -#include "prototype/typeresolver.h" +#include "qmltctyperesolver.h" #include <private/qqmljsdiagnosticmessage_p.h> #include <QtQml/private/qqmlirbuilder_p.h> @@ -41,10 +41,12 @@ #include <variant> #include <functional> +QT_BEGIN_NAMESPACE + struct Qml2CppContext { const QmlIR::Document *document = nullptr; - const Qmltc::TypeResolver *typeResolver = nullptr; + const QmltcTypeResolver *typeResolver = nullptr; QString documentUrl; QQmlJSLogger *logger = nullptr; const QHash<QQmlJSScope::ConstPtr, qsizetype> *typeIndices = nullptr; // TODO: remove this? @@ -81,7 +83,7 @@ class Qml2CppCompilerPassExecutor QList<Qml2CppCompilerPass> m_passes; public: - Qml2CppCompilerPassExecutor(const QmlIR::Document *doc, const Qmltc::TypeResolver *resolver, + Qml2CppCompilerPassExecutor(const QmlIR::Document *doc, const QmltcTypeResolver *resolver, const QString &url, QList<Qml2CppObject> &objects, const QHash<QQmlJSScope::ConstPtr, qsizetype> &typeIndices) : m_context { doc, resolver, url, nullptr, &typeIndices }, m_objects { objects } @@ -105,4 +107,6 @@ public: } }; +QT_END_NAMESPACE + #endif // QML2CPPCONTEXT_H diff --git a/tools/qmltc/prototype/qml2cppdefaultpasses.cpp b/tools/qmltc/prototype/qml2cppdefaultpasses.cpp index efe9215104..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, @@ -1119,3 +1121,5 @@ void setDeferredBindings(const Qml2CppContext &context, QList<Qml2CppObject> &ob // here to only work with root object setDeferred(context, 0, objects); } + +QT_END_NAMESPACE diff --git a/tools/qmltc/prototype/qml2cppdefaultpasses.h b/tools/qmltc/prototype/qml2cppdefaultpasses.h index 443292b30f..6a1d0ca124 100644 --- a/tools/qmltc/prototype/qml2cppdefaultpasses.h +++ b/tools/qmltc/prototype/qml2cppdefaultpasses.h @@ -31,6 +31,8 @@ #include "prototype/qml2cppcontext.h" +QT_BEGIN_NAMESPACE + // verifies that each object, property (and etc.) has valid // QQmlJSScope::ConstPtr associated with it void verifyTypes(const Qml2CppContext &context, QList<Qml2CppObject> &objects); @@ -88,4 +90,6 @@ QSet<QQmlJSScope::ConstPtr> collectIgnoredTypes(const Qml2CppContext &context, void setDeferredBindings(const Qml2CppContext &context, QList<Qml2CppObject> &objects); +QT_END_NAMESPACE + #endif // QML2CPPPASSES_H diff --git a/tools/qmltc/prototype/qml2cpppropertyutils.h b/tools/qmltc/prototype/qml2cpppropertyutils.h index 4b3e513b90..31f3f73297 100644 --- a/tools/qmltc/prototype/qml2cpppropertyutils.h +++ b/tools/qmltc/prototype/qml2cpppropertyutils.h @@ -31,6 +31,8 @@ #include <private/qqmljsmetatypes_p.h> +QT_BEGIN_NAMESPACE + inline QString getUnderlyingType(const QQmlJSMetaProperty &p) { QString underlyingType = p.type()->internalName(); @@ -64,4 +66,6 @@ struct Qml2CppPropertyData QString notify; }; +QT_END_NAMESPACE + #endif // QML2CPPPROPERTYUTILS_H diff --git a/tools/qmltc/prototype/qmlcompiler.h b/tools/qmltc/prototype/qmlcompiler.h index 3c770612cc..60174bdab1 100644 --- a/tools/qmltc/prototype/qmlcompiler.h +++ b/tools/qmltc/prototype/qmlcompiler.h @@ -46,15 +46,7 @@ #include <private/qqmljscompiler_p.h> #include <private/qqmljsmetatypes_p.h> -struct Options -{ - QString outputCppFile; - QString outputHFile; - QString moduleUri; - QString resourcePath; - QString outNamespace; - bool debugGenerateLineDirective = false; -}; +QT_BEGIN_NAMESPACE // TODO: rename the classes into Qmltc* pattern @@ -176,4 +168,6 @@ struct QQmlJSProgram QSet<QString> includes; }; +QT_END_NAMESPACE + #endif // QMLCOMPILER_H diff --git a/tools/qmltc/prototype/typeresolver.h b/tools/qmltc/prototype/typeresolver.h deleted file mode 100644 index a382c4c07a..0000000000 --- a/tools/qmltc/prototype/typeresolver.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TYPERESOLVER_H -#define TYPERESOLVER_H - -#include "prototype/visitor.h" - -#include <private/qqmljsscope_p.h> -#include <private/qqmljsast_p.h> -#include <private/qqmlirbuilder_p.h> -#include <private/qqmljstyperesolver_p.h> - -namespace Qmltc { -class TypeResolver : public QQmlJSTypeResolver -{ -public: - TypeResolver(QQmlJSImporter *importer); - - void init(Visitor &visitor, QQmlJS::AST::Node *program); - - // TODO: this shouldn't be exposed. instead, all the custom passes on - // QQmlJSScope types must happen inside Visitor - QQmlJSScope::Ptr root() const { return m_root; } - - QQmlJSScope::Ptr scopeForLocation(const QV4::CompiledData::Location &location) const; - - // returns an import pair {url, modifiable type} for a given \a type - QPair<QString, QQmlJSScope::Ptr> importedType(const QQmlJSScope::ConstPtr &type) const; - -private: - QQmlJSImporter *m_importer = nullptr; - - QHash<QV4::CompiledData::Location, QQmlJSScope::Ptr> m_objectsByLocationNonConst; - QQmlJSScope::Ptr m_root; -}; -} - -#endif // TYPERESOLVER_H diff --git a/tools/qmltc/prototype/visitor.cpp b/tools/qmltc/prototype/visitor.cpp deleted file mode 100644 index 190b2a59a4..0000000000 --- a/tools/qmltc/prototype/visitor.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "prototype/visitor.h" - -#include <QtCore/qdir.h> -#include <QtCore/qfileinfo.h> - -namespace Qmltc { -Visitor::Visitor(QQmlJSImporter *importer, QQmlJSLogger *logger, - const QString &implicitImportDirectory, const QStringList &qmltypesFiles) - : QQmlJSImportVisitor(importer, logger, implicitImportDirectory, qmltypesFiles) -{ -} - -bool Visitor::visit(QQmlJS::AST::UiInlineComponent *component) -{ - if (!QQmlJSImportVisitor::visit(component)) - return false; - m_logger->log(u"Inline components are not supported"_qs, Log_Compiler, - component->firstSourceLocation()); - // despite the failure, return true here so that we do not assert in - // QQmlJSImportVisitor::endVisit(UiInlineComponent) - return true; -} -} diff --git a/tools/qmltc/prototype/visitor.h b/tools/qmltc/prototype/visitor.h deleted file mode 100644 index 730021b66c..0000000000 --- a/tools/qmltc/prototype/visitor.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VISITOR_H -#define VISITOR_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. - -#include <private/qqmljsimportvisitor_p.h> - -namespace Qmltc { -class Visitor : public QQmlJSImportVisitor -{ -public: - Visitor(QQmlJSImporter *importer, QQmlJSLogger *logger, const QString &implicitImportDirectory, - const QStringList &qmltypesFiles = QStringList()); - - bool visit(QQmlJS::AST::UiInlineComponent *) override; -}; -} - -#endif // VISITOR_H diff --git a/tools/qmltc/prototype/typeresolver.cpp b/tools/qmltc/qmltctyperesolver.cpp index 377787830e..2d46cf38b3 100644 --- a/tools/qmltc/prototype/typeresolver.cpp +++ b/tools/qmltc/qmltctyperesolver.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -26,8 +26,7 @@ ** ****************************************************************************/ -#include "prototype/typeresolver.h" -#include "prototype/visitor.h" +#include "qmltctyperesolver.h" #include <private/qqmljsimporter_p.h> #include <private/qv4value_p.h> @@ -37,17 +36,9 @@ #include <QtCore/qfileinfo.h> #include <QtCore/qdiriterator.h> -Q_LOGGING_CATEGORY(lcTypeResolver2, "qml.compiler.typeresolver", QtInfoMsg); +Q_LOGGING_CATEGORY(lcTypeResolver2, "qml.qmltc.typeresolver", QtInfoMsg); -namespace Qmltc { - -TypeResolver::TypeResolver(QQmlJSImporter *importer) - : QQmlJSTypeResolver(importer), m_importer(importer) -{ - Q_ASSERT(m_importer); -} - -void TypeResolver::init(Visitor &visitor, QQmlJS::AST::Node *program) +void QmltcTypeResolver::init(QmltcVisitor &visitor, QQmlJS::AST::Node *program) { QQmlJSTypeResolver::init(&visitor, program); m_root = visitor.result(); @@ -67,14 +58,16 @@ void TypeResolver::init(Visitor &visitor, QQmlJS::AST::Node *program) } } -QQmlJSScope::Ptr TypeResolver::scopeForLocation(const QV4::CompiledData::Location &location) const +QQmlJSScope::Ptr +QmltcTypeResolver::scopeForLocation(const QV4::CompiledData::Location &location) const { qCDebug(lcTypeResolver2()).nospace() << "looking for object at " << location.line << ':' << location.column; return m_objectsByLocationNonConst.value(location); } -QPair<QString, QQmlJSScope::Ptr> TypeResolver::importedType(const QQmlJSScope::ConstPtr &type) const +QPair<QString, QQmlJSScope::Ptr> +QmltcTypeResolver::importedType(const QQmlJSScope::ConstPtr &type) const { const auto files = m_importer->importedFiles(); auto it = std::find_if(files.cbegin(), files.cend(), [&](const QQmlJSScope::Ptr &importedType) { @@ -84,4 +77,3 @@ QPair<QString, QQmlJSScope::Ptr> TypeResolver::importedType(const QQmlJSScope::C return {}; return { it.key(), it.value() }; } -} diff --git a/tools/qmltc/qmltctyperesolver.h b/tools/qmltc/qmltctyperesolver.h index 495f78b81d..ae9e98c23e 100644 --- a/tools/qmltc/qmltctyperesolver.h +++ b/tools/qmltc/qmltctyperesolver.h @@ -29,6 +29,8 @@ #ifndef QMLTCTYPERESOLVER_H #define QMLTCTYPERESOLVER_H +#include "qmltcvisitor.h" + #include <QtQml/private/qqmlirbuilder_p.h> #include <private/qqmljstyperesolver_p.h> #include <private/qqmljsimporter_p.h> @@ -39,7 +41,27 @@ QT_BEGIN_NAMESPACE class QmltcTypeResolver : public QQmlJSTypeResolver { public: - QmltcTypeResolver(QQmlJSImporter *importer) : QQmlJSTypeResolver(importer) {} + QmltcTypeResolver(QQmlJSImporter *importer) : QQmlJSTypeResolver(importer), m_importer(importer) + { + Q_ASSERT(importer); + } + + void init(QmltcVisitor &visitor, QQmlJS::AST::Node *program); + + // TODO: this shouldn't be exposed. instead, all the custom passes on + // QQmlJSScope types must happen inside Visitor + QQmlJSScope::Ptr root() const { return m_root; } + + QQmlJSScope::Ptr scopeForLocation(const QV4::CompiledData::Location &location) const; + + // returns an import pair {url, modifiable type} for a given \a type + QPair<QString, QQmlJSScope::Ptr> importedType(const QQmlJSScope::ConstPtr &type) const; + +private: + QQmlJSImporter *m_importer = nullptr; + + QHash<QV4::CompiledData::Location, QQmlJSScope::Ptr> m_objectsByLocationNonConst; + QQmlJSScope::Ptr m_root; }; QT_END_NAMESPACE diff --git a/tools/qmltc/qmltcvisitor.cpp b/tools/qmltc/qmltcvisitor.cpp index 37ceee94f8..b70e3fe329 100644 --- a/tools/qmltc/qmltcvisitor.cpp +++ b/tools/qmltc/qmltcvisitor.cpp @@ -187,16 +187,15 @@ bool QmltcVisitor::visit(QQmlJS::AST::UiPublicMember *publicMember) // augment property: set its write/read/etc. methods if (publicMember->type == QQmlJS::AST::UiPublicMember::Property) { const auto name = publicMember->name.toString(); - QQmlJSMetaProperty prop = m_currentScope->ownProperty(name); - const QString nameWithUppercase = name[0].toUpper() + name.sliced(1); - prop.setRead(name); - if (prop.isWritable()) - prop.setWrite(u"set" + nameWithUppercase); - prop.setBindable(u"bindable" + nameWithUppercase); - prop.setNotify(name + u"Changed"); + + // TODO: we should set the composite type property methods here, but as + // of now this is done in the pass over the types after the ast + // traversal + + const QString notifyName = name + u"Changed"_qs; // also check that notify is already a method of m_currentScope { - const auto methods = m_currentScope->ownMethods(prop.notify()); + const auto methods = m_currentScope->ownMethods(notifyName); if (methods.size() != 1) { const QString errorString = methods.isEmpty() ? u"no signal"_qs : u"too many signals"_qs; @@ -206,17 +205,27 @@ bool QmltcVisitor::visit(QQmlJS::AST::UiPublicMember *publicMember) return false; } else if (methods[0].methodType() != QQmlJSMetaMethod::Signal) { m_logger->log(u"internal error: method %1 of property %2 must be a signal"_qs.arg( - prop.notify(), name), + notifyName, name), Log_Compiler, publicMember->identifierToken); return false; } } - m_currentScope->addOwnProperty(prop); } return true; } +bool QmltcVisitor::visit(QQmlJS::AST::UiInlineComponent *component) +{ + if (!QQmlJSImportVisitor::visit(component)) + return false; + m_logger->log(u"Inline components are not supported"_qs, Log_Compiler, + component->firstSourceLocation()); + // despite the failure, return true here so that we do not assert in + // QQmlJSImportVisitor::endVisit(UiInlineComponent) + return true; +} + void QmltcVisitor::endVisit(QQmlJS::AST::UiProgram *program) { QQmlJSImportVisitor::endVisit(program); diff --git a/tools/qmltc/qmltcvisitor.h b/tools/qmltc/qmltcvisitor.h index d69c84d3ca..a543a4271c 100644 --- a/tools/qmltc/qmltcvisitor.h +++ b/tools/qmltc/qmltcvisitor.h @@ -56,10 +56,10 @@ public: bool visit(QQmlJS::AST::UiPublicMember *) override; + bool visit(QQmlJS::AST::UiInlineComponent *) override; + void endVisit(QQmlJS::AST::UiProgram *) override; - // NB: overwrite result() method to return ConstPtr - QQmlJSScope::ConstPtr result() const { return QQmlJSImportVisitor::result(); } QList<QQmlJSScope::ConstPtr> qmlScopesWithQmlBases() const { return m_qmlTypesWithQmlBases; } QSet<QString> cppIncludeFiles() const { return m_cppIncludes; } |