17void QQmlCodeModelManager::onCMakeProberFinished(
int exitCode, QProcess::ExitStatus exitStatus)
37void QQmlCodeModelManager::tryEnableCMakeCalls()
39 m_cmakeStatus = IsProbingCMake;
41 m_cmakeProber.setProgram(u"cmake"_s);
42 m_cmakeProber.setArguments({ u"--version"_s });
43 QObject::connect(&m_cmakeProber, &QProcess::finished,
this,
44 &QQmlCodeModelManager::onCMakeProberFinished);
45 QObject::connect(&m_cmakeProber, &QProcess::errorOccurred,
this,
46 &QQmlCodeModelManager::disableCMakeCalls);
48 m_cmakeProber.start();
51QQmlCodeModelManager::QQmlCodeModelManager(QObject *parent, QQmlToolingSharedSettings *settings)
54 const QByteArray defaultCodeModel;
55 appendWorkspace(defaultCodeModel, ManagedByServer);
65QQmlCodeModelManager::findWorkspaceForFile(
const QByteArray &url)
67 Q_ASSERT(!m_workspaces.empty());
69 if (
auto it = m_file2CodeModel.find(url); it != m_file2CodeModel.end()) {
70 const auto result = findWorkspace(it->second);
71 Q_ASSERT(result != m_workspaces.end());
75 long longestRootUrl = 0;
76 WorkspaceIterator result = m_workspaces.begin();
77 for (
auto it = m_workspaces.begin(), end = m_workspaces.end(); it != end; ++it) {
80 const QByteArray rootUrl = it->url;
81 if (!url.startsWith(rootUrl))
84 if (rootUrl.size() == url.size())
87 const long rootUrlLength = rootUrl.length();
88 if (rootUrlLength > longestRootUrl) {
89 longestRootUrl = rootUrlLength;
95 if (
const ModuleSetting moduleSetting =
96 m_buildInformation.settingFor(QUrl::fromEncoded(url).toLocalFile());
97 !moduleSetting.importPaths.isEmpty()) {
98 const QByteArray rootUrl = QUrl::fromLocalFile(moduleSetting.sourceFolder).toEncoded();
99 if (longestRootUrl < rootUrl.size()) {
100 appendWorkspace(rootUrl, ManagedByServer);
101 return --m_workspaces.end();
104 Q_ASSERT(result != m_workspaces.end());
120void QQmlCodeModelManager::appendWorkspace(
const QByteArray &url, ManagedBy managedBy)
124 ws.codeModel = std::make_unique<QQmlCodeModel>(url,
this, m_settings);
127 if (!m_defaultImportPaths.isEmpty())
128 ws.codeModel->setImportPaths(m_defaultImportPaths);
130 if (!m_defaultDocumentationRootPath.isEmpty())
131 ws.codeModel->setDocumentationRootPath(m_defaultDocumentationRootPath);
134 if (
const QStringList importPaths =
135 m_buildInformation.importPathsFor(QUrl::fromEncoded(url).toLocalFile());
136 !importPaths.isEmpty()) {
137 ws.codeModel->setImportPaths(importPaths);
140 QObject::connect(ws.codeModel.get(), &QQmlCodeModel::updatedSnapshot,
this,
141 &QQmlCodeModelManager::updatedSnapshot);
142 ws.managedByClient = managedBy == ManagedByClient;
144 switch (m_cmakeStatus) {
145 case DoesNotHaveCMake:
146 ws.codeModel->disableCMakeCalls();
149 ws.codeModel->tryEnableCMakeCalls(&m_processScheduler);
155 m_workspaces.emplace_back(std::move(ws));
159QQmlCodeModelManager::workspaceFromBuildFolder(
const QString &fileName,
160 const QStringList &buildFolders)
162 m_buildInformation.loadSettingsFrom(buildFolders);
163 const ModuleSetting setting = m_buildInformation.settingFor(fileName);
164 QByteArray url = QUrl::fromLocalFile(setting.sourceFolder).toEncoded();
165 if (
auto it = findWorkspace(url); it != m_workspaces.end())
167 appendWorkspace(url, ManagedByServer);
168 return --m_workspaces.end();
188void QQmlCodeModelManager::newOpenFile(
const QByteArray &url,
int version,
const QString &docText)
190 const auto ws = findWorkspaceForFile(url);
191 m_file2CodeModel[url] = ws->url;
192 ws->codeModel->newOpenFile(url, version, docText);
205void QQmlCodeModelManager::closeOpenFile(
const QByteArray &url)
207 m_file2CodeModel.erase(url);
208 const auto it = findWorkspaceForFile(url);
209 it->codeModel->closeOpenFile(url);
212 if (it->url.isEmpty())
216 if ((it->managedByClient && it->toBeClosed) || !it->managedByClient) {
217 if (it->codeModel->isEmpty())
218 m_workspaces.erase(it);
232void QQmlCodeModelManager::addRootUrls(
const QList<QByteArray> &urls)
234 for (
const QByteArray &url : urls) {
235 if (
const auto it = findWorkspace(url); it != m_workspaces.end()) {
236 it->toBeClosed =
false;
240 appendWorkspace(url, ManagedByClient);
262QByteArray QQmlCodeModelManager::shortestRootUrlForFile(
const QByteArray &fileUrl)
const
265 QByteArray candidate;
268 Q_ASSERT(m_workspaces.size() > 0);
269 Q_ASSERT(m_workspaces.front().url.isEmpty());
270 auto it = std::find_if(
271 ++m_workspaces.cbegin(), m_workspaces.cend(),
272 [&fileUrl](
const QQmlWorkspace &ws) {
return fileUrl.startsWith(ws.url); });
274 if (it != m_workspaces.cend())
277 for (; it != m_workspaces.cend(); ++it) {
278 if (it->url.length() < candidate.length() && fileUrl.startsWith(it->url))
298void QQmlCodeModelManager::setBuildPathsForRootUrl(
const QByteArray &url,
const QStringList &paths)
300 auto setBuildPaths = [&paths,
this](
const QQmlWorkspace &ws) {
301 ws.codeModel->setBuildPaths(paths);
303 if (
const QStringList importPaths =
304 m_buildInformation.importPathsFor(QUrl::fromEncoded(ws.url).toLocalFile());
305 !importPaths.isEmpty()) {
306 ws.codeModel->setImportPaths(importPaths);
310 m_buildInformation.loadSettingsFrom(paths);
314 for (QQmlWorkspace &ws : m_workspaces)
319 const auto ws = findWorkspaceForFile(url);