diff --git a/src/plugins/clangcodemodel/clangdfindreferences.cpp b/src/plugins/clangcodemodel/clangdfindreferences.cpp index b7e62d6e055..13968801e7b 100644 --- a/src/plugins/clangcodemodel/clangdfindreferences.cpp +++ b/src/plugins/clangcodemodel/clangdfindreferences.cpp @@ -291,12 +291,17 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList for (const Location &loc : locations) fileData[loc.uri()].rangesAndLineText.push_back({loc.range(), {}}); + QSet canonicalFilePaths; for (auto it = fileData.begin(); it != fileData.end();) { const Utils::FilePath filePath = client()->serverUriToHostPath(it.key()); if (!filePath.exists()) { // https://github.com/clangd/clangd/issues/935 it = fileData.erase(it); continue; } + if (!Utils::insert(canonicalFilePaths, filePath.canonicalPath())) { // QTCREATORBUG-30546 + it = fileData.erase(it); + continue; + } const QStringList lines = SymbolSupport::getFileContents(filePath); it->fileContent = lines.join('\n'); for (auto &rangeWithText : it.value().rangesAndLineText) { diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index e9c4443eed3..3a9a1b09705 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -274,6 +274,10 @@ struct ItemData Utils::Text::Range range; QVariant userData; }; +bool operator==(const ItemData &id1, const ItemData &id2) +{ + return id1.range == id2.range && id1.userData == id2.userData; +} QStringList SymbolSupport::getFileContents(const Utils::FilePath &filePath) { @@ -342,15 +346,32 @@ Utils::SearchResultItems generateSearchResultItems( return result; } +using ItemDataPerPath = QMap>; +void filterFileAliases(ItemDataPerPath &itemDataPerPath) +{ + QSet canonicalPaths; + for (auto it = itemDataPerPath.begin(); it != itemDataPerPath.end(); ) { + const Utils::FilePath canonicalPath = it.key().canonicalPath(); + if (!Utils::insert(canonicalPaths, canonicalPath) + && it.value() == itemDataPerPath.value(canonicalPath)) { // QTCREATORBUG-30546 + it = itemDataPerPath.erase(it); + } else { + ++it; + } + } +} + Utils::SearchResultItems generateSearchResultItems( const LanguageClientArray &locations, const DocumentUri::PathMapper &pathMapper) { if (locations.isNull()) return {}; - QMap> rangesInDocument; - for (const Location &location : locations.toList()) + ItemDataPerPath rangesInDocument; + for (const Location &location : locations.toList()) { rangesInDocument[location.uri().toFilePath(pathMapper)] << ItemData{SymbolSupport::convertRange(location.range()), {}}; + } + filterFileAliases(rangesInDocument); return generateSearchResultItems(rangesInDocument); } @@ -552,7 +573,7 @@ Utils::SearchResultItems generateReplaceItems(const WorkspaceEdit &edits, return ItemData{SymbolSupport::convertRange(edit.range()), QVariant(edit)}; }); }; - QMap> rangesInDocument; + ItemDataPerPath rangesInDocument; auto documentChanges = edits.documentChanges().value_or(QList()); if (!documentChanges.isEmpty()) { for (const DocumentChange &documentChange : std::as_const(documentChanges)) { @@ -588,6 +609,7 @@ Utils::SearchResultItems generateReplaceItems(const WorkspaceEdit &edits, for (auto it = changes.begin(), end = changes.end(); it != end; ++it) rangesInDocument[it.key().toFilePath(pathMapper)] = convertEdits(it.value()); } + filterFileAliases(rangesInDocument); items += generateSearchResultItems(rangesInDocument, search, limitToProjects); return items; }