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:
@@ -38,6 +38,7 @@ QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message)
|
|||||||
debug.nospace() << "RequestFollowSymbolMessage(";
|
debug.nospace() << "RequestFollowSymbolMessage(";
|
||||||
|
|
||||||
debug.nospace() << message.m_fileContainer << ", ";
|
debug.nospace() << message.m_fileContainer << ", ";
|
||||||
|
debug.nospace() << message.m_dependentFiles << ", ";
|
||||||
debug.nospace() << message.m_ticketNumber << ", ";
|
debug.nospace() << message.m_ticketNumber << ", ";
|
||||||
debug.nospace() << message.m_line << ", ";
|
debug.nospace() << message.m_line << ", ";
|
||||||
debug.nospace() << message.m_column << ", ";
|
debug.nospace() << message.m_column << ", ";
|
||||||
@@ -52,6 +53,7 @@ std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &mes
|
|||||||
{
|
{
|
||||||
os << "("
|
os << "("
|
||||||
<< message.m_fileContainer << ", "
|
<< message.m_fileContainer << ", "
|
||||||
|
<< message.m_dependentFiles << ", "
|
||||||
<< message.m_ticketNumber << ", "
|
<< message.m_ticketNumber << ", "
|
||||||
<< message.m_line << ", "
|
<< message.m_line << ", "
|
||||||
<< message.m_column << ", "
|
<< message.m_column << ", "
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class RequestFollowSymbolMessage
|
|||||||
public:
|
public:
|
||||||
RequestFollowSymbolMessage() = default;
|
RequestFollowSymbolMessage() = default;
|
||||||
RequestFollowSymbolMessage(const FileContainer &fileContainer,
|
RequestFollowSymbolMessage(const FileContainer &fileContainer,
|
||||||
|
const QVector<Utf8String> &dependentFiles,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
bool resolveTarget = true)
|
bool resolveTarget = true)
|
||||||
@@ -45,6 +46,7 @@ public:
|
|||||||
, m_ticketNumber(++ticketCounter)
|
, m_ticketNumber(++ticketCounter)
|
||||||
, m_line(line)
|
, m_line(line)
|
||||||
, m_column(column)
|
, m_column(column)
|
||||||
|
, m_dependentFiles(dependentFiles)
|
||||||
, m_resolveTarget(resolveTarget)
|
, m_resolveTarget(resolveTarget)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -54,6 +56,11 @@ public:
|
|||||||
return m_fileContainer;
|
return m_fileContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QVector<Utf8String> &dependentFiles() const
|
||||||
|
{
|
||||||
|
return m_dependentFiles;
|
||||||
|
}
|
||||||
|
|
||||||
quint32 line() const
|
quint32 line() const
|
||||||
{
|
{
|
||||||
return m_line;
|
return m_line;
|
||||||
@@ -77,6 +84,7 @@ public:
|
|||||||
friend QDataStream &operator<<(QDataStream &out, const RequestFollowSymbolMessage &message)
|
friend QDataStream &operator<<(QDataStream &out, const RequestFollowSymbolMessage &message)
|
||||||
{
|
{
|
||||||
out << message.m_fileContainer;
|
out << message.m_fileContainer;
|
||||||
|
out << message.m_dependentFiles;
|
||||||
out << message.m_ticketNumber;
|
out << message.m_ticketNumber;
|
||||||
out << message.m_line;
|
out << message.m_line;
|
||||||
out << message.m_column;
|
out << message.m_column;
|
||||||
@@ -88,6 +96,7 @@ public:
|
|||||||
friend QDataStream &operator>>(QDataStream &in, RequestFollowSymbolMessage &message)
|
friend QDataStream &operator>>(QDataStream &in, RequestFollowSymbolMessage &message)
|
||||||
{
|
{
|
||||||
in >> message.m_fileContainer;
|
in >> message.m_fileContainer;
|
||||||
|
in >> message.m_dependentFiles;
|
||||||
in >> message.m_ticketNumber;
|
in >> message.m_ticketNumber;
|
||||||
in >> message.m_line;
|
in >> message.m_line;
|
||||||
in >> message.m_column;
|
in >> message.m_column;
|
||||||
@@ -103,7 +112,8 @@ public:
|
|||||||
&& first.m_line == second.m_line
|
&& first.m_line == second.m_line
|
||||||
&& first.m_column == second.m_column
|
&& first.m_column == second.m_column
|
||||||
&& first.m_fileContainer == second.m_fileContainer
|
&& first.m_fileContainer == second.m_fileContainer
|
||||||
&& first.m_resolveTarget == second.m_resolveTarget;
|
&& first.m_resolveTarget == second.m_resolveTarget
|
||||||
|
&& first.m_dependentFiles == second.m_dependentFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message);
|
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message);
|
||||||
@@ -113,6 +123,7 @@ private:
|
|||||||
quint64 m_ticketNumber = 0;
|
quint64 m_ticketNumber = 0;
|
||||||
quint32 m_line = 0;
|
quint32 m_line = 0;
|
||||||
quint32 m_column = 0;
|
quint32 m_column = 0;
|
||||||
|
QVector<Utf8String> m_dependentFiles;
|
||||||
bool m_resolveTarget = true;
|
bool m_resolveTarget = true;
|
||||||
static CMBIPC_EXPORT quint64 ticketCounter;
|
static CMBIPC_EXPORT quint64 ticketCounter;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -144,6 +144,18 @@ QFuture<CppTools::CursorInfo> IpcReceiver::addExpectedReferencesMessage(quint64
|
|||||||
return futureInterface.future();
|
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
|
bool IpcReceiver::isExpectingCodeCompletedMessage() const
|
||||||
{
|
{
|
||||||
return !m_assistProcessorsTable.isEmpty();
|
return !m_assistProcessorsTable.isEmpty();
|
||||||
@@ -159,6 +171,9 @@ void IpcReceiver::reset()
|
|||||||
for (ReferencesEntry &entry : m_referencesTable)
|
for (ReferencesEntry &entry : m_referencesTable)
|
||||||
entry.futureInterface.cancel();
|
entry.futureInterface.cancel();
|
||||||
m_referencesTable.clear();
|
m_referencesTable.clear();
|
||||||
|
for (QFutureInterface<CppTools::SymbolInfo> &futureInterface : m_followTable)
|
||||||
|
futureInterface.cancel();
|
||||||
|
m_followTable.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcReceiver::alive()
|
void IpcReceiver::alive()
|
||||||
@@ -243,6 +258,24 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
|
|||||||
return result;
|
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)
|
void IpcReceiver::references(const ReferencesMessage &message)
|
||||||
{
|
{
|
||||||
qCDebug(log) << "<<< ReferencesMessage with"
|
qCDebug(log) << "<<< ReferencesMessage with"
|
||||||
@@ -267,7 +300,14 @@ void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message)
|
|||||||
<< message.sourceRange() << "range";
|
<< message.sourceRange() << "range";
|
||||||
|
|
||||||
const quint64 ticket = message.ticketNumber();
|
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
|
class IpcSender : public IpcSenderInterface
|
||||||
@@ -698,6 +738,23 @@ QFuture<CppTools::CursorInfo> IpcCommunicator::requestReferences(
|
|||||||
return m_ipcReceiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
|
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)
|
void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document)
|
||||||
{
|
{
|
||||||
const auto textDocument = qobject_cast<TextDocument*>(document);
|
const auto textDocument = qobject_cast<TextDocument*>(document);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <cpptools/projectpart.h>
|
#include <cpptools/projectpart.h>
|
||||||
#include <cpptools/cppcursorinfo.h>
|
#include <cpptools/cppcursorinfo.h>
|
||||||
|
#include <cpptools/cppsymbolinfo.h>
|
||||||
|
|
||||||
#include <clangbackendipc/clangcodemodelconnectionclient.h>
|
#include <clangbackendipc/clangcodemodelconnectionclient.h>
|
||||||
#include <clangbackendipc/filecontainer.h>
|
#include <clangbackendipc/filecontainer.h>
|
||||||
@@ -77,6 +78,7 @@ public:
|
|||||||
|
|
||||||
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
|
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
|
||||||
QTextDocument *textDocument);
|
QTextDocument *textDocument);
|
||||||
|
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
|
||||||
bool isExpectingCodeCompletedMessage() const;
|
bool isExpectingCodeCompletedMessage() const;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@@ -107,6 +109,8 @@ private:
|
|||||||
QPointer<QTextDocument> textDocument;
|
QPointer<QTextDocument> textDocument;
|
||||||
};
|
};
|
||||||
QHash<quint64, ReferencesEntry> m_referencesTable;
|
QHash<quint64, ReferencesEntry> m_referencesTable;
|
||||||
|
|
||||||
|
QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IpcSenderInterface
|
class IpcSenderInterface
|
||||||
@@ -154,6 +158,11 @@ public:
|
|||||||
QFuture<CppTools::CursorInfo> requestReferences(const FileContainer &fileContainer,
|
QFuture<CppTools::CursorInfo> requestReferences(const FileContainer &fileContainer,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column, QTextDocument *textDocument);
|
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,
|
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
|
|||||||
@@ -341,6 +341,55 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m
|
|||||||
textDocument());
|
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
|
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const
|
||||||
{
|
{
|
||||||
return fileContainerWithArguments(m_projectPart.data());
|
return fileContainerWithArguments(m_projectPart.data());
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ public:
|
|||||||
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
|
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
|
||||||
|
|
||||||
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms) 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;
|
ClangBackEnd::FileContainer fileContainerWithArguments() const;
|
||||||
|
|
||||||
|
|||||||
@@ -386,6 +386,12 @@ CppEditorDocument::cursorInfo(const CppTools::CursorInfoParams ¶ms)
|
|||||||
return processor()->cursorInfo(params);
|
return processor()->cursorInfo(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFuture<CppTools::SymbolInfo>
|
||||||
|
CppEditorDocument::requestFollowSymbol(int line, int column, bool resolveTarget)
|
||||||
|
{
|
||||||
|
return processor()->requestFollowSymbol(line, column, resolveTarget);
|
||||||
|
}
|
||||||
|
|
||||||
const MinimizableInfoBars &CppEditorDocument::minimizableInfoBars() const
|
const MinimizableInfoBars &CppEditorDocument::minimizableInfoBars() const
|
||||||
{
|
{
|
||||||
return m_minimizableInfoBars;
|
return m_minimizableInfoBars;
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ public:
|
|||||||
ParseContextModel &parseContextModel();
|
ParseContextModel &parseContextModel();
|
||||||
|
|
||||||
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms);
|
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms);
|
||||||
|
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line,
|
||||||
|
int column,
|
||||||
|
bool resolveTarget = true);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void codeWarningsUpdated(unsigned contentsRevision,
|
void codeWarningsUpdated(unsigned contentsRevision,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "cppfollowsymbolundercursor.h"
|
#include "cppfollowsymbolundercursor.h"
|
||||||
#include "cppeditor.h"
|
#include "cppeditor.h"
|
||||||
|
#include "cppeditordocument.h"
|
||||||
#include "cppvirtualfunctionassistprovider.h"
|
#include "cppvirtualfunctionassistprovider.h"
|
||||||
|
|
||||||
#include <cplusplus/ASTPath.h>
|
#include <cplusplus/ASTPath.h>
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#include <cpptools/cpptoolsreuse.h>
|
#include <cpptools/cpptoolsreuse.h>
|
||||||
#include <cpptools/symbolfinder.h>
|
#include <cpptools/symbolfinder.h>
|
||||||
#include <texteditor/textdocumentlayout.h>
|
#include <texteditor/textdocumentlayout.h>
|
||||||
|
#include <texteditor/convenience.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -53,6 +55,12 @@ typedef TextEditorWidget::Link Link;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
static bool useClangFollowSymbol()
|
||||||
|
{
|
||||||
|
static bool use = qEnvironmentVariableIntValue("QTC_CLANG_FOLLOW_SYMBOL");
|
||||||
|
return use;
|
||||||
|
}
|
||||||
|
|
||||||
class VirtualFunctionHelper {
|
class VirtualFunctionHelper {
|
||||||
public:
|
public:
|
||||||
VirtualFunctionHelper(TypeOfExpression &typeOfExpression,
|
VirtualFunctionHelper(TypeOfExpression &typeOfExpression,
|
||||||
@@ -487,12 +495,56 @@ static int skipMatchingParentheses(const Tokens &tokens, int idx, int initialDep
|
|||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FollowSymbolUnderCursor::processorFollowSymbol(uint line, uint column, bool resolveTarget,
|
||||||
|
Link &linkResult)
|
||||||
|
{
|
||||||
|
if (!useClangFollowSymbol())
|
||||||
|
return false;
|
||||||
|
CppEditorDocument* editorDocument = m_widget->cppEditorDocument();
|
||||||
|
if (!editorDocument)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QFuture<CppTools::SymbolInfo> info
|
||||||
|
= editorDocument->requestFollowSymbol(static_cast<int>(line),
|
||||||
|
static_cast<int>(column),
|
||||||
|
resolveTarget);
|
||||||
|
if (info.isCanceled())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (!info.isFinished()) {
|
||||||
|
if (info.isCanceled())
|
||||||
|
return false;
|
||||||
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
}
|
||||||
|
CppTools::SymbolInfo result = info.result();
|
||||||
|
|
||||||
|
// Try again with built-in code model (happens with some includes)
|
||||||
|
if (result.failedToFollow)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We did not fail but the result is empty
|
||||||
|
if (result.fileName.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
linkResult = Link(result.fileName, result.startLine, result.startColumn - 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &cursor,
|
TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &cursor,
|
||||||
bool resolveTarget, const Snapshot &theSnapshot, const Document::Ptr &documentFromSemanticInfo,
|
bool resolveTarget, const Snapshot &theSnapshot, const Document::Ptr &documentFromSemanticInfo,
|
||||||
SymbolFinder *symbolFinder, bool inNextSplit)
|
SymbolFinder *symbolFinder, bool inNextSplit)
|
||||||
{
|
{
|
||||||
Link link;
|
Link link;
|
||||||
|
|
||||||
|
int lineNumber = 0, positionInBlock = 0;
|
||||||
|
m_widget->convertPosition(cursor.position(), &lineNumber, &positionInBlock);
|
||||||
|
const unsigned line = lineNumber;
|
||||||
|
const unsigned column = positionInBlock + 1;
|
||||||
|
|
||||||
|
if (resolveTarget && processorFollowSymbol(line, column, resolveTarget, link))
|
||||||
|
return link;
|
||||||
|
|
||||||
Snapshot snapshot = theSnapshot;
|
Snapshot snapshot = theSnapshot;
|
||||||
|
|
||||||
// Move to end of identifier
|
// Move to end of identifier
|
||||||
@@ -519,11 +571,6 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lineNumber = 0, positionInBlock = 0;
|
|
||||||
m_widget->convertPosition(cursor.position(), &lineNumber, &positionInBlock);
|
|
||||||
const unsigned line = lineNumber;
|
|
||||||
const unsigned column = positionInBlock + 1;
|
|
||||||
|
|
||||||
// Try to find a signal or slot inside SIGNAL() or SLOT()
|
// Try to find a signal or slot inside SIGNAL() or SLOT()
|
||||||
int beginOfToken = 0;
|
int beginOfToken = 0;
|
||||||
int endOfToken = 0;
|
int endOfToken = 0;
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ public:
|
|||||||
void setVirtualFunctionAssistProvider(VirtualFunctionAssistProvider *provider);
|
void setVirtualFunctionAssistProvider(VirtualFunctionAssistProvider *provider);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Try to follow symbol with clang processor
|
||||||
|
// Returns false if it has failed and we want to try again with built-in one
|
||||||
|
bool processorFollowSymbol(uint line, uint column, bool resolveTarget,
|
||||||
|
Link &result);
|
||||||
CppEditorWidget *m_widget;
|
CppEditorWidget *m_widget;
|
||||||
VirtualFunctionAssistProvider *m_virtualFunctionAssistProvider;
|
VirtualFunctionAssistProvider *m_virtualFunctionAssistProvider;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "baseeditordocumentparser.h"
|
#include "baseeditordocumentparser.h"
|
||||||
#include "cppcursorinfo.h"
|
#include "cppcursorinfo.h"
|
||||||
|
#include "cppsymbolinfo.h"
|
||||||
#include "cppsemanticinfo.h"
|
#include "cppsemanticinfo.h"
|
||||||
#include "cpptools_global.h"
|
#include "cpptools_global.h"
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ public:
|
|||||||
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config);
|
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config);
|
||||||
|
|
||||||
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) = 0;
|
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) = 0;
|
||||||
|
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column, bool resolveTarget) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
|
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public:
|
|||||||
bool isParserRunning() const override;
|
bool isParserRunning() const override;
|
||||||
|
|
||||||
QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) override;
|
QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) override;
|
||||||
|
QFuture<SymbolInfo> requestFollowSymbol(int, int, bool) override
|
||||||
|
{ return QFuture<SymbolInfo>(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
|
void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
|
||||||
|
|||||||
45
src/plugins/cpptools/cppsymbolinfo.h
Normal file
45
src/plugins/cpptools/cppsymbolinfo.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cpptools_global.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace CppTools {
|
||||||
|
|
||||||
|
class CPPTOOLS_EXPORT SymbolInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int startLine = 0;
|
||||||
|
int startColumn = 0;
|
||||||
|
int endLine = 0;
|
||||||
|
int endColumn = 0;
|
||||||
|
QString fileName;
|
||||||
|
bool failedToFollow = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace CppTools
|
||||||
@@ -87,6 +87,7 @@ HEADERS += \
|
|||||||
cppprojectfilecategorizer.h \
|
cppprojectfilecategorizer.h \
|
||||||
clangcompileroptionsbuilder.h \
|
clangcompileroptionsbuilder.h \
|
||||||
cppprojectpartchooser.h \
|
cppprojectpartchooser.h \
|
||||||
|
cppsymbolinfo.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
abstracteditorsupport.cpp \
|
abstracteditorsupport.cpp \
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &mes
|
|||||||
|
|
||||||
void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage &message)
|
void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage &message)
|
||||||
{
|
{
|
||||||
TIME_SCOPE_DURATION("ClangCodeModelServer::followSymbol");
|
TIME_SCOPE_DURATION("ClangCodeModelServer::requestFollowSymbol");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto projectPartId = message.fileContainer().projectPartId();
|
auto projectPartId = message.fileContainer().projectPartId();
|
||||||
@@ -274,11 +274,12 @@ void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage
|
|||||||
|
|
||||||
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::FollowSymbol);
|
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::FollowSymbol);
|
||||||
fillJobRequest(jobRequest, message);
|
fillJobRequest(jobRequest, message);
|
||||||
|
jobRequest.dependentFiles = message.dependentFiles();
|
||||||
jobRequest.resolveTarget = message.resolveTarget();
|
jobRequest.resolveTarget = message.resolveTarget();
|
||||||
processor.addJob(jobRequest);
|
processor.addJob(jobRequest);
|
||||||
processor.process();
|
processor.process();
|
||||||
} catch (const std::exception &exception) {
|
} catch (const std::exception &exception) {
|
||||||
qWarning() << "Error in ClangCodeModelServer::followSymbol:" << exception.what();
|
qWarning() << "Error in ClangCodeModelServer::requestFollowSymbol:" << exception.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace ClangBackEnd {
|
|||||||
static FollowSymbolJob::AsyncResult runAsyncHelperFollow(const TranslationUnit &translationUnit,
|
static FollowSymbolJob::AsyncResult runAsyncHelperFollow(const TranslationUnit &translationUnit,
|
||||||
quint32 line,
|
quint32 line,
|
||||||
quint32 column,
|
quint32 column,
|
||||||
|
const QVector<Utf8String> &dependentFiles,
|
||||||
bool resolveTarget)
|
bool resolveTarget)
|
||||||
{
|
{
|
||||||
TIME_SCOPE_DURATION("FollowSymbolJobRunner");
|
TIME_SCOPE_DURATION("FollowSymbolJobRunner");
|
||||||
@@ -57,9 +58,10 @@ IAsyncJob::AsyncPrepareResult FollowSymbolJob::prepareAsyncRun()
|
|||||||
= m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
|
= m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
|
||||||
const quint32 line = jobRequest.line;
|
const quint32 line = jobRequest.line;
|
||||||
const quint32 column = jobRequest.column;
|
const quint32 column = jobRequest.column;
|
||||||
|
const QVector<Utf8String> &dependentFiles = jobRequest.dependentFiles;
|
||||||
const bool resolveTarget = jobRequest.resolveTarget;
|
const bool resolveTarget = jobRequest.resolveTarget;
|
||||||
setRunner([translationUnit, line, column, resolveTarget]() {
|
setRunner([translationUnit, line, column, dependentFiles, resolveTarget]() {
|
||||||
return runAsyncHelperFollow(translationUnit, line, column, resolveTarget);
|
return runAsyncHelperFollow(translationUnit, line, column, dependentFiles, resolveTarget);
|
||||||
});
|
});
|
||||||
return AsyncPrepareResult{translationUnit.id()};
|
return AsyncPrepareResult{translationUnit.id()};
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
quint32 line = 0;
|
quint32 line = 0;
|
||||||
quint32 column = 0;
|
quint32 column = 0;
|
||||||
quint64 ticketNumber = 0;
|
quint64 ticketNumber = 0;
|
||||||
|
QVector<Utf8String> dependentFiles;
|
||||||
bool resolveTarget = true;
|
bool resolveTarget = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user