Skip to content

Commit c9c6963

Browse files
committed
[Lexer] Simplify handling quotes in skipToEndOfInterpolatedExpression()
NFC
1 parent 0e9b232 commit c9c6963

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

lib/Parse/Lexer.cpp

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,67 +1454,61 @@ static const char *skipToEndOfInterpolatedExpression(const char *CurPtr,
14541454
if (inStringLiteral() ||
14551455
!(CustomDelimiterLen = advanceIfCustomDelimiter(CurPtr, Diags)))
14561456
continue;
1457+
assert(CurPtr[-1] == '"' &&
1458+
"advanceIfCustomDelimiter() must stop at after the quote");
14571459
LLVM_FALLTHROUGH;
14581460

14591461
case '"':
14601462
case '\'': {
1461-
if (!AllowNewline.back() && inStringLiteral()) {
1462-
if (OpenDelimiters.back() == CurPtr[-1] &&
1463-
delimiterMatches(CustomDelimiter.back(), CurPtr, Diags, true)) {
1464-
// Closing single line string literal.
1465-
OpenDelimiters.pop_back();
1466-
AllowNewline.pop_back();
1467-
CustomDelimiter.pop_back();
1468-
}
1469-
// Otherwise, it's just a quote in string literal. e.g. "foo's".
1470-
continue;
1471-
}
1472-
1473-
bool isMultilineQuote = advanceIfMultilineDelimiter(CurPtr, Diags);
1474-
14751463
if (!inStringLiteral()) {
1476-
// Open string literal
1464+
// Open string literal.
14771465
OpenDelimiters.push_back(CurPtr[-1]);
1478-
AllowNewline.push_back(isMultilineQuote);
1466+
AllowNewline.push_back(advanceIfMultilineDelimiter(CurPtr, Diags));
14791467
CustomDelimiter.push_back(CustomDelimiterLen);
14801468
continue;
14811469
}
14821470

1483-
// We are in multiline string literal.
1484-
assert(AllowNewline.back() && "other cases must be handled above");
1485-
if (isMultilineQuote &&
1486-
delimiterMatches(CustomDelimiter.back(), CurPtr, Diags, true)) {
1487-
// Close multiline string literal.
1488-
OpenDelimiters.pop_back();
1489-
AllowNewline.pop_back();
1490-
CustomDelimiter.pop_back();
1491-
}
1471+
// In string literal.
1472+
1473+
// Skip if it's an another kind of quote in string literal. e.g. "foo's".
1474+
if (OpenDelimiters.back() != CurPtr[-1])
1475+
continue;
1476+
1477+
// Multi-line string can only be closed by '"""'.
1478+
if (AllowNewline.back() && !advanceIfMultilineDelimiter(CurPtr, Diags))
1479+
continue;
1480+
1481+
// Check whether we have equivalent number of '#'s.
1482+
if (!delimiterMatches(CustomDelimiter.back(), CurPtr, Diags, true))
1483+
continue;
14921484

1493-
// Otherwise, it's just a normal character in multiline string.
1485+
// Close string literal.
1486+
OpenDelimiters.pop_back();
1487+
AllowNewline.pop_back();
1488+
CustomDelimiter.pop_back();
14941489
continue;
14951490
}
14961491
case '\\':
1492+
// We ignore invalid escape sequence here. They should be diagnosed in
1493+
// the real lexer functions.
14971494
if (inStringLiteral() &&
14981495
delimiterMatches(CustomDelimiter.back(), CurPtr, Diags)) {
1499-
char escapedChar = *CurPtr++;
1500-
switch (escapedChar) {
1496+
switch (*CurPtr++) {
15011497
case '(':
15021498
// Entering a recursive interpolated expression
15031499
OpenDelimiters.push_back('(');
15041500
continue;
1505-
case '\n': case '\r':
1506-
if (AllowNewline.back())
1507-
continue;
1508-
LLVM_FALLTHROUGH;
1509-
case 0:
1510-
// Don't jump over newline/EOF due to preceding backslash!
1511-
return CurPtr-1;
1501+
case '\n': case '\r': case 0:
1502+
// Don't jump over newline/EOF due to preceding backslash.
1503+
// Let the outer switch to handle it.
1504+
--CurPtr;
1505+
continue;
15121506
default:
15131507
continue;
15141508
}
15151509
}
15161510
continue;
1517-
1511+
15181512
// Paren nesting deeper to support "foo = \((a+b)-(c*d)) bar".
15191513
case '(':
15201514
if (!inStringLiteral()) {

test/Parse/string_literal_eof3.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// expected-error@+2 {{unterminated string literal}}
4+
// expected-error@+1 {{invalid escape sequence in literal}}
5+
_ = "foo \
6+
7+
// NOTE: DO NOT add a newline at EOF.
8+
// expected-error@+2 {{unterminated string literal}}
9+
// expected-error@+1 {{invalid escape sequence in literal}}
10+
_ = "foo \

0 commit comments

Comments
 (0)