Commit 2c7a1104 authored by Christian Kamm's avatar Christian Kamm

C++ semantic highlighting: Report uses sorted by line.

This moves sorting from the gui thread to the future and
allows the incremental application of the extra formats
to assume chunks are sorted.

Change-Id: I38e179e573c43cc955cce820f17ac87e3300a839
Reviewed-on: http://codereview.qt.nokia.com/3869Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
parent 3bf56256
......@@ -291,6 +291,7 @@ CheckSymbols::Future CheckSymbols::go(Document::Ptr doc, const LookupContext &co
CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context)
: ASTVisitor(doc->translationUnit()), _doc(doc), _context(context)
, _lineOfLastUsage(0)
{
CollectSymbols collectTypes(doc, context.snapshot());
......@@ -839,15 +840,23 @@ void CheckSymbols::addUse(unsigned tokenIndex, UseKind kind)
addUse(use);
}
static const int chunkSize = 50;
void CheckSymbols::addUse(const Use &use)
{
if (!use.line)
return;
_lineOfLastUsage = qMax(_lineOfLastUsage, use.line);
if (! enclosingFunctionDefinition()) {
if (_usages.size() >= 50) {
if (_flushRequested && use.line != _flushLine)
if (_usages.size() >= chunkSize) {
if (_flushRequested && use.line > _flushLine) {
flush();
else if (! _flushRequested) {
_lineOfLastUsage = use.line;
} else if (! _flushRequested) {
_flushRequested = true;
_flushLine = use.line;
_flushLine = _lineOfLastUsage;
}
}
}
......@@ -1086,14 +1095,22 @@ bool CheckSymbols::maybeVirtualMethod(const Name *name) const
return false;
}
static bool sortByLinePredicate(const CheckSymbols::Use &lhs, const CheckSymbols::Use &rhs)
{
return lhs.line < rhs.line;
}
void CheckSymbols::flush()
{
_flushRequested = false;
_flushLine = 0;
_lineOfLastUsage = 0;
if (_usages.isEmpty())
return;
qSort(_usages.begin(), _usages.end(), sortByLinePredicate);
reportResults(_usages);
_usages.clear();
_usages.reserve(chunkSize);
}
......@@ -168,6 +168,7 @@ private:
QSet<QByteArray> _potentialStatics;
QList<AST *> _astStack;
QVector<Use> _usages;
unsigned _lineOfLastUsage;
bool _flushRequested;
unsigned _flushLine;
};
......
......@@ -48,33 +48,23 @@ void TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
int from, int to,
const QHash<int, QTextCharFormat> &kindToFormat)
{
QMap<int, QVector<Result> > blockNumberToResults;
for (int i = from; i < to; ++i) {
const Result &result = future.resultAt(i);
if (!result.line)
continue;
blockNumberToResults[result.line - 1].append(result);
}
if (blockNumberToResults.isEmpty())
if (to <= from)
return;
const int firstResultBlockNumber = blockNumberToResults.constBegin().key();
const int firstResultBlockNumber = future.resultAt(from).line - 1;
// blocks between currentBlockNumber and the last block with results will
// be cleaned of additional extra formats if they have no results
int currentBlockNumber = 0;
for (int i = from - 1; i >= 0; --i) {
const Result &result = future.resultAt(i);
if (!result.line)
continue;
const int blockNumber = result.line - 1;
if (blockNumber < firstResultBlockNumber) {
// stop! found where last format stopped
currentBlockNumber = blockNumber + 1;
break;
} else {
// add previous results for the same line to avoid undoing their formats
blockNumberToResults[blockNumber].append(result);
from = i + 1;
break;
}
}
......@@ -82,10 +72,9 @@ void TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
QTC_ASSERT(currentBlockNumber < doc->blockCount(), return);
QTextBlock b = doc->findBlockByNumber(currentBlockNumber);
QMapIterator<int, QVector<Result> > it(blockNumberToResults);
while (b.isValid() && it.hasNext()) {
it.next();
const int blockNumber = it.key();
Result result = future.resultAt(from);
for (int i = from; i < to && b.isValid(); ) {
const int blockNumber = result.line - 1;
QTC_ASSERT(blockNumber < doc->blockCount(), return);
// clear formats of blocks until blockNumber
......@@ -95,17 +84,25 @@ void TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
++currentBlockNumber;
}
// collect all the formats for the current line
QList<QTextLayout::FormatRange> formats;
foreach (const Result &result, it.value()) {
forever {
QTextLayout::FormatRange formatRange;
formatRange.format = kindToFormat.value(result.kind);
if (!formatRange.format.isValid())
continue;
formatRange.start = result.column - 1;
formatRange.length = result.length;
formats.append(formatRange);
if (formatRange.format.isValid()) {
formatRange.start = result.column - 1;
formatRange.length = result.length;
formats.append(formatRange);
}
++i;
if (i >= to)
break;
result = future.resultAt(i);
const int nextBlockNumber = result.line - 1;
if (nextBlockNumber != blockNumber)
break;
}
highlighter->setExtraAdditionalFormats(b, formats);
b = b.next();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment