Skip to content

Commit ddac6ab

Browse files
authored
Merge pull request swiftlang#13301 from rintaro/lexer-lextrivia
[Syntax] Serveral improvements for Trivia lexing
2 parents c5bf2ec + 5571e5c commit ddac6ab

File tree

7 files changed

+184
-153
lines changed

7 files changed

+184
-153
lines changed

include/swift/Parse/Lexer.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,8 @@ class Lexer {
233233
Result = NextToken;
234234
LeadingTriviaResult = {LeadingTrivia};
235235
TrailingTriviaResult = {TrailingTrivia};
236-
if (Result.isNot(tok::eof)) {
237-
LeadingTrivia.clear();
238-
TrailingTrivia.clear();
236+
if (Result.isNot(tok::eof))
239237
lexImpl();
240-
}
241238
}
242239

243240
void lex(Token &Result) {
@@ -288,8 +285,6 @@ class Lexer {
288285
void restoreState(State S, bool enableDiagnostics = false) {
289286
assert(S.isValid());
290287
CurPtr = getBufferPtrForSourceLoc(S.Loc);
291-
LeadingTrivia.clear();
292-
TrailingTrivia.clear();
293288
// Don't reemit diagnostics while readvancing the lexer.
294289
llvm::SaveAndRestore<DiagnosticEngine*>
295290
D(Diags, enableDiagnostics ? Diags : nullptr);
@@ -517,12 +512,7 @@ class Lexer {
517512
void lexOperatorIdentifier();
518513
void lexHexNumber();
519514
void lexNumber();
520-
void lexTrivia(syntax::TriviaList &T, bool StopAtFirstNewline = false);
521-
Optional<syntax::TriviaPiece> lexWhitespace(bool StopAtFirstNewline);
522-
Optional<syntax::TriviaPiece> lexComment();
523-
Optional<syntax::TriviaPiece> lexSingleLineComment(syntax::TriviaKind Kind);
524-
Optional<syntax::TriviaPiece> lexBlockComment(syntax::TriviaKind Kind);
525-
Optional<syntax::TriviaPiece> lexDocComment();
515+
void lexTrivia(syntax::TriviaList &T, bool IsForTrailingTrivia);
526516
static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);
527517

528518
unsigned lexCharacter(const char *&CurPtr,

include/swift/Syntax/Serialization/SyntaxSerialization.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ struct ObjectTraits<syntax::TriviaPiece> {
7474
case syntax::TriviaKind::LineComment:
7575
case syntax::TriviaKind::BlockComment:
7676
case syntax::TriviaKind::DocLineComment:
77-
case syntax::TriviaKind::DocBlockComment: {
77+
case syntax::TriviaKind::DocBlockComment:
78+
case syntax::TriviaKind::GarbageText: {
7879
auto text = value.Text.str();
7980
out.mapRequired("value", text);
8081
break;
@@ -97,6 +98,7 @@ struct ScalarEnumerationTraits<syntax::TriviaKind> {
9798
out.enumCase(value, "DocLineComment", syntax::TriviaKind::DocLineComment);
9899
out.enumCase(value, "DocBlockComment", syntax::TriviaKind::DocBlockComment);
99100
out.enumCase(value, "Backtick", syntax::TriviaKind::Backtick);
101+
out.enumCase(value, "GarbageText", syntax::TriviaKind::GarbageText);
100102
}
101103
};
102104

include/swift/Syntax/Trivia.h

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@
8585
#include <vector>
8686

8787
namespace swift {
88+
89+
namespace json {
90+
template <class T> struct ObjectTraits;
91+
}
92+
8893
namespace syntax {
8994

9095
class AbsolutePosition;
@@ -118,6 +123,9 @@ enum class TriviaKind {
118123
/// A documentation block comment, starting with '/**' and ending with '*/.
119124
DocBlockComment,
120125

126+
/// Any skipped garbage text.
127+
GarbageText,
128+
121129
/// A backtick '`' character, used to escape identifiers.
122130
Backtick,
123131
};
@@ -133,63 +141,88 @@ enum class TriviaKind {
133141
///
134142
/// In general, you should deal with the actual Trivia collection instead
135143
/// of individual pieces whenever possible.
136-
struct TriviaPiece {
144+
class TriviaPiece {
137145
TriviaKind Kind;
138146
unsigned Count;
139147
OwnedString Text;
140148

141-
TriviaPiece(const TriviaKind Kind, const unsigned Count,
142-
const OwnedString Text)
143-
: Kind(Kind), Count(Count), Text(Text) {}
149+
TriviaPiece(const TriviaKind Kind, const OwnedString Text)
150+
: Kind(Kind), Count(1), Text(Text) {}
151+
TriviaPiece(const TriviaKind Kind, const unsigned Count)
152+
: Kind(Kind), Count(Count), Text() {}
144153

154+
friend struct json::ObjectTraits<TriviaPiece>;
155+
156+
public:
145157
/// Return a piece of trivia for some number of space characters in a row.
146158
static TriviaPiece spaces(unsigned Count) {
147-
return TriviaPiece {TriviaKind::Space, Count, OwnedString{}};
159+
return {TriviaKind::Space, Count};
148160
}
149161

150162
/// Return a piece of trivia for some number of tab characters in a row.
151163
static TriviaPiece tabs(unsigned Count) {
152-
return TriviaPiece {TriviaKind::Tab, Count, OwnedString{}};
164+
return {TriviaKind::Tab, Count};
165+
}
166+
167+
/// Return a piece of trivia for some number of vertical tab characters in a
168+
/// row.
169+
static TriviaPiece verticalTabs(unsigned Count) {
170+
return {TriviaKind::VerticalTab, Count};
171+
}
172+
173+
/// Return a piece of trivia for some number of form-feed characters in a row.
174+
static TriviaPiece formfeeds(unsigned Count) {
175+
return {TriviaKind::Formfeed, Count};
153176
}
154177

155178
/// Return a piece of trivia for some number of newline characters
156179
/// in a row.
157180
static TriviaPiece newlines(unsigned Count) {
158-
return TriviaPiece {TriviaKind::Newline, Count, OwnedString{}};
181+
return {TriviaKind::Newline, Count};
159182
}
160183

161184
/// Return a piece of trivia for a single line of ('//') developer comment.
162185
static TriviaPiece lineComment(const OwnedString Text) {
163-
return TriviaPiece {TriviaKind::LineComment, 1, Text};
186+
return {TriviaKind::LineComment, Text};
164187
}
165188

166189
/// Return a piece of trivia for a block comment ('/* ... */')
167190
static TriviaPiece blockComment(const OwnedString Text) {
168-
return TriviaPiece {TriviaKind::BlockComment, 1, Text};
191+
return {TriviaKind::BlockComment, Text};
169192
}
170193

171194
/// Return a piece of trivia for a single line of ('///') doc comment.
172195
static TriviaPiece docLineComment(const OwnedString Text) {
173-
return TriviaPiece {TriviaKind::DocLineComment, 1, Text};
196+
return {TriviaKind::DocLineComment, Text};
174197
}
175198

176199
/// Return a piece of trivia for a documentation block comment ('/** ... */')
177200
static TriviaPiece docBlockComment(const OwnedString Text) {
178-
return TriviaPiece {TriviaKind::DocBlockComment, 1, Text};
201+
return {TriviaKind::DocBlockComment, Text};
202+
}
203+
204+
/// Return a piece of trivia for any skipped garbage text.
205+
static TriviaPiece garbageText(const OwnedString Text) {
206+
return {TriviaKind::GarbageText, Text};
179207
}
180208

181209
/// Return a piece of trivia for a single backtick '`' for escaping
182210
/// an identifier.
183211
static TriviaPiece backtick() {
184-
return TriviaPiece {TriviaKind::Backtick, 1, OwnedString{}};
212+
return {TriviaKind::Backtick, 1};
185213
}
186214

215+
/// Return kind of the trivia.
216+
TriviaKind getKind() const { return Kind; }
217+
218+
/// Return textual length of the trivia.
187219
size_t getTextLength() const {
188220
switch (Kind) {
189221
case TriviaKind::LineComment:
190222
case TriviaKind::BlockComment:
191223
case TriviaKind::DocBlockComment:
192224
case TriviaKind::DocLineComment:
225+
case TriviaKind::GarbageText:
193226
return Text.size();
194227
case TriviaKind::Newline:
195228
case TriviaKind::Space:
@@ -340,15 +373,15 @@ struct Trivia {
340373
if (Count == 0) {
341374
return {};
342375
}
343-
return {{ TriviaPiece {TriviaKind::Space, Count, OwnedString{}} }};
376+
return {{TriviaPiece::spaces(Count)}};
344377
}
345378

346379
/// Return a collection of trivia of some number of tab characters in a row.
347380
static Trivia tabs(unsigned Count) {
348381
if (Count == 0) {
349382
return {};
350383
}
351-
return {{ TriviaPiece {TriviaKind::Tab, Count, OwnedString{}} }};
384+
return {{TriviaPiece::tabs(Count)}};
352385
}
353386

354387
/// Return a collection of trivia of some number of newline characters
@@ -357,43 +390,49 @@ struct Trivia {
357390
if (Count == 0) {
358391
return {};
359392
}
360-
return {{ TriviaPiece {TriviaKind::Newline, Count, OwnedString{}} }};
393+
return {{TriviaPiece::newlines(Count)}};
361394
}
362395

363396
/// Return a collection of trivia with a single line of ('//')
364397
// developer comment.
365398
static Trivia lineComment(const OwnedString Text) {
366399
assert(Text.str().startswith("//"));
367-
return {{ TriviaPiece {TriviaKind::LineComment, 1, Text} }};
400+
return {{TriviaPiece::lineComment(Text)}};
368401
}
369402

370403
/// Return a collection of trivia with a block comment ('/* ... */')
371404
static Trivia blockComment(const OwnedString Text) {
372405
assert(Text.str().startswith("/*"));
373406
assert(Text.str().endswith("*/"));
374-
return {{ TriviaPiece {TriviaKind::BlockComment, 1, Text} }};
407+
return {{TriviaPiece::blockComment(Text)}};
375408
}
376409

377410
/// Return a collection of trivia with a single line of ('///') doc comment.
378411
static Trivia docLineComment(const OwnedString Text) {
379412
assert(Text.str().startswith("///"));
380-
return {{ TriviaPiece {TriviaKind::DocLineComment, 1, Text} }};
413+
return {{TriviaPiece::docLineComment(Text)}};
381414
}
382415

383416
/// Return a collection of trivia with a documentation block
384417
// comment ('/** ... */')
385418
static Trivia docBlockComment(const OwnedString Text) {
386419
assert(Text.str().startswith("/**"));
387420
assert(Text.str().endswith("*/"));
388-
return {{ TriviaPiece {TriviaKind::DocBlockComment, 1, Text} }};
421+
return {{TriviaPiece::docBlockComment(Text)}};
422+
}
423+
424+
/// Return a collection of trivia with any skipped garbage text.
425+
static Trivia garbageText(const OwnedString Text) {
426+
assert(Text.size() > 0);
427+
return {{TriviaPiece::garbageText(Text)}};
389428
}
390429

391430
/// Return a piece of trivia for a single backtick '`' for escaping
392431
/// an identifier.
393432
static Trivia backtick() {
394-
return {{ TriviaPiece {TriviaKind::Backtick, 1, OwnedString{}} }};
433+
return {{TriviaPiece::backtick()}};
395434
}
396435
};
397-
}
398-
}
436+
} // namespace syntax
437+
} // namespace swift
399438
#endif // SWIFT_SYNTAX_TRIVIA_H

0 commit comments

Comments
 (0)