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