LanguageClient: Simplify openedDocument map

Replace custom OpenedDocument struct with custom deleter
of std::unique_ptr.

Change-Id: Ia7606fcad5337685aecae7c9dec064a5df4666fe
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Jarek Kobus
2024-01-29 09:48:44 +01:00
parent 92996b74ae
commit d7bae47f8a

View File

@@ -303,27 +303,9 @@ public:
QString m_displayName; QString m_displayName;
LanguageFilter m_languagFilter; LanguageFilter m_languagFilter;
QJsonObject m_initializationOptions; QJsonObject m_initializationOptions;
class OpenedDocument using TextDocumentDeleter = std::function<void(QTextDocument *)>;
{ using TextDocumentWithDeleter = std::unique_ptr<QTextDocument, TextDocumentDeleter>;
Q_DISABLE_COPY_MOVE(OpenedDocument) std::unordered_map<TextEditor::TextDocument *, TextDocumentWithDeleter> m_openedDocument;
public:
OpenedDocument() = default;
~OpenedDocument()
{
QObject::disconnect(contentsChangedConnection);
QObject::disconnect(filePathChangedConnection);
QObject::disconnect(aboutToSaveConnection);
QObject::disconnect(savedConnection);
delete document;
}
QMetaObject::Connection contentsChangedConnection;
QMetaObject::Connection filePathChangedConnection;
QMetaObject::Connection aboutToSaveConnection;
QMetaObject::Connection savedConnection;
QTextDocument *document = nullptr;
};
std::unordered_map<TextEditor::TextDocument *, std::unique_ptr<OpenedDocument>> m_openedDocument;
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of // Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
// the build. // the build.
@@ -696,43 +678,38 @@ void Client::openDocument(TextEditor::TextDocument *document)
} }
} }
auto openedDocument = new ClientPrivate::OpenedDocument; const QList<QMetaObject::Connection> connections {
d->m_openedDocument.emplace(document, openedDocument); connect(document, &TextDocument::contentsChangedWithPosition, this,
openedDocument->document = new QTextDocument(document->document()->toPlainText());
openedDocument->contentsChangedConnection
= connect(document,
&TextDocument::contentsChangedWithPosition,
this,
[this, document](int position, int charsRemoved, int charsAdded) { [this, document](int position, int charsRemoved, int charsAdded) {
documentContentsChanged(document, position, charsRemoved, charsAdded); documentContentsChanged(document, position, charsRemoved, charsAdded);
}); }),
openedDocument->filePathChangedConnection connect(document, &TextDocument::filePathChanged, this,
= connect(document,
&TextDocument::filePathChanged,
this,
[this, document](const FilePath &oldPath, const FilePath &newPath) { [this, document](const FilePath &oldPath, const FilePath &newPath) {
if (oldPath == newPath) if (oldPath == newPath)
return; return;
closeDocument(document, oldPath); closeDocument(document, oldPath);
if (isSupportedDocument(document)) if (isSupportedDocument(document))
openDocument(document); openDocument(document);
}); }),
openedDocument->savedConnection connect(document, &TextDocument::saved, this,
= connect(document,
&TextDocument::saved,
this,
[this, document](const FilePath &saveFilePath) { [this, document](const FilePath &saveFilePath) {
if (saveFilePath == document->filePath()) if (saveFilePath == document->filePath())
documentContentsSaved(document); documentContentsSaved(document);
}); }),
openedDocument->aboutToSaveConnection connect(document, &TextDocument::aboutToSave, this,
= connect(document,
&TextDocument::aboutToSave,
this,
[this, document](const FilePath &saveFilePath) { [this, document](const FilePath &saveFilePath) {
if (saveFilePath == document->filePath()) if (saveFilePath == document->filePath())
documentWillSave(document); documentWillSave(document);
}); })
};
const auto deleter = [connections](QTextDocument *document) {
for (const QMetaObject::Connection &connection : connections)
QObject::disconnect(connection);
delete document;
};
d->m_openedDocument.emplace(document, ClientPrivate::TextDocumentWithDeleter(
new QTextDocument(document->document()->toPlainText()), deleter));
if (!d->m_documentVersions.contains(filePath)) if (!d->m_documentVersions.contains(filePath))
d->m_documentVersions[filePath] = 0; d->m_documentVersions[filePath] = 0;
d->sendOpenNotification(filePath, document->mimeType(), document->plainText(), d->sendOpenNotification(filePath, document->mimeType(), document->plainText(),
@@ -1249,7 +1226,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
} }
const QString &text = document->textAt(position, charsAdded); const QString &text = document->textAt(position, charsAdded);
QTextCursor cursor(it->second->document); QTextCursor cursor(it->second.get());
// Workaround https://bugreports.qt.io/browse/QTBUG-80662 // Workaround https://bugreports.qt.io/browse/QTBUG-80662
// The contentsChanged gives a character count that can be wrong for QTextCursor // The contentsChanged gives a character count that can be wrong for QTextCursor
// when there are special characters removed/added (like formating characters). // when there are special characters removed/added (like formating characters).
@@ -1257,7 +1234,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
// paragraph separator character. // paragraph separator character.
// This implementation is based on QWidgetTextControlPrivate::_q_contentsChanged. // This implementation is based on QWidgetTextControlPrivate::_q_contentsChanged.
// For charsAdded, textAt handles the case itself. // For charsAdded, textAt handles the case itself.
cursor.setPosition(qMin(it->second->document->characterCount() - 1, position + charsRemoved)); cursor.setPosition(qMin(it->second->characterCount() - 1, position + charsRemoved));
cursor.setPosition(position, QTextCursor::KeepAnchor); cursor.setPosition(position, QTextCursor::KeepAnchor);
if (syncKind != TextDocumentSyncKind::None) { if (syncKind != TextDocumentSyncKind::None) {