diff --git a/Analysis/src/Transpiler.cpp b/Analysis/src/Transpiler.cpp index d0bdf4a4..cdfe6549 100644 --- a/Analysis/src/Transpiler.cpp +++ b/Analysis/src/Transpiler.cpp @@ -519,7 +519,7 @@ struct Printer for (const auto& string : a->strings) { - writer.write(escape(std::string_view(string.data, string.size))); + writer.write(escape(std::string_view(string.data, string.size), /* escapeForInterpString = */ true)); if (index < a->expressions.size) { diff --git a/Ast/include/Luau/StringUtils.h b/Ast/include/Luau/StringUtils.h index 6ae9e977..dab76106 100644 --- a/Ast/include/Luau/StringUtils.h +++ b/Ast/include/Luau/StringUtils.h @@ -35,6 +35,6 @@ bool equalsLower(std::string_view lhs, std::string_view rhs); size_t hashRange(const char* data, size_t size); -std::string escape(std::string_view s); +std::string escape(std::string_view s, bool escapeForInterpString = false); bool isIdentifier(std::string_view s); } // namespace Luau diff --git a/Ast/src/StringUtils.cpp b/Ast/src/StringUtils.cpp index a0e6bf65..11e0076a 100644 --- a/Ast/src/StringUtils.cpp +++ b/Ast/src/StringUtils.cpp @@ -230,7 +230,7 @@ bool isIdentifier(std::string_view s) return (s.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_") == std::string::npos); } -std::string escape(std::string_view s) +std::string escape(std::string_view s, bool escapeForInterpString) { std::string r; r.reserve(s.size() + 50); // arbitrary number to guess how many characters we'll be inserting @@ -243,6 +243,12 @@ std::string escape(std::string_view s) { r += '\\'; + if (escapeForInterpString && (c == '`' || c == '{')) + { + r += c; + continue; + } + switch (c) { case '\a': @@ -272,14 +278,6 @@ std::string escape(std::string_view s) case '\"': r += '\"'; break; - // INTERP CODE REVIEW: This is going to apply it to all escaped strings, not just - // interpolated ones. Is that acceptable, or should this be split into two functions/a toggle? - case '`': - r += '`'; - break; - case '{': - r += '{'; - break; case '\\': r += '\\'; break;