forked from qt-creator/qt-creator
Clang: implement requestFollowSymbol plug-in side
Invoke follow symbol in clang backend if env variable QTC_CLANG_FOLLOW_SYMBOL is 1. Does not include backend implementation. Change-Id: Ia20a677830ebdd7f24800af5c5d6e8b1bf579205 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -144,6 +144,18 @@ QFuture<CppTools::CursorInfo> IpcReceiver::addExpectedReferencesMessage(quint64
|
||||
return futureInterface.future();
|
||||
}
|
||||
|
||||
QFuture<CppTools::SymbolInfo> IpcReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket)
|
||||
{
|
||||
QTC_CHECK(!m_followTable.contains(ticket));
|
||||
|
||||
QFutureInterface<CppTools::SymbolInfo> futureInterface;
|
||||
futureInterface.reportStarted();
|
||||
|
||||
m_followTable.insert(ticket, futureInterface);
|
||||
|
||||
return futureInterface.future();
|
||||
}
|
||||
|
||||
bool IpcReceiver::isExpectingCodeCompletedMessage() const
|
||||
{
|
||||
return !m_assistProcessorsTable.isEmpty();
|
||||
@@ -159,6 +171,9 @@ void IpcReceiver::reset()
|
||||
for (ReferencesEntry &entry : m_referencesTable)
|
||||
entry.futureInterface.cancel();
|
||||
m_referencesTable.clear();
|
||||
for (QFutureInterface<CppTools::SymbolInfo> &futureInterface : m_followTable)
|
||||
futureInterface.cancel();
|
||||
m_followTable.clear();
|
||||
}
|
||||
|
||||
void IpcReceiver::alive()
|
||||
@@ -243,6 +258,24 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message)
|
||||
{
|
||||
CppTools::SymbolInfo result;
|
||||
const SourceRangeContainer &range = message.sourceRange();
|
||||
|
||||
const SourceLocationContainer start = range.start();
|
||||
const SourceLocationContainer end = range.end();
|
||||
result.startLine = static_cast<int>(start.line());
|
||||
result.startColumn = static_cast<int>(start.column());
|
||||
result.endLine = static_cast<int>(end.line());
|
||||
result.endColumn = static_cast<int>(end.column());
|
||||
result.fileName = start.filePath();
|
||||
result.failedToFollow = message.failedToFollow();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void IpcReceiver::references(const ReferencesMessage &message)
|
||||
{
|
||||
qCDebug(log) << "<<< ReferencesMessage with"
|
||||
@@ -267,7 +300,14 @@ void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message)
|
||||
<< message.sourceRange() << "range";
|
||||
|
||||
const quint64 ticket = message.ticketNumber();
|
||||
// TODO: add implementation
|
||||
QFutureInterface<CppTools::SymbolInfo> futureInterface = m_followTable.take(ticket);
|
||||
QTC_CHECK(futureInterface != QFutureInterface<CppTools::SymbolInfo>());
|
||||
|
||||
if (futureInterface.isCanceled())
|
||||
return; // Editor document closed or a new request was issued making this result outdated.
|
||||
|
||||
futureInterface.reportResult(toSymbolInfo(message));
|
||||
futureInterface.reportFinished();
|
||||
}
|
||||
|
||||
class IpcSender : public IpcSenderInterface
|
||||
@@ -698,6 +738,23 @@ QFuture<CppTools::CursorInfo> IpcCommunicator::requestReferences(
|
||||
return m_ipcReceiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
|
||||
}
|
||||
|
||||
QFuture<CppTools::SymbolInfo> IpcCommunicator::requestFollowSymbol(
|
||||
const FileContainer &curFileContainer,
|
||||
const QVector<Utf8String> &dependentFiles,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
bool resolveTarget)
|
||||
{
|
||||
const RequestFollowSymbolMessage message(curFileContainer,
|
||||
dependentFiles,
|
||||
line,
|
||||
column,
|
||||
resolveTarget);
|
||||
m_ipcSender->requestFollowSymbol(message);
|
||||
|
||||
return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber());
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document)
|
||||
{
|
||||
const auto textDocument = qobject_cast<TextDocument*>(document);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <cpptools/projectpart.h>
|
||||
#include <cpptools/cppcursorinfo.h>
|
||||
#include <cpptools/cppsymbolinfo.h>
|
||||
|
||||
#include <clangbackendipc/clangcodemodelconnectionclient.h>
|
||||
#include <clangbackendipc/filecontainer.h>
|
||||
@@ -77,6 +78,7 @@ public:
|
||||
|
||||
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
|
||||
QTextDocument *textDocument);
|
||||
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
|
||||
bool isExpectingCodeCompletedMessage() const;
|
||||
|
||||
void reset();
|
||||
@@ -107,6 +109,8 @@ private:
|
||||
QPointer<QTextDocument> textDocument;
|
||||
};
|
||||
QHash<quint64, ReferencesEntry> m_referencesTable;
|
||||
|
||||
QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable;
|
||||
};
|
||||
|
||||
class IpcSenderInterface
|
||||
@@ -154,6 +158,11 @@ public:
|
||||
QFuture<CppTools::CursorInfo> requestReferences(const FileContainer &fileContainer,
|
||||
quint32 line,
|
||||
quint32 column, QTextDocument *textDocument);
|
||||
QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer,
|
||||
const QVector<Utf8String> &dependentFiles,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
bool resolveTarget);
|
||||
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
|
||||
quint32 line,
|
||||
quint32 column,
|
||||
|
||||
@@ -341,6 +341,55 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m
|
||||
textDocument());
|
||||
}
|
||||
|
||||
static QVector<Utf8String> prioritizeByBaseName(const QString &curPath,
|
||||
const ::Utils::FileNameList &fileDeps)
|
||||
{
|
||||
QList<Utf8String> dependentFiles;
|
||||
dependentFiles.reserve(fileDeps.size());
|
||||
for (const ::Utils::FileName &dep: fileDeps)
|
||||
dependentFiles.push_back(dep.toString());
|
||||
|
||||
const QString curFilename = QFileInfo(curPath).fileName();
|
||||
if (CppTools::ProjectFile::isHeader(CppTools::ProjectFile::classify(curFilename))) {
|
||||
const QString withoutExt = QFileInfo(curFilename).baseName();
|
||||
int posToMove = 0;
|
||||
// Move exact match to the first place and partial matches after it
|
||||
for (int i = 0; i < dependentFiles.size(); ++i) {
|
||||
const QString baseName = QFileInfo(dependentFiles[i]).baseName();
|
||||
if (withoutExt == baseName) {
|
||||
dependentFiles.move(i, 0);
|
||||
posToMove++;
|
||||
continue;
|
||||
}
|
||||
if (baseName.contains(withoutExt))
|
||||
dependentFiles.move(i, posToMove++);
|
||||
}
|
||||
}
|
||||
// Limit the number of scans (don't search for overrides)
|
||||
if (dependentFiles.size() > 5)
|
||||
dependentFiles.erase(dependentFiles.begin() + 5, dependentFiles.end());
|
||||
return QVector<Utf8String>::fromList(dependentFiles);
|
||||
}
|
||||
|
||||
QFuture<CppTools::SymbolInfo>
|
||||
ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column, bool resolveTarget)
|
||||
{
|
||||
QVector<Utf8String> dependentFiles;
|
||||
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
||||
if (modelManager && !modelManager->projectPart(filePath()).isEmpty()) {
|
||||
// This might be not so fast - index will change that
|
||||
const ::Utils::FileNameList fileDeps
|
||||
= modelManager->snapshot().filesDependingOn(filePath());
|
||||
dependentFiles = prioritizeByBaseName(filePath(), fileDeps);
|
||||
}
|
||||
|
||||
return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(),
|
||||
dependentFiles,
|
||||
static_cast<quint32>(line),
|
||||
static_cast<quint32>(column),
|
||||
resolveTarget);
|
||||
}
|
||||
|
||||
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const
|
||||
{
|
||||
return fileContainerWithArguments(m_projectPart.data());
|
||||
|
||||
@@ -86,6 +86,9 @@ public:
|
||||
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
|
||||
|
||||
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms) override;
|
||||
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line,
|
||||
int column,
|
||||
bool resolveTarget) override;
|
||||
|
||||
ClangBackEnd::FileContainer fileContainerWithArguments() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user