Skip to content

Commit 5e1ba8b

Browse files
committed
[libSyntax] Store raw trivia inside RawSyntax and only lex into pieces when requested
1 parent 3adefd3 commit 5e1ba8b

17 files changed

+277
-629
lines changed

include/swift/Syntax/RawSyntax.h

Lines changed: 36 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ typedef unsigned SyntaxNodeId;
150150
///
151151
/// This is implementation detail - do not expose it in public API.
152152
class RawSyntax final
153-
: private llvm::TrailingObjects<RawSyntax, RC<RawSyntax>, OwnedString,
154-
TriviaPiece> {
153+
: private llvm::TrailingObjects<RawSyntax, RC<RawSyntax>, OwnedString> {
155154
friend TrailingObjects;
156155

157156
/// The ID that shall be used for the next node that is created and does not
@@ -198,10 +197,8 @@ class RawSyntax final
198197
uint64_t : bitmax(NumRawSyntaxBits, 64); // align to 16 bits
199198
/// The kind of token this "token" node represents.
200199
unsigned TokenKind : 16;
201-
/// Number of leading trivia pieces.
202-
unsigned NumLeadingTrivia : 16;
203-
/// Number of trailing trivia pieces.
204-
unsigned NumTrailingTrivia : 16;
200+
StringRef LeadingTrivia;
201+
StringRef TrailingTrivia;
205202
} Token;
206203
} Bits;
207204

@@ -211,11 +208,6 @@ class RawSyntax final
211208
size_t numTrailingObjects(OverloadToken<OwnedString>) const {
212209
return isToken() ? 1 : 0;
213210
}
214-
size_t numTrailingObjects(OverloadToken<TriviaPiece>) const {
215-
return isToken()
216-
? Bits.Token.NumLeadingTrivia + Bits.Token.NumTrailingTrivia
217-
: 0;
218-
}
219211

220212
/// Constructor for creating layout nodes.
221213
/// If the node has been allocated inside the bump allocator of a
@@ -232,9 +224,9 @@ class RawSyntax final
232224
/// If \p NodeId is \c None, the next free NodeId is used, if it is passed,
233225
/// the caller needs to assure that the NodeId has not been used yet.
234226
RawSyntax(tok TokKind, OwnedString Text, size_t TextLength,
235-
ArrayRef<TriviaPiece> LeadingTrivia,
236-
ArrayRef<TriviaPiece> TrailingTrivia, SourcePresence Presence,
237-
const RC<SyntaxArena> &Arena, llvm::Optional<SyntaxNodeId> NodeId);
227+
StringRef LeadingTrivia, StringRef TrailingTrivia,
228+
SourcePresence Presence, const RC<SyntaxArena> &Arena,
229+
llvm::Optional<SyntaxNodeId> NodeId);
238230

239231
/// Compute the node's text length by summing up the length of its childern
240232
size_t computeTextLength() {
@@ -295,27 +287,22 @@ class RawSyntax final
295287

296288
/// Make a raw "token" syntax node.
297289
static RC<RawSyntax> make(tok TokKind, OwnedString Text, size_t TextLength,
298-
ArrayRef<TriviaPiece> LeadingTrivia,
299-
ArrayRef<TriviaPiece> TrailingTrivia,
290+
StringRef LeadingTrivia, StringRef TrailingTrivia,
300291
SourcePresence Presence,
301292
const RC<SyntaxArena> &Arena = SyntaxArena::make(),
302293
llvm::Optional<SyntaxNodeId> NodeId = llvm::None);
303294

304295
/// Make a raw "token" syntax node that was allocated in \p Arena.
305-
static RC<RawSyntax> makeAndCalcLength(
306-
tok TokKind, OwnedString Text, ArrayRef<TriviaPiece> LeadingTrivia,
307-
ArrayRef<TriviaPiece> TrailingTrivia, SourcePresence Presence,
308-
const RC<SyntaxArena> &Arena = SyntaxArena::make(),
309-
llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
296+
static RC<RawSyntax>
297+
makeAndCalcLength(tok TokKind, OwnedString Text, StringRef LeadingTrivia,
298+
StringRef TrailingTrivia, SourcePresence Presence,
299+
const RC<SyntaxArena> &Arena = SyntaxArena::make(),
300+
llvm::Optional<SyntaxNodeId> NodeId = llvm::None) {
310301
size_t TextLength = 0;
311302
if (Presence != SourcePresence::Missing) {
312-
for (auto Trivia : LeadingTrivia) {
313-
TextLength += Trivia.getTextLength();
314-
}
303+
TextLength += LeadingTrivia.size();
315304
TextLength += Text.size();
316-
for (auto Trivia : TrailingTrivia) {
317-
TextLength += Trivia.getTextLength();
318-
}
305+
TextLength += TrailingTrivia.size();
319306
}
320307
return make(TokKind, Text, TextLength, LeadingTrivia, TrailingTrivia,
321308
Presence, Arena, NodeId);
@@ -414,18 +401,28 @@ class RawSyntax final
414401
/// disappear when the syntax node gets freed.
415402
StringRef getTokenText() const { return getOwnedTokenText().str(); }
416403

417-
/// Return the leading trivia list of the token.
418-
ArrayRef<TriviaPiece> getLeadingTrivia() const {
404+
/// Return the unparsed leading trivia of the token.
405+
StringRef getLeadingTrivia() const {
419406
assert(isToken());
420-
return {getTrailingObjects<TriviaPiece>(), Bits.Token.NumLeadingTrivia};
407+
return Bits.Token.LeadingTrivia;
421408
}
422-
/// Return the trailing trivia list of the token.
423-
ArrayRef<TriviaPiece> getTrailingTrivia() const {
409+
410+
/// Return the unparsed trailing trivia of the token.
411+
StringRef getTrailingTrivia() const {
424412
assert(isToken());
425-
return {getTrailingObjects<TriviaPiece>() + Bits.Token.NumLeadingTrivia,
426-
Bits.Token.NumTrailingTrivia};
413+
return Bits.Token.TrailingTrivia;
427414
}
428415

416+
/// Return pieces that make up the leading trivia of the token.
417+
/// Note that this triggers trivia parsing which may be expensive. If the
418+
/// trivia pieces are required multiple times, consider caching them.
419+
Trivia getLeadingTriviaPieces() const;
420+
421+
/// Return the trailing trivia list of the token.
422+
/// Note that this triggers trivia parsing which may be expensive. If the
423+
/// trivia pieces are required multiple times, consider caching them.
424+
Trivia getTrailingTriviaPieces() const;
425+
429426
/// Return \c true if this is the given kind of token.
430427
bool isToken(tok K) const { return isToken() && getTokenKind() == K; }
431428

@@ -436,30 +433,20 @@ class RawSyntax final
436433

437434
/// Return a new token like this one, but with the given leading
438435
/// trivia instead.
439-
RC<RawSyntax>
440-
withLeadingTrivia(ArrayRef<TriviaPiece> NewLeadingTrivia) const {
436+
RC<RawSyntax> withLeadingTrivia(StringRef NewLeadingTrivia) const {
441437
return makeAndCalcLength(getTokenKind(), getOwnedTokenText(),
442438
NewLeadingTrivia, getTrailingTrivia(),
443439
getPresence());
444440
}
445441

446-
RC<RawSyntax> withLeadingTrivia(Trivia NewLeadingTrivia) const {
447-
return withLeadingTrivia(NewLeadingTrivia.Pieces);
448-
}
449-
450442
/// Return a new token like this one, but with the given trailing
451443
/// trivia instead.
452-
RC<RawSyntax>
453-
withTrailingTrivia(ArrayRef<TriviaPiece> NewTrailingTrivia) const {
444+
RC<RawSyntax> withTrailingTrivia(StringRef NewTrailingTrivia) const {
454445
return makeAndCalcLength(getTokenKind(), getOwnedTokenText(),
455446
getLeadingTrivia(), NewTrailingTrivia,
456447
getPresence());
457448
}
458449

459-
RC<RawSyntax> withTrailingTrivia(Trivia NewTrailingTrivia) const {
460-
return withTrailingTrivia(NewTrailingTrivia.Pieces);
461-
}
462-
463450
/// @}
464451

465452
/// \name Getter routines for "layout" nodes.
@@ -503,21 +490,9 @@ class RawSyntax final
503490

504491
/// @}
505492

506-
size_t getLeadingTriviaLength() {
507-
size_t Length = 0;
508-
for (auto Trivia : getLeadingTrivia()) {
509-
Length += Trivia.getTextLength();
510-
}
511-
return Length;
512-
}
493+
size_t getLeadingTriviaLength() const { return getLeadingTrivia().size(); }
513494

514-
size_t getTrailingTriviaLength() {
515-
size_t Length = 0;
516-
for (auto Trivia : getTrailingTrivia()) {
517-
Length += Trivia.getTextLength();
518-
}
519-
return Length;
520-
}
495+
size_t getTrailingTriviaLength() const { return getTrailingTrivia().size(); }
521496

522497
/// Print this piece of syntax recursively.
523498
void print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const;
@@ -529,8 +504,7 @@ class RawSyntax final
529504
void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;
530505

531506
static void Profile(llvm::FoldingSetNodeID &ID, tok TokKind, OwnedString Text,
532-
ArrayRef<TriviaPiece> LeadingTrivia,
533-
ArrayRef<TriviaPiece> TrailingTrivia);
507+
StringRef LeadingTrivia, StringRef TrailingTrivia);
534508
};
535509

536510
} // end namespace syntax

include/swift/Syntax/Serialization/SyntaxDeserialization.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ template <> struct MappingTraits<swift::RC<swift::RawSyntax>> {
150150
if (description.hasValue) {
151151
swift::tok tokenKind = description.Kind;
152152
StringRef text = description.Text;
153-
std::vector<swift::TriviaPiece> leadingTrivia;
153+
StringRef leadingTrivia;
154154
in.mapRequired("leadingTrivia", leadingTrivia);
155-
std::vector<swift::TriviaPiece> trailingTrivia;
155+
StringRef trailingTrivia;
156156
in.mapRequired("trailingTrivia", trailingTrivia);
157157
swift::SourcePresence presence;
158158
in.mapRequired("presence", presence);

include/swift/Syntax/SyntaxFactory.h.gyb

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class SyntaxArena;
4646
struct SyntaxFactory {
4747
/// Make any kind of token.
4848
static TokenSyntax makeToken(tok Kind,
49-
OwnedString Text, const Trivia &LeadingTrivia,
50-
const Trivia &TrailingTrivia, SourcePresence Presence,
49+
OwnedString Text, StringRef LeadingTrivia, StringRef TrailingTrivia,
50+
SourcePresence Presence,
5151
const RC<SyntaxArena> &Arena = SyntaxArena::make()
5252
);
5353

@@ -100,16 +100,16 @@ struct SyntaxFactory {
100100

101101
% for token in SYNTAX_TOKENS:
102102
% if token.is_keyword:
103-
static TokenSyntax make${token.name}Keyword(const Trivia &LeadingTrivia,
104-
const Trivia &TrailingTrivia,
103+
static TokenSyntax make${token.name}Keyword(StringRef LeadingTrivia,
104+
StringRef TrailingTrivia,
105105
const RC<SyntaxArena> &Arena = SyntaxArena::make());
106106
% elif token.text:
107-
static TokenSyntax make${token.name}Token(const Trivia &LeadingTrivia,
108-
const Trivia &TrailingTrivia,
107+
static TokenSyntax make${token.name}Token(StringRef LeadingTrivia,
108+
StringRef TrailingTrivia,
109109
const RC<SyntaxArena> &Arena = SyntaxArena::make());
110110
% else:
111111
static TokenSyntax make${token.name}(OwnedString Text,
112-
const Trivia &LeadingTrivia, const Trivia &TrailingTrivia,
112+
StringRef LeadingTrivia, StringRef TrailingTrivia,
113113
const RC<SyntaxArena> &Arena = SyntaxArena::make());
114114
% end
115115
% end
@@ -140,7 +140,7 @@ struct SyntaxFactory {
140140
/// Creates a TypeIdentifierSyntax with the provided name and leading/trailing
141141
/// trivia.
142142
static TypeSyntax makeTypeIdentifier(OwnedString TypeName,
143-
const Trivia &LeadingTrivia = {}, const Trivia &TrailingTrivia = {},
143+
StringRef LeadingTrivia = {}, StringRef TrailingTrivia = {},
144144
const RC<SyntaxArena> &Arena = SyntaxArena::make()
145145
);
146146

@@ -153,32 +153,32 @@ struct SyntaxFactory {
153153
);
154154

155155
/// Creates a TypeIdentifierSyntax for the `Any` type.
156-
static TypeSyntax makeAnyTypeIdentifier(const Trivia &LeadingTrivia = {},
157-
const Trivia &TrailingTrivia = {},
156+
static TypeSyntax makeAnyTypeIdentifier(StringRef LeadingTrivia = {},
157+
StringRef TrailingTrivia = {},
158158
const RC<SyntaxArena> &Arena = SyntaxArena::make()
159159
);
160160

161161
/// Creates a TypeIdentifierSyntax for the `Self` type.
162-
static TypeSyntax makeSelfTypeIdentifier(const Trivia &LeadingTrivia = {},
163-
const Trivia &TrailingTrivia = {},
162+
static TypeSyntax makeSelfTypeIdentifier(StringRef LeadingTrivia = {},
163+
StringRef TrailingTrivia = {},
164164
const RC<SyntaxArena> &Arena = SyntaxArena::make()
165165
);
166166

167167
/// Creates a TokenSyntax for the `Type` identifier.
168-
static TokenSyntax makeTypeToken(const Trivia &LeadingTrivia = {},
169-
const Trivia &TrailingTrivia = {},
168+
static TokenSyntax makeTypeToken(StringRef LeadingTrivia = {},
169+
StringRef TrailingTrivia = {},
170170
const RC<SyntaxArena> &Arena = SyntaxArena::make()
171171
);
172172

173173
/// Creates a TokenSyntax for the `Protocol` identifier.
174-
static TokenSyntax makeProtocolToken(const Trivia &LeadingTrivia = {},
175-
const Trivia &TrailingTrivia = {},
174+
static TokenSyntax makeProtocolToken(StringRef LeadingTrivia = {},
175+
StringRef TrailingTrivia = {},
176176
const RC<SyntaxArena> &Arena = SyntaxArena::make()
177177
);
178178

179179
/// Creates an `==` operator token.
180-
static TokenSyntax makeEqualityOperator(const Trivia &LeadingTrivia = {},
181-
const Trivia &TrailingTrivia = {},
180+
static TokenSyntax makeEqualityOperator(StringRef LeadingTrivia = {},
181+
StringRef TrailingTrivia = {},
182182
const RC<SyntaxArena> &Arena = SyntaxArena::make()
183183
);
184184

include/swift/Syntax/TokenSyntax.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,22 @@ class TokenSyntax final : public Syntax {
3939
return makeRoot<TokenSyntax>(RawSyntax::missing(Kind, Text));
4040
}
4141

42-
Trivia getLeadingTrivia() const {
43-
return Trivia { getRaw()->getLeadingTrivia().vec() };
44-
}
42+
StringRef getLeadingTrivia() const { return getRaw()->getLeadingTrivia(); }
43+
Trivia getLeadingTriviaPieces() const { return getRaw()->getLeadingTriviaPieces(); }
4544

46-
Trivia getTrailingTrivia() const {
47-
return Trivia { getRaw()->getTrailingTrivia().vec() };
45+
StringRef getTrailingTrivia() const { return getRaw()->getTrailingTrivia(); }
46+
Trivia getTrailingTriviaPieces() const {
47+
return getRaw()->getTrailingTriviaPieces();
4848
}
4949

50-
TokenSyntax withLeadingTrivia(const Trivia &Trivia) const {
51-
auto NewRaw = getRaw()->withLeadingTrivia(Trivia.Pieces);
52-
return TokenSyntax(Data.replacingSelf(NewRaw));
50+
TokenSyntax withLeadingTrivia(StringRef Trivia) const {
51+
auto NewRaw = getRaw()->withLeadingTrivia(Trivia);
52+
return TokenSyntax(getData().replacingSelf(NewRaw));
5353
}
5454

55-
TokenSyntax withTrailingTrivia(const Trivia &Trivia) const {
56-
auto NewRaw = getRaw()->withTrailingTrivia(Trivia.Pieces);
57-
return TokenSyntax(Data.replacingSelf(NewRaw));
55+
TokenSyntax withTrailingTrivia(StringRef Trivia) const {
56+
auto NewRaw = getRaw()->withTrailingTrivia(Trivia);
57+
return TokenSyntax(getData().replacingSelf(NewRaw));
5858
}
5959

6060
/* TODO: If we really need them.

lib/Parse/Parser.cpp

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ void tokenize(const LangOptions &LangOpts, const SourceManager &SM,
8484
if (F != ResetTokens.end()) {
8585
assert(F->isNot(tok::string_literal));
8686

87-
DestFunc(*F, ParsedTrivia(), ParsedTrivia());
87+
DestFunc(*F, /*LeadingTrivia=*/StringRef(),
88+
/*TrailingTrivia=*/StringRef());
8889

8990
auto NewState = L.getStateForBeginningOfTokenLoc(
9091
F->getLoc().getAdvancedLoc(F->getLength()));
@@ -96,12 +97,11 @@ void tokenize(const LangOptions &LangOpts, const SourceManager &SM,
9697
std::vector<Token> StrTokens;
9798
getStringPartTokens(Tok, LangOpts, SM, BufferID, StrTokens);
9899
for (auto &StrTok : StrTokens) {
99-
DestFunc(StrTok, ParsedTrivia(), ParsedTrivia());
100+
DestFunc(StrTok, /*LeadingTrivia=*/StringRef(),
101+
/*TrailingTrivia=*/StringRef());
100102
}
101103
} else {
102-
auto LeadingTriviaPieces = TriviaLexer::lexTrivia(LeadingTrivia);
103-
auto TrailingTriviaPieces = TriviaLexer::lexTrivia(TrailingTrivia);
104-
DestFunc(Tok, LeadingTriviaPieces, TrailingTriviaPieces);
104+
DestFunc(Tok, LeadingTrivia, TrailingTrivia);
105105
}
106106

107107
} while (Tok.getKind() != tok::eof);
@@ -308,14 +308,13 @@ std::vector<Token> swift::tokenize(const LangOptions &LangOpts,
308308
ArrayRef<Token> SplitTokens) {
309309
std::vector<Token> Tokens;
310310

311-
tokenize(LangOpts, SM, BufferID, Offset, EndOffset,
312-
Diags,
311+
tokenize(LangOpts, SM, BufferID, Offset, EndOffset, Diags,
313312
KeepComments ? CommentRetentionMode::ReturnAsTokens
314313
: CommentRetentionMode::AttachToNextToken,
315314
TriviaRetentionMode::WithoutTrivia, TokenizeInterpolatedString,
316315
SplitTokens,
317-
[&](const Token &Tok, const ParsedTrivia &LeadingTrivia,
318-
const ParsedTrivia &TrailingTrivia) { Tokens.push_back(Tok); });
316+
[&](const Token &Tok, StringRef LeadingTrivia,
317+
StringRef TrailingTrivia) { Tokens.push_back(Tok); });
319318

320319
assert(Tokens.back().is(tok::eof));
321320
Tokens.pop_back(); // Remove EOF.
@@ -335,24 +334,14 @@ swift::tokenizeWithTrivia(const LangOptions &LangOpts, const SourceManager &SM,
335334
CommentRetentionMode::AttachToNextToken, TriviaRetentionMode::WithTrivia,
336335
/*TokenizeInterpolatedString=*/false,
337336
/*SplitTokens=*/ArrayRef<Token>(),
338-
[&](const Token &Tok, const ParsedTrivia &LeadingTrivia,
339-
const ParsedTrivia &TrailingTrivia) {
337+
[&](const Token &Tok, StringRef LeadingTrivia, StringRef TrailingTrivia) {
340338
CharSourceRange TokRange = Tok.getRange();
341-
SourceLoc LeadingTriviaLoc =
342-
TokRange.getStart().getAdvancedLoc(-LeadingTrivia.getLength());
343-
SourceLoc TrailingTriviaLoc =
344-
TokRange.getStart().getAdvancedLoc(TokRange.getByteLength());
345-
Trivia syntaxLeadingTrivia =
346-
LeadingTrivia.convertToSyntaxTrivia(LeadingTriviaLoc, SM, BufferID);
347-
Trivia syntaxTrailingTrivia =
348-
TrailingTrivia.convertToSyntaxTrivia(TrailingTriviaLoc, SM, BufferID);
349339
auto Text = OwnedString::makeRefCounted(Tok.getRawText());
350-
size_t TextLength = LeadingTrivia.getLength() +
351-
TokRange.getByteLength() +
352-
TrailingTrivia.getLength();
353-
auto ThisToken = RawSyntax::make(
354-
Tok.getKind(), Text, TextLength, syntaxLeadingTrivia.Pieces,
355-
syntaxTrailingTrivia.Pieces, SourcePresence::Present);
340+
size_t TextLength = LeadingTrivia.size() + TokRange.getByteLength() +
341+
TrailingTrivia.size();
342+
auto ThisToken =
343+
RawSyntax::make(Tok.getKind(), Text, TextLength, LeadingTrivia,
344+
TrailingTrivia, SourcePresence::Present);
356345

357346
auto ThisTokenPos =
358347
RunningPos.advancedBy(ThisToken->getLeadingTriviaLength());

0 commit comments

Comments
 (0)