Skip to content

Commit 7b4fc5b

Browse files
committed
[Syntax] Restore Lexer state by restoring LeadingTrivia
Instead of re-lexing Trivias. Trivia might contain skipped garbage which might be re-lexed as tokens.
1 parent 60bfa89 commit 7b4fc5b

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

include/swift/Parse/Lexer.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,18 +243,17 @@ class Lexer {
243243
/// there.
244244
State getStateForBeginningOfToken(const Token &Tok,
245245
const syntax::Trivia &LeadingTrivia = {}) const {
246-
// If trivia parsing mode, start position of trivia is the position we want
247-
// to restore.
248-
if (TriviaRetention == TriviaRetentionMode::WithTrivia)
249-
return State(Tok.getLoc().getAdvancedLoc(-LeadingTrivia.getTextLength()));
250246

251247
// If the token has a comment attached to it, rewind to before the comment,
252248
// not just the start of the token. This ensures that we will re-lex and
253249
// reattach the comment to the token if rewound to this state.
254250
SourceLoc TokStart = Tok.getCommentStart();
255251
if (TokStart.isInvalid())
256252
TokStart = Tok.getLoc();
257-
return getStateForBeginningOfTokenLoc(TokStart);
253+
auto S = getStateForBeginningOfTokenLoc(TokStart);
254+
if (TriviaRetention == TriviaRetentionMode::WithTrivia)
255+
S.LeadingTrivia = LeadingTrivia.Pieces;
256+
return S;
258257
}
259258

260259
State getStateForEndOfTokenLoc(SourceLoc Loc) const {
@@ -273,7 +272,13 @@ class Lexer {
273272
// Don't reemit diagnostics while readvancing the lexer.
274273
llvm::SaveAndRestore<DiagnosticEngine*>
275274
D(Diags, enableDiagnostics ? Diags : nullptr);
275+
276276
lexImpl();
277+
278+
// Restore Trivia.
279+
if (TriviaRetention == TriviaRetentionMode::WithTrivia)
280+
if (auto &LTrivia = S.LeadingTrivia)
281+
LeadingTrivia = std::move(*LTrivia);
277282
}
278283

279284
/// \brief Restore the lexer state to a given state that is located before

include/swift/Parse/LexerState.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#ifndef SWIFT_LEXERSTATE_H
1818
#define SWIFT_LEXERSTATE_H
1919

20+
#include "llvm/ADT/Optional.h"
2021
#include "swift/Basic/SourceLoc.h"
22+
#include "swift/Syntax/Trivia.h"
2123

2224
namespace swift {
23-
class Lexer;
25+
class Lexer;
2426

2527
/// \brief Lexer state can be saved/restored to/from objects of this class.
2628
class LexerState {
@@ -37,6 +39,7 @@ class LexerState {
3739
private:
3840
explicit LexerState(SourceLoc Loc) : Loc(Loc) {}
3941
SourceLoc Loc;
42+
llvm::Optional<syntax::TriviaList> LeadingTrivia;
4043
friend class Lexer;
4144
};
4245

0 commit comments

Comments
 (0)