njames93 updated this revision to Diff 310894.
njames93 added a comment.
Herald added a subscriber: mgorny.

Added test cases.
Added assert to ensure Handler is valid.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92920/new/

https://reviews.llvm.org/D92920

Files:
  clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
  clang-tools-extra/clang-tidy/ClangTidyOptions.h
  clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
  clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
===================================================================
--- clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
@@ -2,6 +2,9 @@
 #include "ClangTidyCheck.h"
 #include "ClangTidyDiagnosticConsumer.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Testing/Support/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 namespace clang {
@@ -122,6 +125,65 @@
   ASSERT_TRUE(Options.UseColor.hasValue());
   EXPECT_TRUE(*Options.UseColor);
 }
+namespace {
+
+struct Diag {
+  Diag(const llvm::SMDiagnostic &D)
+      : Message(D.getMessage()), Kind(D.getKind()) {
+    Pos = D.getLoc().getPointer() -
+          D.getSourceMgr()
+              ->getMemoryBuffer(
+                  D.getSourceMgr()->FindBufferContainingLoc(D.getLoc()))
+              ->getBufferStart();
+  }
+  std::string Message;
+  llvm::SourceMgr::DiagKind Kind;
+  size_t Pos;
+
+  friend void PrintTo(const Diag &D, std::ostream *OS) {
+    *OS << (D.Kind == llvm::SourceMgr::DK_Error ? "error: " : "warning: ")
+        << D.Message << "@" << llvm::to_string(D.Pos);
+  }
+};
+
+MATCHER_P(DiagMessage, M, "") { return arg.Message == M; }
+MATCHER_P(DiagKind, K, "") { return arg.Kind == K; }
+MATCHER_P(DiagPos, P, "") { return arg.Pos == P; }
+} // namespace
+
+using ::testing::AllOf;
+using ::testing::ElementsAre;
+
+TEST(ParseConfiguration, CollectDiags) {
+  std::vector<Diag> Diags;
+  auto ParseWithDiags = [&](llvm::StringRef Buffer) {
+    Diags.clear();
+    return parseConfigurationWithDiags(
+        llvm::MemoryBufferRef(Buffer, "Options"),
+        [&](const llvm::SMDiagnostic &D) { Diags.push_back(D); });
+  };
+  // For some reason the YAML parser records an unknown key error at the value,
+  // not the key.
+  llvm::Annotations Options(R"(
+    Check: ^llvm-include-order
+  )");
+  llvm::ErrorOr<ClangTidyOptions> ParsedOpt = ParseWithDiags(Options.code());
+  EXPECT_TRUE(!ParsedOpt);
+  EXPECT_THAT(Diags,
+              testing::ElementsAre(AllOf(DiagMessage("unknown key 'Check'"),
+                                         DiagKind(llvm::SourceMgr::DK_Error),
+                                         DiagPos(Options.point()))));
+
+  Options = llvm::Annotations(R"(
+    UseColor: ^NotABool
+  )");
+  ParsedOpt = ParseWithDiags(Options.code());
+  EXPECT_TRUE(!ParsedOpt);
+  EXPECT_THAT(Diags,
+              testing::ElementsAre(AllOf(DiagMessage("invalid boolean"),
+                                         DiagKind(llvm::SourceMgr::DK_Error),
+                                         DiagPos(Options.point()))));
+}
 
 namespace {
 class TestCheck : public ClangTidyCheck {
Index: clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
===================================================================
--- clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
+++ clang-tools-extra/unittests/clang-tidy/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   FrontendOpenMP
   Support
+  TestingSupport
   )
 
 get_filename_component(CLANG_LINT_SOURCE_DIR
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include <functional>
 #include <string>
@@ -311,6 +312,11 @@
 llvm::ErrorOr<ClangTidyOptions>
 parseConfiguration(llvm::MemoryBufferRef Config);
 
+using DiagCallback = llvm::function_ref<void(const llvm::SMDiagnostic &)>;
+
+llvm::ErrorOr<ClangTidyOptions>
+parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler);
+
 /// Serializes configuration to a YAML-encoded string.
 std::string configurationAsText(const ClangTidyOptions &Options);
 
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -13,6 +13,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/YAMLTraits.h"
 #include "llvm/Support/raw_ostream.h"
@@ -390,6 +391,22 @@
   return Options;
 }
 
+static void diagHandlerImpl(const llvm::SMDiagnostic &Diag, void *Ctx) {
+  (*reinterpret_cast<DiagCallback *>(Ctx))(Diag);
+};
+
+llvm::ErrorOr<ClangTidyOptions>
+parseConfigurationWithDiags(llvm::MemoryBufferRef Config,
+                            DiagCallback Handler) {
+  assert(Handler && "Handler must be valid");
+  llvm::yaml::Input Input(Config, nullptr, diagHandlerImpl, &Handler);
+  ClangTidyOptions Options;
+  Input >> Options;
+  if (Input.error())
+    return Input.error();
+  return Options;
+}
+
 std::string configurationAsText(const ClangTidyOptions &Options) {
   std::string Text;
   llvm::raw_string_ostream Stream(Text);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to