Editor: replace Utils::Text::Replacement with Utils::ChangeSet::EditOp for formatting

Removes the last usage of Utils::Text::Replacement with a more commonly used pattern.

Change-Id: I0912bf61388a58ddaba424380ec139f9aa15fc4c
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2023-07-04 10:05:33 +02:00
parent 81e8c67686
commit 4743724d4c
11 changed files with 74 additions and 69 deletions

View File

@@ -103,6 +103,8 @@ private:
bool m_error;
};
using EditOperations = QList<ChangeSet::EditOp>;
inline bool operator<(const ChangeSet::Range &r1, const ChangeSet::Range &r2)
{
return r1.start < r2.start;

View File

@@ -361,12 +361,11 @@ static Utils::Text::Position utf16LineColumn(const QByteArray &utf8Buffer, int u
utf8Offset - startOfLineOffset)).length();
return position;
}
Utils::Text::Replacements utf16Replacements(const QTextDocument *doc,
Utils::ChangeSet convertReplacements(const QTextDocument *doc,
const QByteArray &utf8Buffer,
const clang::tooling::Replacements &replacements)
{
Utils::Text::Replacements convertedReplacements;
convertedReplacements.reserve(replacements.size());
Utils::ChangeSet convertedReplacements;
for (const clang::tooling::Replacement &replacement : replacements) {
Utils::Text::Position lineColUtf16 = utf16LineColumn(
@@ -412,7 +411,7 @@ Utils::Text::Replacements utf16Replacements(const QTextDocument *doc,
}
if (!replacementText.isEmpty() || utf16Length > 0)
convertedReplacements.emplace_back(utf16Offset, utf16Length, replacementText);
convertedReplacements.replace(utf16Offset, utf16Offset + utf16Length, replacementText);
}
return convertedReplacements;
@@ -427,19 +426,21 @@ QString selectedLines(QTextDocument *doc, const QTextBlock &startBlock, const QT
- startBlock.position() - 1));
}
int indentationForBlock(const Utils::Text::Replacements &toReplace,
int indentationForBlock(const Utils::ChangeSet &toReplace,
const QByteArray &buffer,
const QTextBlock &currentBlock)
{
const int utf8Offset = Utils::Text::utf8NthLineOffset(currentBlock.document(),
buffer,
currentBlock.blockNumber() + 1);
auto replacementIt = std::find_if(toReplace.begin(),
toReplace.end(),
[utf8Offset](const Utils::Text::Replacement &replacement) {
return replacement.offset == utf8Offset - 1;
auto ops = toReplace.operationList();
auto replacementIt
= std::find_if(ops.begin(), ops.end(), [utf8Offset](const Utils::ChangeSet::EditOp &op) {
QTC_ASSERT(op.type == Utils::ChangeSet::EditOp::Replace, return false);
return op.pos1 == utf8Offset - 1;
});
if (replacementIt == toReplace.end())
if (replacementIt == ops.end())
return -1;
int afterLineBreak = replacementIt->text.lastIndexOf('\n');
@@ -493,7 +494,7 @@ ClangFormatBaseIndenter::ClangFormatBaseIndenter(QTextDocument *doc)
: TextEditor::Indenter(doc)
{}
Utils::Text::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer,
Utils::ChangeSet ClangFormatBaseIndenter::replacements(QByteArray buffer,
const QTextBlock &startBlock,
const QTextBlock &endBlock,
int cursorPositionInEditor,
@@ -501,12 +502,12 @@ Utils::Text::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffe
const QChar &typedChar,
bool secondTry) const
{
QTC_ASSERT(replacementsToKeep != ReplacementsToKeep::All, return Utils::Text::Replacements());
QTC_ASSERT(replacementsToKeep != ReplacementsToKeep::All, return Utils::ChangeSet());
QTC_ASSERT(!m_fileName.isEmpty(), return {});
QByteArray originalBuffer = buffer;
int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, startBlock.blockNumber() + 1);
QTC_ASSERT(utf8Offset >= 0, return Utils::Text::Replacements(););
QTC_ASSERT(utf8Offset >= 0, return Utils::ChangeSet(););
int utf8Length = selectedLines(m_doc, startBlock, endBlock).toUtf8().size();
int rangeStart = 0;
@@ -556,11 +557,11 @@ Utils::Text::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffe
true);
}
return utf16Replacements(m_doc, buffer, filtered);
return convertReplacements(m_doc, buffer, filtered);
}
Utils::Text::Replacements ClangFormatBaseIndenter::format(
const TextEditor::RangesInLines &rangesInLines, FormattingMode mode)
Utils::EditOperations ClangFormatBaseIndenter::format(const TextEditor::RangesInLines &rangesInLines,
FormattingMode mode)
{
bool doFormatting = mode == FormattingMode::Forced || formatCodeInsteadOfIndent();
#ifdef WITH_TESTS
@@ -572,7 +573,7 @@ Utils::Text::Replacements ClangFormatBaseIndenter::format(
QTC_ASSERT(!m_fileName.isEmpty(), return {});
if (rangesInLines.empty())
return Utils::Text::Replacements();
return {};
const QByteArray buffer = m_doc->toPlainText().toUtf8();
std::vector<clang::tooling::Range> ranges;
@@ -598,7 +599,7 @@ Utils::Text::Replacements ClangFormatBaseIndenter::format(
auto changedCode = clang::tooling::applyAllReplacements(buffer.data(), clangReplacements);
QTC_ASSERT(changedCode, {
qDebug() << QString::fromStdString(llvm::toString(changedCode.takeError()));
return Utils::Text::Replacements();
return {};
});
ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges);
@@ -610,13 +611,14 @@ Utils::Text::Replacements ClangFormatBaseIndenter::format(
&status);
clangReplacements = clangReplacements.merge(formatReplacements);
const Utils::Text::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements);
Utils::Text::applyReplacements(m_doc, toReplace);
Utils::ChangeSet changeSet = convertReplacements(m_doc, buffer, clangReplacements);
const Utils::EditOperations editOperations = changeSet.operationList();
changeSet.apply(m_doc);
return toReplace;
return editOperations;
}
Utils::Text::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock,
Utils::ChangeSet ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
const QChar &typedChar,
int cursorPositionInEditor,
@@ -625,7 +627,7 @@ Utils::Text::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBl
if (typedChar != QChar::Null && cursorPositionInEditor > 0
&& m_doc->characterAt(cursorPositionInEditor - 1) == typedChar
&& doNotIndentInContext(m_doc, cursorPositionInEditor - 1)) {
return Utils::Text::Replacements();
return Utils::ChangeSet();
}
startBlock = reverseFindLastEmptyBlock(startBlock);
@@ -664,7 +666,8 @@ void ClangFormatBaseIndenter::indentBlocks(const QTextBlock &startBlock,
const QChar &typedChar,
int cursorPositionInEditor)
{
applyReplacements(m_doc, indentsFor(startBlock, endBlock, typedChar, cursorPositionInEditor));
Utils::ChangeSet changeset = indentsFor(startBlock, endBlock, typedChar, cursorPositionInEditor);
changeset.apply(m_doc);
}
void ClangFormatBaseIndenter::indent(const QTextCursor &cursor,
@@ -708,12 +711,9 @@ int ClangFormatBaseIndenter::indentFor(const QTextBlock &block,
const TextEditor::TabSettings & /*tabSettings*/,
int cursorPositionInEditor)
{
Utils::Text::Replacements toReplace = indentsFor(block,
block,
QChar::Null,
cursorPositionInEditor,
false);
if (toReplace.empty())
Utils::ChangeSet toReplace
= indentsFor(block, block, QChar::Null, cursorPositionInEditor, false);
if (toReplace.isEmpty())
return -1;
const QByteArray buffer = m_doc->toPlainText().toUtf8();
@@ -728,7 +728,7 @@ TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks(
TextEditor::IndentationForBlock ret;
if (blocks.isEmpty())
return ret;
Utils::Text::Replacements toReplace = indentsFor(blocks.front(),
Utils::ChangeSet toReplace = indentsFor(blocks.front(),
blocks.back(),
QChar::Null,
cursorPositionInEditor);

View File

@@ -31,7 +31,7 @@ public:
void autoIndent(const QTextCursor &cursor,
const TextEditor::TabSettings &tabSettings,
int cursorPositionInEditor = -1) override;
Utils::Text::Replacements format(const TextEditor::RangesInLines &rangesInLines,
Utils::EditOperations format(const TextEditor::RangesInLines &rangesInLines,
FormattingMode mode = FormattingMode::Forced) override;
void indentBlock(const QTextBlock &block,
@@ -60,12 +60,12 @@ private:
const QTextBlock &endBlock,
const QChar &typedChar,
int cursorPositionInEditor);
Utils::Text::Replacements indentsFor(QTextBlock startBlock,
Utils::ChangeSet indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
const QChar &typedChar,
int cursorPositionInEditor,
bool trimTrailingWhitespace = true);
Utils::Text::Replacements replacements(QByteArray buffer,
Utils::ChangeSet replacements(QByteArray buffer,
const QTextBlock &startBlock,
const QTextBlock &endBlock,
int cursorPositionInEditor,

View File

@@ -173,7 +173,7 @@ void ClangFormatForwardingIndenter::autoIndent(const QTextCursor &cursor,
currentIndenter()->autoIndent(cursor, tabSettings, cursorPositionInEditor);
}
Utils::Text::Replacements ClangFormatForwardingIndenter::format(
Utils::EditOperations ClangFormatForwardingIndenter::format(
const TextEditor::RangesInLines &rangesInLines, FormattingMode mode)
{
return currentIndenter()->format(rangesInLines, mode);

View File

@@ -40,7 +40,7 @@ public:
void autoIndent(const QTextCursor &cursor,
const TextEditor::TabSettings &tabSettings,
int cursorPositionInEditor = -1) override;
Utils::Text::Replacements format(const TextEditor::RangesInLines &rangesInLines,
Utils::EditOperations format(const TextEditor::RangesInLines &rangesInLines,
FormattingMode mode) override;
bool formatOnSave() const override;
TextEditor::IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,

View File

@@ -126,9 +126,9 @@ void FixitsRefactoringFile::format(TextEditor::Indenter &indenter,
const int end = doc->findBlock(op.pos + op.length).blockNumber() + 1;
ranges.push_back({start, end});
}
const Text::Replacements replacements = indenter.format(ranges);
const EditOperations replacements = indenter.format(ranges);
if (replacements.empty())
if (replacements.isEmpty())
return;
shiftAffectedReplacements(operationsForFile.front()->filePath,
@@ -179,7 +179,7 @@ void FixitsRefactoringFile::shiftAffectedReplacements(const ReplacementOperation
}
void FixitsRefactoringFile::shiftAffectedReplacements(const FilePath &filePath,
const Text::Replacements &replacements,
const EditOperations &replacements,
int startIndex)
{
for (int i = startIndex; i < m_replacementOperations.size(); ++i) {
@@ -187,10 +187,11 @@ void FixitsRefactoringFile::shiftAffectedReplacements(const FilePath &filePath,
if (filePath != current.filePath)
continue;
for (const auto &replacement : replacements) {
if (replacement.offset > current.pos)
for (const auto &op : replacements) {
QTC_ASSERT(op.type == ChangeSet::EditOp::Replace, continue);
if (op.pos1 > current.pos)
break;
current.pos += replacement.text.size() - replacement.length;
current.pos += op.text.size() - op.length1;
}
}
}

View File

@@ -48,7 +48,7 @@ private:
const ReplacementOperations &operationsForFile,
int firstOperationIndex);
void shiftAffectedReplacements(const Utils::FilePath &filePath,
const Utils::Text::Replacements &replacements,
const Utils::EditOperations &replacements,
int startIndex);
mutable Utils::TextFileFormat m_textFileFormat;

View File

@@ -9,6 +9,7 @@
#include <texteditor/refactoringchanges.h>
#include <utils/qtcassert.h>
#include <utils/textutils.h>
namespace ClangTools {
namespace Internal {

View File

@@ -13,6 +13,7 @@
#include <coreplugin/coreplugintr.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditoractionhandler.h>
#include <utils/textutils.h>
#include <QDir>
#include <QTextDocument>

View File

@@ -93,7 +93,7 @@ QFutureWatcher<ChangeSet> *LanguageClientFormatter::format(
m_ignoreCancel = true;
m_progress.reportStarted();
auto watcher = new QFutureWatcher<ChangeSet>();
QObject::connect(watcher, &QFutureWatcher<Text::Replacements>::canceled, [this]() {
QObject::connect(watcher, &QFutureWatcher<ChangeSet>::canceled, [this]() {
cancelCurrentRequest();
});
watcher->setFuture(m_progress.future());

View File

@@ -3,8 +3,8 @@
#pragma once
#include <utils/changeset.h>
#include <utils/fileutils.h>
#include <utils/textutils.h>
#include <QMap>
#include <QTextBlock>
@@ -71,10 +71,10 @@ public:
}
enum class FormattingMode { Forced, Settings };
virtual Utils::Text::Replacements format(const RangesInLines &,
virtual Utils::EditOperations format(const RangesInLines &,
FormattingMode = FormattingMode::Forced)
{
return Utils::Text::Replacements();
return Utils::EditOperations();
}
virtual bool formatOnSave() const { return false; }