ClangCodeModel: Consolidate clangd highlighting data structures

Put all the highlighting-related data in one place.
No functional changes.

Change-Id: Ic13e755601682895b27a358b5783c52acc11794e
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-04-21 13:02:09 +02:00
parent fd02996ec9
commit 7bace9d926

View File

@@ -1117,6 +1117,20 @@ private:
Utils::optional<MessageId> m_currentRequest; Utils::optional<MessageId> m_currentRequest;
}; };
class HighlightingData
{
public:
// For all QPairs, the int member is the corresponding document version.
QPair<QList<ExpandedSemanticToken>, int> previousTokens;
// The ranges of symbols referring to virtual functions,
// as extracted by the highlighting procedure.
QPair<QList<Range>, int> virtualRanges;
// The highlighter is owned by its document.
CppEditor::SemanticHighlighter *highlighter = nullptr;
};
class ClangdClient::Private class ClangdClient::Private
{ {
public: public:
@@ -1169,16 +1183,9 @@ public:
Utils::optional<LocalRefsData> localRefsData; Utils::optional<LocalRefsData> localRefsData;
Utils::optional<QVersionNumber> versionNumber; Utils::optional<QVersionNumber> versionNumber;
// The highlighters are owned by their respective documents. QHash<TextDocument *, HighlightingData> highlightingData;
std::unordered_map<TextDocument *, CppEditor::SemanticHighlighter *> highlighters;
QHash<TextDocument *, QPair<QList<ExpandedSemanticToken>, int>> previousTokens;
QHash<Utils::FilePath, CppEditor::BaseEditorDocumentParser::Configuration> parserConfigs; QHash<Utils::FilePath, CppEditor::BaseEditorDocumentParser::Configuration> parserConfigs;
// The ranges of symbols referring to virtual functions, with document version,
// as extracted by the highlighting procedure.
QHash<TextDocument *, QPair<QList<Range>, int>> virtualRanges;
VersionedDataCache<const TextDocument *, AstNode> astCache; VersionedDataCache<const TextDocument *, AstNode> astCache;
VersionedDataCache<Utils::FilePath, AstNode> externalAstCache; VersionedDataCache<Utils::FilePath, AstNode> externalAstCache;
TaskTimer highlightingTimer{"highlighting"}; TaskTimer highlightingTimer{"highlighting"};
@@ -1582,10 +1589,8 @@ void ClangdClient::handleDocumentOpened(TextDocument *doc)
void ClangdClient::handleDocumentClosed(TextDocument *doc) void ClangdClient::handleDocumentClosed(TextDocument *doc)
{ {
d->highlighters.erase(doc); d->highlightingData.remove(doc);
d->astCache.remove(doc); d->astCache.remove(doc);
d->previousTokens.remove(doc);
d->virtualRanges.remove(doc);
d->parserConfigs.remove(doc->filePath()); d->parserConfigs.remove(doc->filePath());
} }
@@ -2332,7 +2337,7 @@ void ClangdClient::setVirtualRanges(const Utils::FilePath &filePath, const QList
{ {
TextDocument * const doc = documentForFilePath(filePath); TextDocument * const doc = documentForFilePath(filePath);
if (doc && doc->document()->revision() == revision) if (doc && doc->document()->revision() == revision)
d->virtualRanges.insert(doc, {ranges, revision}); d->highlightingData[doc].virtualRanges = {ranges, revision};
} }
void ClangdClient::Private::handleGotoDefinitionResult() void ClangdClient::Private::handleGotoDefinitionResult()
@@ -3055,16 +3060,19 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
return; return;
} }
force = force || isTesting; force = force || isTesting;
const auto previous = previousTokens.find(doc); const auto data = highlightingData.find(doc);
if (previous != previousTokens.end()) { if (data != highlightingData.end()) {
if (!force && previous->first == tokens && previous->second == version) { if (!force && data->previousTokens.first == tokens
&& data->previousTokens.second == version) {
qCInfo(clangdLogHighlight) << "tokens and version same as last time; nothing to do"; qCInfo(clangdLogHighlight) << "tokens and version same as last time; nothing to do";
return; return;
} }
previous->first = tokens; data->previousTokens.first = tokens;
previous->second = version; data->previousTokens.second = version;
} else { } else {
previousTokens.insert(doc, qMakePair(tokens, version)); HighlightingData data;
data.previousTokens = qMakePair(tokens, version);
highlightingData.insert(doc, data);
} }
for (const ExpandedSemanticToken &t : tokens) for (const ExpandedSemanticToken &t : tokens)
qCDebug(clangdLogHighlight()) << '\t' << t.line << t.column << t.length << t.type qCDebug(clangdLogHighlight()) << '\t' << t.line << t.column << t.length << t.type
@@ -3102,15 +3110,13 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
return; return;
} }
auto it = highlighters.find(doc); auto &data = highlightingData[doc];
if (it == highlighters.end()) { if (!data.highlighter)
it = highlighters.insert(std::make_pair(doc, new CppEditor::SemanticHighlighter(doc))) data.highlighter = new CppEditor::SemanticHighlighter(doc);
.first; else
} else { data.highlighter->updateFormatMapFromFontSettings();
it->second->updateFormatMapFromFontSettings(); data.highlighter->setHighlightingRunner(runner);
} data.highlighter->run();
it->second->setHighlightingRunner(runner);
it->second->run();
}; };
getAndHandleAst(doc, astHandler, AstCallbackMode::SyncIfPossible); getAndHandleAst(doc, astHandler, AstCallbackMode::SyncIfPossible);
} }
@@ -4124,13 +4130,14 @@ bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const
// If we have up-to-date highlighting info, we know whether we are dealing with // If we have up-to-date highlighting info, we know whether we are dealing with
// a virtual call. // a virtual call.
if (editorWidget) { if (editorWidget) {
const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument()); const auto highlightingData =
if (virtualRanges != q->d->virtualRanges.constEnd() q->d->highlightingData.constFind(editorWidget->textDocument());
&& virtualRanges->second == docRevision) { if (highlightingData != q->d->highlightingData.constEnd()
&& highlightingData->virtualRanges.second == docRevision) {
const auto matcher = [cursorRange = cursorNode->range()](const Range &r) { const auto matcher = [cursorRange = cursorNode->range()](const Range &r) {
return cursorRange.overlaps(r); return cursorRange.overlaps(r);
}; };
return Utils::contains(virtualRanges->first, matcher); return Utils::contains(highlightingData->virtualRanges.first, matcher);
} }
} }