Skip to content

Commit 01f42c8

Browse files
authored
Merge pull request #13631 from omochi/lex-escape-backtick
[Parse] Lexer build backtick trivia around espaced identifier token
2 parents cfe6e0c + bc88330 commit 01f42c8

File tree

5 files changed

+37
-12
lines changed

5 files changed

+37
-12
lines changed

include/swift/Parse/Lexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ class Lexer {
484484
}
485485

486486
void formToken(tok Kind, const char *TokStart, bool MultilineString = false);
487+
void formEscapedIdentifierToken(const char *TokStart);
487488

488489
/// Advance to the end of the line.
489490
/// If EatNewLine is true, CurPtr will be at end of newline character.

lib/Parse/Lexer.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,19 @@ void Lexer::formToken(tok Kind, const char *TokStart, bool MultilineString) {
271271
NextToken.setToken(Kind, TokenText, CommentLength, MultilineString);
272272
}
273273

274+
void Lexer::formEscapedIdentifierToken(const char *TokStart) {
275+
assert(CurPtr - TokStart >= 3 && "escaped identifier must be longer than or equal 3 bytes");
276+
assert(TokStart[0] == '`' && "escaped identifier starts with backtick");
277+
assert(CurPtr[-1] == '`' && "escaped identifier ends with backtick");
278+
if (TriviaRetention == TriviaRetentionMode::WithTrivia) {
279+
LeadingTrivia.push_back(TriviaPiece::backtick());
280+
assert(TrailingTrivia.size() == 0 && "TrailingTrivia is empty here");
281+
TrailingTrivia.push_back(TriviaPiece::backtick());
282+
}
283+
formToken(tok::identifier, TokStart);
284+
NextToken.setEscapedIdentifier(true);
285+
}
286+
274287
Lexer::State Lexer::getStateForBeginningOfTokenLoc(SourceLoc Loc) const {
275288
const char *Ptr = getBufferPtrForSourceLoc(Loc);
276289
// Skip whitespace backwards until we hit a newline. This is needed to
@@ -1770,17 +1783,15 @@ void Lexer::lexEscapedIdentifier() {
17701783
// If we have the terminating "`", it's an escaped identifier.
17711784
if (*CurPtr == '`') {
17721785
++CurPtr;
1773-
formToken(tok::identifier, Quote);
1774-
NextToken.setEscapedIdentifier(true);
1786+
formEscapedIdentifierToken(Quote);
17751787
return;
17761788
}
17771789
}
17781790

17791791
// Special case; allow '`$`'.
17801792
if (Quote[1] == '$' && Quote[2] == '`') {
17811793
CurPtr = Quote + 3;
1782-
formToken(tok::identifier, Quote);
1783-
NextToken.setEscapedIdentifier(true);
1794+
formEscapedIdentifierToken(Quote);
17841795
return;
17851796
}
17861797

lib/Parse/Parser.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,6 @@ swift::tokenizeWithTrivia(const LangOptions &LangOpts,
286286
Trivia LeadingTrivia, TrailingTrivia;
287287
do {
288288
L.lex(Tok, LeadingTrivia, TrailingTrivia);
289-
if (Tok.isEscapedIdentifier()) {
290-
LeadingTrivia.push_back(TriviaPiece::backtick());
291-
TrailingTrivia.push_front(TriviaPiece::backtick());
292-
}
293289
auto ThisToken = RawTokenSyntax::make(Tok.getKind(), Tok.getText(),
294290
SourcePresence::Present, LeadingTrivia,
295291
TrailingTrivia);

lib/Syntax/SyntaxParsingContext.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ void SyntaxParsingContext::addToken(Token &Tok, Trivia &LeadingTrivia,
7777
if (!Enabled)
7878
return;
7979

80-
if (Tok.isEscapedIdentifier()) {
81-
LeadingTrivia.push_back(TriviaPiece::backtick());
82-
TrailingTrivia.push_front(TriviaPiece::backtick());
83-
}
8480
addRawSyntax(RawTokenSyntax::make(Tok.getKind(), Tok.getText(),
8581
SourcePresence::Present, LeadingTrivia,
8682
TrailingTrivia));
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %swift-syntax-test -input-source-filename %s -dump-full-tokens | %FileCheck %s
2+
let /*leading trivia*/ `if` = 3
3+
print(/*leading trivia*/ `if` )
4+
5+
// CHECK-LABEL: 2:25
6+
// CHECK-NEXT:(token identifier
7+
// CHECK-NEXT: (trivia block_comment/*leading trivia*/)
8+
// CHECK-NEXT: (trivia space 1)
9+
// CHECK-NEXT: (trivia backtick 1)
10+
// CHECK-NEXT: (text="if")
11+
// CHECK-NEXT: (trivia backtick 1)
12+
// CHECK-NEXT: (trivia space 1))
13+
14+
// CHECK-LABEL: 3:27
15+
// CHECK-NEXT:(token identifier
16+
// CHECK-NEXT: (trivia block_comment/*leading trivia*/)
17+
// CHECK-NEXT: (trivia space 1)
18+
// CHECK-NEXT: (trivia backtick 1)
19+
// CHECK-NEXT: (text="if")
20+
// CHECK-NEXT: (trivia backtick 1)
21+
// CHECK-NEXT: (trivia space 1))

0 commit comments

Comments
 (0)