Index: clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp =================================================================== --- clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp +++ clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp @@ -67,8 +67,8 @@ // Eventually we will either hit a class (namespaces aren't in the database // either) and can report that result. bool TookPrefix = false; - std::vector Results; - while (Results.empty() && !Names.empty()) { + std::vector MatchedSymbols; + while (MatchedSymbols.empty() && !Names.empty()) { std::vector Symbols; for (const auto &DB : SymbolIndices) { auto Res = DB->search(Names.back().str()); @@ -78,8 +78,6 @@ DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got " << Symbols.size() << " results...\n"); - rankByPopularity(Symbols); - for (const auto &Symbol : Symbols) { // Match the identifier name without qualifier. if (Symbol.getName() == Names.back()) { @@ -120,15 +118,7 @@ Symbol.getSymbolKind() == SymbolInfo::SymbolKind::Macro)) continue; - // FIXME: file path should never be in the form of <...> or "...", but - // the unit test with fixed database use <...> file path, which might - // need to be changed. - // FIXME: if the file path is a system header name, we want to use - // angle brackets. - std::string FilePath = Symbol.getFilePath().str(); - Results.push_back((FilePath[0] == '"' || FilePath[0] == '<') - ? FilePath - : "\"" + FilePath + "\""); + MatchedSymbols.push_back(Symbol); } } } @@ -136,6 +126,20 @@ TookPrefix = true; } + rankByPopularity(MatchedSymbols); + std::vector Results; + for (const auto &Symbol : MatchedSymbols) { + // FIXME: file path should never be in the form of <...> or "...", but + // the unit test with fixed database use <...> file path, which might + // need to be changed. + // FIXME: if the file path is a system header name, we want to use + // angle brackets. + std::string FilePath = Symbol.getFilePath().str(); + Results.push_back((FilePath[0] == '"' || FilePath[0] == '<') + ? FilePath + : "\"" + FilePath + "\""); + } + return Results; } Index: clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp =================================================================== --- clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp +++ clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp @@ -60,13 +60,20 @@ SymbolInfo("foo", SymbolInfo::SymbolKind::Class, "\"dir/otherdir/qux.h\"", 1, {{SymbolInfo::ContextType::Namespace, "b"}, {SymbolInfo::ContextType::Namespace, "a"}}), - SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar.h\"", - 1, {{SymbolInfo::ContextType::Namespace, "b"}, - {SymbolInfo::ContextType::Namespace, "a"}}), - SymbolInfo("Green", SymbolInfo::SymbolKind::Class, "\"color.h\"", - 1, {{SymbolInfo::ContextType::EnumDecl, "Color"}, - {SymbolInfo::ContextType::Namespace, "b"}, - {SymbolInfo::ContextType::Namespace, "a"}}), + SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar.h\"", 1, + {{SymbolInfo::ContextType::Namespace, "b"}, + {SymbolInfo::ContextType::Namespace, "a"}}), + SymbolInfo("Green", SymbolInfo::SymbolKind::Class, "\"color.h\"", 1, + {{SymbolInfo::ContextType::EnumDecl, "Color"}, + {SymbolInfo::ContextType::Namespace, "b"}, + {SymbolInfo::ContextType::Namespace, "a"}}), + SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 1, + {{SymbolInfo::ContextType::Namespace, "__a"}, + {SymbolInfo::ContextType::Namespace, "a"}}, + /*num_occurrences=*/2), + SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 2, + {{SymbolInfo::ContextType::Namespace, "a"}}, + /*num_occurrences=*/1), }; auto SymbolIndexMgr = llvm::make_unique(); SymbolIndexMgr->addSymbolIndex( @@ -209,6 +216,11 @@ EXPECT_EQ(Expected, runIncludeFixer(Code)); } +TEST(IncludeFixer, DoNotDeleteMatchedSymbol) { + EXPECT_EQ("#include \"Vector.h\"\na::Vector v;", + runIncludeFixer("a::Vector v;")); +} + } // namespace } // namespace include_fixer } // namespace clang