From 63654211c6e751c59607dde99d354e318897046e Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Wed, 27 Jul 2022 22:12:27 -0700 Subject: [PATCH] Allow interpolated strings without expressions, add TODO test for failing interp strings as types --- Ast/src/Lexer.cpp | 2 +- Ast/src/Parser.cpp | 6 +++--- tests/Parser.test.cpp | 18 ++++++++++++++++++ tests/conformance/stringinterp.lua | 3 +++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Ast/src/Lexer.cpp b/Ast/src/Lexer.cpp index 69b097db..093f10c1 100644 --- a/Ast/src/Lexer.cpp +++ b/Ast/src/Lexer.cpp @@ -601,7 +601,7 @@ Lexeme Lexer::readInterpolatedStringBegin() Position start = position(); consume(); - return readInterpolatedStringSection(start, Lexeme::InterpStringBegin, Lexeme::QuotedString); + return readInterpolatedStringSection(start, Lexeme::InterpStringBegin, Lexeme::InterpStringEnd); } Lexeme Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType) diff --git a/Ast/src/Parser.cpp b/Ast/src/Parser.cpp index 327cb167..9bcdea32 100644 --- a/Ast/src/Parser.cpp +++ b/Ast/src/Parser.cpp @@ -2203,7 +2203,7 @@ AstExpr* Parser::parseSimpleExpr() } } } - else if (lexer.current().type == Lexeme::RawString || lexer.current().type == Lexeme::QuotedString) + else if (lexer.current().type == Lexeme::RawString || lexer.current().type == Lexeme::QuotedString || (FFlag::LuauInterpolatedStringBaseSupport && lexer.current().type == Lexeme::InterpStringEnd)) { return parseString(); } @@ -2603,11 +2603,11 @@ AstArray Parser::parseTypeParams() std::optional> Parser::parseCharArray() { - LUAU_ASSERT(lexer.current().type == Lexeme::QuotedString || lexer.current().type == Lexeme::RawString); + LUAU_ASSERT(lexer.current().type == Lexeme::QuotedString || lexer.current().type == Lexeme::RawString || lexer.current().type == Lexeme::InterpStringEnd); scratchData.assign(lexer.current().data, lexer.current().length); - if (lexer.current().type == Lexeme::QuotedString) + if (lexer.current().type == Lexeme::QuotedString || lexer.current().type == Lexeme::InterpStringEnd) { if (!Lexer::fixupQuotedString(scratchData)) { diff --git a/tests/Parser.test.cpp b/tests/Parser.test.cpp index 5e0f6da4..96b1c94c 100644 --- a/tests/Parser.test.cpp +++ b/tests/Parser.test.cpp @@ -1110,6 +1110,24 @@ TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_after_prefixexp") } } +TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_as_type_fail") +{ + ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true}; + + try + { + parse(R"( + local a: `what` = `what` + )"); + FAIL("Expected ParseErrors to be thrown"); + } + catch (const ParseErrors& e) + { + // CHECK_EQ("Interpolated strings cannot be used alone to call a function. Wrap this in parentheses.", e.getErrors().front().getMessage()); + CHECK_EQ("TODO", e.getErrors().front().getMessage()); + } +} + TEST_CASE_FIXTURE(Fixture, "parse_nesting_based_end_detection") { try diff --git a/tests/conformance/stringinterp.lua b/tests/conformance/stringinterp.lua index 2c79504a..3da96228 100644 --- a/tests/conformance/stringinterp.lua +++ b/tests/conformance/stringinterp.lua @@ -31,7 +31,10 @@ assertEq(`This {localName} does not exist`, "This nil does not exist") assertEq(`Welcome to \ {name}!`, "Welcome to \nLuau!") +assertEq(`empty`, "empty") + assertEq(`Escaped brace: \{}`, "Escaped brace: {}") +assertEq(`Escaped brace \{} with {"expression"}`, "Escaped brace {} with expression") assertEq(`Backslash \ that escapes the space is not a part of the string...`, "Backslash that escapes the space is not a part of the string...") assertEq(`Escaped backslash \\`, "Escaped backslash \\") assertEq(`Escaped backtick: \``, "Escaped backtick: `")