mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
288 lines
6.1 KiB
D
288 lines
6.1 KiB
D
module lexer.lexer_dmdlib;
|
|
|
|
import dmd.lexer : Lexer;
|
|
import dmd.tokens : TOK;
|
|
import dmd.errorsink;
|
|
|
|
/// Test that lexing `code` generates the `expected` tokens
|
|
private void test(string code, const TOK[] expected, bool keepComments = false, bool keepWhitespace = false)
|
|
{
|
|
Lexer lexer = new Lexer(null, code.ptr, 0, code.length, /*doDocComment*/ false, keepComments, keepWhitespace, new ErrorSinkStderr);
|
|
TOK[] result;
|
|
|
|
while (lexer.nextToken != TOK.endOfFile)
|
|
result ~= lexer.token.value;
|
|
|
|
assert(result == expected);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "void test() {} // foobar";
|
|
|
|
immutable expected = [
|
|
TOK.void_,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.leftCurly,
|
|
TOK.rightCurly,
|
|
];
|
|
|
|
test(code, expected, false, false);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "void test() {} // foobar";
|
|
|
|
immutable expected = [
|
|
TOK.void_,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.leftCurly,
|
|
TOK.rightCurly,
|
|
TOK.comment,
|
|
];
|
|
|
|
test(code, expected, true, false);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "void test() {} // foobar";
|
|
|
|
TOK[] expected = [
|
|
TOK.void_,
|
|
TOK.whitespace,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.whitespace,
|
|
TOK.leftCurly,
|
|
TOK.rightCurly,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
];
|
|
|
|
test(code, expected, true, true);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "void test() {} // foobar\n";
|
|
|
|
TOK[] expected = [
|
|
TOK.void_,
|
|
TOK.whitespace,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.whitespace,
|
|
TOK.leftCurly,
|
|
TOK.rightCurly,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
TOK.whitespace,
|
|
];
|
|
|
|
test(code, expected, true, true);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code =
|
|
"void test()\n"
|
|
~ "{\n"
|
|
~ "\tint a = 5; // some comment\n"
|
|
~ "} // another comment\n";
|
|
|
|
TOK[] expected = [
|
|
TOK.void_,
|
|
TOK.whitespace,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.whitespace,
|
|
TOK.leftCurly,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.int32,
|
|
TOK.whitespace,
|
|
TOK.identifier,
|
|
TOK.whitespace,
|
|
TOK.assign,
|
|
TOK.whitespace,
|
|
TOK.int32Literal,
|
|
TOK.semicolon,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
TOK.whitespace,
|
|
TOK.rightCurly,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
TOK.whitespace,
|
|
];
|
|
|
|
test(code, expected, true, true);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code =
|
|
"\n"
|
|
~ "\n;"
|
|
~ "\t;\t\r// some comment\n"
|
|
~ "\v\f\r// another comment\n\n";
|
|
|
|
TOK[] expected = [
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.semicolon,
|
|
TOK.whitespace,
|
|
TOK.semicolon,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
TOK.comment,
|
|
TOK.whitespace,
|
|
TOK.whitespace,
|
|
];
|
|
|
|
test(code, expected, true, true);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "void test() {}";
|
|
|
|
immutable expected = [
|
|
TOK.void_,
|
|
TOK.identifier,
|
|
TOK.leftParenthesis,
|
|
TOK.rightParenthesis,
|
|
TOK.leftCurly,
|
|
TOK.rightCurly,
|
|
];
|
|
|
|
Lexer lexer = new Lexer(null, code.ptr, 0, code.length, false, false, new ErrorSinkStderr, null);
|
|
lexer.nextToken;
|
|
|
|
TOK[] result;
|
|
|
|
foreach(TOK t; lexer)
|
|
{
|
|
result ~= t;
|
|
}
|
|
|
|
assert(result == expected);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "// some comment";
|
|
|
|
immutable expected = [
|
|
TOK.comment,
|
|
];
|
|
|
|
Lexer lexer = new Lexer(null, code.ptr, 0, code.length, false, true, new ErrorSinkStderr, null);
|
|
lexer.nextToken;
|
|
|
|
TOK[] result;
|
|
|
|
foreach(TOK t; lexer)
|
|
{
|
|
result ~= t;
|
|
}
|
|
|
|
assert(result == expected);
|
|
assert(lexer.empty);
|
|
lexer.popFront;
|
|
assert(lexer.empty);
|
|
lexer.popFront;
|
|
assert(lexer.empty);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
immutable code = "";
|
|
|
|
immutable expected = [
|
|
TOK.reserved,
|
|
];
|
|
|
|
Lexer lexer = new Lexer(null, code.ptr, 0, code.length, false, false, new ErrorSinkStderr, null);
|
|
|
|
TOK[] result;
|
|
|
|
foreach(TOK t; lexer)
|
|
{
|
|
result ~= t;
|
|
}
|
|
|
|
assert(result == expected);
|
|
assert(lexer.empty);
|
|
}
|
|
|
|
// Issue 22495
|
|
unittest
|
|
{
|
|
import std.conv : text, to;
|
|
import std.string : fromStringz;
|
|
|
|
import core.stdc.stdarg : va_list;
|
|
|
|
import dmd.frontend;
|
|
import dmd.location;
|
|
import dmd.common.outbuffer;
|
|
import dmd.console : Color;
|
|
import dmd.errors;
|
|
|
|
const(char)[][2][] diagnosticMessages;
|
|
nothrow bool diagnosticHandler(const ref SourceLoc loc, Color headerColor, const(char)* header,
|
|
const(char)* format, va_list ap, const(char)* p1, const(char)* p2)
|
|
{
|
|
OutBuffer tmp;
|
|
tmp.vprintf(format, ap);
|
|
diagnosticMessages ~= [loc.filename.fromStringz, to!string(tmp.peekChars())];
|
|
return true;
|
|
}
|
|
|
|
initDMD(&diagnosticHandler);
|
|
scope(exit) deinitializeDMD();
|
|
|
|
immutable codes = [
|
|
"enum myString = \"\u061C\";",
|
|
"enum myString = `\u202E\u2066 \u2069\u2066`;",
|
|
"void test(){} // \u200E comment \u200F"
|
|
];
|
|
|
|
foreach (codeNum, code; codes)
|
|
{
|
|
auto fileName = text("file", codeNum, '\0');
|
|
Lexer lexer = new Lexer(fileName.ptr, code.ptr, 0, code.length, false, false, new ErrorSinkCompiler, null);
|
|
// Generate the errors
|
|
foreach(unused; lexer){}
|
|
}
|
|
|
|
string bidiErrorMessage =
|
|
"Bidirectional control characters are disallowed for security reasons.";
|
|
|
|
string[2][] excepted = [
|
|
["file0", bidiErrorMessage],
|
|
["file1", bidiErrorMessage],
|
|
["file1", bidiErrorMessage],
|
|
["file1", bidiErrorMessage],
|
|
["file1", bidiErrorMessage],
|
|
["file2", bidiErrorMessage],
|
|
["file2", bidiErrorMessage],
|
|
];
|
|
|
|
assert(diagnosticMessages == excepted);
|
|
}
|