Merge pull request #13631 from omochi/lex-escape-backtick
[Parse] Lexer build backtick trivia around espaced identifier token
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index ef2d095..01cd01c 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -484,6 +484,7 @@
}
void formToken(tok Kind, const char *TokStart, bool MultilineString = false);
+ void formEscapedIdentifierToken(const char *TokStart);
/// Advance to the end of the line.
/// If EatNewLine is true, CurPtr will be at end of newline character.
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index f582123..68a09ed 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -271,6 +271,19 @@
NextToken.setToken(Kind, TokenText, CommentLength, MultilineString);
}
+void Lexer::formEscapedIdentifierToken(const char *TokStart) {
+ assert(CurPtr - TokStart >= 3 && "escaped identifier must be longer than or equal 3 bytes");
+ assert(TokStart[0] == '`' && "escaped identifier starts with backtick");
+ assert(CurPtr[-1] == '`' && "escaped identifier ends with backtick");
+ if (TriviaRetention == TriviaRetentionMode::WithTrivia) {
+ LeadingTrivia.push_back(TriviaPiece::backtick());
+ assert(TrailingTrivia.size() == 0 && "TrailingTrivia is empty here");
+ TrailingTrivia.push_back(TriviaPiece::backtick());
+ }
+ formToken(tok::identifier, TokStart);
+ NextToken.setEscapedIdentifier(true);
+}
+
Lexer::State Lexer::getStateForBeginningOfTokenLoc(SourceLoc Loc) const {
const char *Ptr = getBufferPtrForSourceLoc(Loc);
// Skip whitespace backwards until we hit a newline. This is needed to
@@ -1770,8 +1783,7 @@
// If we have the terminating "`", it's an escaped identifier.
if (*CurPtr == '`') {
++CurPtr;
- formToken(tok::identifier, Quote);
- NextToken.setEscapedIdentifier(true);
+ formEscapedIdentifierToken(Quote);
return;
}
}
@@ -1779,8 +1791,7 @@
// Special case; allow '`$`'.
if (Quote[1] == '$' && Quote[2] == '`') {
CurPtr = Quote + 3;
- formToken(tok::identifier, Quote);
- NextToken.setEscapedIdentifier(true);
+ formEscapedIdentifierToken(Quote);
return;
}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 28c22a5..bab7f7e 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -286,10 +286,6 @@
Trivia LeadingTrivia, TrailingTrivia;
do {
L.lex(Tok, LeadingTrivia, TrailingTrivia);
- if (Tok.isEscapedIdentifier()) {
- LeadingTrivia.push_back(TriviaPiece::backtick());
- TrailingTrivia.push_front(TriviaPiece::backtick());
- }
auto ThisToken = RawTokenSyntax::make(Tok.getKind(), Tok.getText(),
SourcePresence::Present, LeadingTrivia,
TrailingTrivia);
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 795201f..21e4171 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -77,10 +77,6 @@
if (!Enabled)
return;
- if (Tok.isEscapedIdentifier()) {
- LeadingTrivia.push_back(TriviaPiece::backtick());
- TrailingTrivia.push_front(TriviaPiece::backtick());
- }
addRawSyntax(RawTokenSyntax::make(Tok.getKind(), Tok.getText(),
SourcePresence::Present, LeadingTrivia,
TrailingTrivia));
diff --git a/test/Syntax/tokens_escaped_identifier.swift b/test/Syntax/tokens_escaped_identifier.swift
new file mode 100644
index 0000000..20e3082
--- /dev/null
+++ b/test/Syntax/tokens_escaped_identifier.swift
@@ -0,0 +1,21 @@
+// RUN: %swift-syntax-test -input-source-filename %s -dump-full-tokens | %FileCheck %s
+let /*leading trivia*/ `if` = 3
+print(/*leading trivia*/ `if` )
+
+// CHECK-LABEL: 2:25
+// CHECK-NEXT:(token identifier
+// CHECK-NEXT: (trivia block_comment/*leading trivia*/)
+// CHECK-NEXT: (trivia space 1)
+// CHECK-NEXT: (trivia backtick 1)
+// CHECK-NEXT: (text="if")
+// CHECK-NEXT: (trivia backtick 1)
+// CHECK-NEXT: (trivia space 1))
+
+// CHECK-LABEL: 3:27
+// CHECK-NEXT:(token identifier
+// CHECK-NEXT: (trivia block_comment/*leading trivia*/)
+// CHECK-NEXT: (trivia space 1)
+// CHECK-NEXT: (trivia backtick 1)
+// CHECK-NEXT: (text="if")
+// CHECK-NEXT: (trivia backtick 1)
+// CHECK-NEXT: (trivia space 1))