mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:37:43 +00:00
LibJS: Fix that windows style line endings were not ignored or converted
These are tested by test262 but the current test262-runner reads the files in python which automatically converts \r\n to \n. This meant that we passed the tests while we should not have.
This commit is contained in:
parent
f2512071f2
commit
3fee7b0d0b
4 changed files with 51 additions and 1 deletions
|
@ -1271,7 +1271,7 @@ NonnullRefPtr<TemplateLiteral> Parser::parse_template_literal(bool is_tagged)
|
||||||
auto token = consume();
|
auto token = consume();
|
||||||
expressions.append(parse_string_literal(token, true));
|
expressions.append(parse_string_literal(token, true));
|
||||||
if (is_tagged)
|
if (is_tagged)
|
||||||
raw_strings.append(create_ast_node<StringLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, token.value()));
|
raw_strings.append(create_ast_node<StringLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, token.raw_template_value()));
|
||||||
} else if (match(TokenType::TemplateLiteralExprStart)) {
|
} else if (match(TokenType::TemplateLiteralExprStart)) {
|
||||||
consume(TokenType::TemplateLiteralExprStart);
|
consume(TokenType::TemplateLiteralExprStart);
|
||||||
if (match(TokenType::TemplateLiteralExprEnd)) {
|
if (match(TokenType::TemplateLiteralExprEnd)) {
|
||||||
|
|
|
@ -61,6 +61,34 @@ test("line terminators can be mixed (but please don't)", () => {
|
||||||
test("all line terminators are valid for line continuations", () => {
|
test("all line terminators are valid for line continuations", () => {
|
||||||
expect(Function('return "a\\\nb"')()).toBe("ab");
|
expect(Function('return "a\\\nb"')()).toBe("ab");
|
||||||
expect(Function('return "a\\\rb"')()).toBe("ab");
|
expect(Function('return "a\\\rb"')()).toBe("ab");
|
||||||
|
expect(Function('return "a\\\r\nb"')()).toBe("ab");
|
||||||
expect(Function('return "a\\
b"')()).toBe("ab");
|
expect(Function('return "a\\
b"')()).toBe("ab");
|
||||||
expect(Function('return "a\\
b"')()).toBe("ab");
|
expect(Function('return "a\\
b"')()).toBe("ab");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("template-literals raw and real value", () => {
|
||||||
|
let lastTemplate;
|
||||||
|
let lastRaw;
|
||||||
|
|
||||||
|
function tag(cs) {
|
||||||
|
lastTemplate = cs[0];
|
||||||
|
lastRaw = cs.raw[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkTemplate(string_value, expected_template, expected_raw) {
|
||||||
|
eval("tag`" + string_value + "`");
|
||||||
|
expect(lastTemplate).toBe(expected_template);
|
||||||
|
expect(lastRaw).toBe(expected_raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTemplate("", "", "");
|
||||||
|
checkTemplate("\n", "\n", "\n");
|
||||||
|
checkTemplate("\r", "\n", "\n");
|
||||||
|
checkTemplate("\r\n", "\n", "\n");
|
||||||
|
checkTemplate("\n\r\n", "\n\n", "\n\n");
|
||||||
|
|
||||||
|
checkTemplate("a\\\nb", "ab", "a\\\nb");
|
||||||
|
checkTemplate("a\\\rb", "ab", "a\\\nb");
|
||||||
|
checkTemplate("a\\
b", "ab", "a\\
b");
|
||||||
|
checkTemplate("a\\
b", "ab", "a\\
b");
|
||||||
|
});
|
||||||
|
|
|
@ -106,6 +106,16 @@ String Token::string_value(StringValueStatus& status) const
|
||||||
while (!lexer.is_eof()) {
|
while (!lexer.is_eof()) {
|
||||||
// No escape, consume one char and continue
|
// No escape, consume one char and continue
|
||||||
if (!lexer.next_is('\\')) {
|
if (!lexer.next_is('\\')) {
|
||||||
|
|
||||||
|
if (is_template && lexer.next_is('\r')) {
|
||||||
|
lexer.ignore();
|
||||||
|
if (lexer.next_is('\n'))
|
||||||
|
lexer.ignore();
|
||||||
|
|
||||||
|
builder.append('\n');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
builder.append(lexer.consume());
|
builder.append(lexer.consume());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +142,8 @@ String Token::string_value(StringValueStatus& status) const
|
||||||
|
|
||||||
// Line continuation
|
// Line continuation
|
||||||
if (lexer.next_is('\n') || lexer.next_is('\r')) {
|
if (lexer.next_is('\n') || lexer.next_is('\r')) {
|
||||||
|
if (lexer.next_is("\r\n"))
|
||||||
|
lexer.ignore();
|
||||||
lexer.ignore();
|
lexer.ignore();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +204,15 @@ String Token::string_value(StringValueStatus& status) const
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 12.8.6.2 Static Semantics: TRV, https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#sec-static-semantics-trv
|
||||||
|
String Token::raw_template_value() const
|
||||||
|
{
|
||||||
|
String base = value().to_string();
|
||||||
|
base.replace("\r\n", "\n", true);
|
||||||
|
base.replace("\r", "\n", true);
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
bool Token::bool_value() const
|
bool Token::bool_value() const
|
||||||
{
|
{
|
||||||
VERIFY(type() == TokenType::BoolLiteral);
|
VERIFY(type() == TokenType::BoolLiteral);
|
||||||
|
|
|
@ -237,6 +237,7 @@ public:
|
||||||
LegacyOctalEscapeSequence,
|
LegacyOctalEscapeSequence,
|
||||||
};
|
};
|
||||||
String string_value(StringValueStatus& status) const;
|
String string_value(StringValueStatus& status) const;
|
||||||
|
String raw_template_value() const;
|
||||||
|
|
||||||
bool is_identifier_name() const;
|
bool is_identifier_name() const;
|
||||||
bool trivia_contains_line_terminator() const;
|
bool trivia_contains_line_terminator() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue