Clang: make workaround for multibyte utf8

Correct columns in clang diagnostics and completion

Task-number: QTCREATORBUG-16775
Change-Id: I7260a0e52007fe261e83492dca5d457c34476497
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2017-05-19 08:55:08 +02:00
parent 34702f8441
commit 707170ca04
4 changed files with 34 additions and 4 deletions

View File

@@ -552,7 +552,8 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
{
int line, column;
TextEditor::Convenience::convertPosition(m_interface->textDocument(), position, &line, &column);
++column;
const QTextBlock block = m_interface->textDocument()->findBlock(position);
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
const QString filePath = m_interface->fileName();

View File

@@ -26,6 +26,7 @@
#include "clangdiagnosticfilter.h"
#include "clangdiagnosticmanager.h"
#include "clangisdiagnosticrelatedtolocation.h"
#include "clangutils.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
@@ -60,9 +61,11 @@ QTextEdit::ExtraSelection createExtraSelections(const QTextCharFormat &mainforma
int positionInText(QTextDocument *textDocument,
const ClangBackEnd::SourceLocationContainer &sourceLocationContainer)
{
auto textBlock = textDocument->findBlockByNumber(int(sourceLocationContainer.line()) - 1);
return textBlock.position() + int(sourceLocationContainer.column()) - 1;
auto textBlock = textDocument->findBlockByNumber(
static_cast<int>(sourceLocationContainer.line()) - 1);
int column = static_cast<int>(sourceLocationContainer.column()) - 1;
column -= ClangCodeModel::Utils::extraUtf8CharsShift(textBlock.text(), column);
return textBlock.position() + column;
}
void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic,

View File

@@ -169,5 +169,29 @@ void setLastSentDocumentRevision(const QString &filePath, uint revision)
document->sendTracker().setLastSentRevision(int(revision));
}
int extraUtf8CharsShift(const QString &str, int column)
{
int shift = 0;
const QByteArray byteArray = str.toUtf8();
for (int i = 0; i < qMin(str.length(), column); ++i) {
const uchar firstByte = static_cast<uchar>(byteArray.at(i));
// Skip different amount of bytes depending on value
if (firstByte < 0xC0) {
continue;
} else if (firstByte < 0xE0) {
++shift;
++i;
} else if (firstByte < 0xF0) {
shift += 2;
i += 2;
} else {
shift += 3;
i += 3;
}
}
return shift;
}
} // namespace Utils
} // namespace Clang

View File

@@ -47,5 +47,7 @@ CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &fil
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
QString projectPartIdForFile(const QString &filePath);
int extraUtf8CharsShift(const QString &str, int column);
} // namespace Utils
} // namespace Clang