This revision was automatically updated to reflect the committed changes.
Closed by commit rL268480: Added XrefsDBManager into include-fixer and made 
XrefsDB return SymbolInfo. (authored by ioeric).

Changed prior to commit:
  http://reviews.llvm.org/D19869?vs=56104&id=56105#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D19869

Files:
  clang-tools-extra/trunk/include-fixer/CMakeLists.txt
  clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.cpp
  clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.h
  clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
  clang-tools-extra/trunk/include-fixer/IncludeFixer.h
  clang-tools-extra/trunk/include-fixer/XrefsDB.h
  clang-tools-extra/trunk/include-fixer/XrefsDBManager.cpp
  clang-tools-extra/trunk/include-fixer/XrefsDBManager.h
  clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp
  clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h
  clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
  clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
  clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp

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
@@ -9,6 +9,7 @@
 
 #include "InMemoryXrefsDB.h"
 #include "IncludeFixer.h"
+#include "XrefsDBManager.h"
 #include "unittests/Tooling/RewriterTestContext.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
@@ -51,10 +52,12 @@
       {"std::string::size_type", {"<string>"}},
       {"a::b::foo", {"dir/otherdir/qux.h"}},
   };
-  auto XrefsDB =
-      llvm::make_unique<include_fixer::InMemoryXrefsDB>(std::move(XrefsMap));
+  auto XrefsDBMgr = llvm::make_unique<include_fixer::XrefsDBManager>();
+  XrefsDBMgr->addXrefsDB(
+      llvm::make_unique<include_fixer::InMemoryXrefsDB>(std::move(XrefsMap)));
+
   std::vector<clang::tooling::Replacement> Replacements;
-  IncludeFixerActionFactory Factory(*XrefsDB, Replacements);
+  IncludeFixerActionFactory Factory(*XrefsDBMgr, Replacements);
   runOnCode(&Factory, Code, "input.cc", ExtraArgs);
   clang::RewriterTestContext Context;
   clang::FileID ID = Context.createInMemoryFile("input.cc", Code);
@@ -79,8 +82,10 @@
       "#include <string>\n#include \"foo.h\"\nstd::string::size_type foo;\n",
       runIncludeFixer("#include \"foo.h\"\nstd::string::size_type foo;\n"));
 
-  // The fixed xrefs db doesn't know how to handle string without std::.
-  EXPECT_EQ("string foo;\n", runIncludeFixer("string foo;\n"));
+  // string without "std::" can also be fixed since fixed db results go through
+  // XrefsDBManager, and XrefsDBManager matches unqualified identifiers too.
+  EXPECT_EQ("#include <string>\nstring foo;\n",
+            runIncludeFixer("string foo;\n"));
 }
 
 TEST(IncludeFixer, IncompleteType) {
Index: clang-tools-extra/trunk/include-fixer/XrefsDB.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/XrefsDB.h
+++ clang-tools-extra/trunk/include-fixer/XrefsDB.h
@@ -10,26 +10,26 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_XREFSDB_H
 #define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_XREFSDB_H
 
+#include "find-all-symbols/SymbolInfo.h"
 #include "llvm/ADT/StringRef.h"
 #include <vector>
 
 namespace clang {
 namespace include_fixer {
 
-/// This class provides an interface for finding the header files corresponding
-/// to an indentifier in the source code.
+/// This class provides an interface for finding all `SymbolInfo`s corresponding
+/// to a symbol name from a symbol database.
 class XrefsDB {
 public:
   virtual ~XrefsDB() = default;
 
-  /// Search for header files to be included for an identifier.
-  /// \param Identifier The identifier being searched for. May or may not be
-  ///                   fully qualified.
-  /// \returns A list of inclusion candidates, in a format ready for being
-  ///          pasted after an #include token.
+  /// Search for all `SymbolInfo`s corresponding to an identifier.
+  /// \param Identifier The unqualified identifier being searched for.
+  /// \returns A list of `SymbolInfo` candidates.
   // FIXME: Expose the type name so we can also insert using declarations (or
   // fix the usage)
-  virtual std::vector<std::string> search(llvm::StringRef Identifier) = 0;
+  virtual std::vector<clang::find_all_symbols::SymbolInfo>
+  search(llvm::StringRef Identifier) = 0;
 };
 
 } // namespace include_fixer
Index: clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.h
+++ clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.h
@@ -21,13 +21,15 @@
 /// Xref database with fixed content.
 class InMemoryXrefsDB : public XrefsDB {
 public:
-  InMemoryXrefsDB(std::map<std::string, std::vector<std::string>> LookupTable)
-      : LookupTable(std::move(LookupTable)) {}
+  InMemoryXrefsDB(
+      const std::map<std::string, std::vector<std::string>> &LookupTable);
 
-  std::vector<std::string> search(llvm::StringRef Identifier) override;
+  std::vector<clang::find_all_symbols::SymbolInfo>
+  search(llvm::StringRef Identifier) override;
 
 private:
-  std::map<std::string, std::vector<std::string>> LookupTable;
+  std::map<std::string, std::vector<clang::find_all_symbols::SymbolInfo>>
+      LookupTable;
 };
 
 } // namespace include_fixer
Index: clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
===================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
+++ clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
@@ -60,8 +60,8 @@
 class Action : public clang::ASTFrontendAction,
                public clang::ExternalSemaSource {
 public:
-  explicit Action(XrefsDB &Xrefs, bool MinimizeIncludePaths)
-      : Xrefs(Xrefs), MinimizeIncludePaths(MinimizeIncludePaths) {}
+  explicit Action(XrefsDBManager &XrefsDBMgr, bool MinimizeIncludePaths)
+      : XrefsDBMgr(XrefsDBMgr), MinimizeIncludePaths(MinimizeIncludePaths) {}
 
   std::unique_ptr<clang::ASTConsumer>
   CreateASTConsumer(clang::CompilerInstance &Compiler,
@@ -224,7 +224,7 @@
     DEBUG(llvm::dbgs() << "Looking up " << Query << " ... ");
 
     std::string error_text;
-    auto SearchReply = Xrefs.search(Query);
+    auto SearchReply = XrefsDBMgr.search(Query);
     DEBUG(llvm::dbgs() << SearchReply.size() << " replies\n");
     if (SearchReply.empty())
       return clang::TypoCorrection();
@@ -240,7 +240,7 @@
   }
 
   /// The client to use to find cross-references.
-  XrefsDB &Xrefs;
+  XrefsDBManager &XrefsDBMgr;
 
   // Remeber things we looked up to avoid querying things twice.
   llvm::StringSet<> SeenQueries;
@@ -303,9 +303,10 @@
 } // namespace
 
 IncludeFixerActionFactory::IncludeFixerActionFactory(
-    XrefsDB &Xrefs, std::vector<clang::tooling::Replacement> &Replacements,
+    XrefsDBManager &XrefsDBMgr,
+    std::vector<clang::tooling::Replacement> &Replacements,
     bool MinimizeIncludePaths)
-    : Xrefs(Xrefs), Replacements(Replacements),
+    : XrefsDBMgr(XrefsDBMgr), Replacements(Replacements),
       MinimizeIncludePaths(MinimizeIncludePaths) {}
 
 IncludeFixerActionFactory::~IncludeFixerActionFactory() = default;
@@ -329,7 +330,7 @@
 
   // Run the parser, gather missing includes.
   auto ScopedToolAction =
-      llvm::make_unique<Action>(Xrefs, MinimizeIncludePaths);
+      llvm::make_unique<Action>(XrefsDBMgr, MinimizeIncludePaths);
   Compiler.ExecuteAction(*ScopedToolAction);
 
   // Generate replacements.
Index: clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp
===================================================================
--- clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp
+++ clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp
@@ -15,6 +15,8 @@
 #include <string>
 #include <vector>
 
+using clang::find_all_symbols::SymbolInfo;
+
 namespace clang {
 namespace include_fixer {
 
@@ -29,33 +31,11 @@
       Buffer.get()->getBuffer());
 }
 
-std::vector<std::string> YamlXrefsDB::search(llvm::StringRef Identifier) {
-  llvm::SmallVector<llvm::StringRef, 16> Names;
-  std::vector<std::string> Results;
-
-  // The identifier may be fully qualified, so split it and get all the context
-  // names.
-  Identifier.split(Names, "::");
+std::vector<SymbolInfo> YamlXrefsDB::search(llvm::StringRef Identifier) {
+  std::vector<SymbolInfo> Results;
   for (const auto &Symbol : Symbols) {
-    // Match the identifier name without qualifier.
-    if (Symbol.Name == Names.back()) {
-      bool IsMatched = true;
-      auto SymbolContext = Symbol.Contexts.begin();
-      // Match the remaining context names.
-      for (auto IdentiferContext = Names.rbegin() + 1;
-           IdentiferContext != Names.rend() &&
-           SymbolContext != Symbol.Contexts.end();
-           ++IdentiferContext, ++SymbolContext) {
-        if (SymbolContext->second != *IdentiferContext) {
-          IsMatched = false;
-          break;
-        }
-      }
-
-      if (IsMatched) {
-        Results.push_back("\"" + Symbol.FilePath + "\"");
-      }
-    }
+    if (Symbol.Name == Identifier)
+      Results.push_back(Symbol);
   }
   return Results;
 }
Index: clang-tools-extra/trunk/include-fixer/XrefsDBManager.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/XrefsDBManager.h
+++ clang-tools-extra/trunk/include-fixer/XrefsDBManager.h
@@ -0,0 +1,45 @@
+//===-- XrefsDBManager.h - Managing multiple XrefsDBs -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_XREFSDBMANAGER_H
+#define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_XREFSDBMANAGER_H
+
+#include "XrefsDB.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace include_fixer {
+
+/// This class provides an interface for finding the header files corresponding
+/// to an indentifier in the source code from multiple symbol databases.
+class XrefsDBManager {
+public:
+  void addXrefsDB(std::unique_ptr<XrefsDB> DB) {
+    XrefsDBs.push_back(std::move(DB));
+  }
+
+  /// Search for header files to be included for an identifier.
+  /// \param Identifier The identifier being searched for. May or may not be
+  ///                   fully qualified.
+  /// \returns A list of inclusion candidates, in a format ready for being
+  ///          pasted after an #include token.
+  // FIXME: Expose the type name so we can also insert using declarations (or
+  // fix the usage)
+  // FIXME: Move mapping from SymbolInfo to headers out of
+  // XrefsDBManager::search and return SymbolInfos instead of header paths.
+  std::vector<std::string> search(llvm::StringRef Identifier) const;
+
+private:
+  std::vector<std::unique_ptr<XrefsDB>> XrefsDBs;
+};
+
+} // namespace include_fixer
+} // namespace clang
+
+#endif
Index: clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.cpp
===================================================================
--- clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.cpp
+++ clang-tools-extra/trunk/include-fixer/InMemoryXrefsDB.cpp
@@ -9,10 +9,34 @@
 
 #include "InMemoryXrefsDB.h"
 
+using clang::find_all_symbols::SymbolInfo;
+
 namespace clang {
 namespace include_fixer {
 
-std::vector<std::string> InMemoryXrefsDB::search(llvm::StringRef Identifier) {
+InMemoryXrefsDB::InMemoryXrefsDB(
+    const std::map<std::string, std::vector<std::string>> &LookupTable) {
+  for (const auto &Entry : LookupTable) {
+    llvm::StringRef Identifier(Entry.first);
+    llvm::SmallVector<llvm::StringRef, 8> Names;
+    Identifier.split(Names, "::");
+    for (const auto &Header : Entry.second) {
+      // FIXME: create a complete instance with static member function when it
+      // is implemented.
+      SymbolInfo Info;
+      Info.Name = Names.back();
+      Info.FilePath = Header;
+      for (auto IdentiferContext = Names.rbegin() + 1;
+           IdentiferContext != Names.rend(); ++IdentiferContext) {
+        Info.Contexts.push_back(
+            {SymbolInfo::ContextType::Namespace, *IdentiferContext});
+      }
+      this->LookupTable[Info.Name].push_back(Info);
+    }
+  }
+}
+
+std::vector<SymbolInfo> InMemoryXrefsDB::search(llvm::StringRef Identifier) {
   auto I = LookupTable.find(Identifier);
   if (I != LookupTable.end())
     return I->second;
Index: clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
===================================================================
--- clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
+++ clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
@@ -9,6 +9,7 @@
 
 #include "InMemoryXrefsDB.h"
 #include "IncludeFixer.h"
+#include "XrefsDBManager.h"
 #include "YamlXrefsDB.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Rewrite/Core/Rewriter.h"
@@ -48,8 +49,8 @@
   tooling::ClangTool tool(options.getCompilations(),
                           options.getSourcePathList());
 
-  // Set up the data source.
-  std::unique_ptr<include_fixer::XrefsDB> XrefsDB;
+  // Set up data source.
+  auto XrefsDBMgr = llvm::make_unique<include_fixer::XrefsDBManager>();
   switch (DatabaseFormat) {
   case fixed: {
     // Parse input and fill the database with it.
@@ -67,19 +68,20 @@
         Headers.push_back(Header.trim());
       XrefsMap[Split.first.trim()] = std::move(Headers);
     }
-    XrefsDB =
-        llvm::make_unique<include_fixer::InMemoryXrefsDB>(std::move(XrefsMap));
+    XrefsDBMgr->addXrefsDB(
+        llvm::make_unique<include_fixer::InMemoryXrefsDB>(std::move(XrefsMap)));
     break;
   }
   case yaml: {
-    XrefsDB = llvm::make_unique<include_fixer::YamlXrefsDB>(Input);
+    XrefsDBMgr->addXrefsDB(
+        llvm::make_unique<include_fixer::YamlXrefsDB>(Input));
     break;
   }
   }
 
   // Now run our tool.
   std::vector<tooling::Replacement> Replacements;
-  include_fixer::IncludeFixerActionFactory Factory(*XrefsDB, Replacements,
+  include_fixer::IncludeFixerActionFactory Factory(*XrefsDBMgr, Replacements,
                                                    MinimizeIncludePaths);
 
   tool.run(&Factory); // Always succeeds.
Index: clang-tools-extra/trunk/include-fixer/CMakeLists.txt
===================================================================
--- clang-tools-extra/trunk/include-fixer/CMakeLists.txt
+++ clang-tools-extra/trunk/include-fixer/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_clang_library(clangIncludeFixer
   IncludeFixer.cpp
   InMemoryXrefsDB.cpp
+  XrefsDBManager.cpp
   YamlXrefsDB.cpp
 
   LINK_LIBS
Index: clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
@@ -21,6 +21,7 @@
 namespace find_all_symbols {
 
 /// \brief Contains all information for a Symbol.
+// FIXME: add static members for creating complete instances.
 struct SymbolInfo {
   enum SymbolKind {
     Function,
Index: clang-tools-extra/trunk/include-fixer/XrefsDBManager.cpp
===================================================================
--- clang-tools-extra/trunk/include-fixer/XrefsDBManager.cpp
+++ clang-tools-extra/trunk/include-fixer/XrefsDBManager.cpp
@@ -0,0 +1,70 @@
+//===-- XrefsDBManager.cpp - Managing multiple XrefsDBs ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XrefsDBManager.h"
+#include "find-all-symbols/SymbolInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "include-fixer"
+
+namespace clang {
+namespace include_fixer {
+
+std::vector<std::string>
+XrefsDBManager::search(llvm::StringRef Identifier) const {
+  // The identifier may be fully qualified, so split it and get all the context
+  // names.
+  llvm::SmallVector<llvm::StringRef, 8> Names;
+  Identifier.split(Names, "::");
+
+  std::vector<clang::find_all_symbols::SymbolInfo> Symbols;
+  for (const auto &DB : XrefsDBs) {
+    auto Res = DB->search(Names.back().str());
+    Symbols.insert(Symbols.end(), Res.begin(), Res.end());
+  }
+
+  DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got "
+                     << Symbols.size() << " results...\n");
+
+  std::vector<std::string> Results;
+  for (const auto &Symbol : Symbols) {
+    // Match the identifier name without qualifier.
+    if (Symbol.Name == Names.back()) {
+      bool IsMatched = true;
+      auto SymbolContext = Symbol.Contexts.begin();
+      // Match the remaining context names.
+      for (auto IdentiferContext = Names.rbegin() + 1;
+           IdentiferContext != Names.rend() &&
+           SymbolContext != Symbol.Contexts.end();
+           ++IdentiferContext, ++SymbolContext) {
+        if (SymbolContext->second != *IdentiferContext) {
+          IsMatched = false;
+          break;
+        }
+      }
+
+      if (IsMatched) {
+        // 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.
+        Results.push_back(
+            (Symbol.FilePath[0] == '"' || Symbol.FilePath[0] == '<')
+                ? Symbol.FilePath
+                : "\"" + Symbol.FilePath + "\"");
+      }
+    }
+  }
+  return Results;
+}
+
+} // namespace include_fixer
+} // namespace clang
Index: clang-tools-extra/trunk/include-fixer/IncludeFixer.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixer.h
+++ clang-tools-extra/trunk/include-fixer/IncludeFixer.h
@@ -10,7 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H
 #define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H
 
-#include "XrefsDB.h"
+#include "XrefsDBManager.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Tooling.h"
 #include <memory>
@@ -27,11 +27,12 @@
 
 class IncludeFixerActionFactory : public clang::tooling::ToolAction {
 public:
-  /// \param Xrefs A source for matching symbols to header files.
+  /// \param XrefsDBMgr A source for matching symbols to header files.
   /// \param Replacements Storage for the output of the fixer.
   /// \param MinimizeIncludePaths whether inserted include paths are optimized.
   IncludeFixerActionFactory(
-      XrefsDB &Xrefs, std::vector<clang::tooling::Replacement> &Replacements,
+      XrefsDBManager &XrefsDBMgr,
+      std::vector<clang::tooling::Replacement> &Replacements,
       bool MinimizeIncludePaths = true);
   ~IncludeFixerActionFactory() override;
 
@@ -43,7 +44,7 @@
 
 private:
   /// The client to use to find cross-references.
-  XrefsDB &Xrefs;
+  XrefsDBManager &XrefsDBMgr;
 
   /// Replacements are written here.
   std::vector<clang::tooling::Replacement> &Replacements;
Index: clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h
===================================================================
--- clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h
+++ clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h
@@ -23,7 +23,8 @@
 public:
   YamlXrefsDB(llvm::StringRef FilePath);
 
-  std::vector<std::string> search(llvm::StringRef Identifier) override;
+  std::vector<clang::find_all_symbols::SymbolInfo>
+  search(llvm::StringRef Identifier) override;
 
 private:
   std::vector<clang::find_all_symbols::SymbolInfo> Symbols;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to