1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLCODEMODEL_P_H
5#define QQMLCODEMODEL_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qlanguageserver_p.h"
19#include "qtextdocument_p.h"
20
21#include <QObject>
22#include <QHash>
23#include <QtCore/qfilesystemwatcher.h>
24#include <QtCore/private/qfactoryloader_p.h>
25#include <QtQmlDom/private/qqmldomitem_p.h>
26#include <QtQmlCompiler/private/qqmljsscope_p.h>
27#include <QtQmlToolingSettings/private/qqmltoolingsettings_p.h>
28
29#include <functional>
30#include <memory>
31
32QT_BEGIN_NAMESPACE
33class TextSynchronization;
34namespace QmlLsp {
35
36class OpenDocumentSnapshot
37{
38public:
39 enum class DumpOption {
40 NoCode = 0,
41 LatestCode = 0x1,
42 ValidCode = 0x2,
43 AllCode = LatestCode | ValidCode
44 };
45 Q_DECLARE_FLAGS(DumpOptions, DumpOption)
46 QStringList searchPath;
47 QByteArray url;
48 std::optional<int> docVersion;
49 QQmlJS::Dom::DomItem doc;
50 std::optional<int> validDocVersion;
51 QQmlJS::Dom::DomItem validDoc;
52 std::optional<int> scopeVersion;
53 QDateTime scopeDependenciesLoadTime;
54 bool scopeDependenciesChanged = false;
55 QQmlJSScope::ConstPtr scope;
56 QDebug dump(QDebug dbg, DumpOptions dump = DumpOption::NoCode);
57};
58
59Q_DECLARE_OPERATORS_FOR_FLAGS(OpenDocumentSnapshot::DumpOptions)
60
61class OpenDocument
62{
63public:
64 OpenDocumentSnapshot snapshot;
65 std::shared_ptr<Utils::TextDocument> textDocument;
66};
67
68struct ToIndex
69{
70 QString path;
71 int leftDepth;
72};
73
74struct RegisteredSemanticTokens
75{
76 QByteArray resultId = "0";
77 QList<int> lastTokens;
78};
79
80class QQmlCodeModel : public QObject
81{
82 Q_OBJECT
83public:
84 enum class UrlLookup { Caching, ForceLookup };
85 enum class State { Running, Stopping };
86
87 explicit QQmlCodeModel(QObject *parent = nullptr, QQmlToolingSettings *settings = nullptr);
88 ~QQmlCodeModel();
89 QQmlJS::Dom::DomItem currentEnv() const { return m_currentEnv; };
90 QQmlJS::Dom::DomItem validEnv() const { return m_validEnv; };
91 OpenDocumentSnapshot snapshotByUrl(const QByteArray &url);
92 OpenDocument openDocumentByUrl(const QByteArray &url);
93
94 void openNeedUpdate();
95 void indexNeedsUpdate();
96 void addDirectoriesToIndex(const QStringList &paths, QLanguageServer *server);
97 void addOpenToUpdate(const QByteArray &);
98 void removeDirectory(const QString &path);
99 // void updateDocument(const OpenDocument &doc);
100 QString url2Path(const QByteArray &url, UrlLookup options = UrlLookup::Caching);
101 void newOpenFile(const QByteArray &url, int version, const QString &docText);
102 void newDocForOpenFile(const QByteArray &url, int version, const QString &docText);
103 void closeOpenFile(const QByteArray &url);
104 void setRootUrls(const QList<QByteArray> &urls);
105 QList<QByteArray> rootUrls() const;
106 void addRootUrls(const QList<QByteArray> &urls);
107 QStringList buildPathsForRootUrl(const QByteArray &url);
108 QStringList buildPathsForFileUrl(const QByteArray &url);
109 void setBuildPathsForRootUrl(QByteArray url, const QStringList &paths);
110 QStringList importPathsForFile(const QString &fileName) const;
111 QStringList importPaths() const { return m_importPaths; };
112 void setImportPaths(const QStringList &paths) { m_importPaths = paths; };
113 void removeRootUrls(const QList<QByteArray> &urls);
114 QQmlToolingSettings *settings() const { return m_settings; }
115 QStringList findFilePathsFromFileNames(const QStringList &fileNames);
116 static QStringList fileNamesToWatch(const QQmlJS::Dom::DomItem &qmlFile);
117 void disableCMakeCalls();
118 const QFactoryLoader &pluginLoader() const { return m_pluginLoader; }
119
120 RegisteredSemanticTokens &registeredTokens();
121 const RegisteredSemanticTokens &registeredTokens() const;
122 QString documentationRootPath() const { return m_documentationRootPath; }
123 void setDocumentationRootPath(const QString &path);
124
125 QSet<QString> ignoreForWatching() const { return m_ignoreForWatching; }
126
127Q_SIGNALS:
128 void updatedSnapshot(const QByteArray &url);
129 void documentationRootPathChanged(const QString &path);
130
131private:
132 void indexDirectory(const QString &path, int depthLeft);
133 int indexEvalProgress() const; // to be called in the mutex
134 void indexStart(); // to be called in the mutex
135 void indexEnd(); // to be called in the mutex
136 void indexSendProgress(int progress);
137 bool indexCancelled();
138 bool indexSome();
139 void addDirectory(const QString &path, int leftDepth);
140 bool openUpdateSome();
141 void openUpdateStart();
142 void openUpdateEnd();
143 void openUpdate(const QByteArray &);
144
145 static bool callCMakeBuild(const QStringList &buildPaths);
146 void addFileWatches(const QQmlJS::Dom::DomItem &qmlFile);
147 enum CMakeStatus { RequiresInitialization, HasCMake, DoesNotHaveCMake };
148 void initializeCMakeStatus(const QString &);
149
150 mutable QMutex m_mutex;
151 State m_state = State::Running;
152 int m_lastIndexProgress = 0;
153 int m_nIndexInProgress = 0;
154 QList<ToIndex> m_toIndex;
155 int m_indexInProgressCost = 0;
156 int m_indexDoneCost = 0;
157 int m_nUpdateInProgress = 0;
158 QStringList m_importPaths;
159 QQmlJS::Dom::DomItem m_currentEnv;
160 QQmlJS::Dom::DomItem m_validEnv;
161 QByteArray m_lastOpenDocumentUpdated;
162 QSet<QByteArray> m_openDocumentsToUpdate;
163 QHash<QByteArray, QStringList> m_buildPathsForRootUrl;
164 QList<QByteArray> m_rootUrls;
165 QHash<QByteArray, QString> m_url2path;
166 QHash<QString, QByteArray> m_path2url;
167 QHash<QByteArray, OpenDocument> m_openDocuments;
168 QQmlToolingSettings *m_settings;
169 QFileSystemWatcher m_cppFileWatcher;
170 QFactoryLoader m_pluginLoader;
171 bool m_rebuildRequired = true; // always trigger a rebuild on start
172 CMakeStatus m_cmakeStatus = RequiresInitialization;
173 RegisteredSemanticTokens m_tokens;
174 QString m_documentationRootPath;
175 QSet<QString> m_ignoreForWatching;
176private slots:
177 void onCppFileChanged(const QString &);
178};
179
180} // namespace QmlLsp
181QT_END_NAMESPACE
182#endif // QQMLCODEMODEL_P_H
183

source code of qtdeclarative/src/qmlls/qqmlcodemodel_p.h