llvm-project

Форк
0
117 строк · 3.7 Кб
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
//===----------------------------------------------------------------------===//
8

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"
15

16
namespace clang {
17
namespace pseudo {
18

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;
31
  }
32
  Result.append(Pos, Code.end() - Pos);
33
  return Result;
34
}
35

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));
40
}
41

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();
53
    }
54
  }
55
  ASSERT_THAT(Stack, testing::IsEmpty());
56
}
57

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};
80
      }
81
    }();
82
    EXPECT_EQ(Tok.Pair > 0, Want.first) << Tok;
83
    EXPECT_EQ(Tok.pair()->Kind, Want.second) << Tok;
84
  }
85
}
86

87
// Verifies an expected bracket pairing like:
88
//   ^( [ ^)
89
// The input is annotated code, with the brackets expected to be matched marked.
90
//
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);
104

105
  verifyMatchedSet(Code, MarkedCode, Stream);
106
  verifyNesting(Stream);
107
  verifyMatchKind(Stream);
108
}
109

110
TEST(Bracket, SimplePair) {
111
  verifyBrackets("^{ ^[ ^( ^)  ^( ^) ^] ^}");
112
  verifyBrackets(") ^{ ^[ ^] ^} (");
113
  verifyBrackets("{ [ ( ] }"); // FIXME
114
}
115

116
} // namespace pseudo
117
} // namespace clang
118

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.