hokein created this revision.
hokein added a reviewer: bkramer.
hokein added a subscriber: cfe-commits.
And some improvements:
* Show better error messages on unfound symbols.
* Fix a typo.
http://reviews.llvm.org/D20827
Files:
include-fixer/IncludeFixer.cpp
include-fixer/IncludeFixerContext.h
include-fixer/tool/ClangIncludeFixer.cpp
include-fixer/tool/clang-include-fixer.py
test/include-fixer/commandline_options.cpp
test/include-fixer/ranking.cpp
Index: test/include-fixer/ranking.cpp
===================================================================
--- test/include-fixer/ranking.cpp
+++ test/include-fixer/ranking.cpp
@@ -1,6 +1,5 @@
-// RUN: clang-include-fixer -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s -implicit-check-not=.h
+// RUN: clang-include-fixer -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s
-// CHECK: "../include/bar.h"
-// CHECK-NEXT: "../include/zbar.h"
+// CHECK: Headers: [ '"../include/bar.h"', '"../include/zbar.h"' ]
bar b;
Index: test/include-fixer/commandline_options.cpp
===================================================================
--- test/include-fixer/commandline_options.cpp
+++ test/include-fixer/commandline_options.cpp
@@ -1,7 +1,7 @@
// REQUIRES: shell
// RUN: sed -e 's#//.*$##' %s > %t.cpp
// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h","bar.h"' -output-headers %t.cpp -- | FileCheck %s -check-prefix=CHECK-HEADERS
-// RUN: cat %t.cpp | clang-include-fixer -stdin -insert-header='"foo.h"' %t.cpp | FileCheck %s -check-prefix=CHECK
+// RUN: cat %t.cpp | clang-include-fixer -stdin -insert-header='{SymbolIdentifier: foo, Headers: ["\"foo.h\""]}' %t.cpp | FileCheck %s -check-prefix=CHECK
//
// CHECK-HEADERS: "foo.h"
// CHECK-HEADERS: "bar.h"
Index: include-fixer/tool/clang-include-fixer.py
===================================================================
--- include-fixer/tool/clang-include-fixer.py
+++ include-fixer/tool/clang-include-fixer.py
@@ -19,6 +19,7 @@
import difflib
import subprocess
import vim
+import yaml
# set g:clang_include_fixer_path to the path to clang-include-fixer if it is not
# on the path.
@@ -49,7 +50,7 @@
def InsertHeaderToVimBuffer(header, text):
- command = [binary, "-stdin", "-insert-header="+header,
+ command = [binary, "-stdin", "-insert-header="+yaml.dump(header),
vim.current.buffer.name]
stdout, stderr = execute(command, text)
if stdout:
@@ -77,30 +78,41 @@
command = [binary, "-stdin", "-output-headers", "-db="+args.db,
"-input="+args.input, vim.current.buffer.name]
stdout, stderr = execute(command, text)
+ include_fixer_context = yaml.load(stdout)
+
lines = stdout.splitlines()
- if len(lines) < 2:
- print "No header is included.\n"
+
+ symbol = include_fixer_context["SymbolIdentifier"]
+ headers = include_fixer_context["Headers"]
+
+ if not symbol:
+ print "The file is fine, no need to add a header.\n"
+ return;
+
+ if not headers:
+ print "Couldn't find a header for {0}.\n".format(symbol)
return
# The first line is the symbol name.
- symbol = lines[0]
# If there is only one suggested header, insert it directly.
- if len(lines) == 2 or maximum_suggested_headers == 1:
- InsertHeaderToVimBuffer(lines[1], text)
- print "Added #include {0} for {1}.\n".format(lines[1], symbol)
+ if len(headers) == 1 or maximum_suggested_headers == 1:
+ InsertHeaderToVimBuffer({"SymbolIdentifier": symbol,
+ "Headers":[headers[0]]}, text)
+ print "Added #include {0} for {1}.\n".format(header[0], symbol)
return
choices_message = ""
index = 1;
- for header in lines[1:1+maximum_suggested_headers]:
+ for header in headers[0:maximum_suggested_headers]:
choices_message += "&{0} {1}\n".format(index, header)
index += 1
select = ShowDialog("choose a header file for {0}.".format(symbol),
choices_message)
# Insert a selected header.
- InsertHeaderToVimBuffer(lines[select], text)
- print "Added #include {0} for {1}.\n".format(lines[select], symbol)
+ InsertHeaderToVimBuffer({"SymbolIdentifier": symbol,
+ "Headers":[headers[select-1]]}, text)
+ print "Added #include {0} for {1}.\n".format(headers[select-1], symbol)
return;
Index: include-fixer/tool/ClangIncludeFixer.cpp
===================================================================
--- include-fixer/tool/ClangIncludeFixer.cpp
+++ include-fixer/tool/ClangIncludeFixer.cpp
@@ -18,9 +18,25 @@
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/YAMLTraits.h"
using namespace clang;
using namespace llvm;
+using clang::include_fixer::IncludeFixerContext;
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(IncludeFixerContext)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<IncludeFixerContext> {
+ static void mapping(IO &io, IncludeFixerContext &Context) {
+ io.mapRequired("SymbolIdentifier", Context.SymbolIdentifier);
+ io.mapRequired("Headers", Context.Headers);
+ }
+};
+} // namespace yaml
+} // namespace llvm
namespace {
cl::OptionCategory IncludeFixerCategory("Tool options");
@@ -60,19 +76,21 @@
cl::opt<bool> OutputHeaders(
"output-headers",
- cl::desc("Output the symbol being quired and all its relevant headers.\n"
- "The first line is the symbol name; The other lines\n"
- "are the headers: \n"
- " b::foo\n"
- " path/to/foo_a.h\n"
- " path/to/foo_b.h\n"),
+ cl::desc("Print the symbol being queried and all its relevant headers in\n"
+ "the YAML format to stdout:\n"
+ " ---\n"
+ " SymbolIdentifier: foo\n"
+ " Headers: ['\"foo_a.h\"', '\"foo_b.h\"']\n"
+ " ...\n"),
cl::init(false), cl::cat(IncludeFixerCategory));
cl::opt<std::string> InsertHeader(
"insert-header",
cl::desc("Insert a specific header. This should run with STDIN mode.\n"
"The result is written to stdout. It is currently used for\n"
- "editor integration."),
+ "editor integration. Support YAML/JSON format:\n"
+ " -insert-header=\"{SymbolIdentifier: foo\n"
+ " Headers: ['\"foo_a.h\"']}\""),
cl::init(""), cl::cat(IncludeFixerCategory));
cl::opt<std::string>
@@ -168,9 +186,18 @@
return 1;
}
+ llvm::yaml::Input yin(InsertHeader);
+ IncludeFixerContext Context;
+ yin >> Context;
+
+ if (Context.Headers.empty()) {
+ errs() << "Expect exact one inserted header.\n";
+ return 1;
+ }
+
tooling::Replacements Replacements =
clang::include_fixer::createInsertHeaderReplacements(
- Code->getBuffer(), FilePath, InsertHeader, InsertStyle);
+ Code->getBuffer(), FilePath, Context.Headers[0], InsertStyle);
tooling::Replacements Replaces(Replacements.begin(), Replacements.end());
std::string ChangedCode =
tooling::applyAllReplacements(Code->getBuffer(), Replaces);
@@ -196,10 +223,8 @@
}
if (OutputHeaders) {
- // FIXME: Output IncludeFixerContext as YAML.
- llvm::outs() << Context.SymbolIdentifer << "\n";
- for (const auto &Header : Context.Headers)
- llvm::outs() << Header << "\n";
+ llvm::yaml::Output yout(llvm::outs());
+ yout << Context;
return 0;
}
Index: include-fixer/IncludeFixerContext.h
===================================================================
--- include-fixer/IncludeFixerContext.h
+++ include-fixer/IncludeFixerContext.h
@@ -19,7 +19,7 @@
/// \brief A context for the symbol being queried.
struct IncludeFixerContext {
/// \brief The symbol name.
- std::string SymbolIdentifer;
+ std::string SymbolIdentifier;
/// \brief The headers which have SymbolIdentifier definitions.
std::vector<std::string> Headers;
};
Index: include-fixer/IncludeFixer.cpp
===================================================================
--- include-fixer/IncludeFixer.cpp
+++ include-fixer/IncludeFixer.cpp
@@ -193,10 +193,7 @@
getIncludeFixerContext(const clang::SourceManager &SourceManager,
clang::HeaderSearch &HeaderSearch) {
IncludeFixerContext FixerContext;
- if (SymbolQueryResults.empty())
- return FixerContext;
-
- FixerContext.SymbolIdentifer = QuerySymbol;
+ FixerContext.SymbolIdentifier = QuerySymbol;
for (const auto &Header : SymbolQueryResults)
FixerContext.Headers.push_back(
minimizeInclude(Header, SourceManager, HeaderSearch));
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits