Skip to content

Commit eed6d78

Browse files
authored
Update type annotation parsing API to return Parsed (#11739)
## Summary This PR updates the return type of `parse_type_annotation` from `Expr` to `Parsed<ModExpression>`. This is to allow accessing the tokens for the parsed sub-expression in the follow-up PR. ## Test Plan `cargo insta test`
1 parent 8338db6 commit eed6d78

File tree

6 files changed

+37
-25
lines changed

6 files changed

+37
-25
lines changed

crates/ruff_linter/src/checkers/ast/mod.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,6 @@ use std::path::Path;
3030

3131
use itertools::Itertools;
3232
use log::debug;
33-
use ruff_python_ast::{
34-
self as ast, AnyParameterRef, Comprehension, ElifElseClause, ExceptHandler, Expr, ExprContext,
35-
FStringElement, Keyword, MatchCase, ModModule, Parameter, Parameters, Pattern, Stmt, Suite,
36-
UnaryOp,
37-
};
38-
use ruff_python_parser::Parsed;
39-
use ruff_text_size::{Ranged, TextRange, TextSize};
4033

4134
use ruff_diagnostics::{Diagnostic, IsolationLevel};
4235
use ruff_notebook::{CellOffsets, NotebookIndex};
@@ -47,10 +40,16 @@ use ruff_python_ast::identifier::Identifier;
4740
use ruff_python_ast::name::QualifiedName;
4841
use ruff_python_ast::str::Quote;
4942
use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor};
43+
use ruff_python_ast::{
44+
self as ast, AnyParameterRef, Comprehension, ElifElseClause, ExceptHandler, Expr, ExprContext,
45+
FStringElement, Keyword, MatchCase, ModExpression, ModModule, Parameter, Parameters, Pattern,
46+
Stmt, Suite, UnaryOp,
47+
};
5048
use ruff_python_ast::{helpers, str, visitor, PySourceType};
5149
use ruff_python_codegen::{Generator, Stylist};
5250
use ruff_python_index::Indexer;
5351
use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind};
52+
use ruff_python_parser::Parsed;
5453
use ruff_python_semantic::all::{DunderAllDefinition, DunderAllFlags};
5554
use ruff_python_semantic::analyze::{imports, typing};
5655
use ruff_python_semantic::{
@@ -60,6 +59,7 @@ use ruff_python_semantic::{
6059
};
6160
use ruff_python_stdlib::builtins::{IPYTHON_BUILTINS, MAGIC_GLOBALS, PYTHON_BUILTINS};
6261
use ruff_source_file::{Locator, OneIndexed, SourceRow};
62+
use ruff_text_size::{Ranged, TextRange, TextSize};
6363

6464
use crate::checkers::ast::annotation::AnnotationContext;
6565
use crate::docstrings::extraction::ExtractionTarget;
@@ -2148,7 +2148,10 @@ impl<'a> Checker<'a> {
21482148
///
21492149
/// class Bar: pass
21502150
/// ```
2151-
fn visit_deferred_string_type_definitions(&mut self, allocator: &'a typed_arena::Arena<Expr>) {
2151+
fn visit_deferred_string_type_definitions(
2152+
&mut self,
2153+
allocator: &'a typed_arena::Arena<Parsed<ModExpression>>,
2154+
) {
21522155
let snapshot = self.semantic.snapshot();
21532156
while !self.visit.string_type_definitions.is_empty() {
21542157
let type_definitions = std::mem::take(&mut self.visit.string_type_definitions);
@@ -2183,7 +2186,7 @@ impl<'a> Checker<'a> {
21832186

21842187
self.semantic.flags |=
21852188
SemanticModelFlags::TYPE_DEFINITION | type_definition_flag;
2186-
self.visit_expr(parsed_annotation);
2189+
self.visit_expr(parsed_annotation.expr());
21872190
} else {
21882191
if self.enabled(Rule::ForwardAnnotationSyntaxError) {
21892192
self.diagnostics.push(Diagnostic::new(
@@ -2258,7 +2261,7 @@ impl<'a> Checker<'a> {
22582261
/// After initial traversal of the source tree has been completed,
22592262
/// recursively visit all AST nodes that were deferred on the first pass.
22602263
/// This includes lambdas, functions, type parameters, and type annotations.
2261-
fn visit_deferred(&mut self, allocator: &'a typed_arena::Arena<Expr>) {
2264+
fn visit_deferred(&mut self, allocator: &'a typed_arena::Arena<Parsed<ModExpression>>) {
22622265
while !self.visit.is_empty() {
22632266
self.visit_deferred_class_bases();
22642267
self.visit_deferred_functions();

crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ fn check_dynamically_typed<F>(
518518
parse_type_annotation(string_expr, checker.locator().contents())
519519
{
520520
if type_hint_resolves_to_any(
521-
&parsed_annotation,
521+
parsed_annotation.expr(),
522522
checker.semantic(),
523523
checker.locator(),
524524
checker.settings.target_version.minor(),

crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub(crate) fn implicit_optional(checker: &mut Checker, parameters: &Parameters)
183183
parse_type_annotation(string_expr, checker.locator().contents())
184184
{
185185
let Some(expr) = type_hint_explicitly_allows_none(
186-
&parsed_annotation,
186+
parsed_annotation.expr(),
187187
checker.semantic(),
188188
checker.locator(),
189189
checker.settings.target_version.minor(),

crates/ruff_linter/src/rules/ruff/typing.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,15 @@ impl<'a> TypingTarget<'a> {
112112
..
113113
}) => Some(TypingTarget::PEP604Union(left, right)),
114114
Expr::NoneLiteral(_) => Some(TypingTarget::None),
115-
Expr::StringLiteral(string_expr) => {
116-
parse_type_annotation(string_expr, locator.contents())
117-
.map_or(None, |(expr, _)| Some(TypingTarget::ForwardReference(expr)))
118-
}
115+
Expr::StringLiteral(string_expr) => parse_type_annotation(
116+
string_expr,
117+
locator.contents(),
118+
)
119+
.map_or(None, |(parsed_annotation, _)| {
120+
Some(TypingTarget::ForwardReference(
121+
parsed_annotation.into_expr(),
122+
))
123+
}),
119124
_ => semantic.resolve_qualified_name(expr).map_or(
120125
// If we can't resolve the call path, it must be defined in the
121126
// same file, so we assume it's `Any` as it could be a type alias.

crates/ruff_python_parser/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ impl Parsed<ModExpression> {
357357
&self.syntax.body
358358
}
359359

360+
/// Returns a mutable reference to the expression contained in this parsed output.
361+
pub fn expr_mut(&mut self) -> &mut Expr {
362+
&mut self.syntax.body
363+
}
364+
360365
/// Consumes the [`Parsed`] output and returns the contained [`Expr`].
361366
pub fn into_expr(self) -> Expr {
362367
*self.syntax.body

crates/ruff_python_parser/src/typing.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
33
use ruff_python_ast::relocate::relocate_expr;
44
use ruff_python_ast::str::raw_contents;
5-
use ruff_python_ast::{Expr, ExprStringLiteral, StringFlags, StringLiteral};
5+
use ruff_python_ast::{ExprStringLiteral, ModExpression, StringFlags, StringLiteral};
66
use ruff_text_size::Ranged;
77

8-
use crate::{parse_expression, parse_expression_range, ParseError};
8+
use crate::{parse_expression, parse_expression_range, ParseError, Parsed};
99

1010
#[derive(Copy, Clone, Debug)]
1111
pub enum AnnotationKind {
@@ -34,7 +34,7 @@ impl AnnotationKind {
3434
pub fn parse_type_annotation(
3535
string_expr: &ExprStringLiteral,
3636
source: &str,
37-
) -> Result<(Expr, AnnotationKind), ParseError> {
37+
) -> Result<(Parsed<ModExpression>, AnnotationKind), ParseError> {
3838
let expr_text = &source[string_expr.range()];
3939

4040
if let [string_literal] = string_expr.value.as_slice() {
@@ -58,24 +58,23 @@ pub fn parse_type_annotation(
5858
fn parse_simple_type_annotation(
5959
string_literal: &StringLiteral,
6060
source: &str,
61-
) -> Result<(Expr, AnnotationKind), ParseError> {
61+
) -> Result<(Parsed<ModExpression>, AnnotationKind), ParseError> {
6262
Ok((
6363
parse_expression_range(
6464
source,
6565
string_literal
6666
.range()
6767
.add_start(string_literal.flags.opener_len())
6868
.sub_end(string_literal.flags.closer_len()),
69-
)?
70-
.into_expr(),
69+
)?,
7170
AnnotationKind::Simple,
7271
))
7372
}
7473

7574
fn parse_complex_type_annotation(
7675
string_expr: &ExprStringLiteral,
77-
) -> Result<(Expr, AnnotationKind), ParseError> {
78-
let mut parsed = parse_expression(string_expr.value.to_str())?.into_expr();
79-
relocate_expr(&mut parsed, string_expr.range());
76+
) -> Result<(Parsed<ModExpression>, AnnotationKind), ParseError> {
77+
let mut parsed = parse_expression(string_expr.value.to_str())?;
78+
relocate_expr(parsed.expr_mut(), string_expr.range());
8079
Ok((parsed, AnnotationKind::Complex))
8180
}

0 commit comments

Comments
 (0)