Skip to content

Commit 6daa4b0

Browse files
alambiffyio
andauthored
Refactor advancing token to avoid duplication, avoid borrow checker issues (#1618)
Co-authored-by: Ifeanyi Ubah <[email protected]>
1 parent 7dbf31b commit 6daa4b0

File tree

1 file changed

+71
-31
lines changed

1 file changed

+71
-31
lines changed

src/parser/mod.rs

+71-31
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,9 @@ impl<'a> Parser<'a> {
13151315

13161316
let dialect = self.dialect;
13171317

1318-
let (next_token, next_token_index) = self.next_token_ref_with_index();
1318+
self.advance_token();
1319+
let next_token_index = self.get_current_index();
1320+
let next_token = self.get_current_token();
13191321
let span = next_token.span;
13201322
let expr = match &next_token.token {
13211323
Token::Word(w) => {
@@ -2953,7 +2955,9 @@ impl<'a> Parser<'a> {
29532955

29542956
let dialect = self.dialect;
29552957

2956-
let (tok, tok_index) = self.next_token_ref_with_index();
2958+
self.advance_token();
2959+
let tok = self.get_current_token();
2960+
let tok_index = self.get_current_index();
29572961
let span = tok.span;
29582962
let regular_binary_operator = match &tok.token {
29592963
Token::Spaceship => Some(BinaryOperator::Spaceship),
@@ -3033,7 +3037,8 @@ impl<'a> Parser<'a> {
30333037
// See https://www.postgresql.org/docs/current/sql-createoperator.html
30343038
let mut idents = vec![];
30353039
loop {
3036-
idents.push(self.next_token_ref().to_string());
3040+
self.advance_token();
3041+
idents.push(self.get_current_token().to_string());
30373042
if !self.consume_token(&Token::Period) {
30383043
break;
30393044
}
@@ -3480,6 +3485,8 @@ impl<'a> Parser<'a> {
34803485

34813486
/// Return the first non-whitespace token that has not yet been processed
34823487
/// or Token::EOF
3488+
///
3489+
/// See [`Self::peek_token_ref`] to avoid the copy.
34833490
pub fn peek_token(&self) -> TokenWithSpan {
34843491
self.peek_nth_token(0)
34853492
}
@@ -3594,47 +3601,70 @@ impl<'a> Parser<'a> {
35943601

35953602
/// Advances to the next non-whitespace token and returns a copy.
35963603
///
3597-
/// See [`Self::next_token_ref`] to avoid the copy.
3604+
/// Please use [`Self::advance_token`] and [`Self::get_current_token`] to
3605+
/// avoid the copy.
35983606
pub fn next_token(&mut self) -> TokenWithSpan {
3599-
self.next_token_ref().clone()
3607+
self.advance_token();
3608+
self.get_current_token().clone()
36003609
}
36013610

3602-
pub fn next_token_ref(&mut self) -> &TokenWithSpan {
3603-
self.next_token_ref_with_index().0
3611+
/// Returns the index of the current token
3612+
///
3613+
/// This can be used with APIs that expect an index, such as
3614+
/// [`Self::token_at`]
3615+
pub fn get_current_index(&self) -> usize {
3616+
self.index.saturating_sub(1)
36043617
}
36053618

3606-
/// Return the first non-whitespace token that has not yet been processed
3607-
/// and that tokens index and advances the tokens
3619+
/// Return the next unprocessed token, possibly whitespace.
3620+
pub fn next_token_no_skip(&mut self) -> Option<&TokenWithSpan> {
3621+
self.index += 1;
3622+
self.tokens.get(self.index - 1)
3623+
}
3624+
3625+
/// Advances the current token to the next non-whitespace token
36083626
///
3609-
/// # Notes:
3610-
/// OK to call repeatedly after reaching EOF.
3611-
pub fn next_token_ref_with_index(&mut self) -> (&TokenWithSpan, usize) {
3627+
/// See [`Self::get_current_token`] to get the current token after advancing
3628+
pub fn advance_token(&mut self) {
36123629
loop {
36133630
self.index += 1;
36143631
match self.tokens.get(self.index - 1) {
36153632
Some(TokenWithSpan {
36163633
token: Token::Whitespace(_),
36173634
span: _,
36183635
}) => continue,
3619-
token => return (token.unwrap_or(&EOF_TOKEN), self.index - 1),
3636+
_ => break,
36203637
}
36213638
}
36223639
}
36233640

36243641
/// Returns a reference to the current token
3625-
pub fn current_token(&self) -> &TokenWithSpan {
3626-
self.tokens.get(self.index - 1).unwrap_or(&EOF_TOKEN)
3642+
///
3643+
/// Does not advance the current token.
3644+
pub fn get_current_token(&self) -> &TokenWithSpan {
3645+
self.token_at(self.index.saturating_sub(1))
36273646
}
36283647

3629-
/// Return the first unprocessed token, possibly whitespace.
3630-
pub fn next_token_no_skip(&mut self) -> Option<&TokenWithSpan> {
3631-
self.index += 1;
3632-
self.tokens.get(self.index - 1)
3648+
/// Returns a reference to the previous token
3649+
///
3650+
/// Does not advance the current token.
3651+
pub fn get_previous_token(&self) -> &TokenWithSpan {
3652+
self.token_at(self.index.saturating_sub(2))
36333653
}
36343654

3635-
/// Push back the last one non-whitespace token. Must be called after
3636-
/// `next_token()`, otherwise might panic. OK to call after
3637-
/// `next_token()` indicates an EOF.
3655+
/// Returns a reference to the next token
3656+
///
3657+
/// Does not advance the current token.
3658+
pub fn get_next_token(&self) -> &TokenWithSpan {
3659+
self.token_at(self.index)
3660+
}
3661+
3662+
/// Seek back the last one non-whitespace token.
3663+
///
3664+
/// Must be called after `next_token()`, otherwise might panic. OK to call
3665+
/// after `next_token()` indicates an EOF.
3666+
///
3667+
// TODO rename to backup_token and deprecate prev_token?
36383668
pub fn prev_token(&mut self) {
36393669
loop {
36403670
assert!(self.index > 0);
@@ -3680,22 +3710,30 @@ impl<'a> Parser<'a> {
36803710
#[must_use]
36813711
pub fn parse_keyword(&mut self, expected: Keyword) -> bool {
36823712
if self.peek_keyword(expected) {
3683-
self.next_token_ref();
3713+
self.advance_token();
36843714
true
36853715
} else {
36863716
false
36873717
}
36883718
}
36893719

3720+
/// If the current token is the `expected` keyword, consume it and returns
3721+
///
3722+
/// See [`Self::parse_keyword_token_ref`] to avoid the copy.
36903723
#[must_use]
36913724
pub fn parse_keyword_token(&mut self, expected: Keyword) -> Option<TokenWithSpan> {
36923725
self.parse_keyword_token_ref(expected).cloned()
36933726
}
36943727

3728+
/// If the current token is the `expected` keyword, consume it and returns a reference to the next token.
3729+
///
36953730
#[must_use]
36963731
pub fn parse_keyword_token_ref(&mut self, expected: Keyword) -> Option<&TokenWithSpan> {
36973732
match &self.peek_token_ref().token {
3698-
Token::Word(w) if expected == w.keyword => Some(self.next_token_ref()),
3733+
Token::Word(w) if expected == w.keyword => {
3734+
self.advance_token();
3735+
Some(self.get_current_token())
3736+
}
36993737
_ => None,
37003738
}
37013739
}
@@ -3722,7 +3760,7 @@ impl<'a> Parser<'a> {
37223760
}
37233761
// consume all tokens
37243762
for _ in 0..(tokens.len() + 1) {
3725-
self.next_token_ref();
3763+
self.advance_token();
37263764
}
37273765
true
37283766
}
@@ -3758,7 +3796,7 @@ impl<'a> Parser<'a> {
37583796
.iter()
37593797
.find(|keyword| **keyword == w.keyword)
37603798
.map(|keyword| {
3761-
self.next_token_ref();
3799+
self.advance_token();
37623800
*keyword
37633801
})
37643802
}
@@ -3813,10 +3851,12 @@ impl<'a> Parser<'a> {
38133851
}
38143852

38153853
/// Consume the next token if it matches the expected token, otherwise return false
3854+
///
3855+
/// See [Self::advance_token] to consume the token unconditionally
38163856
#[must_use]
38173857
pub fn consume_token(&mut self, expected: &Token) -> bool {
38183858
if self.peek_token_ref() == expected {
3819-
self.next_token_ref();
3859+
self.advance_token();
38203860
true
38213861
} else {
38223862
false
@@ -8338,9 +8378,9 @@ impl<'a> Parser<'a> {
83388378
&mut self,
83398379
) -> Result<(DataType, MatchedTrailingBracket), ParserError> {
83408380
let dialect = self.dialect;
8341-
let (next_token, next_token_index) = self.next_token_ref_with_index();
8342-
let _ = next_token; // release ref
8343-
let next_token = self.current_token();
8381+
self.advance_token();
8382+
let next_token = self.get_current_token();
8383+
let next_token_index = self.get_current_index();
83448384

83458385
let mut trailing_bracket: MatchedTrailingBracket = false.into();
83468386
let mut data = match &next_token.token {
@@ -8866,7 +8906,7 @@ impl<'a> Parser<'a> {
88668906
Token::EOF | Token::Eq => break,
88678907
_ => {}
88688908
}
8869-
self.next_token_ref();
8909+
self.advance_token();
88708910
}
88718911
Ok(idents)
88728912
}

0 commit comments

Comments
 (0)