hokein created this revision. hokein added a reviewer: bkramer. hokein added a subscriber: cfe-commits.
https://reviews.llvm.org/D24075 Files: include-fixer/find-all-symbols/SymbolInfo.h include-fixer/tool/ClangIncludeFixer.cpp test/include-fixer/query_symbol.cpp Index: test/include-fixer/query_symbol.cpp =================================================================== --- /dev/null +++ test/include-fixer/query_symbol.cpp @@ -0,0 +1,13 @@ +// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -search-symbol="foo" test.cpp -- | FileCheck %s + +// CHECK: "FilePath": "test.cpp", +// CHECK-NEXT:"QuerySymbolInfos": [ +// CHECK-NEXT: {"RawIdentifier": "foo", +// CHECK-NEXT: "Range":{"Offset":0,"Length":0}} +// CHECK-NEXT:], +// CHECK-NEXT:"HeaderInfos": [ +// CHECK-NEXT: {"Header": "\"foo.h\"", +// CHECK-NEXT: "QualifiedName": "foo"}, +// CHECK-NEXT: {"Header": "\"bar.h\"", +// CHECK-NEXT: "QualifiedName": "foo"} +// CHECK-NEXT:] Index: include-fixer/tool/ClangIncludeFixer.cpp =================================================================== --- include-fixer/tool/ClangIncludeFixer.cpp +++ include-fixer/tool/ClangIncludeFixer.cpp @@ -98,6 +98,12 @@ cl::desc("String to initialize the database"), cl::cat(IncludeFixerCategory)); +cl::opt<std::string> + QuerySymbol("query-symbol", + cl::desc("Query a given symbol (e.g. \"a::b::foo\") in\n" + "database directly without parsing the file."), + cl::cat(IncludeFixerCategory)); + cl::opt<bool> MinimizeIncludePaths("minimize-paths", cl::desc("Whether to minimize added include paths"), @@ -236,6 +242,7 @@ tooling::ClangTool tool(options.getCompilations(), options.getSourcePathList()); + llvm::StringRef SourceFilePath = options.getSourcePathList().front(); // In STDINMode, we override the file content with the <stdin> input. // Since `tool.mapVirtualFile` takes `StringRef`, we define `Code` outside of // the if-block so that `Code` is not released after the if-block. @@ -253,7 +260,7 @@ if (Code->getBufferSize() == 0) return 0; // Skip empty files. - tool.mapVirtualFile(options.getSourcePathList().front(), Code->getBuffer()); + tool.mapVirtualFile(SourceFilePath, Code->getBuffer()); } if (!InsertHeader.empty()) { @@ -314,10 +321,31 @@ // Set up data source. std::unique_ptr<include_fixer::SymbolIndexManager> SymbolIndexMgr = - createSymbolIndexManager(options.getSourcePathList().front()); + createSymbolIndexManager(SourceFilePath); if (!SymbolIndexMgr) return 1; + // Query symbol mode. + if (!QuerySymbol.empty()) { + auto MatchedSymbols = SymbolIndexMgr->search(QuerySymbol); + for (auto &Symbol : MatchedSymbols) { + std::string HeaderPath = Symbol.getFilePath().str(); + Symbol.SetFilePath(((HeaderPath[0] == '"' || HeaderPath[0] == '<') + ? HeaderPath + : "\"" + HeaderPath + "\"")); + } + + // We leave an empty symbol range as we don't know the range of the symbol + // being queried in this mode. include-fixer won't add namespace qualifiers + // if the symbol range is empty, which also fits this case. + IncludeFixerContext::QuerySymbolInfo Symbol; + Symbol.RawIdentifier = QuerySymbol; + auto Context = + IncludeFixerContext(SourceFilePath, {Symbol}, MatchedSymbols); + writeToJson(llvm::outs(), Context); + return 0; + } + // Now run our tool. std::vector<include_fixer::IncludeFixerContext> Contexts; include_fixer::IncludeFixerActionFactory Factory(*SymbolIndexMgr, Contexts, Index: include-fixer/find-all-symbols/SymbolInfo.h =================================================================== --- include-fixer/find-all-symbols/SymbolInfo.h +++ include-fixer/find-all-symbols/SymbolInfo.h @@ -54,6 +54,8 @@ int LineNumber, const std::vector<Context> &Contexts, unsigned NumOccurrences = 0); + void SetFilePath(llvm::StringRef Path) { FilePath = Path; } + /// \brief Get symbol name. llvm::StringRef getName() const { return Name; }
Index: test/include-fixer/query_symbol.cpp =================================================================== --- /dev/null +++ test/include-fixer/query_symbol.cpp @@ -0,0 +1,13 @@ +// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -search-symbol="foo" test.cpp -- | FileCheck %s + +// CHECK: "FilePath": "test.cpp", +// CHECK-NEXT:"QuerySymbolInfos": [ +// CHECK-NEXT: {"RawIdentifier": "foo", +// CHECK-NEXT: "Range":{"Offset":0,"Length":0}} +// CHECK-NEXT:], +// CHECK-NEXT:"HeaderInfos": [ +// CHECK-NEXT: {"Header": "\"foo.h\"", +// CHECK-NEXT: "QualifiedName": "foo"}, +// CHECK-NEXT: {"Header": "\"bar.h\"", +// CHECK-NEXT: "QualifiedName": "foo"} +// CHECK-NEXT:] Index: include-fixer/tool/ClangIncludeFixer.cpp =================================================================== --- include-fixer/tool/ClangIncludeFixer.cpp +++ include-fixer/tool/ClangIncludeFixer.cpp @@ -98,6 +98,12 @@ cl::desc("String to initialize the database"), cl::cat(IncludeFixerCategory)); +cl::opt<std::string> + QuerySymbol("query-symbol", + cl::desc("Query a given symbol (e.g. \"a::b::foo\") in\n" + "database directly without parsing the file."), + cl::cat(IncludeFixerCategory)); + cl::opt<bool> MinimizeIncludePaths("minimize-paths", cl::desc("Whether to minimize added include paths"), @@ -236,6 +242,7 @@ tooling::ClangTool tool(options.getCompilations(), options.getSourcePathList()); + llvm::StringRef SourceFilePath = options.getSourcePathList().front(); // In STDINMode, we override the file content with the <stdin> input. // Since `tool.mapVirtualFile` takes `StringRef`, we define `Code` outside of // the if-block so that `Code` is not released after the if-block. @@ -253,7 +260,7 @@ if (Code->getBufferSize() == 0) return 0; // Skip empty files. - tool.mapVirtualFile(options.getSourcePathList().front(), Code->getBuffer()); + tool.mapVirtualFile(SourceFilePath, Code->getBuffer()); } if (!InsertHeader.empty()) { @@ -314,10 +321,31 @@ // Set up data source. std::unique_ptr<include_fixer::SymbolIndexManager> SymbolIndexMgr = - createSymbolIndexManager(options.getSourcePathList().front()); + createSymbolIndexManager(SourceFilePath); if (!SymbolIndexMgr) return 1; + // Query symbol mode. + if (!QuerySymbol.empty()) { + auto MatchedSymbols = SymbolIndexMgr->search(QuerySymbol); + for (auto &Symbol : MatchedSymbols) { + std::string HeaderPath = Symbol.getFilePath().str(); + Symbol.SetFilePath(((HeaderPath[0] == '"' || HeaderPath[0] == '<') + ? HeaderPath + : "\"" + HeaderPath + "\"")); + } + + // We leave an empty symbol range as we don't know the range of the symbol + // being queried in this mode. include-fixer won't add namespace qualifiers + // if the symbol range is empty, which also fits this case. + IncludeFixerContext::QuerySymbolInfo Symbol; + Symbol.RawIdentifier = QuerySymbol; + auto Context = + IncludeFixerContext(SourceFilePath, {Symbol}, MatchedSymbols); + writeToJson(llvm::outs(), Context); + return 0; + } + // Now run our tool. std::vector<include_fixer::IncludeFixerContext> Contexts; include_fixer::IncludeFixerActionFactory Factory(*SymbolIndexMgr, Contexts, Index: include-fixer/find-all-symbols/SymbolInfo.h =================================================================== --- include-fixer/find-all-symbols/SymbolInfo.h +++ include-fixer/find-all-symbols/SymbolInfo.h @@ -54,6 +54,8 @@ int LineNumber, const std::vector<Context> &Contexts, unsigned NumOccurrences = 0); + void SetFilePath(llvm::StringRef Path) { FilePath = Path; } + /// \brief Get symbol name. llvm::StringRef getName() const { return Name; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits