ConfigTesting.h
2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//===-- ConfigTesting.h - Helpers for configuration tests -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H
#include "Protocol.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock.h"
#include <functional>
namespace clang {
namespace clangd {
namespace config {
// Provides a DiagnosticsCallback that records diganostics.
// Unlike just pushing them into a vector, underlying storage need not survive.
struct CapturedDiags {
std::function<void(const llvm::SMDiagnostic &)> callback() {
return [this](const llvm::SMDiagnostic &D) {
Diagnostics.emplace_back();
Diag &Out = Diagnostics.back();
Out.Message = D.getMessage().str();
Out.Kind = D.getKind();
Out.Pos.line = D.getLineNo() - 1;
Out.Pos.character = D.getColumnNo(); // Zero-based - bug in SourceMgr?
if (!D.getRanges().empty()) {
const auto &R = D.getRanges().front();
Out.Rng.emplace();
Out.Rng->start.line = Out.Rng->end.line = Out.Pos.line;
Out.Rng->start.character = R.first;
Out.Rng->end.character = R.second;
}
};
}
struct Diag {
std::string Message;
llvm::SourceMgr::DiagKind Kind;
Position Pos;
llvm::Optional<Range> Rng;
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);
}
};
std::vector<Diag> Diagnostics;
};
MATCHER_P(DiagMessage, M, "") { return arg.Message == M; }
MATCHER_P(DiagKind, K, "") { return arg.Kind == K; }
MATCHER_P(DiagPos, P, "") { return arg.Pos == P; }
MATCHER_P(DiagRange, R, "") { return arg.Rng == R; }
inline Position toPosition(llvm::SMLoc L, const llvm::SourceMgr &SM) {
auto LineCol = SM.getLineAndColumn(L);
Position P;
P.line = LineCol.first - 1;
P.character = LineCol.second - 1;
return P;
}
inline Range toRange(llvm::SMRange R, const llvm::SourceMgr &SM) {
return Range{toPosition(R.Start, SM), toPosition(R.End, SM)};
}
} // namespace config
} // namespace clangd
} // namespace clang
#endif