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"
22 // Provides a DiagnosticsCallback that records diganostics.
23 // Unlike just pushing them into a vector, underlying storage need not survive.
24 struct CapturedDiags
{
25 std::function
<void(const llvm::SMDiagnostic
&)> callback() {
26 return [this](const llvm::SMDiagnostic
&D
) {
27 if (Files
.empty() || Files
.back() != D
.getFilename())
28 Files
.push_back(D
.getFilename().str());
30 if (D
.getKind() > llvm::SourceMgr::DK_Warning
)
33 Diagnostics
.emplace_back();
34 Diag
&Out
= Diagnostics
.back();
35 Out
.Message
= D
.getMessage().str();
36 Out
.Kind
= D
.getKind();
37 Out
.Pos
.line
= D
.getLineNo() - 1;
38 Out
.Pos
.character
= D
.getColumnNo(); // Zero-based - bug in SourceMgr?
39 if (!D
.getRanges().empty()) {
40 const auto &R
= D
.getRanges().front();
42 Out
.Rng
->start
.line
= Out
.Rng
->end
.line
= Out
.Pos
.line
;
43 Out
.Rng
->start
.character
= R
.first
;
44 Out
.Rng
->end
.character
= R
.second
;
50 llvm::SourceMgr::DiagKind Kind
;
52 llvm::Optional
<Range
> Rng
;
54 friend void PrintTo(const Diag
&D
, std::ostream
*OS
) {
55 *OS
<< (D
.Kind
== llvm::SourceMgr::DK_Error
? "error: " : "warning: ")
56 << D
.Message
<< "@" << llvm::to_string(D
.Pos
);
59 std::vector
<Diag
> Diagnostics
; // Warning or higher.
60 std::vector
<std::string
> Files
; // Filename from diagnostics including notes.
68 MATCHER_P(diagMessage
, M
, "") { return arg
.Message
== M
; }
69 MATCHER_P(diagKind
, K
, "") { return arg
.Kind
== K
; }
70 MATCHER_P(diagPos
, P
, "") { return arg
.Pos
== P
; }
71 MATCHER_P(diagRange
, R
, "") { return arg
.Rng
== R
; }
73 inline Position
toPosition(llvm::SMLoc L
, const llvm::SourceMgr
&SM
) {
74 auto LineCol
= SM
.getLineAndColumn(L
);
76 P
.line
= LineCol
.first
- 1;
77 P
.character
= LineCol
.second
- 1;
81 inline Range
toRange(llvm::SMRange R
, const llvm::SourceMgr
&SM
) {
82 return Range
{toPosition(R
.Start
, SM
), toPosition(R
.End
, SM
)};