diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-02-21 11:58:16 +0100 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-03-19 13:37:46 +0000 |
commit | 08d1274ccc0e9b116626afad60afaa970fe2fbbf (patch) | |
tree | e6fc80b45812c84f47bb72018b0e8362e3b31073 /src | |
parent | d471006d8136cd6f99f668d5a55e4f7a7483737e (diff) |
CppTools: Remove processEvents call from follow symbol
processEvents is a bad way of dealing with asynchronous
requests. Use QFutureWatcher for that purpose.
Change-Id: I3839cb9db80a6d391f6af1178e96986a325b7b99
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Diffstat (limited to 'src')
22 files changed, 199 insertions, 128 deletions
diff --git a/src/libs/utils/link.h b/src/libs/utils/link.h index 8f89e4e7fd..d6df02c076 100644 --- a/src/libs/utils/link.h +++ b/src/libs/utils/link.h @@ -28,6 +28,8 @@ #include <QString> #include <qmetatype.h> +#include <functional> + namespace Utils { struct Link @@ -57,6 +59,8 @@ struct Link int targetColumn; }; +using ProcessLinkCallback = std::function<void(const Link &)>; + } // namespace Utils Q_DECLARE_METATYPE(Utils::Link) diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.cpp b/src/plugins/clangcodemodel/clangfollowsymbol.cpp index f9ab5bb211..41872a4f51 100644 --- a/src/plugins/clangcodemodel/clangfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangfollowsymbol.cpp @@ -93,12 +93,13 @@ static Utils::Link linkAtCursor(QTextCursor cursor, const QString &filePath, uin return Link(); } -Utils::Link ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data, - bool resolveTarget, - const CPlusPlus::Snapshot &snapshot, - const CPlusPlus::Document::Ptr &documentFromSemanticInfo, - CppTools::SymbolFinder *symbolFinder, - bool inNextSplit) +void ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data, + ::Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget, + const CPlusPlus::Snapshot &snapshot, + const CPlusPlus::Document::Ptr &documentFromSemanticInfo, + CppTools::SymbolFinder *symbolFinder, + bool inNextSplit) { int lineNumber = 0, positionInBlock = 0; QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor()); @@ -111,34 +112,40 @@ Utils::Link ClangFollowSymbol::findLink(const CppTools::CursorInEditor &data, ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get( data.filePath().toString()); if (!processor) - return Link(); + return processLinkCallback(Utils::Link()); - if (!resolveTarget) - return linkAtCursor(cursor, data.filePath().toString(), line, column, processor); + if (!resolveTarget) { + processLinkCallback(linkAtCursor(cursor, data.filePath().toString(), line, column, + processor)); + return; + } - QFuture<CppTools::SymbolInfo> info + QFuture<CppTools::SymbolInfo> infoFuture = processor->requestFollowSymbol(static_cast<int>(line), static_cast<int>(column)); - if (info.isCanceled()) - return Link(); - - while (!info.isFinished()) { - if (info.isCanceled()) - return Link(); - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); - } - CppTools::SymbolInfo result = info.result(); - - // We did not fail but the result is empty - if (result.fileName.isEmpty()) { - const CppTools::RefactoringEngineInterface &refactoringEngine - = *CppTools::CppModelManager::instance(); - return refactoringEngine.globalFollowSymbol(data, snapshot, documentFromSemanticInfo, - symbolFinder, inNextSplit); - } - - return Link(result.fileName, result.startLine, result.startColumn - 1); + if (infoFuture.isCanceled()) + return processLinkCallback(Utils::Link()); + + QObject::connect(&m_watcher, &FutureSymbolWatcher::finished, + [=, watcher=&m_watcher, callback=std::move(processLinkCallback)]() mutable { + CppTools::SymbolInfo result = watcher->result(); + // We did not fail but the result is empty + if (result.fileName.isEmpty()) { + const CppTools::RefactoringEngineInterface &refactoringEngine + = *CppTools::CppModelManager::instance(); + refactoringEngine.globalFollowSymbol(data, + std::move(callback), + snapshot, + documentFromSemanticInfo, + symbolFinder, + inNextSplit); + } else { + callback(Link(result.fileName, result.startLine, result.startColumn - 1)); + } + }); + + m_watcher.setFuture(infoFuture); } } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.h b/src/plugins/clangcodemodel/clangfollowsymbol.h index 8c9da83592..dd7abb38fc 100644 --- a/src/plugins/clangcodemodel/clangfollowsymbol.h +++ b/src/plugins/clangcodemodel/clangfollowsymbol.h @@ -26,6 +26,9 @@ #pragma once #include <cpptools/followsymbolinterface.h> +#include <cpptools/cppsymbolinfo.h> + +#include <QFutureWatcher> namespace ClangCodeModel { namespace Internal { @@ -33,12 +36,16 @@ namespace Internal { class ClangFollowSymbol : public CppTools::FollowSymbolInterface { public: - Link findLink(const CppTools::CursorInEditor &data, + void findLink(const CppTools::CursorInEditor &data, + ::Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, CppTools::SymbolFinder *symbolFinder, bool inNextSplit) override; +private: + using FutureSymbolWatcher = QFutureWatcher<CppTools::SymbolInfo>; + FutureSymbolWatcher m_watcher; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangrefactoringengine.h b/src/plugins/clangcodemodel/clangrefactoringengine.h index 10ad96aa0d..fee9a85cf5 100644 --- a/src/plugins/clangcodemodel/clangrefactoringengine.h +++ b/src/plugins/clangcodemodel/clangrefactoringengine.h @@ -46,11 +46,13 @@ public: void globalRename(const CppTools::CursorInEditor &, CppTools::UsagesCallback &&, const QString &) override {} void findUsages(const CppTools::CursorInEditor &, CppTools::UsagesCallback &&) const override {} - Link globalFollowSymbol(const CppTools::CursorInEditor &, const CPlusPlus::Snapshot &, - const CPlusPlus::Document::Ptr &, CppTools::SymbolFinder *, + void globalFollowSymbol(const CppTools::CursorInEditor &, + ::Utils::ProcessLinkCallback &&, + const CPlusPlus::Snapshot &, + const CPlusPlus::Document::Ptr &, + CppTools::SymbolFinder *, bool) const override { - return Link(); } private: diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp index 7c69cfc9d1..952ed9bf19 100644 --- a/src/plugins/clangrefactoring/refactoringengine.cpp +++ b/src/plugins/clangrefactoring/refactoringengine.cpp @@ -123,11 +123,12 @@ void RefactoringEngine::findUsages(const CppTools::CursorInEditor &data, showUsagesCallback(locationsAt(data)); } -RefactoringEngine::Link RefactoringEngine::globalFollowSymbol(const CppTools::CursorInEditor &data, - const CPlusPlus::Snapshot &, - const CPlusPlus::Document::Ptr &, - CppTools::SymbolFinder *, - bool) const +void RefactoringEngine::globalFollowSymbol(const CppTools::CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, + const CPlusPlus::Snapshot &, + const CPlusPlus::Document::Ptr &, + CppTools::SymbolFinder *, + bool) const { // TODO: replace that with specific followSymbol query const CppTools::Usages usages = locationsAt(data); @@ -138,7 +139,7 @@ RefactoringEngine::Link RefactoringEngine::globalFollowSymbol(const CppTools::Cu return true; }); - return Link(usage.path, usage.line, usage.column); + processLinkCallback(Link(usage.path, usage.line, usage.column)); } bool RefactoringEngine::isRefactoringEngineAvailable() const diff --git a/src/plugins/clangrefactoring/refactoringengine.h b/src/plugins/clangrefactoring/refactoringengine.h index 951a18fb53..739b545310 100644 --- a/src/plugins/clangrefactoring/refactoringengine.h +++ b/src/plugins/clangrefactoring/refactoringengine.h @@ -57,7 +57,8 @@ public: const QString &) override; void findUsages(const CppTools::CursorInEditor &data, CppTools::UsagesCallback &&showUsagesCallback) const override; - Link globalFollowSymbol(const CppTools::CursorInEditor &data, + void globalFollowSymbol(const CppTools::CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &, const CPlusPlus::Document::Ptr &, CppTools::SymbolFinder *, diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp index a197345419..a1b529e3e9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp @@ -117,7 +117,10 @@ public: private: bool save(const QString &fileName = QString()); - Utils::Link findLinkAt(const QTextCursor &cursor, bool resolveTarget = true, bool inNextSplit = false) override; + void findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget = true, + bool inNextSplit = false) override; void contextMenuEvent(QContextMenuEvent *e) override; }; @@ -136,8 +139,10 @@ static bool isValidFileNameChar(const QChar &c) || c == QLatin1Char('\\'); } -Utils::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, - bool/* resolveTarget*/, bool /*inNextSplit*/) +void CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool/* resolveTarget*/, + bool /*inNextSplit*/) { Utils::Link link; @@ -149,7 +154,7 @@ Utils::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, // check if the current position is commented out const int hashPos = block.indexOf(QLatin1Char('#')); if (hashPos >= 0 && hashPos < positionInBlock) - return link; + return processLinkCallback(link); // find the beginning of a filename QString buffer; @@ -177,7 +182,7 @@ Utils::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, } if (buffer.isEmpty()) - return link; + return processLinkCallback(link); // TODO: Resolve variables @@ -191,13 +196,13 @@ Utils::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, if (QFileInfo::exists(subProject)) fileName = subProject; else - return link; + return processLinkCallback(link); } link.targetFileName = fileName; link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } - return link; + processLinkCallback(link); } static TextDocument *createCMakeDocument() diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 778936570e..b6032fee4a 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -718,21 +718,23 @@ void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit) openLink(symbolLink, inNextSplit != alwaysOpenLinksInNextSplit()); } -Utils::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor, - bool resolveTarget, - bool inNextSplit) +void CppEditorWidget::findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget, + bool inNextSplit) { if (!d->m_modelManager) - return Utils::Link(); + return processLinkCallback(Utils::Link()); const Utils::FileName &filePath = textDocument()->filePath(); - return followSymbolInterface().findLink(CppTools::CursorInEditor{cursor, filePath, this}, - resolveTarget, - d->m_modelManager->snapshot(), - d->m_lastSemanticInfo.doc, - d->m_modelManager->symbolFinder(), - inNextSplit); + followSymbolInterface().findLink(CppTools::CursorInEditor{cursor, filePath, this}, + std::move(processLinkCallback), + resolveTarget, + d->m_modelManager->snapshot(), + d->m_lastSemanticInfo.doc, + d->m_modelManager->symbolFinder(), + inNextSplit); } unsigned CppEditorWidget::documentRevision() const diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h index 486c1ef474..d5538e63bf 100644 --- a/src/plugins/cppeditor/cppeditorwidget.h +++ b/src/plugins/cppeditor/cppeditorwidget.h @@ -100,8 +100,10 @@ protected: void keyPressEvent(QKeyEvent *e) override; bool handleStringSplitting(QKeyEvent *e) const; - Utils::Link findLinkAt(const QTextCursor &, bool resolveTarget = true, - bool inNextSplit = false) override; + void findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget = true, + bool inNextSplit = false) override; void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override; diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp index 191746923e..304d938cd8 100644 --- a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp @@ -480,8 +480,9 @@ static int skipMatchingParentheses(const Tokens &tokens, int idx, int initialDep return j; } -Link FollowSymbolUnderCursor::findLink( +void FollowSymbolUnderCursor::findLink( const CppTools::CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget, const Snapshot &theSnapshot, const Document::Ptr &documentFromSemanticInfo, @@ -518,7 +519,7 @@ Link FollowSymbolUnderCursor::findLink( link = attemptFuncDeclDef(cursor, snapshot, documentFromSemanticInfo, symbolFinder); if (link.hasValidLinkText()) - return link; + return processLinkCallback(link); } } @@ -590,7 +591,7 @@ Link FollowSymbolUnderCursor::findLink( link = attemptFuncDeclDef(cursor, theSnapshot, documentFromSemanticInfo, symbolFinder); if (link.hasValidLinkText()) - return link; + return processLinkCallback(link); } else if (tk.isOperator() && i > 0 && tokens.at(i - 1).is(T_OPERATOR)) { QTextCursor c = cursor; c.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, @@ -598,7 +599,7 @@ Link FollowSymbolUnderCursor::findLink( link = attemptFuncDeclDef(c, theSnapshot, documentFromSemanticInfo, symbolFinder); if (link.hasValidLinkText()) - return link; + return processLinkCallback(link); } } else if (cursorRegionReached) { break; @@ -608,13 +609,14 @@ Link FollowSymbolUnderCursor::findLink( CppEditorWidgetInterface *editorWidget = data.editorWidget(); if (!editorWidget) - return link; + return processLinkCallback(link); + // Now we prefer the doc from the snapshot with macros expanded. Document::Ptr doc = snapshot.document(data.filePath()); if (!doc) { doc = documentFromSemanticInfo; if (!doc) - return link; + return processLinkCallback(link); } if (!recognizedQtMethod) { @@ -638,13 +640,14 @@ Link FollowSymbolUnderCursor::findLink( link.targetFileName = incl.resolvedFileName(); link.linkTextStart = beginOfToken + 1; link.linkTextEnd = endOfToken - 1; - return link; + processLinkCallback(link); + return; } } } if (tk.isNot(T_IDENTIFIER) && !tk.isQtKeyword()) - return link; + return processLinkCallback(link); tc.setPosition(endOfToken); } @@ -655,7 +658,7 @@ Link FollowSymbolUnderCursor::findLink( QTextCursor macroCursor = cursor; const QByteArray name = CppTools::identifierUnderCursor(¯oCursor).toUtf8(); if (macro->name() == name) - return link; //already on definition! + return processLinkCallback(link); //already on definition! } else if (const Document::MacroUse *use = doc->findMacroUseAt(endOfToken - 1)) { const QString fileName = use->macro().fileName(); if (fileName == CppModelManager::editorConfigurationFileName()) { @@ -667,13 +670,14 @@ Link FollowSymbolUnderCursor::findLink( link.linkTextStart = use->utf16charsBegin(); link.linkTextEnd = use->utf16charsEnd(); } - return link; + processLinkCallback(link); + return; } // Find the last symbol up to the cursor position Scope *scope = doc->scopeAt(line, column); if (!scope) - return link; + return processLinkCallback(link); // Evaluate the type of the expression under the cursor QTC_CHECK(document == tc.document()); @@ -741,7 +745,8 @@ Link FollowSymbolUnderCursor::findLink( Link link; link.linkTextStart = beginOfToken; link.linkTextEnd = endOfToken; - return link; + processLinkCallback(link); + return; } Symbol *lastVisibleSymbol = doc->lastVisibleSymbolAt(line, column); @@ -765,7 +770,8 @@ Link FollowSymbolUnderCursor::findLink( link = (def ? def : symbol)->toLink(); link.linkTextStart = beginOfToken; link.linkTextEnd = endOfToken; - return link; + processLinkCallback(link); + return; } } @@ -776,10 +782,11 @@ Link FollowSymbolUnderCursor::findLink( if (link.hasValidTarget()) { link.linkTextStart = macroCursor.selectionStart(); link.linkTextEnd = macroCursor.selectionEnd(); - return link; + processLinkCallback(link); + return; } - return Link(); + processLinkCallback(Link()); } QSharedPointer<VirtualFunctionAssistProvider> FollowSymbolUnderCursor::virtualFunctionAssistProvider() diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.h b/src/plugins/cpptools/cppfollowsymbolundercursor.h index 8e93a7097d..a3bdf17736 100644 --- a/src/plugins/cpptools/cppfollowsymbolundercursor.h +++ b/src/plugins/cpptools/cppfollowsymbolundercursor.h @@ -36,7 +36,8 @@ class CPPTOOLS_EXPORT FollowSymbolUnderCursor : public CppTools::FollowSymbolInt public: FollowSymbolUnderCursor(); - Link findLink(const CppTools::CursorInEditor &data, + void findLink(const CppTools::CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index c28995c709..953b0eb06f 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -327,17 +327,18 @@ void CppModelManager::findUsages(const CppTools::CursorInEditor &data, engine->findUsages(data, std::move(showUsagesCallback)); } -CppModelManager::Link CppModelManager::globalFollowSymbol( +void CppModelManager::globalFollowSymbol( const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, SymbolFinder *symbolFinder, bool inNextSplit) const { RefactoringEngineInterface *engine = getRefactoringEngine(d->m_refactoringEngines); - QTC_ASSERT(engine, return Link();); - return engine->globalFollowSymbol(data, snapshot, documentFromSemanticInfo, - symbolFinder, inNextSplit); + QTC_ASSERT(engine, return;); + engine->globalFollowSymbol(data, std::move(processLinkCallback), snapshot, documentFromSemanticInfo, + symbolFinder, inNextSplit); } void CppModelManager::addRefactoringEngine(RefactoringEngineType type, diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index a472fa4924..f7a9d6ddd6 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -163,7 +163,8 @@ public: const QString &replacement) final; void findUsages(const CppTools::CursorInEditor &data, UsagesCallback &&showUsagesCallback) const final; - Link globalFollowSymbol(const CursorInEditor &data, + void globalFollowSymbol(const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, SymbolFinder *symbolFinder, diff --git a/src/plugins/cpptools/cpprefactoringengine.cpp b/src/plugins/cpptools/cpprefactoringengine.cpp index 1f66829e96..f816b507a5 100644 --- a/src/plugins/cpptools/cpprefactoringengine.cpp +++ b/src/plugins/cpptools/cpprefactoringengine.cpp @@ -100,16 +100,17 @@ void CppRefactoringEngine::findUsages(const CursorInEditor &data, } } -CppRefactoringEngine::Link CppRefactoringEngine::globalFollowSymbol( +void CppRefactoringEngine::globalFollowSymbol( const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, SymbolFinder *symbolFinder, bool inNextSplit) const { FollowSymbolUnderCursor followSymbol; - return followSymbol.findLink(data, true, snapshot, documentFromSemanticInfo, - symbolFinder, inNextSplit); + return followSymbol.findLink(data, std::move(processLinkCallback), true, snapshot, + documentFromSemanticInfo, symbolFinder, inNextSplit); } } // namespace CppEditor diff --git a/src/plugins/cpptools/cpprefactoringengine.h b/src/plugins/cpptools/cpprefactoringengine.h index 72a81136e3..17b24062f7 100644 --- a/src/plugins/cpptools/cpprefactoringengine.h +++ b/src/plugins/cpptools/cpprefactoringengine.h @@ -38,7 +38,8 @@ public: void globalRename(const CursorInEditor &data, UsagesCallback &&, const QString &replacement) override; void findUsages(const CursorInEditor &data, UsagesCallback &&) const override; - Link globalFollowSymbol(const CursorInEditor &data, + void globalFollowSymbol(const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, SymbolFinder *symbolFinder, diff --git a/src/plugins/cpptools/followsymbolinterface.h b/src/plugins/cpptools/followsymbolinterface.h index 94dbfc9827..bde155c5f3 100644 --- a/src/plugins/cpptools/followsymbolinterface.h +++ b/src/plugins/cpptools/followsymbolinterface.h @@ -42,7 +42,8 @@ public: using Link = Utils::Link; virtual ~FollowSymbolInterface() {} - virtual Link findLink(const CursorInEditor &data, + virtual void findLink(const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, diff --git a/src/plugins/cpptools/refactoringengineinterface.h b/src/plugins/cpptools/refactoringengineinterface.h index fa9435bf77..d47855b686 100644 --- a/src/plugins/cpptools/refactoringengineinterface.h +++ b/src/plugins/cpptools/refactoringengineinterface.h @@ -69,7 +69,8 @@ public: const QString &replacement) = 0; virtual void findUsages(const CppTools::CursorInEditor &data, UsagesCallback &&showUsagesCallback) const = 0; - virtual Link globalFollowSymbol(const CursorInEditor &data, + virtual void globalFollowSymbol(const CursorInEditor &data, + Utils::ProcessLinkCallback &&processLinkCallback, const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Document::Ptr &documentFromSemanticInfo, SymbolFinder *symbolFinder, diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index 49b1f3993b..cccb3ba98b 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -57,7 +57,9 @@ namespace Internal { class ProFileEditorWidget : public TextEditorWidget { protected: - virtual Link findLinkAt(const QTextCursor &, bool resolveTarget = true, + virtual void findLinkAt(const QTextCursor &, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget = true, bool inNextSplit = false) override; void contextMenuEvent(QContextMenuEvent *) override; }; @@ -72,9 +74,10 @@ static bool isValidFileNameChar(const QChar &c) || c == QLatin1Char('\\'); } -Utils::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, - bool /*resolveTarget*/, - bool /*inNextSplit*/) +void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool /*resolveTarget*/, + bool /*inNextSplit*/) { Link link; @@ -86,7 +89,7 @@ Utils::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, // check if the current position is commented out const int hashPos = block.indexOf(QLatin1Char('#')); if (hashPos >= 0 && hashPos < positionInBlock) - return link; + return processLinkCallback(link); // find the beginning of a filename QString buffer; @@ -159,7 +162,7 @@ Utils::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, } if (buffer.isEmpty()) - return link; + return processLinkCallback(link); // remove trailing '\' since it can be line continuation char if (buffer.at(buffer.size() - 1) == QLatin1Char('\\')) { @@ -181,13 +184,13 @@ Utils::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, if (QFileInfo::exists(subProject)) fileName = subProject; else - return link; + return processLinkCallback(link); } link.targetFileName = QDir::cleanPath(fileName); link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } - return link; + processLinkCallback(link); } void ProFileEditorWidget::contextMenuEvent(QContextMenuEvent *e) diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index b2628c0783..1cc059c046 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -712,18 +712,19 @@ void QmlJSEditorWidget::inspectElementUnderCursor() const widget->textDocument()->setPlainText(buf); } -Utils::Link QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, - bool /*resolveTarget*/, - bool /*inNextSplit*/) +void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool /*resolveTarget*/, + bool /*inNextSplit*/) { const SemanticInfo semanticInfo = m_qmlJsEditorDocument->semanticInfo(); if (! semanticInfo.isValid()) - return Utils::Link(); + return processLinkCallback(Utils::Link()); const unsigned cursorPosition = cursor.position(); AST::Node *node = semanticInfo.astNodeAt(cursorPosition); - QTC_ASSERT(node, return Utils::Link()); + QTC_ASSERT(node, return;); if (AST::UiImport *importAst = cast<AST::UiImport *>(node)) { // if it's a file import, link to the file @@ -732,10 +733,12 @@ Utils::Link QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, Utils::Link link(import.path()); link.linkTextStart = importAst->firstSourceLocation().begin(); link.linkTextEnd = importAst->lastSourceLocation().end(); - return link; + processLinkCallback(Utils::Link()); + return; } } - return Utils::Link(); + processLinkCallback(Utils::Link()); + return; } // string literals that could refer to a file link to them @@ -746,14 +749,16 @@ Utils::Link QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, link.linkTextEnd = literal->literalToken.end(); if (semanticInfo.snapshot.document(text)) { link.targetFileName = text; - return link; + processLinkCallback(link); + return; } const QString relative = QString::fromLatin1("%1/%2").arg( semanticInfo.document->path(), text); if (semanticInfo.snapshot.document(relative)) { link.targetFileName = relative; - return link; + processLinkCallback(link); + return; } } @@ -765,7 +770,7 @@ Utils::Link QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, int line = 0, column = 0; if (! (value && value->getSourceLocation(&fileName, &line, &column))) - return Utils::Link(); + return processLinkCallback(Utils::Link()); Utils::Link link; link.targetFileName = fileName; @@ -777,22 +782,25 @@ Utils::Link QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor, if (! tail->next && cursorPosition <= tail->identifierToken.end()) { link.linkTextStart = tail->identifierToken.begin(); link.linkTextEnd = tail->identifierToken.end(); - return link; + processLinkCallback(link); + return; } } } else if (AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(node)) { link.linkTextStart = id->firstSourceLocation().begin(); link.linkTextEnd = id->lastSourceLocation().end(); - return link; + processLinkCallback(link); + return; } else if (AST::FieldMemberExpression *mem = AST::cast<AST::FieldMemberExpression *>(node)) { link.linkTextStart = mem->lastSourceLocation().begin(); link.linkTextEnd = mem->lastSourceLocation().end(); - return link; + processLinkCallback(link); + return; } - return Utils::Link(); + processLinkCallback(Utils::Link()); } void QmlJSEditorWidget::findUsages() diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index f857acc8be..1b2767d43e 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -103,9 +103,10 @@ protected: void scrollContentsBy(int dx, int dy) override; void applyFontSettings() override; void createToolBar(); - Utils::Link findLinkAt(const QTextCursor &cursor, - bool resolveTarget = true, - bool inNextSplit = false) override; + void findLinkAt(const QTextCursor &cursor, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget = true, + bool inNextSplit = false) override; QString foldReplacementText(const QTextBlock &block) const override; void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index f36f208376..916f738f12 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -1847,15 +1847,21 @@ void TextEditorWidget::redo() void TextEditorWidget::openLinkUnderCursor() { const bool openInNextSplit = alwaysOpenLinksInNextSplit(); - Utils::Link symbolLink = findLinkAt(textCursor(), true, openInNextSplit); - openLink(symbolLink, openInNextSplit); + findLinkAt(textCursor(), + [openInNextSplit, self = QPointer<TextEditorWidget>(this)](const Link &symbolLink) { + if (self) + self->openLink(symbolLink, openInNextSplit); + }, true, openInNextSplit); } void TextEditorWidget::openLinkUnderCursorInNextSplit() { const bool openInNextSplit = !alwaysOpenLinksInNextSplit(); - Utils::Link symbolLink = findLinkAt(textCursor(), true, openInNextSplit); - openLink(symbolLink, openInNextSplit); + findLinkAt(textCursor(), + [openInNextSplit, self = QPointer<TextEditorWidget>(this)](const Link &symbolLink) { + if (self) + self->openLink(symbolLink, openInNextSplit); + }, true, openInNextSplit); } void TextEditorWidget::abortAssist() @@ -5581,10 +5587,12 @@ void TextEditorWidget::mouseReleaseEvent(QMouseEvent *e) EditorManager::addCurrentPositionToNavigationHistory(); bool inNextSplit = ((e->modifiers() & Qt::AltModifier) && !alwaysOpenLinksInNextSplit()) || (alwaysOpenLinksInNextSplit() && !(e->modifiers() & Qt::AltModifier)); - if (openLink(findLinkAt(cursorForPosition(e->pos())), inNextSplit)) { - d->clearLink(); - return; - } + + findLinkAt(textCursor(), + [inNextSplit, self = QPointer<TextEditorWidget>(this)](const Link &symbolLink) { + if (self && self->openLink(symbolLink, inNextSplit)) + self->d->clearLink(); + }, true, inNextSplit); } if (!HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e)) @@ -6136,9 +6144,8 @@ void TextEditorWidget::zoomReset() showZoomIndicator(this, 100); } -Utils::Link TextEditorWidget::findLinkAt(const QTextCursor &, bool, bool) +void TextEditorWidget::findLinkAt(const QTextCursor &, Utils::ProcessLinkCallback &&, bool, bool) { - return Utils::Link(); } bool TextEditorWidget::openLink(const Utils::Link &link, bool inNextSplit) @@ -6204,11 +6211,16 @@ void TextEditorWidgetPrivate::updateLink() return; m_lastLinkUpdate = m_pendingLinkUpdate; - const Utils::Link link = q->findLinkAt(m_pendingLinkUpdate, false); - if (link.hasValidLinkText()) - showLink(link); - else - clearLink(); + q->findLinkAt(m_pendingLinkUpdate, + [parent = QPointer<TextEditorWidget>(q), this](const Link &link) { + if (!parent) + return; + + if (link.hasValidLinkText()) + showLink(link); + else + clearLink(); + }, false); } void TextEditorWidgetPrivate::showLink(const Utils::Link &link) diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index c08187ed4d..937bff13d1 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -548,8 +548,10 @@ protected: \a resolveTarget is set to true when the target of the link is relevant (it isn't until the link is used). */ - virtual Utils::Link findLinkAt(const QTextCursor &, bool resolveTarget = true, - bool inNextSplit = false); + virtual void findLinkAt(const QTextCursor &, + Utils::ProcessLinkCallback &&processLinkCallback, + bool resolveTarget = true, + bool inNextSplit = false); /*! Returns whether the link was opened successfully. |