Clang: use HighlightingMarks for hover with Ctrl highlighting

Make this highlighting work without builtin code model
but based on the HighlightingMarks that we already have
from ClangCodeModel.
Redundant parameters are removed by this change.

Change-Id: I73b5dab46ba59d2f813236831818f0a9bc94c5bc
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2017-09-08 09:33:35 +02:00
parent c73793414b
commit f130de2400
31 changed files with 265 additions and 191 deletions

View File

@@ -36,8 +36,7 @@ QDebug operator<<(QDebug debug, const FollowSymbolMessage &message)
debug.nospace() << "FollowSymbolMessage("
<< message.m_fileContainer
<< ", " << message.m_ticketNumber
<< ", " << message.m_sourceRange
<< ", " << message.m_failedToFollow;
<< ", " << message.m_sourceRange;
debug.nospace() << ")";
@@ -50,7 +49,6 @@ std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message)
<< message.m_fileContainer << ", "
<< message.m_ticketNumber << ", "
<< message.m_sourceRange << ", "
<< message.m_failedToFollow << ", "
<< ")";
return os;

View File

@@ -39,12 +39,10 @@ public:
FollowSymbolMessage() = default;
FollowSymbolMessage(const FileContainer &fileContainer,
const SourceRangeContainer &range,
bool failedToFollow,
quint64 ticketNumber)
: m_fileContainer(fileContainer)
, m_sourceRange(range)
, m_ticketNumber(ticketNumber)
, m_failedToFollow(failedToFollow)
{
}
const FileContainer &fileContainer() const
@@ -57,11 +55,6 @@ public:
return m_sourceRange;
}
bool failedToFollow() const
{
return m_failedToFollow;
}
quint64 ticketNumber() const
{
return m_ticketNumber;
@@ -72,7 +65,6 @@ public:
out << message.m_fileContainer;
out << message.m_sourceRange;
out << message.m_ticketNumber;
out << message.m_failedToFollow;
return out;
}
@@ -81,7 +73,6 @@ public:
in >> message.m_fileContainer;
in >> message.m_sourceRange;
in >> message.m_ticketNumber;
in >> message.m_failedToFollow;
return in;
}
@@ -89,8 +80,7 @@ public:
{
return first.m_ticketNumber == second.m_ticketNumber
&& first.m_fileContainer == second.m_fileContainer
&& first.m_sourceRange == second.m_sourceRange
&& first.m_failedToFollow == second.m_failedToFollow;
&& first.m_sourceRange == second.m_sourceRange;
}
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FollowSymbolMessage &message);
@@ -99,7 +89,6 @@ private:
FileContainer m_fileContainer;
SourceRangeContainer m_sourceRange;
quint64 m_ticketNumber = 0;
bool m_failedToFollow = false;
};
DECLARE_MESSAGE(FollowSymbolMessage);

View File

@@ -65,6 +65,8 @@ QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container)
<< container.column() << ", "
<< container.length() << ", "
<< highlightingTypeToCStringLiteral(container.types().mainHighlightingType) << ", "
<< container.isIdentifier() << ", "
<< container.isIncludeDirectivePath()
<< ")";
return debug;
@@ -94,7 +96,9 @@ std::ostream &operator<<(std::ostream &os, const HighlightingMarkContainer &cont
<< container.line() << ", "
<< container.column() << ", "
<< container.length() << ", "
<< container.types()
<< container.types() << ", "
<< container.isIdentifier() << ", "
<< container.isIncludeDirectivePath()
<< ")";
return os;

View File

@@ -44,11 +44,14 @@ class HighlightingMarkContainer
{
public:
HighlightingMarkContainer() = default;
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types)
HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types,
bool isIdentifier = false, bool isIncludeDirectivePath = false)
: line_(line),
column_(column),
length_(length),
types_(types)
types_(types),
isIdentifier_(isIdentifier),
isIncludeDirectivePath_(isIncludeDirectivePath)
{
}
@@ -80,12 +83,29 @@ public:
return types_;
}
bool isInvalid() const
{
return line_ == 0 && column_ == 0 && length_ == 0;
}
bool isIdentifier() const
{
return isIdentifier_;
}
bool isIncludeDirectivePath() const
{
return isIncludeDirectivePath_;
}
friend QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container)
{
out << container.line_;
out << container.column_;
out << container.length_;
out << container.types_;
out << container.isIdentifier_;
out << container.isIncludeDirectivePath_;
return out;
}
@@ -96,6 +116,8 @@ public:
in >> container.column_;
in >> container.length_;
in >> container.types_;
in >> container.isIdentifier_;
in >> container.isIncludeDirectivePath_;
return in;
}
@@ -105,7 +127,9 @@ public:
return first.line_ == second.line_
&& first.column_ == second.column_
&& first.length_ == second.length_
&& first.types_ == second.types_;
&& first.types_ == second.types_
&& first.isIdentifier_ == second.isIdentifier_
&& first.isIncludeDirectivePath_ == second.isIncludeDirectivePath_;
}
private:
@@ -113,6 +137,8 @@ private:
uint column_ = 0;
uint length_ = 0;
HighlightingTypes types_;
bool isIdentifier_ = false;
bool isIncludeDirectivePath_ = false;
};
inline QDataStream &operator<<(QDataStream &out, HighlightingType highlightingType)

View File

@@ -42,7 +42,6 @@ QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message)
debug.nospace() << message.m_ticketNumber << ", ";
debug.nospace() << message.m_line << ", ";
debug.nospace() << message.m_column << ", ";
debug.nospace() << message.m_resolveTarget << ", ";
debug.nospace() << ")";
@@ -57,7 +56,6 @@ std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &mes
<< message.m_ticketNumber << ", "
<< message.m_line << ", "
<< message.m_column << ", "
<< message.m_resolveTarget << ", "
<< ")";
return os;

View File

@@ -40,14 +40,12 @@ public:
RequestFollowSymbolMessage(const FileContainer &fileContainer,
const QVector<Utf8String> &dependentFiles,
quint32 line,
quint32 column,
bool resolveTarget = true)
quint32 column)
: m_fileContainer(fileContainer)
, m_ticketNumber(++ticketCounter)
, m_line(line)
, m_column(column)
, m_dependentFiles(dependentFiles)
, m_resolveTarget(resolveTarget)
{
}
@@ -71,11 +69,6 @@ public:
return m_column;
}
bool resolveTarget() const
{
return m_resolveTarget;
}
quint64 ticketNumber() const
{
return m_ticketNumber;
@@ -88,7 +81,6 @@ public:
out << message.m_ticketNumber;
out << message.m_line;
out << message.m_column;
out << message.m_resolveTarget;
return out;
}
@@ -100,7 +92,6 @@ public:
in >> message.m_ticketNumber;
in >> message.m_line;
in >> message.m_column;
in >> message.m_resolveTarget;
return in;
}
@@ -112,7 +103,6 @@ public:
&& first.m_line == second.m_line
&& first.m_column == second.m_column
&& first.m_fileContainer == second.m_fileContainer
&& first.m_resolveTarget == second.m_resolveTarget
&& first.m_dependentFiles == second.m_dependentFiles;
}
@@ -124,7 +114,6 @@ private:
quint32 m_line = 0;
quint32 m_column = 0;
QVector<Utf8String> m_dependentFiles;
bool m_resolveTarget = true;
static CMBIPC_EXPORT quint64 ticketCounter;
};

View File

@@ -275,7 +275,6 @@ CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message)
result.endLine = static_cast<int>(end.line());
result.endColumn = static_cast<int>(end.column());
result.fileName = start.filePath();
result.failedToFollow = message.failedToFollow();
return result;
}
@@ -748,14 +747,12 @@ QFuture<CppTools::SymbolInfo> IpcCommunicator::requestFollowSymbol(
const FileContainer &curFileContainer,
const QVector<Utf8String> &dependentFiles,
quint32 line,
quint32 column,
bool resolveTarget)
quint32 column)
{
const RequestFollowSymbolMessage message(curFileContainer,
dependentFiles,
line,
column,
resolveTarget);
column);
m_ipcSender->requestFollowSymbol(message);
return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber());

View File

@@ -169,8 +169,7 @@ public:
QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer,
const QVector<Utf8String> &dependentFiles,
quint32 line,
quint32 column,
bool resolveTarget);
quint32 column);
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
quint32 line,
quint32 column,

View File

@@ -225,6 +225,12 @@ toTextEditorBlocks(QTextDocument *textDocument,
}
}
const QVector<ClangBackEnd::HighlightingMarkContainer>
&ClangEditorDocumentProcessor::highlightingMarks() const
{
return m_highlightingMarks;
}
void ClangEditorDocumentProcessor::updateHighlighting(
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
@@ -234,6 +240,7 @@ void ClangEditorDocumentProcessor::updateHighlighting(
const auto skippedPreprocessorBlocks = toTextEditorBlocks(textDocument(), skippedPreprocessorRanges);
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
m_highlightingMarks = highlightingMarks;
m_semanticHighlighter.setHighlightingRunner(
[highlightingMarks]() {
auto *reporter = new HighlightingMarksReporter(highlightingMarks);
@@ -376,7 +383,7 @@ static QVector<Utf8String> prioritizeByBaseName(const QString &curPath,
}
QFuture<CppTools::SymbolInfo>
ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column, bool resolveTarget)
ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column)
{
QVector<Utf8String> dependentFiles;
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
@@ -390,8 +397,7 @@ ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column, bool res
return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(),
dependentFiles,
static_cast<quint32>(line),
static_cast<quint32>(column),
resolveTarget);
static_cast<quint32>(column));
}
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const

View File

@@ -86,14 +86,14 @@ public:
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams &params) override;
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line,
int column,
bool resolveTarget) override;
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override;
ClangBackEnd::FileContainer fileContainerWithArguments() const;
void clearDiagnosticsWithFixIts();
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks() const;
public:
static ClangEditorDocumentProcessor *get(const QString &filePath);
@@ -122,6 +122,7 @@ private:
QTimer m_updateTranslationUnitTimer;
unsigned m_parserRevision;
QVector<ClangBackEnd::HighlightingMarkContainer> m_highlightingMarks;
CppTools::SemanticHighlighter m_semanticHighlighter;
CppTools::BuiltinEditorDocumentProcessor m_builtinProcessor;
};

View File

@@ -23,14 +23,78 @@
**
****************************************************************************/
#include "clangfollowsymbol.h"
#include "clangeditordocumentprocessor.h"
#include "texteditor/texteditor.h"
#include "texteditor/convenience.h"
#include "clangfollowsymbol.h"
#include <texteditor/convenience.h>
#include <texteditor/texteditor.h>
#include <clangsupport/highlightingmarkcontainer.h>
#include <utils/algorithm.h>
namespace ClangCodeModel {
namespace Internal {
// Returns invalid Mark if it is not found at (line, column)
static bool findMark(const QVector<ClangBackEnd::HighlightingMarkContainer> &marks,
uint line,
uint column,
ClangBackEnd::HighlightingMarkContainer &mark)
{
mark = Utils::findOrDefault(marks,
[line, column](const ClangBackEnd::HighlightingMarkContainer &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::HighlightingMarkContainer &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 TextEditor::TextEditorWidget::Link linkAtCursor(QTextCursor cursor,
const QString &filePath,
uint line,
uint column,
ClangEditorDocumentProcessor *processor)
{
using Link = TextEditor::TextEditorWidget::Link;
const QVector<ClangBackEnd::HighlightingMarkContainer> &marks
= processor->highlightingMarks();
ClangBackEnd::HighlightingMarkContainer mark;
if (!findMark(marks, line, column, mark))
return Link();
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
const QString tokenStr = cursor.selectedText();
Link token(filePath, mark.line(), mark.column());
token.linkTextStart = getMarkPos(cursor, mark);
token.linkTextEnd = token.linkTextStart + mark.length();
if (mark.isIncludeDirectivePath()) {
if (tokenStr != "include" && tokenStr != "#" && tokenStr != "<")
return token;
return Link();
}
if (mark.isIdentifier() || tokenStr == "operator")
return token;
return Link();
}
TextEditor::TextEditorWidget::Link ClangFollowSymbol::findLink(
const CppTools::CursorInEditor &data,
bool resolveTarget,
@@ -39,42 +103,39 @@ TextEditor::TextEditorWidget::Link ClangFollowSymbol::findLink(
CppTools::SymbolFinder *,
bool)
{
Link link;
int lineNumber = 0, positionInBlock = 0;
QTextCursor cursor = TextEditor::Convenience::wordStartCursor(data.cursor());
TextEditor::Convenience::convertPosition(cursor.document(), cursor.position(), &lineNumber,
&positionInBlock);
const unsigned line = lineNumber;
const unsigned column = positionInBlock + 1;
if (!resolveTarget)
return link;
const uint line = lineNumber;
const uint column = positionInBlock + 1;
ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get(
data.filePath().toString());
if (!processor)
return link;
return Link();
if (!resolveTarget)
return linkAtCursor(cursor, data.filePath().toString(), line, column, processor);
QFuture<CppTools::SymbolInfo> info
= processor->requestFollowSymbol(static_cast<int>(line),
static_cast<int>(column),
resolveTarget);
static_cast<int>(column));
if (info.isCanceled())
return link;
return Link();
while (!info.isFinished()) {
if (info.isCanceled())
return link;
return Link();
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
CppTools::SymbolInfo result = info.result();
if (result.failedToFollow)
return link;
// We did not fail but the result is empty
if (result.fileName.isEmpty())
return link;
return Link();
return Link(result.fileName, result.startLine, result.startColumn - 1);
}

View File

@@ -158,8 +158,15 @@ void HighlightingMarksReporter::run_internal()
if (isCanceled())
return;
for (const auto &highlightingMark : m_highlightingMarks)
using ClangBackEnd::HighlightingType;
for (const auto &highlightingMark : m_highlightingMarks) {
const HighlightingType mainType = highlightingMark.types().mainHighlightingType;
if (mainType == HighlightingType::StringLiteral)
continue;
reportChunkWise(toHighlightingResult(highlightingMark));
}
if (isCanceled())
return;

View File

@@ -649,15 +649,6 @@ CppEditorWidget::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor,
return Link();
const Utils::FileName &filePath = textDocument()->filePath();
if (!resolveTarget) {
// TODO: get that part also from clang
return d->m_builtinFollowSymbol.findLink(CppTools::CursorInEditor{cursor, filePath, this},
resolveTarget,
d->m_modelManager->snapshot(),
d->m_lastSemanticInfo.doc,
d->m_modelManager->symbolFinder(),
inNextSplit);
}
return followSymbolInterface()->findLink(CppTools::CursorInEditor{cursor, filePath, this},
resolveTarget,

View File

@@ -76,7 +76,7 @@ public:
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config);
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) = 0;
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column, bool resolveTarget) = 0;
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
public:
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;

View File

@@ -52,7 +52,7 @@ public:
bool isParserRunning() const override;
QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) override;
QFuture<SymbolInfo> requestFollowSymbol(int, int, bool) override
QFuture<SymbolInfo> requestFollowSymbol(int, int) override
{ return QFuture<SymbolInfo>(); }
private:

View File

@@ -39,7 +39,6 @@ public:
int endLine = 0;
int endColumn = 0;
QString fileName;
bool failedToFollow = false;
};
} // namespace CppTools

View File

@@ -281,7 +281,6 @@ void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::FollowSymbol);
fillJobRequest(jobRequest, message);
jobRequest.dependentFiles = message.dependentFiles();
jobRequest.resolveTarget = message.resolveTarget();
processor.addJob(jobRequest);
processor.process();
} catch (const std::exception &exception) {

View File

@@ -41,10 +41,16 @@ namespace {
struct Tokens
{
Tokens(const Tokens &) = delete;
Tokens(const Cursor &cursor) {
tu = cursor.cxTranslationUnit();
clang_tokenize(tu, cursor.cxSourceRange(), &data, &tokenCount);
}
Tokens(const CXTranslationUnit &tu) {
const CXSourceRange range
= clang_getCursorExtent(clang_getTranslationUnitCursor(tu));
clang_tokenize(tu, range, &data, &tokenCount);
}
~Tokens() {
clang_disposeTokens(tu, data, tokenCount);
}
@@ -198,11 +204,11 @@ static IndexerCallbacks createIndexerCallbacks()
};
}
static FollowSymbolResult followSymbolInDependentFiles(CXIndex index,
const Cursor &cursor,
const Utf8String &tokenSpelling,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs)
static SourceRangeContainer followSymbolInDependentFiles(CXIndex index,
const Cursor &cursor,
const Utf8String &tokenSpelling,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs)
{
int argsCount = 0;
if (currentArgs.data())
@@ -250,63 +256,61 @@ static FollowSymbolResult followSymbolInDependentFiles(CXIndex index,
for (const std::future<void> &future: indexFutures)
future.wait();
FollowSymbolResult result;
for (const FollowSymbolData &data: dataVector) {
if (!data.result().start().filePath().isEmpty()) {
result.range = data.result();
break;
return data.result();
}
}
return result;
return SourceRangeContainer();
}
FollowSymbolResult FollowSymbol::followSymbol(CXIndex index,
const Cursor &fullCursor,
uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs)
SourceRangeContainer FollowSymbol::followSymbol(CXTranslationUnit tu,
CXIndex index,
const Cursor &fullCursor,
uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs)
{
FollowSymbolResult result;
Tokens tokens(fullCursor);
if (!tokens.tokenCount) {
result.failedToFollow = true;
return result;
}
std::unique_ptr<Tokens> tokens(new Tokens(fullCursor));
const CXTranslationUnit tu = fullCursor.cxTranslationUnit();
if (!tokens->tokenCount)
tokens.reset(new Tokens(tu));
QVector<CXCursor> cursors(static_cast<int>(tokens.tokenCount));
clang_annotateTokens(tu, tokens.data, tokens.tokenCount, cursors.data());
int tokenIndex = getTokenIndex(tu, tokens, line, column);
QTC_ASSERT(tokenIndex >= 0, return result);
if (!tokens->tokenCount)
return SourceRangeContainer();
const Utf8String tokenSpelling = ClangString(clang_getTokenSpelling(tu, tokens.data[tokenIndex]));
QVector<CXCursor> cursors(static_cast<int>(tokens->tokenCount));
clang_annotateTokens(tu, tokens->data, tokens->tokenCount, cursors.data());
int tokenIndex = getTokenIndex(tu, *tokens, line, column);
QTC_ASSERT(tokenIndex >= 0, return SourceRangeContainer());
const Utf8String tokenSpelling = ClangString(
clang_getTokenSpelling(tu, tokens->data[tokenIndex]));
if (tokenSpelling.isEmpty())
return result;
return SourceRangeContainer();
Cursor cursor{cursors[tokenIndex]};
if (cursor.kind() == CXCursor_InclusionDirective) {
CXFile file = clang_getIncludedFile(cursors[tokenIndex]);
const ClangString filename(clang_getFileName(file));
const SourceLocation loc(tu, filename, 1, 1);
result.range = SourceRange(loc, loc);
return result;
return SourceRange(loc, loc);
}
if (cursor.isDefinition()) {
// For definitions we can always find a declaration in current TU
result.range = extractMatchingTokenRange(cursor.canonical(), tokenSpelling);
return result;
}
// For definitions we can always find a declaration in current TU
if (cursor.isDefinition())
return extractMatchingTokenRange(cursor.canonical(), tokenSpelling);
SourceRangeContainer result;
if (!cursor.isDeclaration()) {
// This is the symbol usage
// We want to return definition or at least declaration of this symbol
const Cursor referencedCursor = cursor.referenced();
if (referencedCursor.isNull() || referencedCursor == cursor)
return result;
result.range = extractMatchingTokenRange(referencedCursor, tokenSpelling);
return SourceRangeContainer();
result = extractMatchingTokenRange(referencedCursor, tokenSpelling);
// We've already found what we need
if (referencedCursor.isDefinition())
@@ -317,17 +321,16 @@ FollowSymbolResult FollowSymbol::followSymbol(CXIndex index,
const Cursor definitionCursor = cursor.definition();
if (!definitionCursor.isNull() && definitionCursor != cursor) {
// If we are able to find a definition in current TU
result.range = extractMatchingTokenRange(definitionCursor, tokenSpelling);
return result;
return extractMatchingTokenRange(definitionCursor, tokenSpelling);
}
// Search for the definition in the dependent files
FollowSymbolResult dependentFilesResult = followSymbolInDependentFiles(index,
cursor,
tokenSpelling,
dependentFiles,
currentArgs);
return dependentFilesResult.range.start().filePath().isEmpty() ?
SourceRangeContainer dependentFilesResult = followSymbolInDependentFiles(index,
cursor,
tokenSpelling,
dependentFiles,
currentArgs);
return dependentFilesResult.start().filePath().isEmpty() ?
result : dependentFilesResult;
}

View File

@@ -34,18 +34,19 @@ class Utf8String;
namespace ClangBackEnd {
class Cursor;
class FollowSymbolResult;
class SourceRangeContainer;
class CommandLineArguments;
class FollowSymbol
{
public:
static FollowSymbolResult followSymbol(CXIndex index,
const Cursor &fullCursor,
uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs);
static SourceRangeContainer followSymbol(CXTranslationUnit tu,
CXIndex index,
const Cursor &fullCursor,
uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs);
};
} // namespace ClangBackEnd

View File

@@ -38,8 +38,6 @@ IAsyncJob::AsyncPrepareResult FollowSymbolJob::prepareAsyncRun()
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::FollowSymbol,
return AsyncPrepareResult());
// Is too slow because of IPC timings, no implementation for now
QTC_ASSERT(jobRequest.resolveTarget, return AsyncPrepareResult());
QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
const TranslationUnit translationUnit = *m_translationUnit;
@@ -66,8 +64,7 @@ void FollowSymbolJob::finalizeAsyncRun()
const AsyncResult result = asyncResult();
const FollowSymbolMessage message(m_pinnedFileContainer,
result.range,
result.failedToFollow,
result,
context().jobRequest.ticketNumber);
context().client->followSymbol(message);
}

View File

@@ -31,29 +31,10 @@
namespace ClangBackEnd {
class FollowSymbolResult
class FollowSymbolJob : public DocumentJob<SourceRangeContainer>
{
public:
FollowSymbolResult() = default;
FollowSymbolResult(const SourceRangeContainer &range, bool failedToFollow = false)
: range(range)
, failedToFollow(failedToFollow)
{}
friend bool operator==(const FollowSymbolResult &first, const FollowSymbolResult &second)
{
return first.range == second.range
&& first.failedToFollow == second.failedToFollow;
}
SourceRangeContainer range;
bool failedToFollow = false;
};
class FollowSymbolJob : public DocumentJob<FollowSymbolResult>
{
public:
using AsyncResult = FollowSymbolResult;
using AsyncResult = SourceRangeContainer;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;

View File

@@ -229,7 +229,6 @@ void JobRequest::cancelJob(ClangCodeModelClientInterface &client) const
case JobRequest::Type::FollowSymbol:
client.followSymbol(FollowSymbolMessage(FileContainer(),
SourceRangeContainer(),
true,
ticketNumber));
break;
}

View File

@@ -118,7 +118,6 @@ public:
qint32 funcNameStartColumn = -1;
quint64 ticketNumber = 0;
Utf8StringVector dependentFiles;
bool resolveTarget = true;
};
using JobRequests = QVector<JobRequest>;

View File

@@ -243,13 +243,13 @@ void TranslationUnit::extractDiagnostics(DiagnosticContainer &firstHeaderErrorDi
}
}
FollowSymbolResult TranslationUnit::followSymbol(uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs) const
SourceRangeContainer TranslationUnit::followSymbol(uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs) const
{
return FollowSymbol::followSymbol(m_cxIndex, cursorAt(line, column), line, column,
dependentFiles, currentArgs);
return FollowSymbol::followSymbol(m_cxTranslationUnit, m_cxIndex, cursorAt(line, column), line,
column, dependentFiles, currentArgs);
}
} // namespace ClangBackEnd

View File

@@ -37,7 +37,6 @@ class DiagnosticSet;
class HighlightingMarkContainer;
class HighlightingMarks;
class ReferencesResult;
class FollowSymbolResult;
class SkippedSourceRanges;
class SourceLocation;
class SourceRange;
@@ -101,10 +100,10 @@ public:
HighlightingMarks highlightingMarksInRange(const SourceRange &range) const;
SkippedSourceRanges skippedSourceRanges() const;
FollowSymbolResult followSymbol(uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs) const;
SourceRangeContainer followSymbol(uint line,
uint column,
const QVector<Utf8String> &dependentFiles,
const CommandLineArguments &currentArgs) const;
private:
const Utf8String m_id;

View File

@@ -105,7 +105,8 @@ bool HighlightingMark::hasFunctionArguments() const
HighlightingMark::operator HighlightingMarkContainer() const
{
return HighlightingMarkContainer(m_line, m_column, m_length, m_types);
return HighlightingMarkContainer(m_line, m_column, m_length, m_types, m_isIdentifier,
m_isInclusion);
}
namespace {
@@ -288,6 +289,8 @@ void HighlightingMark::functionKind(const Cursor &cursor, Recursion recursion)
void HighlightingMark::identifierKind(const Cursor &cursor, Recursion recursion)
{
m_isIdentifier = (cursor.kind() != CXCursor_PreprocessingDirective);
switch (cursor.kind()) {
case CXCursor_Destructor:
case CXCursor_Constructor:
@@ -352,6 +355,7 @@ HighlightingType literalKind(const Cursor &cursor)
switch (cursor.kind()) {
case CXCursor_CharacterLiteral:
case CXCursor_StringLiteral:
case CXCursor_InclusionDirective:
case CXCursor_ObjCStringLiteral: return HighlightingType::StringLiteral;
case CXCursor_IntegerLiteral:
case CXCursor_ImaginaryLiteral:
@@ -438,6 +442,8 @@ void HighlightingMark::collectKinds(CXTranslationUnit cxTranslationUnit,
case CXToken_Comment: m_types.mainHighlightingType = HighlightingType::Comment; break;
case CXToken_Literal: m_types.mainHighlightingType = literalKind(cursor); break;
}
m_isInclusion = (cursor.kind() == CXCursor_InclusionDirective);
}
std::ostream &operator<<(std::ostream &os, const HighlightingMark& highlightingMark)

View File

@@ -87,6 +87,8 @@ private:
uint m_length;
uint m_offset = 0;
HighlightingTypes m_types;
bool m_isIdentifier = false;
bool m_isInclusion = false;
};

View File

@@ -68,15 +68,12 @@ QVector<HighlightingMarkContainer> HighlightingMarks::toHighlightingMarksContain
const auto isValidHighlightMark = [] (const HighlightingMark &highlightMark) {
return !highlightMark.hasInvalidMainType()
&& !highlightMark.hasMainType(HighlightingType::StringLiteral)
&& !highlightMark.hasMainType(HighlightingType::NumberLiteral)
&& !highlightMark.hasMainType(HighlightingType::Comment);
&& !highlightMark.hasMainType(HighlightingType::NumberLiteral)
&& !highlightMark.hasMainType(HighlightingType::Comment);
};
for (const HighlightingMark &highlightMark : *this) {
for (const HighlightingMark &highlightMark : *this)
if (isValidHighlightMark(highlightMark))
containers.push_back(highlightMark);
}
return containers;
}

View File

@@ -56,20 +56,11 @@ using ::ClangBackEnd::UnsavedFiles;
using ::ClangBackEnd::ReferencesResult;
using ::ClangBackEnd::SourceRangeContainer;
using ClangBackEnd::FollowSymbolResult;
namespace {
const Utf8String sourceFilePath = Utf8StringLiteral(TESTDATA_DIR"/followsymbol_main.cpp");
const Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/followsymbol_header.h");
const Utf8String cursorPath = Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp");
std::ostream &operator<<(std::ostream &os, const FollowSymbolResult &result)
{
os << result.range;
return os;
}
MATCHER_P3(MatchesHeaderSourceRange, line, column, length,
std::string(negation ? "isn't " : "is ")
+ PrintToString(SourceRangeContainer {
@@ -83,7 +74,7 @@ MATCHER_P3(MatchesHeaderSourceRange, line, column, length,
SourceLocationContainer(headerFilePath, line, column + length)
};
return arg == FollowSymbolResult {expected, false};
return arg == expected;
}
MATCHER_P3(MatchesSourceRange, line, column, length,
@@ -99,7 +90,7 @@ MATCHER_P3(MatchesSourceRange, line, column, length,
SourceLocationContainer(sourceFilePath, line, column + length)
};
return arg == FollowSymbolResult {expected, false};
return arg == expected;
}
MATCHER_P4(MatchesFileSourceRange, filename, line, column, length,
@@ -115,7 +106,7 @@ MATCHER_P4(MatchesFileSourceRange, filename, line, column, length,
SourceLocationContainer(filename, line, column + length)
};
return arg == FollowSymbolResult {expected, false};
return arg == expected;
}
class Data {
@@ -150,7 +141,7 @@ private:
class FollowSymbol : public ::testing::Test
{
protected:
FollowSymbolResult followSymbol(uint line, uint column)
SourceRangeContainer followSymbol(uint line, uint column)
{
ClangBackEnd::TranslationUnitUpdateInput updateInput = d->document().createUpdateInput();
const ClangBackEnd::CommandLineArguments currentArgs(updateInput.filePath.constData(),
@@ -162,7 +153,7 @@ protected:
currentArgs);
}
FollowSymbolResult followHeaderSymbol(uint line, uint column)
SourceRangeContainer followHeaderSymbol(uint line, uint column)
{
ClangBackEnd::TranslationUnitUpdateInput updateInput
= d->headerDocument().createUpdateInput();

View File

@@ -1184,6 +1184,42 @@ TEST_F(HighlightingMarks, UsingTemplateFunction)
ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function));
}
TEST_F(HighlightingMarks, HeaderNameIsInclusion)
{
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(239, 31));
ClangBackEnd::HighlightingMarkContainer container(infos[2]);
ASSERT_THAT(container.isIncludeDirectivePath(), true);
}
TEST_F(HighlightingMarks, HeaderNameIsInclusionWithAngleBrackets)
{
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(289, 31));
ClangBackEnd::HighlightingMarkContainer container(infos[2]);
ASSERT_THAT(container.isIncludeDirectivePath(), true);
}
TEST_F(HighlightingMarks, NotInclusion)
{
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(241, 13));
ClangBackEnd::HighlightingMarkContainer container(infos[1]);
ASSERT_THAT(container.isIncludeDirectivePath(), false);
}
TEST_F(HighlightingMarks, MacroIsIdentifier)
{
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(232, 30));
ClangBackEnd::HighlightingMarkContainer container(infos[2]);
ASSERT_THAT(container.isIdentifier(), true);
}
TEST_F(HighlightingMarks, DefineIsNotIdentifier)
{
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(232, 30));
ClangBackEnd::HighlightingMarkContainer container(infos[1]);
ASSERT_THAT(container.isIncludeDirectivePath(), false);
}
Data *HighlightingMarks::d;
void HighlightingMarks::SetUpTestCase()

View File

@@ -208,8 +208,7 @@ TEST_F(ReadAndWriteMessageBlock, CompareRequestFollowSymbol)
QVector<Utf8String> dependentFiles;
dependentFiles.push_back(QString("somefile.cpp"));
dependentFiles.push_back(QString("otherfile.cpp"));
CompareMessage(ClangBackEnd::RequestFollowSymbolMessage{fileContainer, dependentFiles, 13, 37,
false});
CompareMessage(ClangBackEnd::RequestFollowSymbolMessage{fileContainer, dependentFiles, 13, 37});
}
TEST_F(ReadAndWriteMessageBlock, CompareReferences)