From 2c7a1104fab5631fe55a9baa8b99c08201fb6208 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 30 Aug 2011 10:52:41 +0200 Subject: [PATCH] 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/3869 Reviewed-by: Roberto Raggi --- src/plugins/cppeditor/cppchecksymbols.cpp | 25 +++++++++-- src/plugins/cppeditor/cppchecksymbols.h | 1 + .../texteditor/semantichighlighter.cpp | 45 +++++++++---------- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp index ee1e0c4540f..5e05fe655de 100644 --- a/src/plugins/cppeditor/cppchecksymbols.cpp +++ b/src/plugins/cppeditor/cppchecksymbols.cpp @@ -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); } diff --git a/src/plugins/cppeditor/cppchecksymbols.h b/src/plugins/cppeditor/cppchecksymbols.h index f54a7fb6e03..0827d0a5db4 100644 --- a/src/plugins/cppeditor/cppchecksymbols.h +++ b/src/plugins/cppeditor/cppchecksymbols.h @@ -168,6 +168,7 @@ private: QSet _potentialStatics; QList _astStack; QVector _usages; + unsigned _lineOfLastUsage; bool _flushRequested; unsigned _flushLine; }; diff --git a/src/plugins/texteditor/semantichighlighter.cpp b/src/plugins/texteditor/semantichighlighter.cpp index 6c6ad628231..0e541e8f41c 100644 --- a/src/plugins/texteditor/semantichighlighter.cpp +++ b/src/plugins/texteditor/semantichighlighter.cpp @@ -48,33 +48,23 @@ void TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats( int from, int to, const QHash &kindToFormat) { - QMap > 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 > 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 formats; - foreach (const Result &result, it.value()) { + forever { QTextLayout::FormatRange formatRange; formatRange.format = kindToFormat.value(result.kind); - if (!formatRange.format.isValid()) - continue; + if (formatRange.format.isValid()) { + formatRange.start = result.column - 1; + formatRange.length = result.length; + formats.append(formatRange); + } - 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();