blob: e2e4cc7f5c6a45ed0fc53d9b93a472765f4e7e06 [file] [log] [blame]
//===-- RustLexTest.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
#include <cstdarg>
#include "Plugins/ExpressionParser/Rust/RustLex.h"
#include "lldb/Utility/Status.h"
using namespace lldb_private;
using namespace lldb_private::rust;
template<std::size_t N>
static void
TestLex(const char *input, const std::array<Token, N> &expected) {
Lexer lexer(input);
for (std::size_t i = 0; i < N; ++i) {
EXPECT_EQ(lexer.Next(), expected[i]) << "tokens differ at index " << i
<< " for \"" << input << "\"";
}
EXPECT_EQ(lexer.Next(), Token(THATSALLFOLKS)) << "EOF expected for input \""
<< input << "\"";
}
static void
TestSingle(const char *input, const Token &token) {
std::array<Token, 1> tokens { token };
TestLex(input, tokens);
}
TEST(RustLexTest, Keywords) {
TestSingle("as", Token(AS));
TestSingle("true", Token(TRUE));
TestSingle("false", Token(FALSE));
TestSingle("super", Token(SUPER));
TestSingle("self", Token(SELF));
TestSingle("mut", Token(MUT));
TestSingle("const", Token(CONST));
TestSingle("fn", Token(FN));
TestSingle("sizeof", Token(SIZEOF));
TestSingle("..", Token(DOTDOT));
TestSingle("..=", Token(DOTDOTEQ));
TestSingle("||", Token(OROR));
TestSingle("|=", Token(OR_EQ));
TestSingle("&&", Token(ANDAND));
TestSingle("&=", Token(AND_EQ));
TestSingle("^=", Token(XOR_EQ));
TestSingle("==", Token(EQEQ));
TestSingle("!=", Token(NOTEQ));
TestSingle("<=", Token(LTEQ));
TestSingle(">=", Token(GTEQ));
TestSingle("<<", Token(LSH));
TestSingle(">>", Token(RSH));
TestSingle("+=", Token(PLUS_EQ));
TestSingle("-=", Token(MINUS_EQ));
TestSingle("*=", Token(STAR_EQ));
TestSingle("/=", Token(SLASH_EQ));
TestSingle("%=", Token(PERCENT_EQ));
TestSingle("<<=", Token(LSH_EQ));
TestSingle(">>=", Token(RSH_EQ));
TestSingle("::", Token(COLONCOLON));
TestSingle("->", Token(ARROW));
TestSingle(".", Token('.'));
TestSingle("|", Token('|'));
TestSingle("&", Token('&'));
TestSingle("=", Token('='));
TestSingle("!", Token('!'));
TestSingle("<", Token('<'));
TestSingle(">", Token('>'));
TestSingle("+", Token('+'));
TestSingle("-", Token('-'));
TestSingle("*", Token('*'));
TestSingle("/", Token('/'));
TestSingle("%", Token('%'));
TestSingle(":", Token(':'));
TestSingle("[", Token('['));
TestSingle("]", Token(']'));
TestSingle("(", Token('('));
TestSingle(")", Token(')'));
TestSingle("{", Token('{'));
TestSingle("}", Token('}'));
}
TEST(RustLexTest, Identifiers) {
TestSingle("one", Token(IDENTIFIER, "one"));
TestSingle("o_e", Token(IDENTIFIER, "o_e"));
TestSingle("_E001__Z", Token(IDENTIFIER, "_E001__Z"));
TestSingle("b", Token(IDENTIFIER, "b"));
TestSingle("br", Token(IDENTIFIER, "br"));
TestSingle("brrrr", Token(IDENTIFIER, "brrrr"));
}
TEST(RustLexTest, Integers) {
TestSingle("1", Token(INTEGER, uint64_t(1)));
TestSingle("1usize", Token(INTEGER, uint64_t(1), "usize"));
TestSingle("2_33", Token(INTEGER, uint64_t(233)));
TestSingle("2_33i64", Token(INTEGER, uint64_t(233), "i64"));
TestSingle("0x_ff", Token(INTEGER, uint64_t(255)));
TestSingle("0xFf", Token(INTEGER, uint64_t(255)));
TestSingle("0b_1111_1111", Token(INTEGER, uint64_t(255)));
TestSingle("0o11_u64", Token(INTEGER, uint64_t(9), "u64"));
}
TEST(RustLexTest, Floats) {
TestSingle("1.0", Token(FLOAT, 1.0));
TestSingle("1.5f32", Token(FLOAT, 1.5, "f32"));
TestSingle("1.5E+02", Token(FLOAT, 150.0));
TestSingle("1.5e+03", Token(FLOAT, 1500.0));
TestSingle("1e+03f64", Token(FLOAT, 1000.0, "f64"));
}
TEST(RustLexTest, ByteLiteral) {
TestSingle("b'b'", Token(BYTE, uint64_t('b')));
TestSingle("b'\\''", Token(BYTE, uint64_t('\'')));
TestSingle("b'\\x9A'", Token(BYTE, uint64_t(154)));
TestSingle("b'\\x9A", Token(INVALID));
TestSingle("b'", Token(INVALID));
// TestSingle("b'\\u{9A}'", Token(INVALID));
}
TEST(RustLexTest, Characters) {
TestSingle("'b'", Token(CHAR, uint64_t('b')));
TestSingle("'\\''", Token(CHAR, uint64_t('\'')));
TestSingle("'\\x9A'", Token(CHAR, uint64_t(154)));
TestSingle("'\\x9A'", Token(CHAR, uint64_t(154)));
TestSingle("'\\x9A", Token(INVALID));
TestSingle("'\\u{9A}'", Token(CHAR, uint64_t(154)));
TestSingle("'\\u{00009A}'", Token(CHAR, uint64_t(154)));
TestSingle("'\\u{0000fff", Token(INVALID));
TestSingle("'\\u{0000ff}", Token(INVALID));
TestSingle("'", Token(INVALID));
}
TEST(RustLexTest, Strings) {
TestSingle("\"hi\"", Token(STRING, "hi"));
TestSingle("\"\\u{68}\\u{000069}\"", Token(STRING, "hi"));
TestSingle("\"\\x68\\x69\"", Token(STRING, "hi"));
}
TEST(RustLexTest, RawStrings) {
TestSingle("r\"hi\"", Token(STRING, "hi"));
TestSingle("r########\"hi\"########", Token(STRING, "hi"));
TestSingle("r########\"h\"#######i\"########", Token(STRING, "h\"#######i"));
TestSingle("r########\"\\'\"########", Token(STRING, "\\'"));
}
TEST(RustLexTest, RawByteStrings) {
TestSingle("br\"hi\"", Token(BYTESTRING, "hi"));
TestSingle("br########\"hi\"########", Token(BYTESTRING, "hi"));
TestSingle("br########\"h\"#######i\"########", Token(BYTESTRING, "h\"#######i"));
TestSingle("br########\"\\'\"########", Token(BYTESTRING, "\\'"));
}
TEST(RustLexTest, Streams) {
TestLex("57 as i64", std::array<Token, 3> {
Token(INTEGER, uint64_t(57)),
Token(AS),
Token(IDENTIFIER, "i64")
});
TestLex("0..", std::array<Token, 2> {
Token(INTEGER, uint64_t(0)),
Token(DOTDOT)
});
}