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 RegisteredSemanticTokens
69{
70 QByteArray resultId = "0";
71 QList<int> lastTokens;
72};
73
74struct ModuleSetting
75{
76 QString sourceFolder;
77 QStringList importPaths;
78};
79
80using ModuleSettings = QList<ModuleSetting>;
81class QQmllsBuildInformation
82{
83public:
84 QQmllsBuildInformation();
85 void loadSettingsFrom(const QStringList &buildPaths);
86 QStringList importPathsFor(const QString &filePath);
87
88private:
89 QString m_docDir;
90 ModuleSettings m_moduleSettings;
91 QSet<QString> m_seenSettings;
92};
93
94class QQmlCodeModel : public QObject
95{
96 Q_OBJECT
97public:
98 enum class UrlLookup { Caching, ForceLookup };
99 enum class State { Running, Stopping };
100
101 explicit QQmlCodeModel(QObject *parent = nullptr, QQmlToolingSettings *settings = nullptr);
102 ~QQmlCodeModel();
103 QQmlJS::Dom::DomItem currentEnv() const { return m_currentEnv; };
104 QQmlJS::Dom::DomItem validEnv() const { return m_validEnv; };
105 OpenDocumentSnapshot snapshotByUrl(const QByteArray &url);
106 OpenDocument openDocumentByUrl(const QByteArray &url);
107
108 void openNeedUpdate();
109 void addOpenToUpdate(const QByteArray &);
110 void removeDirectory(const QString &path);
111 // void updateDocument(const OpenDocument &doc);
112 QString url2Path(const QByteArray &url, UrlLookup options = UrlLookup::Caching);
113 void newOpenFile(const QByteArray &url, int version, const QString &docText);
114 void newDocForOpenFile(const QByteArray &url, int version, const QString &docText);
115 void closeOpenFile(const QByteArray &url);
116 void setRootUrls(const QList<QByteArray> &urls);
117 QList<QByteArray> rootUrls() const;
118 void addRootUrls(const QList<QByteArray> &urls);
119 QStringList buildPathsForRootUrl(const QByteArray &url);
120 QStringList buildPathsForFileUrl(const QByteArray &url);
121 void setBuildPathsForRootUrl(QByteArray url, const QStringList &paths);
122 QStringList importPathsForFile(const QString &fileName);
123 QStringList importPaths() const { return m_importPaths; };
124 void setImportPaths(const QStringList &paths) { m_importPaths = paths; };
125 void removeRootUrls(const QList<QByteArray> &urls);
126 QQmlToolingSettings *settings() const { return m_settings; }
127 QStringList findFilePathsFromFileNames(const QStringList &fileNames);
128 static QStringList fileNamesToWatch(const QQmlJS::Dom::DomItem &qmlFile);
129 void disableCMakeCalls();
130 const QFactoryLoader &pluginLoader() const { return m_pluginLoader; }
131
132 RegisteredSemanticTokens &registeredTokens();
133 const RegisteredSemanticTokens &registeredTokens() const;
134 QString documentationRootPath() const { return m_documentationRootPath; }
135 void setDocumentationRootPath(const QString &path);
136
137 QSet<QString> ignoreForWatching() const { return m_ignoreForWatching; }
138
139Q_SIGNALS:
140 void updatedSnapshot(const QByteArray &url);
141 void documentationRootPathChanged(const QString &path);
142
143private:
144 void addDirectory(const QString &path, int leftDepth);
145 bool openUpdateSome();
146 void openUpdateStart();
147 void openUpdateEnd();
148 void openUpdate(const QByteArray &);
149
150 static bool callCMakeBuild(const QStringList &buildPaths);
151 void addFileWatches(const QQmlJS::Dom::DomItem &qmlFile);
152 enum CMakeStatus { RequiresInitialization, HasCMake, DoesNotHaveCMake };
153 void initializeCMakeStatus(const QString &);
154
155 mutable QMutex m_mutex;
156 State m_state = State::Running;
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 QQmllsBuildInformation m_buildInformation;
170 QFileSystemWatcher m_cppFileWatcher;
171 QFactoryLoader m_pluginLoader;
172 bool m_rebuildRequired = true; // always trigger a rebuild on start
173 CMakeStatus m_cmakeStatus = RequiresInitialization;
174 RegisteredSemanticTokens m_tokens;
175 QString m_documentationRootPath;
176 QSet<QString> m_ignoreForWatching;
177private slots:
178 void onCppFileChanged(const QString &);
179};
180
181} // namespace QmlLsp
182QT_END_NAMESPACE
183#endif // QQMLCODEMODEL_P_H
184

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