forked from qt-creator/qt-creator
CppEditor: Fix semantic highlighting
... for the case where the first line with semantic tokens has multiple
tokens.
This was not considered in the algorithm and uncovered by
d6f5d07639.
Also improve variable names and comments.
Fixes: QTCREATORBUG-29218
Change-Id: I0a1927c21edd70a3a91efc902e7e6ad2c734c91f
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -82,26 +82,28 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(SyntaxHighlight
|
|||||||
if (to <= from)
|
if (to <= from)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int firstResultBlockNumber = int(future.resultAt(from).line) - 1;
|
const int resultStartLine = future.resultAt(from).line;
|
||||||
|
int formattingStartLine = 1;
|
||||||
|
|
||||||
// blocks between currentBlockNumber and the last block with results will
|
// Find the line on which to start formatting, where "formatting" means to either
|
||||||
// be cleaned of additional extra formats if they have no results
|
// clear out formats from outdated document versions (if there is no current result
|
||||||
int currentBlockNumber = 0;
|
// on that line), or apply the format corresponding to the respective result.
|
||||||
|
// Note that if there are earlier results on the same line, we have to make sure they
|
||||||
|
// get re-applied by adapting the from variable accordingly.
|
||||||
for (int i = from - 1; i >= 0; --i) {
|
for (int i = from - 1; i >= 0; --i) {
|
||||||
const HighlightingResult &result = future.resultAt(i);
|
const HighlightingResult &result = future.resultAt(i);
|
||||||
const int blockNumber = int(result.line) - 1;
|
if (result.line == resultStartLine) {
|
||||||
if (blockNumber < firstResultBlockNumber) {
|
from = i;
|
||||||
// stop! found where last format stopped
|
} else if (result.line < resultStartLine) {
|
||||||
currentBlockNumber = blockNumber + 1;
|
formattingStartLine = result.line + 1;
|
||||||
// add previous results for the same line to avoid undoing their formats
|
|
||||||
from = i + 1;
|
from = i + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextDocument *doc = highlighter->document();
|
QTextDocument *doc = highlighter->document();
|
||||||
QTC_ASSERT(currentBlockNumber < doc->blockCount(), return);
|
QTC_ASSERT(formattingStartLine <= doc->blockCount(), return);
|
||||||
QTextBlock currentBlock = doc->findBlockByNumber(currentBlockNumber);
|
QTextBlock currentBlock = doc->findBlockByNumber(formattingStartLine - 1);
|
||||||
|
|
||||||
std::map<QTextBlock, QVector<QTextLayout::FormatRange>> formatRanges;
|
std::map<QTextBlock, QVector<QTextLayout::FormatRange>> formatRanges;
|
||||||
for (int i = from; i < to; ++i) {
|
for (int i = from; i < to; ++i) {
|
||||||
|
|||||||
@@ -301,6 +301,41 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats()
|
|||||||
// should have no results since the new results do not contain a highlight at that position
|
// should have no results since the new results do not contain a highlight at that position
|
||||||
formats = emptyLineBlock.layout()->formats();
|
formats = emptyLineBlock.layout()->formats();
|
||||||
QVERIFY(formats.isEmpty());
|
QVERIFY(formats.isEmpty());
|
||||||
|
|
||||||
|
// QTCREATORBUG-29218
|
||||||
|
highlighter->clearAllExtraFormats();
|
||||||
|
const HighlightingResults bug29218Results{HighlightingResult(1, 1, 2, 0),
|
||||||
|
HighlightingResult(1, 3, 2, 1)};
|
||||||
|
QFutureInterface<HighlightingResult> fi29218;
|
||||||
|
fi29218.reportResults(bug29218Results);
|
||||||
|
formats = firstBlock.layout()->formats();
|
||||||
|
QVERIFY(formats.isEmpty());
|
||||||
|
SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
|
||||||
|
fi29218.future(),
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
formatHash);
|
||||||
|
formats = firstBlock.layout()->formats();
|
||||||
|
QCOMPARE(formats.size(), 1);
|
||||||
|
QCOMPARE(formats.at(0).format.fontItalic(), true);
|
||||||
|
QCOMPARE(formats.at(0).format.fontOverline(), false);
|
||||||
|
QCOMPARE(formats.at(0).start, 0);
|
||||||
|
QCOMPARE(formats.at(0).length, 2);
|
||||||
|
SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
|
||||||
|
fi29218.future(),
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
formatHash);
|
||||||
|
formats = firstBlock.layout()->formats();
|
||||||
|
QCOMPARE(formats.size(), 2);
|
||||||
|
QCOMPARE(formats.at(0).format.fontItalic(), true);
|
||||||
|
QCOMPARE(formats.at(0).format.fontOverline(), false);
|
||||||
|
QCOMPARE(formats.at(0).start, 0);
|
||||||
|
QCOMPARE(formats.at(0).length, 2);
|
||||||
|
QCOMPARE(formats.at(1).format.fontItalic(), false);
|
||||||
|
QCOMPARE(formats.at(1).format.fontOverline(), true);
|
||||||
|
QCOMPARE(formats.at(1).start, 2);
|
||||||
|
QCOMPARE(formats.at(1).length, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_highlighter::cleanup()
|
void tst_highlighter::cleanup()
|
||||||
|
|||||||
Reference in New Issue
Block a user