Skip to content

Commit 0bfba29

Browse files
committed
Fix lexer to properly handle single quote strings
Lexer now suggests escaping unescaped double quotes and unescaping escaped single quotes in single quote strings..
1 parent 2f670a8 commit 0bfba29

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

lib/Parse/Lexer.cpp

+22-2
Original file line numberDiff line numberDiff line change
@@ -1164,11 +1164,31 @@ void Lexer::lexStringLiteral() {
11641164
if (*TokStart == '\'') {
11651165
// Complain about single-quote string and suggest replacement with
11661166
// double-quoted equivalent.
1167-
// FIXME: Fixit should replace ['"'] with ["\""] (radar 22709931)
11681167
StringRef orig(TokStart, CurPtr - TokStart);
11691168
llvm::SmallString<32> replacement;
11701169
replacement += '"';
1171-
replacement += orig.slice(1, orig.size() - 1);
1170+
std::string str = orig.slice(1, orig.size() - 1).str();
1171+
std::string quot = "\"";
1172+
size_t pos = 0;
1173+
while (pos != str.length()) {
1174+
if (str.at(pos) == '\\') {
1175+
if (str.at(pos + 1) == '\'') {
1176+
// Un-escape escaped single quotes.
1177+
str.replace(pos, 2, "'");
1178+
++pos;
1179+
} else {
1180+
// Skip over escaped characters.
1181+
pos += 2;
1182+
}
1183+
} else if (str.at(pos) == '"') {
1184+
str.replace(pos, 1, "\\\"");
1185+
// Advance past the newly added ["\""].
1186+
pos += 2;
1187+
} else {
1188+
++pos;
1189+
}
1190+
}
1191+
replacement += StringRef(str);
11721192
replacement += '"';
11731193
diagnose(TokStart, diag::lex_single_quote_string)
11741194
.fixItReplaceChars(getSourceLoc(TokStart), getSourceLoc(CurPtr),

test/expr/expressions.swift

+4-6
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,11 @@ func testSingleQuoteStringLiterals() {
448448
'abc" // expected-error{{unterminated string literal}}
449449
"a'c"
450450

451-
// FIXME: <rdar://problem/22709931> QoI: Single-quote => double-quote string literal fixit should escape quote chars
452-
// FIXME: The suggested replacement should un-escape the single quote
453-
// character.
454-
'ab\'c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab\\'c"}}
451+
'ab\'c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab'c"}}
455452

456-
// FIXME: The suggested replacement should escape the double-quote character.
457-
'ab"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-9="ab"c"}}
453+
'ab"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-9="ab\\"c"}}
454+
'ab\"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab\\"c"}}
455+
'ab\\"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-11="ab\\\\\\"c"}}
458456
}
459457

460458
// <rdar://problem/17128913>

0 commit comments

Comments
 (0)