diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2022-04-25 13:37:58 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2022-04-28 09:47:52 +0000 |
commit | f2c267f3283ef70ad053b507b17513be068b2e6b (patch) | |
tree | f7dd540213b7042a6e51e83f6252d55f5fa248b4 /src/plugins/clangcodemodel/clangfollowsymbol.cpp | |
parent | 8e586dfa022232a82762503c896a0088429cd8c7 (diff) | |
download | qt-creator-f2c267f3283ef70ad053b507b17513be068b2e6b.tar.gz |
ClangCodeModel: Remove libclang fallback for "follow symbol"
... and "switch between declaration/definition".
It's either clangd or built-in code model now.
Use the opportunity to dissolve the pointless FollowSymbolInterface
class hierarchy, which introduced a confusing parallel inheritance
chain.
Change-Id: I792ad55656c5dd9f10c6b4db7c5c36cf7be45125
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/clangcodemodel/clangfollowsymbol.cpp')
-rw-r--r-- | src/plugins/clangcodemodel/clangfollowsymbol.cpp | 274 |
1 files changed, 0 insertions, 274 deletions
diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.cpp b/src/plugins/clangcodemodel/clangfollowsymbol.cpp deleted file mode 100644 index c81bbe1268..0000000000 --- a/src/plugins/clangcodemodel/clangfollowsymbol.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "clangfollowsymbol.h" - -#include "clangdclient.h" -#include "clangeditordocumentprocessor.h" -#include "clangmodelmanagersupport.h" - -#include <coreplugin/editormanager/editormanager.h> -#include <cppeditor/cppmodelmanager.h> -#include <cppeditor/cppfollowsymbolundercursor.h> -#include <texteditor/texteditor.h> - -#include <clangsupport/tokeninfocontainer.h> - -#include <utils/textutils.h> -#include <utils/algorithm.h> - -#include <memory> - -namespace ClangCodeModel { -namespace Internal { - -// Returns invalid Mark if it is not found at (line, column) -static bool findMark(const QVector<ClangBackEnd::TokenInfoContainer> &marks, - int line, - int column, - ClangBackEnd::TokenInfoContainer &mark) -{ - mark = Utils::findOrDefault(marks, - [line, column](const ClangBackEnd::TokenInfoContainer &curMark) { - if (curMark.line != line) - return false; - if (curMark.column == column) - return true; - if (curMark.column < column && curMark.column + curMark.length > column) - return true; - return false; - }); - if (mark.isInvalid()) - return false; - return true; -} - -static int getMarkPos(QTextCursor cursor, const ClangBackEnd::TokenInfoContainer &mark) -{ - cursor.setPosition(0); - cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, mark.line - 1); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, mark.column - 1); - return cursor.position(); -} - -static bool isValidIncludePathToken(const ClangBackEnd::TokenInfoContainer &token) -{ - if (!token.extraInfo.includeDirectivePath) - return false; - const Utf8String &tokenName = token.extraInfo.token; - return !tokenName.startsWith("include") && tokenName != Utf8String("<") - && tokenName != Utf8String(">") && tokenName != Utf8String("#"); -} - -static int includePathStartIndex(const QVector<ClangBackEnd::TokenInfoContainer> &marks, - int currentIndex) -{ - int startIndex = currentIndex - 1; - while (startIndex >= 0 && isValidIncludePathToken(marks[startIndex])) - --startIndex; - return startIndex + 1; -} - -static int includePathEndIndex(const QVector<ClangBackEnd::TokenInfoContainer> &marks, - int currentIndex) -{ - int endIndex = currentIndex + 1; - while (endIndex < marks.size() && isValidIncludePathToken(marks[endIndex])) - ++endIndex; - return endIndex - 1; -} - -static Utils::Link linkAtCursor(const QTextCursor &cursor, - const QString &filePath, - uint line, - uint column, - ClangEditorDocumentProcessor *processor) -{ - using Link = Utils::Link; - - const QVector<ClangBackEnd::TokenInfoContainer> &marks - = processor->tokenInfos(); - ClangBackEnd::TokenInfoContainer mark; - if (!findMark(marks, line, column, mark)) - return Link(); - - if (mark.extraInfo.includeDirectivePath && !isValidIncludePathToken(mark)) - return Link(); - - Link token(Utils::FilePath::fromString(filePath), mark.line, mark.column); - token.linkTextStart = getMarkPos(cursor, mark); - token.linkTextEnd = token.linkTextStart + mark.length; - - if (mark.extraInfo.includeDirectivePath) { - // Tweak include paths to cover everything between "" or <>. - if (mark.extraInfo.token.startsWith("\"")) { - token.linkTextStart++; - token.linkTextEnd--; - } else { - // '#include <path/file.h>' case. Clang gives us a separate token for each part of - // the path. We want to have the full range instead therefore we search for < and > - // tokens around the current token. - const int index = marks.indexOf(mark); - const int startIndex = includePathStartIndex(marks, index); - const int endIndex = includePathEndIndex(marks, index); - - if (startIndex != index) - token.linkTextStart = getMarkPos(cursor, marks[startIndex]); - if (endIndex != index) - token.linkTextEnd = getMarkPos(cursor, marks[endIndex]) + marks[endIndex].length; - } - return token; - } - - if (mark.extraInfo.identifier || mark.extraInfo.token == "operator" - || mark.extraInfo.token == "auto") { - return token; - } - return Link(); -} - -static ::Utils::ProcessLinkCallback extendedCallback(::Utils::ProcessLinkCallback &&callback, - const CppEditor::SymbolInfo &result) -{ - // If globalFollowSymbol finds nothing follow to the declaration. - return [original_callback = std::move(callback), result](const ::Utils::Link &link) { - if (link.linkTextStart < 0 && result.isResultOnlyForFallBack) { - return original_callback(Utils::Link( - Utils::FilePath::fromString(result.fileName).cleanPath(), - result.startLine, - result.startColumn - 1)); - } - return original_callback(link); - }; -} - -static bool isSameInvocationContext(const Utils::FilePath &filePath) -{ - return TextEditor::BaseTextEditor::currentTextEditor()->editorWidget()->isVisible() - && Core::EditorManager::currentDocument()->filePath() == filePath; -} - -void ClangFollowSymbol::findLink(const CppEditor::CursorInEditor &data, - ::Utils::ProcessLinkCallback &&processLinkCallback, - bool resolveTarget, - const CPlusPlus::Snapshot &snapshot, - const CPlusPlus::Document::Ptr &documentFromSemanticInfo, - CppEditor::SymbolFinder *symbolFinder, - bool inNextSplit) -{ - ClangdClient * const client - = ClangModelManagerSupport::instance()->clientForFile(data.filePath()); - if (client && client->isFullyIndexed()) { - client->followSymbol(data.textDocument(), data.cursor(), data.editorWidget(), - std::move(processLinkCallback), resolveTarget, inNextSplit); - return; - } - - int line = 0; - int column = 0; - QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor()); - Utils::Text::convertPosition(cursor.document(), cursor.position(), &line, &column); - - ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get( - data.filePath().toString()); - if (!processor) - return processLinkCallback(Utils::Link()); - - if (!resolveTarget) { - Utils::Link link = linkAtCursor(cursor, - data.filePath().toString(), - static_cast<uint>(line), - static_cast<uint>(column), - processor); - if (link == Utils::Link()) { - CppEditor::FollowSymbolUnderCursor followSymbol; - return followSymbol.findLink(data, - std::move(processLinkCallback), - false, - snapshot, - documentFromSemanticInfo, - symbolFinder, - inNextSplit); - } - return processLinkCallback(link); - } - - QFuture<CppEditor::SymbolInfo> infoFuture - = processor->requestFollowSymbol(static_cast<int>(line), - static_cast<int>(column)); - - if (infoFuture.isCanceled()) - return processLinkCallback(Utils::Link()); - - if (m_watcher) - m_watcher->cancel(); - - m_watcher = std::make_unique<FutureSymbolWatcher>(); - - QObject::connect(m_watcher.get(), &FutureSymbolWatcher::finished, [=, filePath=data.filePath(), - callback=std::move(processLinkCallback)]() mutable { - if (m_watcher->isCanceled() || !isSameInvocationContext(filePath)) - return callback(Utils::Link()); - CppEditor::SymbolInfo result = m_watcher->result(); - // We did not fail but the result is empty - if (result.fileName.isEmpty() || result.isResultOnlyForFallBack) { - const CppEditor::RefactoringEngineInterface &refactoringEngine - = *CppEditor::CppModelManager::instance(); - refactoringEngine.globalFollowSymbol(data, - extendedCallback(std::move(callback), result), - snapshot, - documentFromSemanticInfo, - symbolFinder, - inNextSplit); - } else { - callback(Link(Utils::FilePath::fromString(result.fileName).cleanPath(), - result.startLine, - result.startColumn - 1)); - } - }); - - m_watcher->setFuture(infoFuture); -} - -void ClangFollowSymbol::switchDeclDef(const CppEditor::CursorInEditor &data, - Utils::ProcessLinkCallback &&processLinkCallback, - const CPlusPlus::Snapshot &snapshot, - const CPlusPlus::Document::Ptr &documentFromSemanticInfo, - CppEditor::SymbolFinder *symbolFinder) -{ - ClangdClient * const client - = ClangModelManagerSupport::instance()->clientForFile(data.filePath()); - if (client && client->isFullyIndexed()) { - client->switchDeclDef(data.textDocument(), data.cursor(), data.editorWidget(), - std::move(processLinkCallback)); - return; - } - CppEditor::CppModelManager::builtinFollowSymbol().switchDeclDef( - data, std::move(processLinkCallback), snapshot, documentFromSemanticInfo, - symbolFinder); -} - -} // namespace Internal -} // namespace ClangCodeModel |