mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Most of these were fixed automatically (including things like adding `[[nodiscard]]` and such). A number of others required manual edits. I think all of them were pretty nice improvements. There were a few places where the issues really stem from external constraints and I've disabled the checks: GoogleTest macros or the specific LibFuzzer entry points. The only other places I disabled are the implicit conversions to a private `enum` in the classes wrapping those `enum`s. These implicit conversions are necessarily implicit to serve their only purpose: enabling their use in `switch` statements and `case` labels. When these were highlighted, it showed that one of these was actually converting to an *`int`*. I've switched that to use the private `enum` instead as doing so is important to enable warnings on non-covering `switch` statements over than `enum`. And indeed, there is a `switch` that was was implicitly relying on falling through in this way, so I've added the explicit documentation of the intentional pattern to address that warning. Sorry this is so large, all of this somewhat fell out of enabling the `clang-tidy` checks. If it is too difficult to review as lump, I can work on breaking it apart as needed. Just let me know.
94 lines
4.8 KiB
C++
94 lines
4.8 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "lexer/token_kind.h"
|
|
|
|
#include <cstring>
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
namespace Carbon {
|
|
namespace {
|
|
|
|
using ::testing::MatchesRegex;
|
|
|
|
// We restrict symbols to punctuation characters that are expected to be widely
|
|
// available on modern keyboards used for programming.
|
|
constexpr llvm::StringLiteral SymbolRegex = "[][{}!@#%^&*()/?\\|;:.,<>=+~-]+";
|
|
|
|
// We restrict keywords to be lowercase ASCII letters and underscores.
|
|
constexpr llvm::StringLiteral KeywordRegex = "[a-z_]+";
|
|
|
|
#define CARBON_TOKEN(TokenName) \
|
|
TEST(TokenKindTest, TokenName) { \
|
|
EXPECT_EQ(#TokenName, TokenKind::TokenName().Name()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsKeyword()); \
|
|
EXPECT_EQ("", TokenKind::TokenName().GetFixedSpelling()); \
|
|
}
|
|
#define CARBON_SYMBOL_TOKEN(TokenName, Spelling) \
|
|
TEST(TokenKindTest, TokenName) { \
|
|
EXPECT_EQ(#TokenName, TokenKind::TokenName().Name()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsGroupingSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsOpeningSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsClosingSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsKeyword()); \
|
|
EXPECT_EQ(Spelling, TokenKind::TokenName().GetFixedSpelling()); \
|
|
EXPECT_THAT(Spelling, MatchesRegex(SymbolRegex.str())); \
|
|
}
|
|
#define CARBON_OPENING_GROUP_SYMBOL_TOKEN(TokenName, Spelling, ClosingName) \
|
|
TEST(TokenKindTest, TokenName) { \
|
|
EXPECT_EQ(#TokenName, TokenKind::TokenName().Name()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsSymbol()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsGroupingSymbol()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsOpeningSymbol()); \
|
|
EXPECT_EQ(TokenKind::ClosingName(), \
|
|
TokenKind::TokenName().GetClosingSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsClosingSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsKeyword()); \
|
|
EXPECT_EQ(Spelling, TokenKind::TokenName().GetFixedSpelling()); \
|
|
EXPECT_THAT(Spelling, MatchesRegex(SymbolRegex.str())); \
|
|
}
|
|
#define CARBON_CLOSING_GROUP_SYMBOL_TOKEN(TokenName, Spelling, OpeningName) \
|
|
TEST(TokenKindTest, TokenName) { \
|
|
EXPECT_EQ(#TokenName, TokenKind::TokenName().Name()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsSymbol()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsGroupingSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsOpeningSymbol()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsClosingSymbol()); \
|
|
EXPECT_EQ(TokenKind::OpeningName(), \
|
|
TokenKind::TokenName().GetOpeningSymbol()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsKeyword()); \
|
|
EXPECT_EQ(Spelling, TokenKind::TokenName().GetFixedSpelling()); \
|
|
EXPECT_THAT(Spelling, MatchesRegex(SymbolRegex.str())); \
|
|
}
|
|
#define CARBON_KEYWORD_TOKEN(TokenName, Spelling) \
|
|
TEST(TokenKindTest, TokenName) { \
|
|
EXPECT_EQ(#TokenName, TokenKind::TokenName().Name()); \
|
|
EXPECT_FALSE(TokenKind::TokenName().IsSymbol()); \
|
|
EXPECT_TRUE(TokenKind::TokenName().IsKeyword()); \
|
|
EXPECT_EQ(Spelling, TokenKind::TokenName().GetFixedSpelling()); \
|
|
EXPECT_THAT(Spelling, MatchesRegex(KeywordRegex.str())); \
|
|
}
|
|
#include "lexer/token_registry.def"
|
|
|
|
// Verify that the symbol tokens are sorted from longest to shortest. This is
|
|
// important to ensure that simply in-order testing will identify tokens
|
|
// following the max-munch rule.
|
|
TEST(TokenKindTest, SymbolsInDescendingLength) {
|
|
int previous_length = INT_MAX;
|
|
#define CARBON_SYMBOL_TOKEN(TokenName, Spelling) \
|
|
EXPECT_LE(llvm::StringRef(Spelling).size(), previous_length) \
|
|
<< "Symbol token not in descending length order: " << #TokenName; \
|
|
previous_length = llvm::StringRef(Spelling).size();
|
|
#include "lexer/token_registry.def"
|
|
EXPECT_GT(previous_length, 0);
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace Carbon
|