diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp index ee1e0c4540fc69494c61933b2f92ee4ddbee298e..5e05fe655de40beb31346321ad1317318975f837 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 f54a7fb6e037f601dc5674b169d19ebd4886d34b..0827d0a5db411dc00acea4132adeac368ed2ed20 100644 --- a/src/plugins/cppeditor/cppchecksymbols.h +++ b/src/plugins/cppeditor/cppchecksymbols.h @@ -168,6 +168,7 @@ private: QSet<QByteArray> _potentialStatics; QList<AST *> _astStack; QVector<Use> _usages; + unsigned _lineOfLastUsage; bool _flushRequested; unsigned _flushLine; }; diff --git a/src/plugins/texteditor/semantichighlighter.cpp b/src/plugins/texteditor/semantichighlighter.cpp index 6c6ad62823130457f9841ac17ec034a2aa2756a9..0e541e8f41c93ea934ab78b8ad36c55ae5f9518a 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<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();