1 //===-- ConfigTesting.h - Helpers for configuration tests -------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H
13 #include "llvm/Support/ScopedPrinter.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "gmock/gmock.h"
23 // Provides a DiagnosticsCallback that records diganostics.
24 // Unlike just pushing them into a vector, underlying storage need not survive.
25 struct CapturedDiags
{
26 std::function
<void(const llvm::SMDiagnostic
&)> callback() {
27 return [this](const llvm::SMDiagnostic
&D
) {
28 if (Files
.empty() || Files
.back() != D
.getFilename())
29 Files
.push_back(D
.getFilename().str());
31 if (D
.getKind() > llvm::SourceMgr::DK_Warning
)
34 Diagnostics
.emplace_back();
35 Diag
&Out
= Diagnostics
.back();
36 Out
.Message
= D
.getMessage().str();
37 Out
.Kind
= D
.getKind();
38 Out
.Pos
.line
= D
.getLineNo() - 1;
39 Out
.Pos
.character
= D
.getColumnNo(); // Zero-based - bug in SourceMgr?
40 if (!D
.getRanges().empty()) {
41 const auto &R
= D
.getRanges().front();
43 Out
.Rng
->start
.line
= Out
.Rng
->end
.line
= Out
.Pos
.line
;
44 Out
.Rng
->start
.character
= R
.first
;
45 Out
.Rng
->end
.character
= R
.second
;
51 llvm::SourceMgr::DiagKind Kind
;
53 std::optional
<Range
> Rng
;
55 friend void PrintTo(const Diag
&D
, std::ostream
*OS
) {
56 *OS
<< (D
.Kind
== llvm::SourceMgr::DK_Error
? "error: " : "warning: ")
57 << D
.Message
<< "@" << llvm::to_string(D
.Pos
);
60 std::vector
<Diag
> Diagnostics
; // Warning or higher.
61 std::vector
<std::string
> Files
; // Filename from diagnostics including notes.
69 MATCHER_P(diagMessage
, M
, "") { return arg
.Message
== M
; }
70 MATCHER_P(diagKind
, K
, "") { return arg
.Kind
== K
; }
71 MATCHER_P(diagPos
, P
, "") { return arg
.Pos
== P
; }
72 MATCHER_P(diagRange
, R
, "") { return arg
.Rng
== R
; }
74 inline Position
toPosition(llvm::SMLoc L
, const llvm::SourceMgr
&SM
) {
75 auto LineCol
= SM
.getLineAndColumn(L
);
77 P
.line
= LineCol
.first
- 1;
78 P
.character
= LineCol
.second
- 1;
82 inline Range
toRange(llvm::SMRange R
, const llvm::SourceMgr
&SM
) {
83 return Range
{toPosition(R
.Start
, SM
), toPosition(R
.End
, SM
)};