Commit 7bfe2318 authored by Nikolai Kosjar's avatar Nikolai Kosjar

CppEditor: Make local renaming more robust again

This will update the use selections synchronously again in case the user
triggered "Rename Symbol Under Cursor", just as before

    commit 89bd4ee3
    C++: Base parsing on editor document instead of widget

Change-Id: I8d4d3dcc7140a61f9ac611a505db09dc96a17740
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent ec5ea375
......@@ -342,21 +342,12 @@ void CppEditorWidget::renameUsages(const QString &replacement)
void CppEditorWidget::renameSymbolUnderCursor()
{
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo());
d->m_useSelectionsUpdater.abortSchedule();
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
/*updateUseSelectionSynchronously=*/ true);
// Trigger once the use selections updater is finished and thus has updated
// the use selections for the local renaming
QSharedPointer<QMetaObject::Connection> connection(new QMetaObject::Connection);
*connection.data() = connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished,
[this, connection] () {
QObject::disconnect(*connection);
if (!d->m_localRenaming.start()) // Rename local symbol
renameUsages(); // Rename non-local symbol or macro
});
d->m_useSelectionsUpdater.update();
if (!d->m_localRenaming.start()) // Rename local symbol
renameUsages(); // Rename non-local symbol or macro
}
void CppEditorWidget::updatePreprocessorButtonTooltip()
......@@ -618,15 +609,20 @@ bool CppEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit)
flags);
}
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
bool updateUseSelectionSynchronously)
{
if (semanticInfo.revision != documentRevision())
return;
d->m_lastSemanticInfo = semanticInfo;
if (!d->m_localRenaming.isActive())
d->m_useSelectionsUpdater.update();
if (!d->m_localRenaming.isActive()) {
const CppUseSelectionsUpdater::CallType type = updateUseSelectionSynchronously
? CppUseSelectionsUpdater::Synchronous
: CppUseSelectionsUpdater::Asynchronous;
d->m_useSelectionsUpdater.update(type);
}
// schedule a check for a decl/def link
updateFunctionDeclDefLink();
......
......@@ -133,7 +133,8 @@ private slots:
void onIfdefedOutBlocksUpdated(unsigned revision,
const QList<TextEditor::BlockRange> ifdefedOutBlocks);
void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo);
void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo,
bool updateUseSelectionSynchronously = false);
void updatePreprocessorButtonTooltip();
void performQuickFix(int index);
......
......@@ -36,6 +36,7 @@
#include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cpptoolsreuse.h>
#include <texteditor/basetexteditor.h>
#include <texteditor/convenience.h>
#include <texteditor/fontsettings.h>
#include <cplusplus/Macro.h>
......@@ -119,8 +120,19 @@ QTextEdit::ExtraSelection extraSelection(const QTextCharFormat &format, const QT
return selection;
}
struct Params
class Params
{
public:
Params(const QTextCursor &textCursor, const Document::Ptr document, const Snapshot &snapshot)
: document(document), snapshot(snapshot)
{
TextEditor::Convenience::convertPosition(textCursor.document(), textCursor.position(),
&line, &column);
CppEditor::Internal::CanonicalSymbol canonicalSymbol(document, snapshot);
scope = canonicalSymbol.getScopeAndExpression(textCursor, &expression);
}
public:
// Shared
Document::Ptr document;
......@@ -239,7 +251,7 @@ void CppUseSelectionsUpdater::abortSchedule()
m_timer.stop();
}
void CppUseSelectionsUpdater::update()
void CppUseSelectionsUpdater::update(CallType callType)
{
CppEditorWidget *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
QTC_ASSERT(cppEditorWidget, return);
......@@ -255,14 +267,15 @@ void CppUseSelectionsUpdater::update()
QTC_ASSERT(document->translationUnit()->ast(), return);
QTC_ASSERT(!snapshot.isEmpty(), return);
QTextCursor textCursor = m_editorWidget->textCursor();
if (handleMacroCase(textCursor, document)) {
if (handleMacroCase(document)) {
emit finished(CppTools::SemanticInfo::LocalUseMap());
return;
}
handleSymbolCase(textCursor, document, snapshot);
if (callType == Asynchronous)
handleSymbolCaseAsynchronously(document, snapshot);
else
handleSymbolCaseSynchronously(document, snapshot);
}
void CppUseSelectionsUpdater::onFindUsesFinished()
......@@ -276,39 +289,16 @@ void CppUseSelectionsUpdater::onFindUsesFinished()
if (m_findUsesCursorPosition != m_editorWidget->position())
return;
const UseSelectionsResult result = m_findUsesWatcher->result();
const bool hasUsesForLocalVariable = !result.selectionsForLocalVariableUnderCursor.isEmpty();
const bool hasReferences = !result.references.isEmpty();
ExtraSelections localVariableSelections;
if (hasUsesForLocalVariable) {
localVariableSelections = toExtraSelections(result.selectionsForLocalVariableUnderCursor,
TextEditor::C_OCCURRENCES);
updateUseSelections(localVariableSelections);
} else if (hasReferences) {
const ExtraSelections selections = toExtraSelections(result.references,
TextEditor::C_OCCURRENCES);
updateUseSelections(selections);
} else {
if (!currentUseSelections().isEmpty())
updateUseSelections(ExtraSelections());
}
updateUnusedSelections(toExtraSelections(result.selectionsForLocalUnusedVariables,
TextEditor::C_OCCURRENCES_UNUSED));
processSymbolCaseResults(m_findUsesWatcher->result());
m_findUsesWatcher.reset();
m_document.reset();
m_snapshot = Snapshot();
emit selectionsForVariableUnderCursorUpdated(localVariableSelections);
emit finished(result.localUses);
}
bool CppUseSelectionsUpdater::handleMacroCase(const QTextCursor &textCursor,
const Document::Ptr document)
bool CppUseSelectionsUpdater::handleMacroCase(const Document::Ptr document)
{
const Macro *macro = CppTools::findCanonicalMacro(textCursor, document);
const Macro *macro = CppTools::findCanonicalMacro(m_editorWidget->textCursor(), document);
if (!macro)
return false;
......@@ -345,9 +335,8 @@ bool CppUseSelectionsUpdater::handleMacroCase(const QTextCursor &textCursor,
return true;
}
void CppUseSelectionsUpdater::handleSymbolCase(const QTextCursor &textCursor,
const Document::Ptr document,
const Snapshot &snapshot)
void CppUseSelectionsUpdater::handleSymbolCaseAsynchronously(const Document::Ptr document,
const Snapshot &snapshot)
{
m_document = document;
m_snapshot = snapshot;
......@@ -360,16 +349,44 @@ void CppUseSelectionsUpdater::handleSymbolCase(const QTextCursor &textCursor,
m_findUsesRevision = textDocument()->revision();
m_findUsesCursorPosition = m_editorWidget->position();
Params params;
params.document = document;
m_editorWidget->convertPosition(m_findUsesCursorPosition, &params.line, &params.column);
CanonicalSymbol canonicalSymbol(document, snapshot);
params.scope = canonicalSymbol.getScopeAndExpression(textCursor, &params.expression);
params.snapshot = snapshot;
const Params params = Params(m_editorWidget->textCursor(), document, snapshot);
m_findUsesWatcher->setFuture(QtConcurrent::run(&findUses, params));
}
void CppUseSelectionsUpdater::handleSymbolCaseSynchronously(const Document::Ptr document,
const Snapshot &snapshot)
{
const Params params = Params(m_editorWidget->textCursor(), document, snapshot);
const UseSelectionsResult result = findUses(params);
processSymbolCaseResults(result);
}
void CppUseSelectionsUpdater::processSymbolCaseResults(const UseSelectionsResult &result)
{
const bool hasUsesForLocalVariable = !result.selectionsForLocalVariableUnderCursor.isEmpty();
const bool hasReferences = !result.references.isEmpty();
ExtraSelections localVariableSelections;
if (hasUsesForLocalVariable) {
localVariableSelections = toExtraSelections(result.selectionsForLocalVariableUnderCursor,
TextEditor::C_OCCURRENCES);
updateUseSelections(localVariableSelections);
} else if (hasReferences) {
const ExtraSelections selections = toExtraSelections(result.references,
TextEditor::C_OCCURRENCES);
updateUseSelections(selections);
} else {
if (!currentUseSelections().isEmpty())
updateUseSelections(ExtraSelections());
}
updateUnusedSelections(toExtraSelections(result.selectionsForLocalUnusedVariables,
TextEditor::C_OCCURRENCES_UNUSED));
emit selectionsForVariableUnderCursorUpdated(localVariableSelections);
emit finished(result.localUses);
}
ExtraSelections CppUseSelectionsUpdater::toExtraSelections(const SemanticUses &uses,
TextEditor::TextStyle style) const
{
......
......@@ -68,10 +68,12 @@ class CppUseSelectionsUpdater : public QObject
public:
explicit CppUseSelectionsUpdater(TextEditor::BaseTextEditorWidget *editorWidget);
enum CallType { Synchronous, Asynchronous };
public slots:
void scheduleUpdate();
void abortSchedule();
void update();
void update(CallType callType = Asynchronous);
signals:
void finished(CppTools::SemanticInfo::LocalUseMap localUses);
......@@ -83,11 +85,13 @@ private slots:
private:
CppUseSelectionsUpdater();
bool handleMacroCase(const QTextCursor &textCursor,
const CPlusPlus::Document::Ptr document);
void handleSymbolCase(const QTextCursor &textCursor,
const CPlusPlus::Document::Ptr document,
const CPlusPlus::Snapshot &snapshot);
bool handleMacroCase(const CPlusPlus::Document::Ptr document);
void handleSymbolCaseAsynchronously(const CPlusPlus::Document::Ptr document,
const CPlusPlus::Snapshot &snapshot);
void handleSymbolCaseSynchronously(const CPlusPlus::Document::Ptr document,
const CPlusPlus::Snapshot &snapshot);
void processSymbolCaseResults(const UseSelectionsResult &result);
ExtraSelections toExtraSelections(const SemanticUses &uses, TextEditor::TextStyle style) const;
ExtraSelections toExtraSelections(const QList<int> &references,
......
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