mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Implement SE-0200 (extended escaping in string literals)
Supports string literals like #"foo"\n"bar"#.
This commit is contained in:
committed by
Brent Royal-Gordon
parent
5e2b705f6d
commit
4da8cbe655
@@ -364,12 +364,13 @@ public:
|
||||
enum : char { Literal, Expr } Kind;
|
||||
// Loc+Length for the segment inside the string literal, without quotes.
|
||||
SourceLoc Loc;
|
||||
unsigned Length, IndentToStrip;
|
||||
unsigned Length, IndentToStrip, CustomDelimiterLen;
|
||||
bool IsFirstSegment, IsLastSegment;
|
||||
|
||||
static StringSegment getLiteral(SourceLoc Loc, unsigned Length,
|
||||
bool IsFirstSegment, bool IsLastSegment,
|
||||
unsigned IndentToStrip) {
|
||||
unsigned IndentToStrip,
|
||||
unsigned CustomDelimiterLen) {
|
||||
StringSegment Result;
|
||||
Result.Kind = Literal;
|
||||
Result.Loc = Loc;
|
||||
@@ -377,6 +378,7 @@ public:
|
||||
Result.IsFirstSegment = IsFirstSegment;
|
||||
Result.IsLastSegment = IsLastSegment;
|
||||
Result.IndentToStrip = IndentToStrip;
|
||||
Result.CustomDelimiterLen = CustomDelimiterLen;
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -388,6 +390,7 @@ public:
|
||||
Result.IsFirstSegment = false;
|
||||
Result.IsLastSegment = false;
|
||||
Result.IndentToStrip = 0;
|
||||
Result.CustomDelimiterLen = 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -404,13 +407,14 @@ public:
|
||||
SmallVectorImpl<char> &Buffer,
|
||||
bool IsFirstSegment = false,
|
||||
bool IsLastSegment = false,
|
||||
unsigned IndentToStrip = 0);
|
||||
unsigned IndentToStrip = 0,
|
||||
unsigned CustomDelimiterLen = 0);
|
||||
StringRef getEncodedStringSegment(StringSegment Segment,
|
||||
SmallVectorImpl<char> &Buffer) const {
|
||||
return getEncodedStringSegment(
|
||||
StringRef(getBufferPtrForSourceLoc(Segment.Loc), Segment.Length),
|
||||
Buffer, Segment.IsFirstSegment, Segment.IsLastSegment,
|
||||
Segment.IndentToStrip);
|
||||
Segment.IndentToStrip, Segment.CustomDelimiterLen);
|
||||
}
|
||||
|
||||
/// \brief Given a string literal token, separate it into string/expr segments
|
||||
@@ -474,7 +478,8 @@ private:
|
||||
return diagnose(Loc, Diagnostic(DiagID, std::forward<ArgTypes>(Args)...));
|
||||
}
|
||||
|
||||
void formToken(tok Kind, const char *TokStart, bool MultilineString = false);
|
||||
void formToken(tok Kind, const char *TokStart, bool IsMultilineString = false,
|
||||
unsigned CustomDelimiterLen = 0);
|
||||
void formEscapedIdentifierToken(const char *TokStart);
|
||||
|
||||
/// Advance to the end of the line.
|
||||
@@ -498,10 +503,10 @@ private:
|
||||
void lexTrivia(syntax::Trivia &T, bool IsForTrailingTrivia);
|
||||
static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);
|
||||
|
||||
unsigned lexCharacter(const char *&CurPtr,
|
||||
char StopQuote, bool EmitDiagnostics,
|
||||
bool MultilineString = false);
|
||||
void lexStringLiteral();
|
||||
unsigned lexCharacter(const char *&CurPtr, char StopQuote,
|
||||
bool EmitDiagnostics, bool IsMultilineString = false,
|
||||
unsigned CustomDelimiterLen = 0);
|
||||
void lexStringLiteral(unsigned CustomDelimiterLen = 0);
|
||||
void lexEscapedIdentifier();
|
||||
|
||||
void tryLexEditorPlaceholder();
|
||||
|
||||
@@ -45,7 +45,10 @@ class Token {
|
||||
/// Modifiers for string literals
|
||||
unsigned MultilineString : 1;
|
||||
|
||||
// Padding bits == 32 - sizeof(Kind) * 8 - 3;
|
||||
/// Length of custom delimiter of "raw" string literals
|
||||
unsigned CustomDelimiterLen : 8;
|
||||
|
||||
// Padding bits == 32 - 11;
|
||||
|
||||
/// \brief The length of the comment that precedes the token.
|
||||
unsigned CommentLength;
|
||||
@@ -62,8 +65,8 @@ class Token {
|
||||
public:
|
||||
Token(tok Kind, StringRef Text, unsigned CommentLength = 0)
|
||||
: Kind(Kind), AtStartOfLine(false), EscapedIdentifier(false),
|
||||
MultilineString(false), CommentLength(CommentLength),
|
||||
Text(Text) {}
|
||||
MultilineString(false), CustomDelimiterLen(0),
|
||||
CommentLength(CommentLength), Text(Text) {}
|
||||
|
||||
Token() : Token(tok::NUM_TOKENS, {}, 0) {}
|
||||
|
||||
@@ -266,17 +269,24 @@ public:
|
||||
|
||||
/// \brief Set the token to the specified kind and source range.
|
||||
void setToken(tok K, StringRef T, unsigned CommentLength = 0,
|
||||
bool MultilineString = false) {
|
||||
bool IsMultilineString = false, unsigned CustomDelimiterLen = 0) {
|
||||
Kind = K;
|
||||
Text = T;
|
||||
this->CommentLength = CommentLength;
|
||||
EscapedIdentifier = false;
|
||||
this->MultilineString = MultilineString;
|
||||
this->MultilineString = IsMultilineString;
|
||||
this->CustomDelimiterLen = CustomDelimiterLen;
|
||||
assert(this->CustomDelimiterLen == CustomDelimiterLen &&
|
||||
"custom string delimiter length > 255");
|
||||
}
|
||||
|
||||
bool IsMultilineString() const {
|
||||
bool isMultilineString() const {
|
||||
return MultilineString;
|
||||
}
|
||||
|
||||
unsigned getCustomDelimiterLen() const {
|
||||
return CustomDelimiterLen;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
Reference in New Issue
Block a user