Skip to content

Commit f192c72

Browse files
authored
Remove type parameter from parse_* methods (#9466)
1 parent 25bafd2 commit f192c72

File tree

13 files changed

+98
-84
lines changed

13 files changed

+98
-84
lines changed

crates/ruff_benchmark/benches/linter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn benchmark_linter(mut group: BenchmarkGroup, settings: &LinterSettings) {
5555
&case,
5656
|b, case| {
5757
// Tokenize the source.
58-
let tokens = lexer::lex(case.code(), Mode::Module).collect::<Vec<_>>();
58+
let tokens: Vec<_> = lexer::lex(case.code(), Mode::Module).collect();
5959

6060
// Parse the source.
6161
let ast = parse_program_tokens(tokens.clone(), case.code(), false).unwrap();

crates/ruff_python_ast/tests/preorder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn f_strings() {
149149

150150
fn trace_preorder_visitation(source: &str) -> String {
151151
let tokens = lex(source, Mode::Module);
152-
let parsed = parse_tokens(tokens, source, Mode::Module).unwrap();
152+
let parsed = parse_tokens(tokens.collect(), source, Mode::Module).unwrap();
153153

154154
let mut visitor = RecordVisitor::default();
155155
visitor.visit_mod(&parsed);

crates/ruff_python_ast/tests/visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn f_strings() {
160160

161161
fn trace_visitation(source: &str) -> String {
162162
let tokens = lex(source, Mode::Module);
163-
let parsed = parse_tokens(tokens, source, Mode::Module).unwrap();
163+
let parsed = parse_tokens(tokens.collect(), source, Mode::Module).unwrap();
164164

165165
let mut visitor = RecordVisitor::default();
166166
walk_module(&mut visitor, &parsed);

crates/ruff_python_formatter/src/cli.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use clap::{command, Parser, ValueEnum};
88
use ruff_formatter::SourceCode;
99
use ruff_python_ast::PySourceType;
1010
use ruff_python_index::tokens_and_ranges;
11-
use ruff_python_parser::{parse_ok_tokens, AsMode};
11+
use ruff_python_parser::{parse_tokens, AsMode};
1212
use ruff_text_size::Ranged;
1313

1414
use crate::comments::collect_comments;
@@ -51,7 +51,7 @@ pub fn format_and_debug_print(source: &str, cli: &Cli, source_path: &Path) -> Re
5151

5252
// Parse the AST.
5353
let module =
54-
parse_ok_tokens(tokens, source, source_type.as_mode()).context("Syntax error in input")?;
54+
parse_tokens(tokens, source, source_type.as_mode()).context("Syntax error in input")?;
5555

5656
let options = PyFormatOptions::from_extension(source_path)
5757
.with_preview(if cli.preview {

crates/ruff_python_formatter/src/comments/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ use ruff_python_ast::Mod;
102102
use ruff_python_trivia::{CommentRanges, PythonWhitespace};
103103
use ruff_source_file::Locator;
104104
use ruff_text_size::{Ranged, TextRange};
105+
pub(crate) use visitor::collect_comments;
105106

106107
use crate::comments::debug::{DebugComment, DebugComments};
107108
use crate::comments::map::{LeadingDanglingTrailing, MultiMap};
108109
use crate::comments::node_key::NodeRefEqualityKey;
109110
use crate::comments::visitor::{CommentsMapBuilder, CommentsVisitor};
110-
pub(crate) use visitor::collect_comments;
111111

112112
mod debug;
113113
pub(crate) mod format;
@@ -563,8 +563,7 @@ mod tests {
563563
use ruff_formatter::SourceCode;
564564
use ruff_python_ast::{Mod, PySourceType};
565565
use ruff_python_index::tokens_and_ranges;
566-
567-
use ruff_python_parser::{parse_ok_tokens, AsMode};
566+
use ruff_python_parser::{parse_tokens, AsMode};
568567
use ruff_python_trivia::CommentRanges;
569568

570569
use crate::comments::Comments;
@@ -581,7 +580,7 @@ mod tests {
581580
let source_type = PySourceType::Python;
582581
let (tokens, comment_ranges) =
583582
tokens_and_ranges(source, source_type).expect("Expect source to be valid Python");
584-
let parsed = parse_ok_tokens(tokens, source, source_type.as_mode())
583+
let parsed = parse_tokens(tokens, source, source_type.as_mode())
585584
.expect("Expect source to be valid Python");
586585

587586
CommentsTestCase {

crates/ruff_python_formatter/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, Source
66
use ruff_python_ast::AstNode;
77
use ruff_python_ast::Mod;
88
use ruff_python_index::tokens_and_ranges;
9-
use ruff_python_parser::{parse_ok_tokens, AsMode, ParseError, ParseErrorType};
9+
use ruff_python_parser::{parse_tokens, AsMode, ParseError, ParseErrorType};
1010
use ruff_python_trivia::CommentRanges;
1111
use ruff_source_file::Locator;
1212

@@ -126,7 +126,7 @@ pub fn format_module_source(
126126
offset: err.location,
127127
error: ParseErrorType::Lexical(err.error),
128128
})?;
129-
let module = parse_ok_tokens(tokens, source, source_type.as_mode())?;
129+
let module = parse_tokens(tokens, source, source_type.as_mode())?;
130130
let formatted = format_module_ast(&module, &comment_ranges, source, options)?;
131131
Ok(formatted.print()?)
132132
}
@@ -169,7 +169,7 @@ mod tests {
169169

170170
use ruff_python_ast::PySourceType;
171171
use ruff_python_index::tokens_and_ranges;
172-
use ruff_python_parser::{parse_ok_tokens, AsMode};
172+
use ruff_python_parser::{parse_tokens, AsMode};
173173

174174
use crate::{format_module_ast, format_module_source, PyFormatOptions};
175175

@@ -213,7 +213,7 @@ def main() -> None:
213213

214214
// Parse the AST.
215215
let source_path = "code_inline.py";
216-
let module = parse_ok_tokens(tokens, source, source_type.as_mode()).unwrap();
216+
let module = parse_tokens(tokens, source, source_type.as_mode()).unwrap();
217217
let options = PyFormatOptions::from_extension(Path::new(source_path));
218218
let formatted = format_module_ast(&module, &comment_ranges, source, options).unwrap();
219219

crates/ruff_python_formatter/src/string/docstring.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,7 @@ fn docstring_format_source(
15161516
let source_type = options.source_type();
15171517
let (tokens, comment_ranges) =
15181518
ruff_python_index::tokens_and_ranges(source, source_type).map_err(ParseError::from)?;
1519-
let module = ruff_python_parser::parse_ok_tokens(tokens, source, source_type.as_mode())?;
1519+
let module = ruff_python_parser::parse_tokens(tokens, source, source_type.as_mode())?;
15201520
let source_code = ruff_formatter::SourceCode::new(source);
15211521
let comments = crate::Comments::from_ast(&module, source_code, &comment_ranges);
15221522
let locator = Locator::new(source);

crates/ruff_python_index/src/comment_ranges.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Debug;
22

33
use ruff_python_ast::PySourceType;
4-
use ruff_python_parser::lexer::{lex, LexicalError};
4+
use ruff_python_parser::lexer::{lex, LexResult, LexicalError};
55
use ruff_python_parser::{AsMode, Tok};
66
use ruff_python_trivia::CommentRanges;
77
use ruff_text_size::TextRange;
@@ -27,15 +27,16 @@ impl CommentRangesBuilder {
2727
pub fn tokens_and_ranges(
2828
source: &str,
2929
source_type: PySourceType,
30-
) -> Result<(Vec<(Tok, TextRange)>, CommentRanges), LexicalError> {
30+
) -> Result<(Vec<LexResult>, CommentRanges), LexicalError> {
3131
let mut tokens = Vec::new();
3232
let mut comment_ranges = CommentRangesBuilder::default();
3333

3434
for result in lex(source, source_type.as_mode()) {
35-
let (token, range) = result?;
35+
if let Ok((token, range)) = &result {
36+
comment_ranges.visit_token(token, *range);
37+
}
3638

37-
comment_ranges.visit_token(&token, range);
38-
tokens.push((token, range));
39+
tokens.push(result);
3940
}
4041

4142
let comment_ranges = comment_ranges.finish();

crates/ruff_python_parser/src/invalid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ mod tests {
687687

688688
let src = r"!foo = 42";
689689
let tokens = crate::lexer::lex(src, Mode::Ipython);
690-
let ast = crate::parse_tokens(tokens, src, Mode::Ipython);
690+
let ast = crate::parse_tokens(tokens.collect(), src, Mode::Ipython);
691691
insta::assert_debug_snapshot!(ast);
692692
}
693693

crates/ruff_python_parser/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
//! return bool(i & 1)
8686
//! "#;
8787
//! let tokens = lex(python_source, Mode::Module);
88-
//! let ast = parse_tokens(tokens, python_source, Mode::Module);
88+
//! let ast = parse_tokens(tokens.collect(), python_source, Mode::Module);
8989
//!
9090
//! assert!(ast.is_ok());
9191
//! ```
@@ -110,8 +110,8 @@
110110
//! [lexer]: crate::lexer
111111
112112
pub use parser::{
113-
parse, parse_expression, parse_expression_starts_at, parse_ok_tokens, parse_program,
114-
parse_starts_at, parse_suite, parse_tokens, ParseError, ParseErrorType,
113+
parse, parse_expression, parse_expression_starts_at, parse_program, parse_starts_at,
114+
parse_suite, parse_tokens, ParseError, ParseErrorType,
115115
};
116116
use ruff_python_ast::{Mod, PySourceType, Suite};
117117
pub use string::FStringErrorType;
@@ -128,6 +128,7 @@ mod parser;
128128
mod soft_keywords;
129129
mod string;
130130
mod token;
131+
mod token_source;
131132
pub mod typing;
132133

133134
/// Collect tokens up to and including the first error.
@@ -145,7 +146,7 @@ pub fn tokenize(contents: &str, mode: Mode) -> Vec<LexResult> {
145146

146147
/// Parse a full Python program from its tokens.
147148
pub fn parse_program_tokens(
148-
lxr: Vec<LexResult>,
149+
tokens: Vec<LexResult>,
149150
source: &str,
150151
is_jupyter_notebook: bool,
151152
) -> anyhow::Result<Suite, ParseError> {
@@ -154,7 +155,7 @@ pub fn parse_program_tokens(
154155
} else {
155156
Mode::Module
156157
};
157-
match parse_tokens(lxr, source, mode)? {
158+
match parse_tokens(tokens, source, mode)? {
158159
Mod::Module(m) => Ok(m.body),
159160
Mod::Expression(_) => unreachable!("Mode::Module doesn't return other variant"),
160161
}

crates/ruff_python_parser/src/parser.rs

Lines changed: 20 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,7 @@
1414
1515
use itertools::Itertools;
1616
pub(super) use lalrpop_util::ParseError as LalrpopError;
17-
use ruff_text_size::{Ranged, TextRange, TextSize};
1817

19-
use crate::lexer::{lex, lex_starts_at, Spanned};
20-
use crate::{
21-
lexer::{self, LexResult, LexicalError, LexicalErrorType},
22-
python,
23-
token::Tok,
24-
Mode,
25-
};
2618
use ruff_python_ast::{
2719
Expr, ExprAttribute, ExprAwait, ExprBinOp, ExprBoolOp, ExprBooleanLiteral, ExprBytesLiteral,
2820
ExprCall, ExprCompare, ExprDict, ExprDictComp, ExprEllipsisLiteral, ExprFString,
@@ -31,6 +23,16 @@ use ruff_python_ast::{
3123
ExprStarred, ExprStringLiteral, ExprSubscript, ExprTuple, ExprUnaryOp, ExprYield,
3224
ExprYieldFrom, Mod, ModModule, Suite,
3325
};
26+
use ruff_text_size::{Ranged, TextRange, TextSize};
27+
28+
use crate::lexer::{lex, lex_starts_at, LexResult};
29+
use crate::token_source::TokenSource;
30+
use crate::{
31+
lexer::{self, LexicalError, LexicalErrorType},
32+
python,
33+
token::Tok,
34+
Mode,
35+
};
3436

3537
/// Parse a full Python program usually consisting of multiple lines.
3638
///
@@ -54,7 +56,7 @@ use ruff_python_ast::{
5456
/// ```
5557
pub fn parse_program(source: &str) -> Result<ModModule, ParseError> {
5658
let lexer = lex(source, Mode::Module);
57-
match parse_tokens(lexer, source, Mode::Module)? {
59+
match parse_tokens(lexer.collect(), source, Mode::Module)? {
5860
Mod::Module(m) => Ok(m),
5961
Mod::Expression(_) => unreachable!("Mode::Module doesn't return other variant"),
6062
}
@@ -82,7 +84,7 @@ pub fn parse_suite(source: &str) -> Result<Suite, ParseError> {
8284
/// ```
8385
pub fn parse_expression(source: &str) -> Result<Expr, ParseError> {
8486
let lexer = lex(source, Mode::Expression);
85-
match parse_tokens(lexer, source, Mode::Expression)? {
87+
match parse_tokens(lexer.collect(), source, Mode::Expression)? {
8688
Mod::Expression(expression) => Ok(*expression.body),
8789
Mod::Module(_m) => unreachable!("Mode::Expression doesn't return other variant"),
8890
}
@@ -107,7 +109,7 @@ pub fn parse_expression(source: &str) -> Result<Expr, ParseError> {
107109
/// ```
108110
pub fn parse_expression_starts_at(source: &str, offset: TextSize) -> Result<Expr, ParseError> {
109111
let lexer = lex_starts_at(source, Mode::Module, offset);
110-
match parse_tokens(lexer, source, Mode::Expression)? {
112+
match parse_tokens(lexer.collect(), source, Mode::Expression)? {
111113
Mod::Expression(expression) => Ok(*expression.body),
112114
Mod::Module(_m) => unreachable!("Mode::Expression doesn't return other variant"),
113115
}
@@ -188,7 +190,7 @@ pub fn parse(source: &str, mode: Mode) -> Result<Mod, ParseError> {
188190
/// ```
189191
pub fn parse_starts_at(source: &str, mode: Mode, offset: TextSize) -> Result<Mod, ParseError> {
190192
let lxr = lexer::lex_starts_at(source, mode, offset);
191-
parse_tokens(lxr, source, mode)
193+
parse_tokens(lxr.collect(), source, mode)
192194
}
193195

194196
/// Parse an iterator of [`LexResult`]s using the specified [`Mode`].
@@ -204,48 +206,12 @@ pub fn parse_starts_at(source: &str, mode: Mode, offset: TextSize) -> Result<Mod
204206
/// use ruff_python_parser::{lexer::lex, Mode, parse_tokens};
205207
///
206208
/// let source = "1 + 2";
207-
/// let expr = parse_tokens(lex(source, Mode::Expression), source, Mode::Expression);
209+
/// let expr = parse_tokens(lex(source, Mode::Expression).collect(), source, Mode::Expression);
208210
/// assert!(expr.is_ok());
209211
/// ```
210-
pub fn parse_tokens(
211-
lxr: impl IntoIterator<Item = LexResult>,
212-
source: &str,
213-
mode: Mode,
214-
) -> Result<Mod, ParseError> {
215-
let lxr = lxr.into_iter();
216-
217-
parse_filtered_tokens(
218-
lxr.filter_ok(|(tok, _)| !matches!(tok, Tok::Comment { .. } | Tok::NonLogicalNewline)),
219-
source,
220-
mode,
221-
)
222-
}
223-
224-
/// Parse tokens into an AST like [`parse_tokens`], but we already know all tokens are valid.
225-
pub fn parse_ok_tokens(
226-
lxr: impl IntoIterator<Item = Spanned>,
227-
source: &str,
228-
mode: Mode,
229-
) -> Result<Mod, ParseError> {
230-
let lxr = lxr
231-
.into_iter()
232-
.filter(|(tok, _)| !matches!(tok, Tok::Comment { .. } | Tok::NonLogicalNewline));
233-
let marker_token = (Tok::start_marker(mode), TextRange::default());
234-
let lexer = std::iter::once(marker_token)
235-
.chain(lxr)
236-
.map(|(t, range)| (range.start(), t, range.end()));
237-
python::TopParser::new()
238-
.parse(source, mode, lexer)
239-
.map_err(parse_error_from_lalrpop)
240-
}
241-
242-
fn parse_filtered_tokens(
243-
lxr: impl IntoIterator<Item = LexResult>,
244-
source: &str,
245-
mode: Mode,
246-
) -> Result<Mod, ParseError> {
212+
pub fn parse_tokens(tokens: Vec<LexResult>, source: &str, mode: Mode) -> Result<Mod, ParseError> {
247213
let marker_token = (Tok::start_marker(mode), TextRange::default());
248-
let lexer = std::iter::once(Ok(marker_token)).chain(lxr);
214+
let lexer = std::iter::once(Ok(marker_token)).chain(TokenSource::new(tokens));
249215
python::TopParser::new()
250216
.parse(
251217
source,
@@ -597,9 +563,10 @@ impl From<ExprSlice> for ParenthesizedExpr {
597563

598564
#[cfg(target_pointer_width = "64")]
599565
mod size_assertions {
600-
use crate::parser::ParenthesizedExpr;
601566
use static_assertions::assert_eq_size;
602567

568+
use crate::parser::ParenthesizedExpr;
569+
603570
assert_eq_size!(ParenthesizedExpr, [u8; 88]);
604571
}
605572

@@ -1475,7 +1442,7 @@ a = 1
14751442
"
14761443
.trim();
14771444
let lxr = lexer::lex_starts_at(source, Mode::Ipython, TextSize::default());
1478-
let parse_err = parse_tokens(lxr, source, Mode::Module).unwrap_err();
1445+
let parse_err = parse_tokens(lxr.collect(), source, Mode::Module).unwrap_err();
14791446
assert_eq!(
14801447
parse_err.to_string(),
14811448
"IPython escape commands are only allowed in `Mode::Ipython` at byte offset 6"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::lexer::LexResult;
2+
use crate::Tok;
3+
use std::iter::FusedIterator;
4+
5+
#[derive(Clone, Debug)]
6+
pub(crate) struct TokenSource {
7+
tokens: std::vec::IntoIter<LexResult>,
8+
}
9+
10+
impl TokenSource {
11+
pub(crate) fn new(tokens: Vec<LexResult>) -> Self {
12+
Self {
13+
tokens: tokens.into_iter(),
14+
}
15+
}
16+
}
17+
18+
impl FromIterator<LexResult> for TokenSource {
19+
#[inline]
20+
fn from_iter<T: IntoIterator<Item = LexResult>>(iter: T) -> Self {
21+
Self::new(Vec::from_iter(iter))
22+
}
23+
}
24+
25+
impl Iterator for TokenSource {
26+
type Item = LexResult;
27+
28+
#[inline]
29+
fn next(&mut self) -> Option<Self::Item> {
30+
loop {
31+
let next = self.tokens.next()?;
32+
33+
if is_trivia(&next) {
34+
continue;
35+
}
36+
37+
break Some(next);
38+
}
39+
}
40+
}
41+
42+
impl FusedIterator for TokenSource {}
43+
44+
const fn is_trivia(result: &LexResult) -> bool {
45+
matches!(result, Ok((Tok::Comment(_) | Tok::NonLogicalNewline, _)))
46+
}

0 commit comments

Comments
 (0)