DiffEditor: Fix Qt6 build

QStringRef is gone. QStringView::split is not available until Qt6.
Since using a ref/view might actually have a performance impact in this
case, work around this with a typedef to the available type.

Task-number: QTCREATORBUG-24098
Change-Id: I72dcb4a9c93b73e396dfb9a2760af924db809eaf
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Eike Ziller
2020-09-07 15:41:01 +02:00
parent 58e633a8a4
commit 03db57f524
3 changed files with 163 additions and 166 deletions

View File

@@ -43,4 +43,21 @@ using QHashValueType = uint;
using QHashValueType = size_t; using QHashValueType = size_t;
#endif #endif
// StringView - either QStringRef or QStringView
// Can be used where it is not possible to completely switch to QStringView
// For example where QString::splitRef / QStringView::split is essential.
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using StringView = QStringRef;
#else
using StringView = QStringView;
#endif
inline StringView make_stringview(const QString &s)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
return QStringRef(&s);
#else
return QStringView(s);
#endif
}
} // namespace Utils } // namespace Utils

View File

@@ -27,6 +27,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/differ.h> #include <utils/differ.h>
#include <utils/porting.h>
#include <QFutureInterfaceBase> #include <QFutureInterfaceBase>
#include <QRegularExpression> #include <QRegularExpression>
@@ -39,7 +40,7 @@ namespace DiffEditor {
int ChunkSelection::selectedRowsCount() const int ChunkSelection::selectedRowsCount() const
{ {
return Utils::toSet(leftSelection).unite(Utils::toSet(rightSelection)).count(); return Utils::toSet(leftSelection).unite(Utils::toSet(rightSelection)).size();
} }
static QList<TextLineData> assemblyRows(const QList<TextLineData> &lines, static QList<TextLineData> assemblyRows(const QList<TextLineData> &lines,
@@ -47,7 +48,7 @@ static QList<TextLineData> assemblyRows(const QList<TextLineData> &lines,
{ {
QList<TextLineData> data; QList<TextLineData> data;
const int lineCount = lines.count(); const int lineCount = lines.size();
for (int i = 0; i <= lineCount; i++) { for (int i = 0; i <= lineCount; i++) {
for (int j = 0; j < lineSpans.value(i); j++) for (int j = 0; j < lineSpans.value(i); j++)
data.append(TextLineData(TextLineData::Separator)); data.append(TextLineData(TextLineData::Separator));
@@ -74,7 +75,7 @@ static void handleLine(const QStringList &newLines,
QList<TextLineData> *lines, QList<TextLineData> *lines,
int *lineNumber) int *lineNumber)
{ {
if (line < newLines.count()) { if (line < newLines.size()) {
const QString text = newLines.at(line); const QString text = newLines.at(line);
if (lines->isEmpty() || line > 0) { if (lines->isEmpty() || line > 0) {
if (line > 0) if (line > 0)
@@ -91,14 +92,12 @@ static void handleDifference(const QString &text,
int *lineNumber) int *lineNumber)
{ {
const QStringList newLines = text.split('\n'); const QStringList newLines = text.split('\n');
for (int line = 0; line < newLines.count(); ++line) { for (int line = 0; line < newLines.size(); ++line) {
const int startPos = line > 0 const int startPos = line > 0 ? -1 : lines->isEmpty() ? 0 : lines->last().text.size();
? -1
: lines->isEmpty() ? 0 : lines->last().text.count();
handleLine(newLines, line, lines, lineNumber); handleLine(newLines, line, lines, lineNumber);
const int endPos = line < newLines.count() - 1 const int endPos = line < newLines.size() - 1
? -1 ? -1
: lines->isEmpty() ? 0 : lines->last().text.count(); : lines->isEmpty() ? 0 : lines->last().text.size();
if (!lines->isEmpty()) if (!lines->isEmpty())
lines->last().changedPositions.insert(startPos, endPos); lines->last().changedPositions.insert(startPos, endPos);
} }
@@ -130,31 +129,27 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
int rightLineAligned = -1; int rightLineAligned = -1;
bool lastLineEqual = true; bool lastLineEqual = true;
while (i <= leftDiffList.count() && j <= rightDiffList.count()) { while (i <= leftDiffList.size() && j <= rightDiffList.size()) {
const Diff leftDiff = i < leftDiffList.count() const Diff leftDiff = i < leftDiffList.size() ? leftDiffList.at(i) : Diff(Diff::Equal);
? leftDiffList.at(i) const Diff rightDiff = j < rightDiffList.size() ? rightDiffList.at(j) : Diff(Diff::Equal);
: Diff(Diff::Equal);
const Diff rightDiff = j < rightDiffList.count()
? rightDiffList.at(j)
: Diff(Diff::Equal);
if (leftDiff.command == Diff::Delete) { if (leftDiff.command == Diff::Delete) {
if (j == rightDiffList.count() && lastLineEqual && leftDiff.text.startsWith('\n')) if (j == rightDiffList.size() && lastLineEqual && leftDiff.text.startsWith('\n'))
equalLines.insert(leftLineNumber, rightLineNumber); equalLines.insert(leftLineNumber, rightLineNumber);
// process delete // process delete
handleDifference(leftDiff.text, &leftLines, &leftLineNumber); handleDifference(leftDiff.text, &leftLines, &leftLineNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines); lastLineEqual = lastLinesEqual(leftLines, rightLines);
if (j == rightDiffList.count()) if (j == rightDiffList.size())
lastLineEqual = false; lastLineEqual = false;
i++; i++;
} }
if (rightDiff.command == Diff::Insert) { if (rightDiff.command == Diff::Insert) {
if (i == leftDiffList.count() && lastLineEqual && rightDiff.text.startsWith('\n')) if (i == leftDiffList.size() && lastLineEqual && rightDiff.text.startsWith('\n'))
equalLines.insert(leftLineNumber, rightLineNumber); equalLines.insert(leftLineNumber, rightLineNumber);
// process insert // process insert
handleDifference(rightDiff.text, &rightLines, &rightLineNumber); handleDifference(rightDiff.text, &rightLines, &rightLineNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines); lastLineEqual = lastLinesEqual(leftLines, rightLines);
if (i == leftDiffList.count()) if (i == leftDiffList.size())
lastLineEqual = false; lastLineEqual = false;
j++; j++;
} }
@@ -165,13 +160,13 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
int line = 0; int line = 0;
if (i < leftDiffList.count() || j < rightDiffList.count() || (!leftLines.isEmpty() && !rightLines.isEmpty())) { if (i < leftDiffList.size() || j < rightDiffList.size()
while (line < qMax(newLeftLines.count(), newRightLines.count())) { || (!leftLines.isEmpty() && !rightLines.isEmpty())) {
while (line < qMax(newLeftLines.size(), newRightLines.size())) {
handleLine(newLeftLines, line, &leftLines, &leftLineNumber); handleLine(newLeftLines, line, &leftLines, &leftLineNumber);
handleLine(newRightLines, line, &rightLines, &rightLineNumber); handleLine(newRightLines, line, &rightLines, &rightLineNumber);
const int commonLineCount = qMin(newLeftLines.count(), const int commonLineCount = qMin(newLeftLines.size(), newRightLines.size());
newRightLines.count());
if (line < commonLineCount) { if (line < commonLineCount) {
// try to align // try to align
const int leftDifference = leftLineNumber - leftLineAligned; const int leftDifference = leftLineNumber - leftLineAligned;
@@ -195,8 +190,7 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
doAlign = false; doAlign = false;
// unless it's the last dummy line (don't omit in that case) // unless it's the last dummy line (don't omit in that case)
if (i == leftDiffList.count() if (i == leftDiffList.size() && j == rightDiffList.size())
&& j == rightDiffList.count())
doAlign = true; doAlign = true;
} }
@@ -217,10 +211,10 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
} }
// check if lines are equal // check if lines are equal
if ((line < commonLineCount - 1) // before the last common line in equality if ((line < commonLineCount - 1) // before the last common line in equality
|| (line == commonLineCount - 1 // or the last common line in equality || (line == commonLineCount - 1 // or the last common line in equality
&& i == leftDiffList.count() // and it's the last iteration && i == leftDiffList.size() // and it's the last iteration
&& j == rightDiffList.count())) { && j == rightDiffList.size())) {
if (line > 0 || lastLineEqual) if (line > 0 || lastLineEqual)
equalLines.insert(leftLineNumber, rightLineNumber); equalLines.insert(leftLineNumber, rightLineNumber);
} }
@@ -242,12 +236,12 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
rightSpans); rightSpans);
// fill ending separators // fill ending separators
for (int i = leftData.count(); i < rightData.count(); i++) for (int i = leftData.size(); i < rightData.size(); i++)
leftData.append(TextLineData(TextLineData::Separator)); leftData.append(TextLineData(TextLineData::Separator));
for (int i = rightData.count(); i < leftData.count(); i++) for (int i = rightData.size(); i < leftData.size(); i++)
rightData.append(TextLineData(TextLineData::Separator)); rightData.append(TextLineData(TextLineData::Separator));
const int visualLineCount = leftData.count(); const int visualLineCount = leftData.size();
int leftLine = -1; int leftLine = -1;
int rightLine = -1; int rightLine = -1;
ChunkData chunkData; ChunkData chunkData;
@@ -281,25 +275,24 @@ FileData DiffUtils::calculateContextData(const ChunkData &originalData, int cont
QMap<int, bool> hiddenRows; QMap<int, bool> hiddenRows;
int i = 0; int i = 0;
while (i < originalData.rows.count()) { while (i < originalData.rows.size()) {
const RowData &row = originalData.rows[i]; const RowData &row = originalData.rows[i];
if (row.equal) { if (row.equal) {
// count how many equal // count how many equal
int equalRowStart = i; int equalRowStart = i;
i++; i++;
while (i < originalData.rows.count()) { while (i < originalData.rows.size()) {
const RowData originalRow = originalData.rows.at(i); const RowData originalRow = originalData.rows.at(i);
if (!originalRow.equal) if (!originalRow.equal)
break; break;
i++; i++;
} }
const bool first = equalRowStart == 0; // includes first line? const bool first = equalRowStart == 0; // includes first line?
const bool last = i == originalData.rows.count(); // includes last line? const bool last = i == originalData.rows.size(); // includes last line?
const int firstLine = first const int firstLine = first
? 0 : equalRowStart + contextLineCount; ? 0 : equalRowStart + contextLineCount;
const int lastLine = last const int lastLine = last ? originalData.rows.size() : i - contextLineCount;
? originalData.rows.count() : i - contextLineCount;
if (firstLine < lastLine - joinChunkThreshold) { if (firstLine < lastLine - joinChunkThreshold) {
for (int j = firstLine; j < lastLine; j++) { for (int j = firstLine; j < lastLine; j++) {
@@ -314,13 +307,13 @@ FileData DiffUtils::calculateContextData(const ChunkData &originalData, int cont
i = 0; i = 0;
int leftLineNumber = 0; int leftLineNumber = 0;
int rightLineNumber = 0; int rightLineNumber = 0;
while (i < originalData.rows.count()) { while (i < originalData.rows.size()) {
const bool contextChunk = hiddenRows.contains(i); const bool contextChunk = hiddenRows.contains(i);
ChunkData chunkData; ChunkData chunkData;
chunkData.contextChunk = contextChunk; chunkData.contextChunk = contextChunk;
chunkData.leftStartingLineNumber = leftLineNumber; chunkData.leftStartingLineNumber = leftLineNumber;
chunkData.rightStartingLineNumber = rightLineNumber; chunkData.rightStartingLineNumber = rightLineNumber;
while (i < originalData.rows.count()) { while (i < originalData.rows.size()) {
if (contextChunk != hiddenRows.contains(i)) if (contextChunk != hiddenRows.contains(i))
break; break;
RowData rowData = originalData.rows.at(i); RowData rowData = originalData.rows.at(i);
@@ -378,7 +371,7 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
// Detect the case when the last equal line is followed by // Detect the case when the last equal line is followed by
// only separators on left or on right. In that case // only separators on left or on right. In that case
// the last equal line needs to be split. // the last equal line needs to be split.
const int rowCount = chunkData.rows.count(); const int rowCount = chunkData.rows.size();
int i = 0; int i = 0;
for (i = rowCount; i > 0; i--) { for (i = rowCount; i > 0; i--) {
const RowData &rowData = chunkData.rows.at(i - 1); const RowData &rowData = chunkData.rows.at(i - 1);
@@ -401,20 +394,20 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
rowToBeSplit = commonSeparator - 1; rowToBeSplit = commonSeparator - 1;
} }
for (int i = 0; i <= chunkData.rows.count(); i++) { for (int i = 0; i <= chunkData.rows.size(); i++) {
const RowData &rowData = i < chunkData.rows.count() const RowData &rowData = i < chunkData.rows.size()
? chunkData.rows.at(i) ? chunkData.rows.at(i)
: RowData(TextLineData(TextLineData::Separator)); // dummy, : RowData(TextLineData(TextLineData::Separator)); // dummy,
// ensure we process buffers to the end. // ensure we process buffers to the end.
// rowData will be equal // rowData will be equal
if (rowData.equal && i != rowToBeSplit) { if (rowData.equal && i != rowToBeSplit) {
if (!leftBuffer.isEmpty()) { if (!leftBuffer.isEmpty()) {
for (int j = 0; j < leftBuffer.count(); j++) { for (int j = 0; j < leftBuffer.size(); j++) {
const QString line = makePatchLine('-', const QString line = makePatchLine('-',
leftBuffer.at(j).text, leftBuffer.at(j).text,
lastChunk, lastChunk,
i == chunkData.rows.count() i == chunkData.rows.size()
&& j == leftBuffer.count() - 1); && j == leftBuffer.size() - 1);
if (!line.isEmpty()) if (!line.isEmpty())
++leftLineCount; ++leftLineCount;
@@ -424,12 +417,12 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
leftBuffer.clear(); leftBuffer.clear();
} }
if (!rightBuffer.isEmpty()) { if (!rightBuffer.isEmpty()) {
for (int j = 0; j < rightBuffer.count(); j++) { for (int j = 0; j < rightBuffer.size(); j++) {
const QString line = makePatchLine('+', const QString line = makePatchLine('+',
rightBuffer.at(j).text, rightBuffer.at(j).text,
lastChunk, lastChunk,
i == chunkData.rows.count() i == chunkData.rows.size()
&& j == rightBuffer.count() - 1); && j == rightBuffer.size() - 1);
if (!line.isEmpty()) if (!line.isEmpty())
++rightLineCount; ++rightLineCount;
@@ -438,11 +431,11 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
} }
rightBuffer.clear(); rightBuffer.clear();
} }
if (i < chunkData.rows.count()) { if (i < chunkData.rows.size()) {
const QString line = makePatchLine(' ', const QString line = makePatchLine(' ',
rowData.rightLine.text, rowData.rightLine.text,
lastChunk, lastChunk,
i == chunkData.rows.count() - 1); i == chunkData.rows.size() - 1);
if (!line.isEmpty()) { if (!line.isEmpty()) {
++leftLineCount; ++leftLineCount;
@@ -525,7 +518,7 @@ QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned forma
QString diffText; QString diffText;
QTextStream str(&diffText); QTextStream str(&diffText);
for (int i = 0; i < fileDataList.count(); i++) { for (int i = 0; i < fileDataList.size(); i++) {
const FileData &fileData = fileDataList.at(i); const FileData &fileData = fileDataList.at(i);
if (formatFlags & GitFormat) { if (formatFlags & GitFormat) {
str << "diff --git a/" << fileData.leftFileInfo.fileName str << "diff --git a/" << fileData.leftFileInfo.fileName
@@ -556,10 +549,10 @@ QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned forma
str << leftFileName(fileData, formatFlags) << "\n"; str << leftFileName(fileData, formatFlags) << "\n";
str << "+++ "; str << "+++ ";
str << rightFileName(fileData, formatFlags) << "\n"; str << rightFileName(fileData, formatFlags) << "\n";
for (int j = 0; j < fileData.chunks.count(); j++) { for (int j = 0; j < fileData.chunks.size(); j++) {
str << makePatch(fileData.chunks.at(j), str << makePatch(fileData.chunks.at(j),
(j == fileData.chunks.count() - 1) (j == fileData.chunks.size() - 1)
&& fileData.lastChunkAtTheEndOfFile); && fileData.lastChunkAtTheEndOfFile);
} }
} }
} }
@@ -567,10 +560,7 @@ QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned forma
return diffText; return diffText;
} }
static QList<RowData> readLines(QStringRef patch, static QList<RowData> readLines(StringView patch, bool lastChunk, bool *lastChunkAtTheEndOfFile, bool *ok)
bool lastChunk,
bool *lastChunkAtTheEndOfFile,
bool *ok)
{ {
QList<Diff> diffList; QList<Diff> diffList;
@@ -584,13 +574,13 @@ static QList<RowData> readLines(QStringRef patch,
int noNewLineInDelete = -1; int noNewLineInDelete = -1;
int noNewLineInInsert = -1; int noNewLineInInsert = -1;
const QVector<QStringRef> lines = patch.split(newLine); const QVector<StringView> lines = patch.split(newLine);
int i; int i;
for (i = 0; i < lines.count(); i++) { for (i = 0; i < lines.size(); i++) {
QStringRef line = lines.at(i); StringView line = lines.at(i);
if (line.isEmpty()) { // need to have at least one character (1 column) if (line.isEmpty()) { // need to have at least one character (1 column)
if (lastChunk) if (lastChunk)
i = lines.count(); // pretend as we've read all the lines (we just ignore the rest) i = lines.size(); // pretend as we've read all the lines (we just ignore the rest)
break; break;
} }
const QChar firstCharacter = line.at(0); const QChar firstCharacter = line.at(0);
@@ -605,15 +595,15 @@ static QList<RowData> readLines(QStringRef patch,
if (last.command == Diff::Equal) { if (last.command == Diff::Equal) {
if (noNewLineInEqual >= 0) if (noNewLineInEqual >= 0)
break; break;
noNewLineInEqual = diffList.count() - 1; noNewLineInEqual = diffList.size() - 1;
} else if (last.command == Diff::Delete) { } else if (last.command == Diff::Delete) {
if (noNewLineInDelete >= 0) if (noNewLineInDelete >= 0)
break; break;
noNewLineInDelete = diffList.count() - 1; noNewLineInDelete = diffList.size() - 1;
} else if (last.command == Diff::Insert) { } else if (last.command == Diff::Insert) {
if (noNewLineInInsert >= 0) if (noNewLineInInsert >= 0)
break; break;
noNewLineInInsert = diffList.count() - 1; noNewLineInInsert = diffList.size() - 1;
} }
} }
} else { } else {
@@ -626,7 +616,7 @@ static QList<RowData> readLines(QStringRef patch,
command = Diff::Insert; command = Diff::Insert;
} else { // no other character may exist as the first character } else { // no other character may exist as the first character
if (lastChunk) if (lastChunk)
i = lines.count(); // pretend as we've read all the lines (we just ignore the rest) i = lines.size(); // pretend as we've read all the lines (we just ignore the rest)
break; break;
} }
@@ -638,23 +628,23 @@ static QList<RowData> readLines(QStringRef patch,
diffList.append(diffToBeAdded); diffList.append(diffToBeAdded);
if (command == Diff::Equal) // common line if (command == Diff::Equal) // common line
lastEqual = diffList.count() - 1; lastEqual = diffList.size() - 1;
else if (command == Diff::Delete) // deleted line else if (command == Diff::Delete) // deleted line
lastDelete = diffList.count() - 1; lastDelete = diffList.size() - 1;
else if (command == Diff::Insert) // inserted line else if (command == Diff::Insert) // inserted line
lastInsert = diffList.count() - 1; lastInsert = diffList.size() - 1;
} }
} }
if (i < lines.count() // we broke before if (i < lines.size() // we broke before
// or we have noNewLine in some equal line and in either delete or insert line // or we have noNewLine in some equal line and in either delete or insert line
|| (noNewLineInEqual >= 0 && (noNewLineInDelete >= 0 || noNewLineInInsert >= 0)) || (noNewLineInEqual >= 0 && (noNewLineInDelete >= 0 || noNewLineInInsert >= 0))
// or we have noNewLine in not the last equal line // or we have noNewLine in not the last equal line
|| (noNewLineInEqual >= 0 && noNewLineInEqual != lastEqual) || (noNewLineInEqual >= 0 && noNewLineInEqual != lastEqual)
// or we have noNewLine in not the last delete line or there is a equal line after the noNewLine for delete // or we have noNewLine in not the last delete line or there is a equal line after the noNewLine for delete
|| (noNewLineInDelete >= 0 && (noNewLineInDelete != lastDelete || lastEqual > lastDelete)) || (noNewLineInDelete >= 0 && (noNewLineInDelete != lastDelete || lastEqual > lastDelete))
// or we have noNewLine in not the last insert line or there is a equal line after the noNewLine for insert // or we have noNewLine in not the last insert line or there is a equal line after the noNewLine for insert
|| (noNewLineInInsert >= 0 && (noNewLineInInsert != lastInsert || lastEqual > lastInsert))) { || (noNewLineInInsert >= 0 && (noNewLineInInsert != lastInsert || lastEqual > lastInsert))) {
if (ok) if (ok)
*ok = false; *ok = false;
return QList<RowData>(); return QList<RowData>();
@@ -704,15 +694,15 @@ static QList<RowData> readLines(QStringRef patch,
if (removeNewLineFromLastEqual) { if (removeNewLineFromLastEqual) {
Diff &diff = diffList[lastEqual]; Diff &diff = diffList[lastEqual];
diff.text = diff.text.left(diff.text.count() - 1); diff.text = diff.text.left(diff.text.size() - 1);
} }
if (removeNewLineFromLastDelete) { if (removeNewLineFromLastDelete) {
Diff &diff = diffList[lastDelete]; Diff &diff = diffList[lastDelete];
diff.text = diff.text.left(diff.text.count() - 1); diff.text = diff.text.left(diff.text.size() - 1);
} }
if (removeNewLineFromLastInsert) { if (removeNewLineFromLastInsert) {
Diff &diff = diffList[lastInsert]; Diff &diff = diffList[lastInsert];
diff.text = diff.text.left(diff.text.count() - 1); diff.text = diff.text.left(diff.text.size() - 1);
} }
if (prependNewLineAfterLastEqual) { if (prependNewLineAfterLastEqual) {
Diff &diff = diffList[lastEqual + 1]; Diff &diff = diffList[lastEqual + 1];
@@ -740,13 +730,13 @@ static QList<RowData> readLines(QStringRef patch,
outputRightDiffList).rows; outputRightDiffList).rows;
} }
static QStringRef readLine(QStringRef text, QStringRef *remainingText, bool *hasNewLine) static StringView readLine(StringView text, StringView *remainingText, bool *hasNewLine)
{ {
const QChar newLine('\n'); const QChar newLine('\n');
const int indexOfFirstNewLine = text.indexOf(newLine); const int indexOfFirstNewLine = text.indexOf(newLine);
if (indexOfFirstNewLine < 0) { if (indexOfFirstNewLine < 0) {
if (remainingText) if (remainingText)
*remainingText = QStringRef(); *remainingText = StringView();
if (hasNewLine) if (hasNewLine)
*hasNewLine = false; *hasNewLine = false;
return text; return text;
@@ -761,12 +751,10 @@ static QStringRef readLine(QStringRef text, QStringRef *remainingText, bool *has
return text.left(indexOfFirstNewLine); return text.left(indexOfFirstNewLine);
} }
static bool detectChunkData(QStringRef chunkDiff, static bool detectChunkData(StringView chunkDiff, ChunkData *chunkData, StringView *remainingPatch)
ChunkData *chunkData,
QStringRef *remainingPatch)
{ {
bool hasNewLine; bool hasNewLine;
const QStringRef chunkLine = readLine(chunkDiff, remainingPatch, &hasNewLine); const StringView chunkLine = readLine(chunkDiff, remainingPatch, &hasNewLine);
const QLatin1String leftPosMarker("@@ -"); const QLatin1String leftPosMarker("@@ -");
const QLatin1String rightPosMarker(" +"); const QLatin1String rightPosMarker(" +");
@@ -786,15 +774,15 @@ static bool detectChunkData(QStringRef chunkDiff,
const int leftPosStart = leftPosIndex + leftPosMarker.size(); const int leftPosStart = leftPosIndex + leftPosMarker.size();
const int leftPosLength = rightPosIndex - leftPosStart; const int leftPosLength = rightPosIndex - leftPosStart;
QStringRef leftPos = chunkLine.mid(leftPosStart, leftPosLength); StringView leftPos = chunkLine.mid(leftPosStart, leftPosLength);
const int rightPosStart = rightPosIndex + rightPosMarker.size(); const int rightPosStart = rightPosIndex + rightPosMarker.size();
const int rightPosLength = optionalHintIndex - rightPosStart; const int rightPosLength = optionalHintIndex - rightPosStart;
QStringRef rightPos = chunkLine.mid(rightPosStart, rightPosLength); StringView rightPos = chunkLine.mid(rightPosStart, rightPosLength);
const int optionalHintStart = optionalHintIndex + optionalHintMarker.size(); const int optionalHintStart = optionalHintIndex + optionalHintMarker.size();
const int optionalHintLength = chunkLine.size() - optionalHintStart; const int optionalHintLength = chunkLine.size() - optionalHintStart;
const QStringRef optionalHint = chunkLine.mid(optionalHintStart, optionalHintLength); const StringView optionalHint = chunkLine.mid(optionalHintStart, optionalHintLength);
const QChar comma(','); const QChar comma(',');
bool ok; bool ok;
@@ -820,9 +808,7 @@ static bool detectChunkData(QStringRef chunkDiff,
return true; return true;
} }
static QList<ChunkData> readChunks(QStringRef patch, static QList<ChunkData> readChunks(StringView patch, bool *lastChunkAtTheEndOfFile, bool *ok)
bool *lastChunkAtTheEndOfFile,
bool *ok)
{ {
QList<ChunkData> chunkDataList; QList<ChunkData> chunkDataList;
int position = -1; int position = -1;
@@ -837,20 +823,21 @@ static QList<ChunkData> readChunks(QStringRef patch,
const QChar newLine('\n'); const QChar newLine('\n');
bool readOk = true; bool readOk = true;
const int count = startingPositions.count(); const int count = startingPositions.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
const int chunkStart = startingPositions.at(i); const int chunkStart = startingPositions.at(i);
const int chunkEnd = (i < count - 1) const int chunkEnd = (i < count - 1)
// drop the newline before the next chunk start // drop the newline before the next chunk start
? startingPositions.at(i + 1) - 1 ? startingPositions.at(i + 1) - 1
// drop the possible newline by the end of patch // drop the possible newline by the end of patch
: (patch.at(patch.count() - 1) == newLine ? patch.count() - 1 : patch.count()); : (patch.at(patch.size() - 1) == newLine ? patch.size() - 1
: patch.size());
// extract just one chunk // extract just one chunk
const QStringRef chunkDiff = patch.mid(chunkStart, chunkEnd - chunkStart); const StringView chunkDiff = patch.mid(chunkStart, chunkEnd - chunkStart);
ChunkData chunkData; ChunkData chunkData;
QStringRef lines; StringView lines;
readOk = detectChunkData(chunkDiff, &chunkData, &lines); readOk = detectChunkData(chunkDiff, &chunkData, &lines);
if (!readOk) if (!readOk)
@@ -870,10 +857,9 @@ static QList<ChunkData> readChunks(QStringRef patch,
return chunkDataList; return chunkDataList;
} }
static FileData readDiffHeaderAndChunks(QStringRef headerAndChunks, static FileData readDiffHeaderAndChunks(StringView headerAndChunks, bool *ok)
bool *ok)
{ {
QStringRef patch = headerAndChunks; StringView patch = headerAndChunks;
FileData fileData; FileData fileData;
bool readOk = false; bool readOk = false;
@@ -925,9 +911,7 @@ static FileData readDiffHeaderAndChunks(QStringRef headerAndChunks,
} }
static QList<FileData> readDiffPatch(QStringRef patch, static QList<FileData> readDiffPatch(StringView patch, bool *ok, QFutureInterfaceBase *jobController)
bool *ok,
QFutureInterfaceBase *jobController)
{ {
const QRegularExpression diffRegExp("(?:\\n|^)" // new line of the beginning of a patch const QRegularExpression diffRegExp("(?:\\n|^)" // new line of the beginning of a patch
"(" // either "(" // either
@@ -959,8 +943,7 @@ static QList<FileData> readDiffPatch(QStringRef patch,
int pos = diffMatch.capturedStart(); int pos = diffMatch.capturedStart();
if (lastPos >= 0) { if (lastPos >= 0) {
QStringRef headerAndChunks = patch.mid(lastPos, StringView headerAndChunks = patch.mid(lastPos, pos - lastPos);
pos - lastPos);
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks, const FileData fileData = readDiffHeaderAndChunks(headerAndChunks,
&readOk); &readOk);
@@ -976,8 +959,7 @@ static QList<FileData> readDiffPatch(QStringRef patch,
} while (diffMatch.hasMatch()); } while (diffMatch.hasMatch());
if (readOk) { if (readOk) {
QStringRef headerAndChunks = patch.mid(lastPos, StringView headerAndChunks = patch.mid(lastPos, patch.size() - lastPos - 1);
patch.count() - lastPos - 1);
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks, const FileData fileData = readDiffHeaderAndChunks(headerAndChunks,
&readOk); &readOk);
@@ -1024,9 +1006,7 @@ static QList<FileData> readDiffPatch(QStringRef patch,
// +++ [rightFileNameOrDevNull]\n // +++ [rightFileNameOrDevNull]\n
// <Chunks> // <Chunks>
static bool detectIndexAndBinary(QStringRef patch, static bool detectIndexAndBinary(StringView patch, FileData *fileData, StringView *remainingPatch)
FileData *fileData,
QStringRef *remainingPatch)
{ {
bool hasNewLine; bool hasNewLine;
*remainingPatch = patch; *remainingPatch = patch;
@@ -1043,14 +1023,14 @@ static bool detectIndexAndBinary(QStringRef patch,
} }
} }
QStringRef afterNextLine; StringView afterNextLine;
// index [leftIndexSha]..[rightIndexSha] <optionally: octalNumber> // index [leftIndexSha]..[rightIndexSha] <optionally: octalNumber>
const QStringRef nextLine = readLine(patch, &afterNextLine, &hasNewLine); const StringView nextLine = readLine(patch, &afterNextLine, &hasNewLine);
const QLatin1String indexHeader("index "); const QLatin1String indexHeader("index ");
if (nextLine.startsWith(indexHeader)) { if (nextLine.startsWith(indexHeader)) {
const QStringRef indices = nextLine.mid(indexHeader.size()); const StringView indices = nextLine.mid(indexHeader.size());
const int dotsPosition = indices.indexOf(QStringLiteral("..")); const int dotsPosition = indices.indexOf(QStringLiteral(".."));
if (dotsPosition < 0) if (dotsPosition < 0)
return false; return false;
@@ -1086,14 +1066,14 @@ static bool detectIndexAndBinary(QStringRef patch,
if (*remainingPatch == binaryLine) { if (*remainingPatch == binaryLine) {
fileData->binaryFiles = true; fileData->binaryFiles = true;
*remainingPatch = QStringRef(); *remainingPatch = StringView();
return true; return true;
} }
const QString leftStart = "--- " + leftFileName; const QString leftStart = "--- " + leftFileName;
QStringRef afterMinuses; StringView afterMinuses;
// --- leftFileName // --- leftFileName
const QStringRef minuses = readLine(*remainingPatch, &afterMinuses, &hasNewLine); const StringView minuses = readLine(*remainingPatch, &afterMinuses, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
return false; // we need to have at least one more line return false; // we need to have at least one more line
@@ -1101,9 +1081,9 @@ static bool detectIndexAndBinary(QStringRef patch,
return false; return false;
const QString rightStart = "+++ " + rightFileName; const QString rightStart = "+++ " + rightFileName;
QStringRef afterPluses; StringView afterPluses;
// +++ rightFileName // +++ rightFileName
const QStringRef pluses = readLine(afterMinuses, &afterPluses, &hasNewLine); const StringView pluses = readLine(afterMinuses, &afterPluses, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
return false; // we need to have at least one more line return false; // we need to have at least one more line
@@ -1114,25 +1094,25 @@ static bool detectIndexAndBinary(QStringRef patch,
return true; return true;
} }
static bool extractCommonFileName(QStringRef fileNames, QStringRef *fileName) static bool extractCommonFileName(StringView fileNames, StringView *fileName)
{ {
// we should have 1 space between filenames // we should have 1 space between filenames
if (fileNames.size() % 2 == 0) if (fileNames.size() % 2 == 0)
return false; return false;
if (!fileNames.startsWith(QStringLiteral("a/"))) if (!fileNames.startsWith(QLatin1String("a/")))
return false; return false;
// drop the space in between // drop the space in between
const int fileNameSize = fileNames.size() / 2; const int fileNameSize = fileNames.size() / 2;
if (!fileNames.mid(fileNameSize).startsWith(" b/")) if (!fileNames.mid(fileNameSize).startsWith(QLatin1String(" b/")))
return false; return false;
// drop "a/" // drop "a/"
const QStringRef leftFileName = fileNames.mid(2, fileNameSize - 2); const StringView leftFileName = fileNames.mid(2, fileNameSize - 2);
// drop the first filename + " b/" // drop the first filename + " b/"
const QStringRef rightFileName = fileNames.mid(fileNameSize + 3, fileNameSize - 2); const StringView rightFileName = fileNames.mid(fileNameSize + 3, fileNameSize - 2);
if (leftFileName != rightFileName) if (leftFileName != rightFileName)
return false; return false;
@@ -1141,28 +1121,27 @@ static bool extractCommonFileName(QStringRef fileNames, QStringRef *fileName)
return true; return true;
} }
static bool detectFileData(QStringRef patch, static bool detectFileData(StringView patch, FileData *fileData, StringView *remainingPatch)
FileData *fileData, {
QStringRef *remainingPatch) {
bool hasNewLine; bool hasNewLine;
QStringRef afterDiffGit; StringView afterDiffGit;
// diff --git a/leftFileName b/rightFileName // diff --git a/leftFileName b/rightFileName
const QStringRef diffGit = readLine(patch, &afterDiffGit, &hasNewLine); const StringView diffGit = readLine(patch, &afterDiffGit, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
return false; // we need to have at least one more line return false; // we need to have at least one more line
const QLatin1String gitHeader("diff --git "); const QLatin1String gitHeader("diff --git ");
const QStringRef fileNames = diffGit.mid(gitHeader.size()); const StringView fileNames = diffGit.mid(gitHeader.size());
QStringRef commonFileName; StringView commonFileName;
if (extractCommonFileName(fileNames, &commonFileName)) { if (extractCommonFileName(fileNames, &commonFileName)) {
// change / new / delete // change / new / delete
fileData->fileOperation = FileData::ChangeFile; fileData->fileOperation = FileData::ChangeFile;
fileData->leftFileInfo.fileName = fileData->rightFileInfo.fileName = commonFileName.toString(); fileData->leftFileInfo.fileName = fileData->rightFileInfo.fileName = commonFileName.toString();
QStringRef afterSecondLine; StringView afterSecondLine;
const QStringRef secondLine = readLine(afterDiffGit, &afterSecondLine, &hasNewLine); const StringView secondLine = readLine(afterDiffGit, &afterSecondLine, &hasNewLine);
if (secondLine.startsWith(QStringLiteral("new file mode "))) { if (secondLine.startsWith(QStringLiteral("new file mode "))) {
fileData->fileOperation = FileData::NewFile; fileData->fileOperation = FileData::NewFile;
@@ -1171,7 +1150,7 @@ static bool detectFileData(QStringRef patch,
fileData->fileOperation = FileData::DeleteFile; fileData->fileOperation = FileData::DeleteFile;
*remainingPatch = afterSecondLine; *remainingPatch = afterSecondLine;
} else if (secondLine.startsWith(QStringLiteral("old mode "))) { } else if (secondLine.startsWith(QStringLiteral("old mode "))) {
QStringRef afterThirdLine; StringView afterThirdLine;
// new mode // new mode
readLine(afterSecondLine, &afterThirdLine, &hasNewLine); readLine(afterSecondLine, &afterThirdLine, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
@@ -1186,7 +1165,7 @@ static bool detectFileData(QStringRef patch,
} else { } else {
// copy / rename // copy / rename
QStringRef afterSimilarity; StringView afterSimilarity;
// (dis)similarity index [0-100]% // (dis)similarity index [0-100]%
readLine(afterDiffGit, &afterSimilarity, &hasNewLine); readLine(afterDiffGit, &afterSimilarity, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
@@ -1194,9 +1173,9 @@ static bool detectFileData(QStringRef patch,
// TODO: validate similarity line // TODO: validate similarity line
QStringRef afterCopyRenameFrom; StringView afterCopyRenameFrom;
// [copy / rename] from leftFileName // [copy / rename] from leftFileName
const QStringRef copyRenameFrom = readLine(afterSimilarity, &afterCopyRenameFrom, &hasNewLine); const StringView copyRenameFrom = readLine(afterSimilarity, &afterCopyRenameFrom, &hasNewLine);
if (!hasNewLine) if (!hasNewLine)
return false; // we need to have at least one more line return false; // we need to have at least one more line
@@ -1212,9 +1191,9 @@ static bool detectFileData(QStringRef patch,
return false; return false;
} }
QStringRef afterCopyRenameTo; StringView afterCopyRenameTo;
// [copy / rename] to rightFileName // [copy / rename] to rightFileName
const QStringRef copyRenameTo = readLine(afterCopyRenameFrom, &afterCopyRenameTo, &hasNewLine); const StringView copyRenameTo = readLine(afterCopyRenameFrom, &afterCopyRenameTo, &hasNewLine);
// if (dis)similarity index is 100% we don't have more lines // if (dis)similarity index is 100% we don't have more lines
@@ -1233,8 +1212,7 @@ static bool detectFileData(QStringRef patch,
return detectIndexAndBinary(*remainingPatch, fileData, remainingPatch); return detectIndexAndBinary(*remainingPatch, fileData, remainingPatch);
} }
static QList<FileData> readGitPatch(QStringRef patch, bool *ok, static QList<FileData> readGitPatch(StringView patch, bool *ok, QFutureInterfaceBase *jobController)
QFutureInterfaceBase *jobController)
{ {
int position = -1; int position = -1;
@@ -1247,7 +1225,7 @@ static QList<FileData> readGitPatch(QStringRef patch, bool *ok,
class PatchInfo { class PatchInfo {
public: public:
QStringRef patch; StringView patch;
FileData fileData; FileData fileData;
}; };
@@ -1255,23 +1233,24 @@ static QList<FileData> readGitPatch(QStringRef patch, bool *ok,
bool readOk = true; bool readOk = true;
QVector<PatchInfo> patches; QVector<PatchInfo> patches;
const int count = startingPositions.count(); const int count = startingPositions.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (jobController && jobController->isCanceled()) if (jobController && jobController->isCanceled())
return QList<FileData>(); return QList<FileData>();
const int diffStart = startingPositions.at(i); const int diffStart = startingPositions.at(i);
const int diffEnd = (i < count - 1) const int diffEnd = (i < count - 1)
// drop the newline before the next header start // drop the newline before the next header start
? startingPositions.at(i + 1) - 1 ? startingPositions.at(i + 1) - 1
// drop the possible newline by the end of file // drop the possible newline by the end of file
: (patch.at(patch.count() - 1) == newLine ? patch.count() - 1 : patch.count()); : (patch.at(patch.size() - 1) == newLine ? patch.size() - 1
: patch.size());
// extract the patch for just one file // extract the patch for just one file
const QStringRef fileDiff = patch.mid(diffStart, diffEnd - diffStart); const StringView fileDiff = patch.mid(diffStart, diffEnd - diffStart);
FileData fileData; FileData fileData;
QStringRef remainingFileDiff; StringView remainingFileDiff;
readOk = detectFileData(fileDiff, &fileData, &remainingFileDiff); readOk = detectFileData(fileDiff, &fileData, &remainingFileDiff);
if (!readOk) if (!readOk)
@@ -1287,7 +1266,7 @@ static QList<FileData> readGitPatch(QStringRef patch, bool *ok,
} }
if (jobController) if (jobController)
jobController->setProgressRange(0, patches.count()); jobController->setProgressRange(0, patches.size());
QList<FileData> fileDataList; QList<FileData> fileDataList;
readOk = false; readOk = false;
@@ -1331,7 +1310,7 @@ QList<FileData> DiffUtils::readPatch(const QString &patch, bool *ok,
jobController->setProgressRange(0, 1); jobController->setProgressRange(0, 1);
jobController->setProgressValue(0); jobController->setProgressValue(0);
} }
QStringRef croppedPatch(&patch); StringView croppedPatch = make_stringview(patch);
// Crop e.g. "-- \n2.10.2.windows.1\n\n" at end of file // Crop e.g. "-- \n2.10.2.windows.1\n\n" at end of file
const QRegularExpression formatPatchEndingRegExp("(\\n-- \\n\\S*\\n\\n$)"); const QRegularExpression formatPatchEndingRegExp("(\\n-- \\n\\S*\\n\\n$)");
const QRegularExpressionMatch match = formatPatchEndingRegExp.match(croppedPatch); const QRegularExpressionMatch match = formatPatchEndingRegExp.match(croppedPatch);

View File

@@ -45,6 +45,7 @@
#include <coreplugin/find/highlightscrollbarcontroller.h> #include <coreplugin/find/highlightscrollbarcontroller.h>
#include <coreplugin/minisplitter.h> #include <coreplugin/minisplitter.h>
#include <utils/porting.h>
#include <utils/tooltip/tooltip.h> #include <utils/tooltip/tooltip.h>
using namespace Core; using namespace Core;
@@ -293,7 +294,7 @@ QString SideDiffEditorWidget::plainTextFromSelection(const QTextCursor &cursor)
if (textInserted) if (textInserted)
text += '\n'; text += '\n';
if (block == endBlock) if (block == endBlock)
text += block.text().leftRef(endPosition - block.position()); text += make_stringview(block.text()).left(endPosition - block.position());
else else
text += block.text(); text += block.text();
} }