blob: 08bbc5241cfbfafef596cb1db9631396f89824c9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "virtualfilesystemoverlay.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/documentmodel.h>
#include <texteditor/textdocument.h>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLoggingCategory>
#include <QTextDocument>
static Q_LOGGING_CATEGORY(LOG, "qtc.clangtools.vfso", QtWarningMsg)
namespace ClangTools {
namespace Internal {
VirtualFileSystemOverlay::VirtualFileSystemOverlay(const QString &rootPattern)
: m_root(rootPattern)
, m_overlayFilePath(m_root.filePath("vfso.yaml"))
{ }
void VirtualFileSystemOverlay::update()
{
overlayFilePath().removeRecursively();
std::map<Utils::FilePath, QList<Core::IDocument *>> documentRoots;
const QList<Core::IDocument *> &modifiedDocuments = Core::DocumentManager::modifiedDocuments();
QHash<Core::IDocument *, AutoSavedPath> newSaved;
for (Core::IDocument *doc : modifiedDocuments) {
auto document = qobject_cast<TextEditor::TextDocument *>(doc);
if (!document)
continue;
documentRoots[doc->filePath().absolutePath()] << doc;
AutoSavedPath saved = m_saved.take(document);
if (saved.revision != document->document()->revision()) {
saved.path.removeRecursively();
saved.revision = document->document()->revision();
saved.path = m_root.filePath(doc->filePath().fileName() + ".auto");
while (saved.path.exists())
saved.path = saved.path.stringAppended(".1");
if (Utils::Result res = doc->save(saved.path, true); !res) {
qCDebug(LOG) << res.error();
continue;
}
}
newSaved[doc] = saved;
}
for (const AutoSavedPath &path : std::as_const(m_saved)) {
QString error;
if (!path.path.removeRecursively(&error))
qCDebug(LOG) << error;
}
m_saved = newSaved;
m_mapping.clear();
for (auto it = m_saved.constBegin(), end = m_saved.constEnd(); it != end; ++it)
m_mapping[it.value().path] = it.key()->filePath();
auto toContent = [this](Core::IDocument *document) {
QJsonObject content;
content["name"] = document->filePath().fileName();
content["type"] = "file";
content["external-contents"] = m_saved[document].path.toUserOutput();
return content;
};
QJsonObject main;
main["version"] = 0;
QJsonArray jsonRoots;
for (auto [root, documents] : documentRoots) {
QJsonObject jsonRoot;
jsonRoot["type"] = "directory";
jsonRoot["name"] = root.toUserOutput();
QJsonArray contents;
for (auto doc : std::as_const(documents))
contents << toContent(doc);
jsonRoot["contents"] = contents;
jsonRoots << jsonRoot;
}
main["roots"] = jsonRoots;
QJsonDocument overlay(main);
const Utils::expected_str<qint64> res = m_overlayFilePath.writeFileContents(
overlay.toJson(QJsonDocument::Compact));
if (!res)
qCDebug(LOG) << "failed to write vfso to " << m_overlayFilePath;
}
Utils::FilePath VirtualFileSystemOverlay::overlayFilePath() const { return m_overlayFilePath; }
Utils::FilePath VirtualFileSystemOverlay::autoSavedFilePath(Core::IDocument *doc) const
{
const auto it = m_saved.constFind(doc);
if (it != m_saved.constEnd())
return it.value().path;
return doc->filePath();
}
Utils::FilePath VirtualFileSystemOverlay::originalFilePath(const Utils::FilePath &file) const
{
return m_mapping.value(file, file);
}
} // namespace Internal
} // namespace ClangTools
|