forked from qt-creator/qt-creator
C++: release more futures.
The CPPEditorWidget retained two futures, as did the attached future watchers retained them too. Together, each future and the watcher held on to a complete snapshot that would only get released when another future was set. This could result into retaining old snapshots in editors that were invisible/unused for long. Change-Id: I1133e857c620437b4a69b9dad468f6bd458304b8 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
committed by
Eike Ziller
parent
4089012735
commit
58af02f074
@@ -549,19 +549,14 @@ void CPPEditorWidget::ctor()
|
|||||||
this, SLOT(onDocumentUpdated()));
|
this, SLOT(onDocumentUpdated()));
|
||||||
connect(editorSupport, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
|
connect(editorSupport, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
|
||||||
this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
|
this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
|
||||||
connect(editorSupport, SIGNAL(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint)),
|
connect(editorSupport, SIGNAL(highlighterStarted(QFuture<TextEditor::HighlightingResult>,uint)),
|
||||||
this, SLOT(highlighterStarted(QFuture<TextEditor::HighlightingResult>*,uint)));
|
this, SLOT(highlighterStarted(QFuture<TextEditor::HighlightingResult>,uint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_highlightRevision = 0;
|
m_highlightRevision = 0;
|
||||||
connect(&m_highlightWatcher, SIGNAL(resultsReadyAt(int,int)),
|
|
||||||
SLOT(highlightSymbolUsages(int,int)));
|
|
||||||
connect(&m_highlightWatcher, SIGNAL(finished()),
|
|
||||||
SLOT(finishHighlightSymbolUsages()));
|
|
||||||
|
|
||||||
m_referencesRevision = 0;
|
m_referencesRevision = 0;
|
||||||
m_referencesCursorPosition = 0;
|
m_referencesCursorPosition = 0;
|
||||||
connect(&m_referencesWatcher, SIGNAL(finished()), SLOT(markSymbolsNow()));
|
|
||||||
|
|
||||||
connect(this, SIGNAL(refactorMarkerClicked(TextEditor::RefactorMarker)),
|
connect(this, SIGNAL(refactorMarkerClicked(TextEditor::RefactorMarker)),
|
||||||
this, SLOT(onRefactorMarkerClicked(TextEditor::RefactorMarker)));
|
this, SLOT(onRefactorMarkerClicked(TextEditor::RefactorMarker)));
|
||||||
@@ -854,40 +849,39 @@ void CPPEditorWidget::renameUsages()
|
|||||||
|
|
||||||
void CPPEditorWidget::markSymbolsNow()
|
void CPPEditorWidget::markSymbolsNow()
|
||||||
{
|
{
|
||||||
if (m_references.isCanceled())
|
QTC_ASSERT(m_referencesWatcher, return);
|
||||||
return;
|
if (!m_referencesWatcher->isCanceled()
|
||||||
else if (m_referencesCursorPosition != position())
|
&& m_referencesCursorPosition == position()
|
||||||
return;
|
&& m_referencesRevision == editorRevision()) {
|
||||||
else if (m_referencesRevision != editorRevision())
|
const SemanticInfo info = m_lastSemanticInfo;
|
||||||
return;
|
TranslationUnit *unit = info.doc->translationUnit();
|
||||||
|
const QList<int> result = m_referencesWatcher->result();
|
||||||
|
|
||||||
const SemanticInfo info = m_lastSemanticInfo;
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
TranslationUnit *unit = info.doc->translationUnit();
|
|
||||||
const QList<int> result = m_references.result();
|
|
||||||
|
|
||||||
QList<QTextEdit::ExtraSelection> selections;
|
foreach (int index, result) {
|
||||||
|
unsigned line, column;
|
||||||
|
unit->getTokenPosition(index, &line, &column);
|
||||||
|
|
||||||
foreach (int index, result) {
|
if (column)
|
||||||
unsigned line, column;
|
--column; // adjust the column position.
|
||||||
unit->getTokenPosition(index, &line, &column);
|
|
||||||
|
|
||||||
if (column)
|
const int len = unit->tokenAt(index).f.length;
|
||||||
--column; // adjust the column position.
|
|
||||||
|
|
||||||
const int len = unit->tokenAt(index).f.length;
|
QTextCursor cursor(document()->findBlockByNumber(line - 1));
|
||||||
|
cursor.setPosition(cursor.position() + column);
|
||||||
|
cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
QTextCursor cursor(document()->findBlockByNumber(line - 1));
|
QTextEdit::ExtraSelection sel;
|
||||||
cursor.setPosition(cursor.position() + column);
|
sel.format = baseTextDocument()->fontSettings()
|
||||||
cursor.setPosition(cursor.position() + len, QTextCursor::KeepAnchor);
|
.toTextCharFormat(TextEditor::C_OCCURRENCES);
|
||||||
|
sel.cursor = cursor;
|
||||||
QTextEdit::ExtraSelection sel;
|
selections.append(sel);
|
||||||
sel.format = baseTextDocument()->fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
|
}
|
||||||
sel.cursor = cursor;
|
|
||||||
selections.append(sel);
|
|
||||||
|
|
||||||
|
setExtraSelections(CodeSemanticsSelection, selections);
|
||||||
}
|
}
|
||||||
|
m_referencesWatcher.reset();
|
||||||
setExtraSelections(CodeSemanticsSelection, selections);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc,
|
static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc,
|
||||||
@@ -951,12 +945,15 @@ void CPPEditorWidget::markSymbols(const QTextCursor &tc, const SemanticInfo &inf
|
|||||||
CanonicalSymbol cs(this, info);
|
CanonicalSymbol cs(this, info);
|
||||||
QString expression;
|
QString expression;
|
||||||
if (Scope *scope = cs.getScopeAndExpression(this, info, tc, &expression)) {
|
if (Scope *scope = cs.getScopeAndExpression(this, info, tc, &expression)) {
|
||||||
m_references.cancel();
|
if (m_referencesWatcher)
|
||||||
|
m_referencesWatcher->cancel();
|
||||||
|
m_referencesWatcher.reset(new QFutureWatcher<QList<int> >);
|
||||||
|
connect(m_referencesWatcher.data(), SIGNAL(finished()), SLOT(markSymbolsNow()));
|
||||||
|
|
||||||
m_referencesRevision = info.revision;
|
m_referencesRevision = info.revision;
|
||||||
m_referencesCursorPosition = position();
|
m_referencesCursorPosition = position();
|
||||||
m_references = QtConcurrent::run(&lazyFindReferences, scope, expression, info.doc,
|
m_referencesWatcher->setFuture(QtConcurrent::run(&lazyFindReferences, scope, expression,
|
||||||
info.snapshot);
|
info.doc, info.snapshot));
|
||||||
m_referencesWatcher.setFuture(m_references);
|
|
||||||
} else {
|
} else {
|
||||||
const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection);
|
const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection);
|
||||||
|
|
||||||
@@ -1164,8 +1161,10 @@ void CPPEditorWidget::updateOutlineToolTip()
|
|||||||
|
|
||||||
void CPPEditorWidget::updateUses()
|
void CPPEditorWidget::updateUses()
|
||||||
{
|
{
|
||||||
if (editorRevision() != m_highlightRevision)
|
if (m_highlightWatcher) {
|
||||||
m_highlighter.cancel();
|
m_highlightWatcher->cancel();
|
||||||
|
m_highlightWatcher.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Block premature semantic info calculation when editor is created.
|
// Block premature semantic info calculation when editor is created.
|
||||||
if (m_modelManager && m_modelManager->cppEditorSupport(editor())->initialized())
|
if (m_modelManager && m_modelManager->cppEditorSupport(editor())->initialized())
|
||||||
@@ -1185,32 +1184,29 @@ void CPPEditorWidget::highlightSymbolUsages(int from, int to)
|
|||||||
if (editorRevision() != m_highlightRevision)
|
if (editorRevision() != m_highlightRevision)
|
||||||
return; // outdated
|
return; // outdated
|
||||||
|
|
||||||
else if (m_highlighter.isCanceled())
|
else if (!m_highlightWatcher || m_highlightWatcher->isCanceled())
|
||||||
return; // aborted
|
return; // aborted
|
||||||
|
|
||||||
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
|
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
|
||||||
QTC_ASSERT(highlighter, return);
|
QTC_ASSERT(highlighter, return);
|
||||||
|
|
||||||
TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
|
TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
|
||||||
highlighter, m_highlighter, from, to, m_semanticHighlightFormatMap);
|
highlighter, m_highlightWatcher->future(), from, to, m_semanticHighlightFormatMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPPEditorWidget::finishHighlightSymbolUsages()
|
void CPPEditorWidget::finishHighlightSymbolUsages()
|
||||||
{
|
{
|
||||||
if (editorRevision() != m_highlightRevision)
|
QTC_ASSERT(m_highlightWatcher, return);
|
||||||
return; // outdated
|
if (!m_highlightWatcher->isCanceled()
|
||||||
|
&& editorRevision() == m_highlightRevision
|
||||||
if (m_highlighter.isCanceled())
|
&& !m_lastSemanticInfo.doc.isNull()) {
|
||||||
return; // aborted
|
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
|
||||||
|
QTC_CHECK(highlighter);
|
||||||
else if (m_lastSemanticInfo.doc.isNull())
|
if (highlighter)
|
||||||
return;
|
TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(highlighter,
|
||||||
|
m_highlightWatcher->future());
|
||||||
TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
|
}
|
||||||
QTC_ASSERT(highlighter, return);
|
m_highlightWatcher.reset();
|
||||||
|
|
||||||
TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
|
|
||||||
highlighter, m_highlighter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPPEditorWidget::switchDeclarationDefinition(bool inNextSplit)
|
void CPPEditorWidget::switchDeclarationDefinition(bool inNextSplit)
|
||||||
@@ -1612,12 +1608,18 @@ void CPPEditorWidget::semanticRehighlight(bool force)
|
|||||||
m_modelManager->cppEditorSupport(editor())->recalculateSemanticInfoDetached(force);
|
m_modelManager->cppEditorSupport(editor())->recalculateSemanticInfoDetached(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPPEditorWidget::highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter,
|
void CPPEditorWidget::highlighterStarted(QFuture<TextEditor::HighlightingResult> highlighter,
|
||||||
unsigned revision)
|
unsigned revision)
|
||||||
{
|
{
|
||||||
m_highlighter = *highlighter;
|
|
||||||
m_highlightRevision = revision;
|
m_highlightRevision = revision;
|
||||||
m_highlightWatcher.setFuture(m_highlighter);
|
|
||||||
|
m_highlightWatcher.reset(new QFutureWatcher<TextEditor::HighlightingResult>);
|
||||||
|
connect(m_highlightWatcher.data(), SIGNAL(resultsReadyAt(int,int)),
|
||||||
|
SLOT(highlightSymbolUsages(int,int)));
|
||||||
|
connect(m_highlightWatcher.data(), SIGNAL(finished()),
|
||||||
|
SLOT(finishHighlightSymbolUsages()));
|
||||||
|
|
||||||
|
m_highlightWatcher->setFuture(highlighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
|
void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
|
||||||
|
|||||||
@@ -144,10 +144,10 @@ public:
|
|||||||
|
|
||||||
FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests
|
FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests
|
||||||
|
|
||||||
Q_SIGNALS:
|
signals:
|
||||||
void outlineModelIndexChanged(const QModelIndex &index);
|
void outlineModelIndexChanged(const QModelIndex &index);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public slots:
|
||||||
void setSortedOutline(bool sort);
|
void setSortedOutline(bool sort);
|
||||||
void switchDeclarationDefinition(bool inNextSplit);
|
void switchDeclarationDefinition(bool inNextSplit);
|
||||||
void renameSymbolUnderCursor();
|
void renameSymbolUnderCursor();
|
||||||
@@ -156,7 +156,7 @@ public Q_SLOTS:
|
|||||||
void showPreProcessorWidget();
|
void showPreProcessorWidget();
|
||||||
void renameUsagesNow(const QString &replacement = QString());
|
void renameUsagesNow(const QString &replacement = QString());
|
||||||
void semanticRehighlight(bool force = false);
|
void semanticRehighlight(bool force = false);
|
||||||
void highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter,
|
void highlighterStarted(QFuture<TextEditor::HighlightingResult> highlighter,
|
||||||
unsigned revision);
|
unsigned revision);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -169,10 +169,10 @@ protected:
|
|||||||
|
|
||||||
const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
|
const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
|
||||||
CPlusPlus::Document::Ptr doc) const;
|
CPlusPlus::Document::Ptr doc) const;
|
||||||
protected Q_SLOTS:
|
protected slots:
|
||||||
void slotCodeStyleSettingsChanged(const QVariant &);
|
void slotCodeStyleSettingsChanged(const QVariant &);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private slots:
|
||||||
void jumpToOutlineElement(int index);
|
void jumpToOutlineElement(int index);
|
||||||
void updateOutlineNow();
|
void updateOutlineNow();
|
||||||
void updateOutlineIndex();
|
void updateOutlineIndex();
|
||||||
@@ -254,12 +254,10 @@ private:
|
|||||||
QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
|
QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
|
||||||
bool m_objcEnabled;
|
bool m_objcEnabled;
|
||||||
|
|
||||||
QFuture<TextEditor::HighlightingResult> m_highlighter;
|
QScopedPointer<QFutureWatcher<TextEditor::HighlightingResult> > m_highlightWatcher;
|
||||||
QFutureWatcher<TextEditor::HighlightingResult> m_highlightWatcher;
|
|
||||||
unsigned m_highlightRevision; // the editor revision that requested the highlight
|
unsigned m_highlightRevision; // the editor revision that requested the highlight
|
||||||
|
|
||||||
QFuture<QList<int> > m_references;
|
QScopedPointer<QFutureWatcher<QList<int> > > m_referencesWatcher;
|
||||||
QFutureWatcher<QList<int> > m_referencesWatcher;
|
|
||||||
unsigned m_referencesRevision;
|
unsigned m_referencesRevision;
|
||||||
int m_referencesCursorPosition;
|
int m_referencesCursorPosition;
|
||||||
|
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ void CppEditorSupport::startHighlighting()
|
|||||||
|
|
||||||
m_highlighter = m_highlightingSupport->highlightingFuture(doc, snapshot);
|
m_highlighter = m_highlightingSupport->highlightingFuture(doc, snapshot);
|
||||||
m_lastHighlightRevision = revision;
|
m_lastHighlightRevision = revision;
|
||||||
emit highlighterStarted(&m_highlighter, m_lastHighlightRevision);
|
emit highlighterStarted(m_highlighter, m_lastHighlightRevision);
|
||||||
} else {
|
} else {
|
||||||
const unsigned revision = currentSource(false).revision;
|
const unsigned revision = currentSource(false).revision;
|
||||||
if (m_lastHighlightRevision == revision)
|
if (m_lastHighlightRevision == revision)
|
||||||
@@ -400,7 +400,7 @@ void CppEditorSupport::startHighlighting()
|
|||||||
static const Document::Ptr dummyDoc;
|
static const Document::Ptr dummyDoc;
|
||||||
static const Snapshot dummySnapshot;
|
static const Snapshot dummySnapshot;
|
||||||
m_highlighter = m_highlightingSupport->highlightingFuture(dummyDoc, dummySnapshot);
|
m_highlighter = m_highlightingSupport->highlightingFuture(dummyDoc, dummySnapshot);
|
||||||
emit highlighterStarted(&m_highlighter, m_lastHighlightRevision);
|
emit highlighterStarted(m_highlighter, m_lastHighlightRevision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,6 +500,8 @@ void CppEditorSupport::onCurrentEditorChanged()
|
|||||||
|
|
||||||
void CppEditorSupport::releaseResources()
|
void CppEditorSupport::releaseResources()
|
||||||
{
|
{
|
||||||
|
m_highlighter.cancel();
|
||||||
|
m_highlighter = QFuture<TextEditor::HighlightingResult>();
|
||||||
snapshotUpdater()->releaseSnapshot();
|
snapshotUpdater()->releaseSnapshot();
|
||||||
QMutexLocker semanticLocker(&m_lastSemanticInfoLock);
|
QMutexLocker semanticLocker(&m_lastSemanticInfoLock);
|
||||||
m_lastSemanticInfo = SemanticInfo();
|
m_lastSemanticInfo = SemanticInfo();
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ signals:
|
|||||||
void documentUpdated();
|
void documentUpdated();
|
||||||
void diagnosticsChanged();
|
void diagnosticsChanged();
|
||||||
void semanticInfoUpdated(CppTools::SemanticInfo);
|
void semanticInfoUpdated(CppTools::SemanticInfo);
|
||||||
void highlighterStarted(QFuture<TextEditor::HighlightingResult> *, unsigned revision);
|
void highlighterStarted(QFuture<TextEditor::HighlightingResult>, unsigned revision);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onMimeTypeChanged();
|
void onMimeTypeChanged();
|
||||||
|
|||||||
Reference in New Issue
Block a user