[clang-tools-extra] r271382 - [include-fixer] Use YAML format in -output-headers and -insert-header mode.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 1 04:43:19 PDT 2016


Author: hokein
Date: Wed Jun  1 06:43:10 2016
New Revision: 271382

URL: http://llvm.org/viewvc/llvm-project?rev=271382&view=rev
Log:
[include-fixer] Use YAML format in -output-headers and -insert-header mode.

Summary:
And some improvements:
* Show better error messages on unfound symbols.
* Fix a typo.

Reviewers: bkramer

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D20827

Modified:
    clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
    clang-tools-extra/trunk/include-fixer/IncludeFixerContext.h
    clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
    clang-tools-extra/trunk/include-fixer/tool/clang-include-fixer.py
    clang-tools-extra/trunk/test/include-fixer/commandline_options.cpp
    clang-tools-extra/trunk/test/include-fixer/ranking.cpp

Modified: clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp?rev=271382&r1=271381&r2=271382&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp Wed Jun  1 06:43:10 2016
@@ -193,10 +193,7 @@ public:
   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));

Modified: clang-tools-extra/trunk/include-fixer/IncludeFixerContext.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/IncludeFixerContext.h?rev=271382&r1=271381&r2=271382&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixerContext.h (original)
+++ clang-tools-extra/trunk/include-fixer/IncludeFixerContext.h Wed Jun  1 06:43:10 2016
@@ -19,7 +19,7 @@ namespace include_fixer {
 /// \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;
 };

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=271382&r1=271381&r2=271382&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp Wed Jun  1 06:43:10 2016
@@ -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>
 
 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"
+             "JSON format to stdout:\n"
+             "  {\n"
+             "    \"SymbolIdentifier\": \"foo\",\n"
+             "    \"Headers\": [\"\\\"foo_a.h\\\"\"]\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>
@@ -134,6 +152,19 @@ createSymbolIndexManager(StringRef FileP
   return SymbolIndexMgr;
 }
 
+void writeToJson(llvm::raw_ostream &OS, const IncludeFixerContext& Context) {
+  OS << "{\n"
+        "  \"SymbolIdentifier\": \"" << Context.SymbolIdentifier << "\",\n"
+        "  \"Headers\": [ ";
+  for (const auto &Header : Context.Headers) {
+    OS << " \"" << llvm::yaml::escape(Header) << "\"";
+    if (Header != Context.Headers.back())
+      OS << ", ";
+  }
+  OS << " ]\n"
+        "}\n";
+}
+
 int includeFixerMain(int argc, const char **argv) {
   tooling::CommonOptionsParser options(argc, argv, IncludeFixerCategory);
   tooling::ClangTool tool(options.getCompilations(),
@@ -168,9 +199,18 @@ int includeFixerMain(int argc, const cha
       return 1;
     }
 
+    llvm::yaml::Input yin(InsertHeader);
+    IncludeFixerContext Context;
+    yin >> Context;
+
+    if (Context.Headers.size() != 1) {
+      errs() << "Expect exactly 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 +236,7 @@ int includeFixerMain(int argc, const cha
   }
 
   if (OutputHeaders) {
-    // FIXME: Output IncludeFixerContext as YAML.
-    llvm::outs() << Context.SymbolIdentifer << "\n";
-    for (const auto &Header : Context.Headers)
-      llvm::outs() << Header << "\n";
+    writeToJson(llvm::outs(), Context);
     return 0;
   }
 

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=271382&r1=271381&r2=271382&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 Jun  1 06:43:10 2016
@@ -19,6 +19,7 @@ import argparse
 import difflib
 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.
@@ -49,7 +50,7 @@ def execute(command, text):
 
 
 def InsertHeaderToVimBuffer(header, text):
-  command = [binary, "-stdin", "-insert-header="+header,
+  command = [binary, "-stdin", "-insert-header="+json.dumps(header),
              vim.current.buffer.name]
   stdout, stderr = execute(command, text)
   if stdout:
@@ -77,30 +78,42 @@ def main():
   command = [binary, "-stdin", "-output-headers", "-db="+args.db,
              "-input="+args.input, vim.current.buffer.name]
   stdout, stderr = execute(command, text)
-  lines = stdout.splitlines()
-  if len(lines) < 2:
-    print "No header is included.\n"
+  if stderr:
+    print >> sys.stderr, "Error while running clang-include-fixer: " + stderr
+    return
+
+  include_fixer_context = json.loads(stdout)
+  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(headers[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;
 
 

Modified: clang-tools-extra/trunk/test/include-fixer/commandline_options.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/commandline_options.cpp?rev=271382&r1=271381&r2=271382&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/commandline_options.cpp (original)
+++ clang-tools-extra/trunk/test/include-fixer/commandline_options.cpp Wed Jun  1 06:43:10 2016
@@ -1,10 +1,9 @@
 // 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"
+// CHECK-HEADERS: "Headers": [ "\"foo.h\"", "\"bar.h\"" ]
 //
 // CHECK: #include "foo.h"
 // CHECK: foo f;

Modified: clang-tools-extra/trunk/test/include-fixer/ranking.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/ranking.cpp?rev=271382&r1=271381&r2=271382&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/ranking.cpp (original)
+++ clang-tools-extra/trunk/test/include-fixer/ranking.cpp Wed Jun  1 06:43:10 2016
@@ -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;




More information about the cfe-commits mailing list