Skip to content

Commit 9670e11

Browse files
committed
Introduce peek_prev_nth_token_no_skip helper
- and use it for `expect_previously_only_whitespace_until_newline` so that can be simplified accordingly
1 parent fe08280 commit 9670e11

File tree

1 file changed

+59
-20
lines changed

1 file changed

+59
-20
lines changed

src/parser/mod.rs

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4059,6 +4059,26 @@ impl<'a> Parser<'a> {
40594059
})
40604060
}
40614061

4062+
/// Return nth previous token, possibly whitespace
4063+
/// (or [`Token::EOF`] when before the beginning of the stream).
4064+
pub fn peek_prev_nth_token_no_skip(&self, n: usize) -> TokenWithSpan {
4065+
// 0 = next token, -1 = current token, -2 = previous token
4066+
let peek_index = self.index.saturating_sub(1).saturating_sub(n);
4067+
if peek_index == 0 {
4068+
return TokenWithSpan {
4069+
token: Token::EOF,
4070+
span: Span::empty(),
4071+
};
4072+
}
4073+
self.tokens
4074+
.get(peek_index)
4075+
.cloned()
4076+
.unwrap_or(TokenWithSpan {
4077+
token: Token::EOF,
4078+
span: Span::empty(),
4079+
})
4080+
}
4081+
40624082
/// Return true if the next tokens exactly `expected`
40634083
///
40644084
/// Does not advance the current token.
@@ -4175,16 +4195,15 @@ impl<'a> Parser<'a> {
41754195
)
41764196
}
41774197

4178-
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline
4179-
pub fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4180-
let mut look_back_count = 2;
4198+
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline or beginning of string
4199+
pub(crate) fn expect_previously_only_whitespace_until_newline(
4200+
&mut self,
4201+
) -> Result<(), ParserError> {
4202+
let mut look_back_count = 1;
41814203
loop {
4182-
let prev_index = self.index.saturating_sub(look_back_count);
4183-
if prev_index == 0 {
4184-
break;
4185-
}
4186-
let prev_token = self.token_at(prev_index);
4204+
let prev_token = self.peek_prev_nth_token_no_skip(look_back_count);
41874205
match prev_token.token {
4206+
Token::EOF => break,
41884207
Token::Whitespace(ref w) => match w {
41894208
Whitespace::Newline => break,
41904209
// special consideration required for single line comments since that string includes the newline
@@ -4196,18 +4215,13 @@ impl<'a> Parser<'a> {
41964215
}
41974216
_ => look_back_count += 1,
41984217
},
4199-
_ => {
4200-
let current_token = self.get_current_token();
4201-
if prev_token == current_token {
4202-
// if we are at the start of the statement, we can skip this check
4203-
break;
4204-
}
4205-
4206-
self.expected(
4207-
&format!("newline before current token ({})", current_token),
4208-
prev_token.clone(),
4209-
)?
4210-
}
4218+
_ => self.expected(
4219+
&format!(
4220+
"newline before current token ({})",
4221+
self.get_current_token()
4222+
),
4223+
prev_token.clone(),
4224+
)?,
42114225
};
42124226
}
42134227
Ok(())
@@ -16802,6 +16816,31 @@ mod tests {
1680216816
})
1680316817
}
1680416818

16819+
#[test]
16820+
fn test_peek_prev_nth_token_no_skip() {
16821+
all_dialects().run_parser_method(
16822+
"SELECT 1;\n-- a comment\nRAISERROR('test', 16, 0);",
16823+
|parser| {
16824+
parser.index = 1;
16825+
assert_eq!(parser.peek_prev_nth_token_no_skip(0), Token::EOF);
16826+
assert_eq!(parser.index, 1);
16827+
parser.index = 7;
16828+
assert_eq!(
16829+
parser.token_at(parser.index - 1).token,
16830+
Token::Word(Word {
16831+
value: "RAISERROR".to_string(),
16832+
quote_style: None,
16833+
keyword: Keyword::RAISERROR,
16834+
})
16835+
);
16836+
assert_eq!(
16837+
parser.peek_prev_nth_token_no_skip(2),
16838+
Token::Whitespace(Whitespace::Newline)
16839+
);
16840+
},
16841+
);
16842+
}
16843+
1680516844
#[cfg(test)]
1680616845
mod test_parse_data_type {
1680716846
use crate::ast::{

0 commit comments

Comments
 (0)