Skip to content

Commit 3b19df0

Browse files
authored
Use cursor offset for lexer checkpoint (#11734)
## Summary This PR updates the lexer checkpoint to store the cursor offset instead of cloning the cursor itself. This reduces the size of `LexerCheckpoint` from 136 to 112 bytes and also removes the need for lifetime. ## Test Plan `cargo insta test`
1 parent 6ffb961 commit 3b19df0

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

crates/ruff_python_parser/src/lexer.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,13 +1338,13 @@ impl<'src> Lexer<'src> {
13381338
}
13391339

13401340
/// Creates a checkpoint to which the lexer can later return to using [`Self::rewind`].
1341-
pub(crate) fn checkpoint(&self) -> LexerCheckpoint<'src> {
1341+
pub(crate) fn checkpoint(&self) -> LexerCheckpoint {
13421342
LexerCheckpoint {
13431343
value: self.current_value.clone(),
13441344
current_kind: self.current_kind,
13451345
current_range: self.current_range,
13461346
current_flags: self.current_flags,
1347-
cursor: self.cursor.clone(),
1347+
cursor_offset: self.offset(),
13481348
state: self.state,
13491349
nesting: self.nesting,
13501350
indentations_checkpoint: self.indentations.checkpoint(),
@@ -1355,13 +1355,13 @@ impl<'src> Lexer<'src> {
13551355
}
13561356

13571357
/// Restore the lexer to the given checkpoint.
1358-
pub(crate) fn rewind(&mut self, checkpoint: LexerCheckpoint<'src>) {
1358+
pub(crate) fn rewind(&mut self, checkpoint: LexerCheckpoint) {
13591359
let LexerCheckpoint {
13601360
value,
13611361
current_kind,
13621362
current_range,
13631363
current_flags,
1364-
cursor,
1364+
cursor_offset,
13651365
state,
13661366
nesting,
13671367
indentations_checkpoint,
@@ -1370,6 +1370,10 @@ impl<'src> Lexer<'src> {
13701370
errors_position,
13711371
} = checkpoint;
13721372

1373+
let mut cursor = Cursor::new(self.source);
1374+
// We preserve the previous char using this method.
1375+
cursor.skip_bytes(cursor_offset.to_usize());
1376+
13731377
self.current_value = value;
13741378
self.current_kind = current_kind;
13751379
self.current_range = current_range;
@@ -1700,12 +1704,12 @@ pub(crate) enum TokenValue {
17001704
},
17011705
}
17021706

1703-
pub(crate) struct LexerCheckpoint<'src> {
1707+
pub(crate) struct LexerCheckpoint {
17041708
value: TokenValue,
17051709
current_kind: TokenKind,
17061710
current_range: TextRange,
17071711
current_flags: TokenFlags,
1708-
cursor: Cursor<'src>,
1712+
cursor_offset: TextSize,
17091713
state: State,
17101714
nesting: u32,
17111715
indentations_checkpoint: IndentationsCheckpoint,

crates/ruff_python_parser/src/parser/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ impl<'src> Parser<'src> {
609609
}
610610

611611
/// Creates a checkpoint to which the parser can later return to using [`Self::rewind`].
612-
fn checkpoint(&self) -> ParserCheckpoint<'src> {
612+
fn checkpoint(&self) -> ParserCheckpoint {
613613
ParserCheckpoint {
614614
tokens: self.tokens.checkpoint(),
615615
errors_position: self.errors.len(),
@@ -620,7 +620,7 @@ impl<'src> Parser<'src> {
620620
}
621621

622622
/// Restore the parser to the given checkpoint.
623-
fn rewind(&mut self, checkpoint: ParserCheckpoint<'src>) {
623+
fn rewind(&mut self, checkpoint: ParserCheckpoint) {
624624
let ParserCheckpoint {
625625
tokens,
626626
errors_position,
@@ -637,8 +637,8 @@ impl<'src> Parser<'src> {
637637
}
638638
}
639639

640-
struct ParserCheckpoint<'src> {
641-
tokens: TokenSourceCheckpoint<'src>,
640+
struct ParserCheckpoint {
641+
tokens: TokenSourceCheckpoint,
642642
errors_position: usize,
643643
current_token_id: TokenId,
644644
prev_token_end: TextSize,

crates/ruff_python_parser/src/token_source.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl<'src> TokenSource<'src> {
126126
}
127127

128128
/// Creates a checkpoint to which the token source can later return to using [`Self::rewind`].
129-
pub(crate) fn checkpoint(&self) -> TokenSourceCheckpoint<'src> {
129+
pub(crate) fn checkpoint(&self) -> TokenSourceCheckpoint {
130130
TokenSourceCheckpoint {
131131
lexer_checkpoint: self.lexer.checkpoint(),
132132
tokens_position: self.tokens.len(),
@@ -135,7 +135,7 @@ impl<'src> TokenSource<'src> {
135135
}
136136

137137
/// Restore the token source to the given checkpoint.
138-
pub(crate) fn rewind(&mut self, checkpoint: TokenSourceCheckpoint<'src>) {
138+
pub(crate) fn rewind(&mut self, checkpoint: TokenSourceCheckpoint) {
139139
let TokenSourceCheckpoint {
140140
lexer_checkpoint,
141141
tokens_position,
@@ -168,8 +168,8 @@ impl<'src> TokenSource<'src> {
168168
}
169169
}
170170

171-
pub(crate) struct TokenSourceCheckpoint<'src> {
172-
lexer_checkpoint: LexerCheckpoint<'src>,
171+
pub(crate) struct TokenSourceCheckpoint {
172+
lexer_checkpoint: LexerCheckpoint,
173173
tokens_position: usize,
174174
comments_position: usize,
175175
}

0 commit comments

Comments
 (0)