Skip to content

Commit 2509f50

Browse files
committed
Syntax: introduce a token kind for single quote to preserve round-trip printing of syntax tree
For invalid code, lexer is forgiving enough to allow single quote '\'' as the starting point of string literals. Later, parser assumes the string literals are always using double quote "\"", and passes such knowledge to SwiftSyntax side, leading to the round-trip failure we observed in the radar. This commit fixes the issue by introducing another token kind for single quote. rdar://51071021
1 parent 57666fd commit 2509f50

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,8 +1963,9 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
19631963
unsigned QuoteLength;
19641964
tok QuoteKind;
19651965
std::tie(QuoteLength, QuoteKind) =
1966-
Tok.isMultilineString() ? std::make_tuple(3, tok::multiline_string_quote)
1967-
: std::make_tuple(1, tok::string_quote);
1966+
Tok.isMultilineString() ? std::make_tuple(3, tok::multiline_string_quote)
1967+
: std::make_tuple(1, Tok.getText().startswith("\'") ?
1968+
tok::single_quote: tok::string_quote);
19681969
unsigned CloseQuoteBegin = Tok.getLength() - DelimiterLength - QuoteLength;
19691970

19701971
OpenDelimiterStr = Tok.getRawText().take_front(DelimiterLength);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: rm -rf %t
2+
// RUN: %swift-syntax-test -input-source-filename %s -parse-gen > %t
3+
// RUN: diff -u %s %t
4+
5+
"abc"
6+
7+
RoundedRectangle(cornerRadius: 6.0)lengthlength'Integer' field' [binding value: \(int.value)]int'Double' field [binding value: \(double.value)]double

utils/gyb_syntax_support/Token.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ def macro_name(self):
249249

250250
Punctuator('StringQuote', 'string_quote', text='\\\"',
251251
classification='StringLiteral', serialization_code=102),
252+
Punctuator('SingleQuote', 'single_quote', text='\\\'',
253+
classification='StringLiteral', serialization_code=120),
252254
Punctuator('MultilineStringQuote', 'multiline_string_quote',
253255
text='\\\"\\\"\\\"', classification='StringLiteral',
254256
serialization_code=103),

0 commit comments

Comments
 (0)