[clang-tools-extra] r280824 - [include-fixer] Support finding headers for the symbol under cursor.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 7 09:34:36 PDT 2016
Author: hokein
Date: Wed Sep 7 11:34:35 2016
New Revision: 280824
URL: http://llvm.org/viewvc/llvm-project?rev=280824&view=rev
Log:
[include-fixer] Support finding headers for the symbol under cursor.
Summary:
* Add a `query-symbol` option to query symbol without parsing the source file.
* Update Vim & Emacs integration scripts.
Reviewers: bkramer, massberg
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D24075
Added:
clang-tools-extra/trunk/test/include-fixer/query_symbol.cpp
Modified:
clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.el
clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h?rev=280824&r1=280823&r2=280824&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h Wed Sep 7 11:34:35 2016
@@ -54,6 +54,8 @@ public:
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; }
Modified: clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp?rev=280824&r1=280823&r2=280824&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp Wed Sep 7 11:34:35 2016
@@ -98,6 +98,12 @@ cl::opt<std::string> Input("input",
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 @@ int includeFixerMain(int argc, const cha
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 @@ int includeFixerMain(int argc, const cha
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 @@ int includeFixerMain(int argc, const cha
// 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,
Modified: clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.el
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.el?rev=280824&r1=280823&r2=280824&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.el (original)
+++ clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.el Wed Sep 7 11:34:35 2016
@@ -36,11 +36,17 @@
(defcustom clang-include-fixer-init-string
""
- "clang-include-fixer input format."
+ "clang-include-fixer init string."
:group 'clang-include-fixer
:type 'string
:risky t)
+(defcustom clang-include-fixer-query-mode
+ nil
+ "clang-include-fixer query mode."
+ :group 'clang-include-fixer
+ :type 'boolean
+ :risky t)
(defun clang-include-fixer-call-executable (callee
include-fixer-parameter-a
@@ -197,11 +203,28 @@
(message (concat "Calling the include fixer. "
"This might take some seconds. Please wait."))
- (clang-include-fixer-call-executable
- 'clang-include-fixer-add-header
- (concat "-db=" clang-include-fixer-input-format)
- (concat "-input=" clang-include-fixer-init-string)
- "-output-headers"))
+ (if clang-include-fixer-query-mode
+ (let (p1 p2)
+ (save-excursion
+ (skip-chars-backward "-a-zA-Z0-9_:")
+ (setq p1 (point))
+ (skip-chars-forward "-a-zA-Z0-9_:")
+ (setq p2 (point))
+ (setq query-symbol (buffer-substring-no-properties p1 p2))
+ (if (string= "" query-symbol)
+ (message "Skip querying empty symbol.")
+ (clang-include-fixer-call-executable
+ 'clang-include-fixer-add-header
+ (concat "-db=" clang-include-fixer-input-format)
+ (concat "-input=" clang-include-fixer-init-string)
+ (concat "-query-symbol=" (thing-at-point 'symbol))
+ ))))
+ (clang-include-fixer-call-executable
+ 'clang-include-fixer-add-header
+ (concat "-db=" clang-include-fixer-input-format)
+ (concat "-input=" clang-include-fixer-init-string)
+ "-output-headers"))
+ )
(provide 'clang-include-fixer)
;;; clang-include-fixer.el ends here
Modified: clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py?rev=280824&r1=280823&r2=280824&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py (original)
+++ clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py Wed Sep 7 11:34:35 2016
@@ -17,9 +17,10 @@
import argparse
import difflib
+import json
+import re
import subprocess
import vim
-import json
# set g:clang_include_fixer_path to the path to clang-include-fixer if it is not
# on the path.
@@ -44,6 +45,10 @@ jump_to_include = False
if vim.eval('exists("g:clang_include_fixer_jump_to_include")') == "1":
jump_to_include = vim.eval('g:clang_include_fixer_jump_to_include') != "0"
+query_mode = True
+if vim.eval('exists("g:clang_include_fixer_query_mode")') == "1":
+ query_mode = vim.eval('g:clang_include_fixer_query_mode') != "0"
+
def GetUserSelection(message, headers, maximum_suggested_headers):
eval_message = message + '\n'
@@ -105,6 +110,25 @@ def InsertHeaderToVimBuffer(header, text
vim.current.window.cursor = (line_num, 0)
+# The vim internal implementation (expand("cword"/"cWORD")) doesn't support
+# our use case very well, we re-implement our own one.
+def get_symbol_under_cursor():
+ line = vim.eval("line(\".\")")
+ # column number in vim is 1-based.
+ col = int(vim.eval("col(\".\")")) - 1
+ line_text = vim.eval("getline({0})".format(line))
+ if len(line_text) == 0: return ""
+ symbol_pos_begin = col
+ p = re.compile('[a-zA-Z0-9:_]')
+ while symbol_pos_begin >= 0 and p.match(line_text[symbol_pos_begin]):
+ symbol_pos_begin -= 1
+
+ symbol_pos_end = col
+ while symbol_pos_end < len(line_text) and p.match(line_text[symbol_pos_end]):
+ symbol_pos_end += 1
+ return line_text[symbol_pos_begin+1:symbol_pos_end]
+
+
def main():
parser = argparse.ArgumentParser(
description='Vim integration for clang-include-fixer')
@@ -118,9 +142,18 @@ def main():
buf = vim.current.buffer
text = '\n'.join(buf)
- # Run command to get all headers.
- command = [binary, "-stdin", "-output-headers", "-db=" + args.db,
- "-input=" + args.input, vim.current.buffer.name]
+ if query_mode:
+ symbol = get_symbol_under_cursor()
+ if len(symbol) == 0:
+ print "Skip querying empty symbol."
+ return
+ command = [binary, "-stdin", "-query-symbol="+get_symbol_under_cursor(),
+ "-db=" + args.db, "-input=" + args.input,
+ vim.current.buffer.name]
+ else:
+ # Run command to get all headers.
+ command = [binary, "-stdin", "-output-headers", "-db=" + args.db,
+ "-input=" + args.input, vim.current.buffer.name]
stdout, stderr = execute(command, text)
if stderr:
print >> sys.stderr, "Error while running clang-include-fixer: " + stderr
Added: clang-tools-extra/trunk/test/include-fixer/query_symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/query_symbol.cpp?rev=280824&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/query_symbol.cpp (added)
+++ clang-tools-extra/trunk/test/include-fixer/query_symbol.cpp Wed Sep 7 11:34:35 2016
@@ -0,0 +1,13 @@
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -query-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:]
More information about the cfe-commits
mailing list