Bump version to 19.1.0 (final)
[llvm-project.git] / clang-tools-extra / pseudo / unittests / BracketTest.cpp
blob2fbfc6415136489ee49d884de16adeb47eed60ec
1 //===--- BracketTest.cpp -------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "clang-pseudo/Bracket.h"
10 #include "clang-pseudo/Token.h"
11 #include "clang/Basic/LangOptions.h"
12 #include "llvm/Testing/Annotations/Annotations.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
16 namespace clang {
17 namespace pseudo {
19 // Return a version of Code with each paired bracket marked with ^.
20 std::string decorate(llvm::StringRef Code, const TokenStream &Stream) {
21 std::string Result;
22 const char *Pos = Code.data();
23 for (const Token &Tok : Stream.tokens()) {
24 if (Tok.Pair == 0)
25 continue;
26 const char *NewPos = Tok.text().begin();
27 assert(NewPos >= Code.begin() && NewPos < Code.end());
28 Result.append(Pos, NewPos - Pos);
29 Result.push_back('^');
30 Pos = NewPos;
32 Result.append(Pos, Code.end() - Pos);
33 return Result;
36 // Checks that the brackets matched in Stream are those annotated in MarkedCode.
37 void verifyMatchedSet(llvm::StringRef Code, llvm::StringRef MarkedCode,
38 const TokenStream &Stream) {
39 EXPECT_EQ(MarkedCode, decorate(Code, Stream));
42 // Checks that paired brackets within the stream nest properly.
43 void verifyNesting(const TokenStream &Stream) {
44 std::vector<const Token *> Stack;
45 for (const auto &Tok : Stream.tokens()) {
46 if (Tok.Pair > 0)
47 Stack.push_back(&Tok);
48 else if (Tok.Pair < 0) {
49 ASSERT_FALSE(Stack.empty()) << Tok;
50 ASSERT_EQ(Stack.back(), Tok.pair())
51 << *Stack.back() << " != " << *Tok.pair() << " = pair of " << Tok;
52 Stack.pop_back();
55 ASSERT_THAT(Stack, testing::IsEmpty());
58 // Checks that ( pairs with a ) on its right, etc.
59 void verifyMatchKind(const TokenStream &Stream) {
60 for (const auto &Tok : Stream.tokens()) {
61 if (Tok.Pair == 0)
62 continue;
63 auto Want = [&]() -> std::pair<bool, tok::TokenKind> {
64 switch (Tok.Kind) {
65 case tok::l_paren:
66 return {true, tok::r_paren};
67 case tok::r_paren:
68 return {false, tok::l_paren};
69 case tok::l_brace:
70 return {true, tok::r_brace};
71 case tok::r_brace:
72 return {false, tok::l_brace};
73 case tok::l_square:
74 return {true, tok::r_square};
75 case tok::r_square:
76 return {false, tok::l_square};
77 default:
78 ADD_FAILURE() << "Paired non-bracket " << Tok;
79 return {false, tok::eof};
81 }();
82 EXPECT_EQ(Tok.Pair > 0, Want.first) << Tok;
83 EXPECT_EQ(Tok.pair()->Kind, Want.second) << Tok;
87 // Verifies an expected bracket pairing like:
88 // ^( [ ^)
89 // The input is annotated code, with the brackets expected to be matched marked.
91 // The input doesn't specify which bracket matches with which, but we verify:
92 // - exactly the marked subset are paired
93 // - ( is paired to a later ), etc
94 // - brackets properly nest
95 // This uniquely determines the bracket structure, so we indirectly verify it.
96 // If particular tests should emphasize which brackets are paired, use comments.
97 void verifyBrackets(llvm::StringRef MarkedCode) {
98 SCOPED_TRACE(MarkedCode);
99 llvm::Annotations A(MarkedCode);
100 std::string Code = A.code().str();
101 LangOptions LangOpts;
102 auto Stream = lex(Code, LangOpts);
103 pairBrackets(Stream);
105 verifyMatchedSet(Code, MarkedCode, Stream);
106 verifyNesting(Stream);
107 verifyMatchKind(Stream);
110 TEST(Bracket, SimplePair) {
111 verifyBrackets("^{ ^[ ^( ^) ^( ^) ^] ^}");
112 verifyBrackets(") ^{ ^[ ^] ^} (");
113 verifyBrackets("{ [ ( ] }"); // FIXME
116 } // namespace pseudo
117 } // namespace clang