Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An implementation for 0168-multi-line-string-literals.md #8813

Merged
merged 39 commits into from Apr 26, 2017
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d37fa1c
prototype implementation of multiline string literals
johnno1962 Apr 10, 2017
8ad6272
tidyup of line ending normalisation
johnno1962 Apr 11, 2017
12cfc63
Add multiline string literal tests
beccadax Apr 12, 2017
5c960fc
Permit tabs in multiline strings
beccadax Apr 12, 2017
3f52458
Merge pull request #1 from brentdax/multiline-literal
johnno1962 Apr 12, 2017
201acde
innitial deleimter not required to be at end of line for indent strip…
johnno1962 Apr 12, 2017
9575546
Merge branch 'master' of https://github.com/DoubleSpeak/swift
johnno1962 Apr 12, 2017
9129aaa
initial deleimter not required to be at end of line for indent stripping
johnno1962 Apr 12, 2017
e36bbd5
reinstate stripping of initial empty line
johnno1962 Apr 13, 2017
ecccee0
warning for whitespace at eand of line
johnno1962 Apr 14, 2017
965378f
always trim first line
johnno1962 Apr 14, 2017
bccae22
separate out tests
johnno1962 Apr 14, 2017
3157849
separate out tests
johnno1962 Apr 14, 2017
5723d97
better comment
johnno1962 Apr 15, 2017
cee194e
tweaks
johnno1962 Apr 17, 2017
4691cb2
fix test
johnno1962 Apr 17, 2017
ab9f827
updated to core team decision
johnno1962 Apr 23, 2017
c7d651d
strictly compliant with core team decision
johnno1962 Apr 23, 2017
49ec123
strictly compliant with core team decision
johnno1962 Apr 23, 2017
31609d0
more tests, less nits
johnno1962 Apr 23, 2017
7e512dd
tested tests
johnno1962 Apr 23, 2017
d73ef5f
test for errors
johnno1962 Apr 24, 2017
f5cf99c
test for errors
johnno1962 Apr 24, 2017
fa47a67
rewrite away from find/replace of indent
johnno1962 Apr 24, 2017
7c7b9fd
restructure tests
johnno1962 Apr 24, 2017
cadd9b9
rename tests
johnno1962 Apr 24, 2017
2c3eb13
requested changes
johnno1962 Apr 25, 2017
2ecf9a9
requested changes
johnno1962 Apr 25, 2017
1b6e411
assorted typos
johnno1962 Apr 25, 2017
f1ce3c5
additional tests
johnno1962 Apr 25, 2017
03e2ecd
bools it is
johnno1962 Apr 25, 2017
ef1dfdd
multiline inside interpolation
johnno1962 Apr 25, 2017
1e12e89
remove unused argument
johnno1962 Apr 25, 2017
56536b9
error for multi-line inside interpolation
johnno1962 Apr 25, 2017
14b1143
tests with tabs
johnno1962 Apr 25, 2017
7194004
better safe
johnno1962 Apr 25, 2017
5d3b897
typo
johnno1962 Apr 25, 2017
38be1f4
better diagnostics
johnno1962 Apr 25, 2017
0dd605f
better diagnostics
johnno1962 Apr 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/swift/AST/DiagnosticsParse.def
Expand Up @@ -125,9 +125,15 @@ ERROR(lex_invalid_u_escape_rbrace,none,
"expected '}' in \\u{...} escape sequence", ())

ERROR(lex_invalid_unicode_scalar,none,
"invalid unicode scalar", ())
"invalid unicode scalar", ())
ERROR(lex_unicode_escape_braces,none,
"expected hexadecimal code in braces after unicode escape", ())
ERROR(lex_illegal_multiline_string_start,none,
"invalid start of multi-line string literal", ())
ERROR(lex_illegal_multiline_string_end,none,
"invalid end of multi-line string literal", ())
ERROR(lex_ambiguous_string_indent,none,
"invalid mix of multi-line string literal indentation", ())


ERROR(lex_invalid_character,none,
Expand Down
28 changes: 20 additions & 8 deletions include/swift/Parse/Lexer.h
Expand Up @@ -374,13 +374,17 @@ class Lexer {
enum : char { Literal, Expr } Kind;
// Loc+Length for the segment inside the string literal, without quotes.
SourceLoc Loc;
unsigned Length;

static StringSegment getLiteral(SourceLoc Loc, unsigned Length) {
unsigned Length, Modifiers, IdentToStrip;
Copy link
Collaborator

@xwu xwu Apr 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent not Ident!


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: what is Modifiers for? If this is an option set of the enum below, please make this an OptionSet<> (or a type alias thereof). Similarly, plumbed throughout.

static StringSegment getLiteral(SourceLoc Loc, unsigned Length,
unsigned Modifiers,
unsigned IdentToStrip) {
StringSegment Result;
Result.Kind = Literal;
Result.Loc = Loc;
Result.Length = Length;
Result.Modifiers = Modifiers;
Result.IdentToStrip = IdentToStrip;
return Result;
}

Expand All @@ -389,6 +393,8 @@ class Lexer {
Result.Kind = Expr;
Result.Loc = Loc;
Result.Length = Length;
Result.Modifiers = 0;
Result.IdentToStrip = 0;
return Result;
}
};
Expand All @@ -397,12 +403,14 @@ class Lexer {
/// If a copy needs to be made, it will be allocated out of the provided
/// Buffer.
static StringRef getEncodedStringSegment(StringRef Str,
SmallVectorImpl<char> &Buffer);
SmallVectorImpl<char> &Buffer,
unsigned Modifiers = 0,
unsigned IdentToStrip = 0);
StringRef getEncodedStringSegment(StringSegment Segment,
SmallVectorImpl<char> &Buffer) const {
return getEncodedStringSegment(
StringRef(getBufferPtrForSourceLoc(Segment.Loc), Segment.Length),
Buffer);
Buffer, Segment.Modifiers, Segment.IdentToStrip);
}

/// \brief Given a string literal token, separate it into string/expr segments
Expand Down Expand Up @@ -464,7 +472,7 @@ class Lexer {
return diagnose(Loc, Diagnostic(DiagID, std::forward<ArgTypes>(Args)...));
}

void formToken(tok Kind, const char *TokStart);
void formToken(tok Kind, const char *TokStart, unsigned Modifiers = 0);

/// Advance to the end of the line but leave the current buffer pointer
/// at that newline character.
Expand Down Expand Up @@ -495,8 +503,9 @@ class Lexer {
static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);

unsigned lexCharacter(const char *&CurPtr,
char StopQuote, bool EmitDiagnostics);
void lexStringLiteral();
char StopQuote, bool EmitDiagnostics,
unsigned Modifiers = 0);
void lexStringLiteral(unsigned Modifiers = 0);
void lexEscapedIdentifier();

void tryLexEditorPlaceholder();
Expand All @@ -505,6 +514,9 @@ class Lexer {
/// Try to lex conflict markers by checking for the presence of the start and
/// end of the marker in diff3 or Perforce style respectively.
bool tryLexConflictMarker();

/// Check multiline string literal is indented correctly.
void validateMultilineIndents(const Token &Str);
};

} // end namespace swift
Expand Down
14 changes: 12 additions & 2 deletions include/swift/Parse/Token.h
Expand Up @@ -46,6 +46,9 @@ class Token {
/// \brief Whether this token is an escaped `identifier` token.
unsigned EscapedIdentifier : 1;

/// Modifiers for string literals
unsigned StringModifiers : 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to MultilineString. Update comment. Treat it as a boolean variable below (store false as initial value, etc.)


/// Text - The actual string covered by the token in the source buffer.
StringRef Text;

Expand All @@ -60,7 +63,7 @@ class Token {
EscapedIdentifier(false) {}
Token(tok Kind, StringRef Text)
: Kind(Kind), AtStartOfLine(false), CommentLength(0),
EscapedIdentifier(false),
EscapedIdentifier(false), StringModifiers(0),
Text(Text) {}

tok getKind() const { return Kind; }
Expand Down Expand Up @@ -273,11 +276,18 @@ class Token {
void setText(StringRef T) { Text = T; }

/// \brief Set the token to the specified kind and source range.
void setToken(tok K, StringRef T, unsigned CommentLength = 0) {
void setToken(tok K, StringRef T, unsigned CommentLength = 0,
unsigned Modifiers = 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to bool.

Kind = K;
Text = T;
this->CommentLength = CommentLength;
EscapedIdentifier = false;
StringModifiers = Modifiers;
assert(StringModifiers == Modifiers && "Modifier overflow");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this->MultilineString = MultilineString, remove assert.

}

unsigned getStringModifiers() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to bool, rename to isMultilineString.

return StringModifiers;
}
};

Expand Down