// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Qt-Security score:significant reason:default #ifndef QQMLCODEMODEL_P_H #define QQMLCODEMODEL_P_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 "qlanguageserver_p.h" #include "qtextdocument_p.h" #include "qprocessscheduler_p.h" #include "qqmllshelputils_p.h" #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class TextSynchronization; namespace QmlLsp { class OpenDocumentSnapshot { public: enum class DumpOption { NoCode = 0, LatestCode = 0x1, ValidCode = 0x2, AllCode = LatestCode | ValidCode }; Q_DECLARE_FLAGS(DumpOptions, DumpOption) QStringList searchPath; QByteArray url; std::optional docVersion; QQmlJS::Dom::DomItem doc; std::optional validDocVersion; QQmlJS::Dom::DomItem validDoc; QDateTime scopeDependenciesLoadTime; bool scopeDependenciesChanged = false; QQmlJSScope::ConstPtr scope; QDebug dump(QDebug dbg, DumpOptions dump = DumpOption::NoCode); }; Q_DECLARE_OPERATORS_FOR_FLAGS(OpenDocumentSnapshot::DumpOptions) class OpenDocument { public: OpenDocumentSnapshot snapshot; std::shared_ptr textDocument; }; struct RegisteredSemanticTokens { QByteArray resultId = "0"; QList lastTokens; }; struct ModuleSetting { QString sourceFolder; QStringList importPaths; }; using ModuleSettings = QList; class QQmllsBuildInformation { public: QQmllsBuildInformation(); void loadSettingsFrom(const QStringList &buildPaths); QStringList importPathsFor(const QString &filePath); ModuleSetting settingFor(const QString &filePath); private: QString m_docDir; ModuleSettings m_moduleSettings; QSet m_seenSettings; }; enum UpdatePolicy { NormalUpdate, ForceUpdate }; class QQmlCodeModel : public QObject { Q_OBJECT public: enum class UrlLookup { Caching, ForceLookup }; enum class State { Running, Stopping }; explicit QQmlCodeModel(const QByteArray &rootUrl = {}, QObject *parent = nullptr, QQmlToolingSharedSettings *settings = nullptr); ~QQmlCodeModel(); QQmlJS::Dom::DomItem currentEnv() const { return m_currentEnv; }; QQmlJS::Dom::DomItem validEnv() const { return m_validEnv; }; OpenDocumentSnapshot snapshotByUrl(const QByteArray &url); OpenDocument openDocumentByUrl(const QByteArray &url); bool isEmpty() const; void addOpenToUpdate(const QByteArray &, UpdatePolicy policy); void removeDirectory(const QByteArray &); // void updateDocument(const OpenDocument &doc); void newOpenFile(const QByteArray &url, int version, const QString &docText); void newDocForOpenFile(const QByteArray &url, int version, const QString &docText, UpdatePolicy policy); void closeOpenFile(const QByteArray &url); QByteArray rootUrl() const; QStringList buildPaths(); QStringList buildPathsForFileUrl(const QByteArray &url); void setBuildPaths(const QStringList &paths); QStringList buildPathsForOpenedFiles(); QStringList importPathsForUrl(const QByteArray &); QStringList importPaths() const; void setImportPaths(const QStringList &paths); QQmlToolingSharedSettings *settings() const { return m_settings; } QStringList findFilePathsFromFileNames(const QStringList &fileNames, const QSet &alreadyWatchedFiles); static QStringList fileNamesToWatch(const QQmlJS::Dom::DomItem &qmlFile); void disableCMakeCalls(); void tryEnableCMakeCalls(QProcessScheduler *scheduler); RegisteredSemanticTokens ®isteredTokens(); const RegisteredSemanticTokens ®isteredTokens() const; QString documentationRootPath() const { QMutexLocker l(&m_mutex); return m_documentationRootPath; } void setDocumentationRootPath(const QString &path); QSet ignoreForWatching() const { QMutexLocker guard(&m_mutex); return m_ignoreForWatching; } HelpManager *helpManager() { return &m_helpManager; } void setVerbose(bool verbose) { QMutexLocker guard(&m_mutex); m_verbose = verbose; } bool verbose() const { QMutexLocker guard(&m_mutex); return m_verbose; } Q_SIGNALS: void updatedSnapshot(const QByteArray &url, UpdatePolicy policy); void documentationRootPathChanged(const QString &path); private: void addDirectory(const QString &path, int leftDepth); bool openUpdateSome(); void openUpdateStart(); void openUpdateEnd(); void openUpdate(const QByteArray &, UpdatePolicy policy); void openNeedUpdate(); QString url2Path(const QByteArray &url, UrlLookup options = UrlLookup::Caching); void callCMakeBuild(QProcessScheduler *scheduler); void onCMakeProcessFinished(const QByteArray &id); void addFileWatches(const QQmlJS::Dom::DomItem &qmlFile); void onBuildOrImportPathChanged(); enum CMakeStatus { RequiresInitialization, HasCMake, DoesNotHaveCMake }; CMakeStatus cmakeStatus() const { QMutexLocker guard(&m_mutex); return m_cmakeStatus; } void setCMakeStatus(CMakeStatus status) { QMutexLocker guard(&m_mutex); m_cmakeStatus = status; } mutable QMutex m_mutex; const QByteArray m_rootUrl; // note: access without m_mutex, is const QQmlJS::Dom::DomItem m_currentEnv; // note: access without m_mutex, has thread-safe API QQmlJS::Dom::DomItem m_validEnv; // note: access without m_mutex, has thread-safe API QQmlToolingSharedSettings *m_settings; // note: access without m_mutex. has thread-safe API HelpManager m_helpManager; // note: access without m_mutex, has thread-safe API QHash m_openDocumentsToUpdate; QStringList m_buildPaths; QStringList m_importPaths; QHash m_url2path; QHash m_path2url; QHash m_openDocuments; QQmllsBuildInformation m_buildInformation; QFileSystemWatcher m_cppFileWatcher; RegisteredSemanticTokens m_tokens; QString m_documentationRootPath; QSet m_ignoreForWatching; int m_nUpdateInProgress = 0; CMakeStatus m_cmakeStatus = RequiresInitialization; bool m_verbose = false; }; } // namespace QmlLsp QT_END_NAMESPACE #endif // QQMLCODEMODEL_P_H