mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-14 06:15:13 +00:00
Remove parser dependency from ruff-python-ast (#6096)
This commit is contained in:
parent
99127243f4
commit
2cf00fee96
658 changed files with 1714 additions and 1546 deletions
48
crates/ruff_python_parser/src/typing.rs
Normal file
48
crates/ruff_python_parser/src/typing.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use anyhow::Result;
|
||||
use ruff_python_ast::relocate::relocate_expr;
|
||||
use ruff_python_ast::str;
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
use rustpython_ast::Expr;
|
||||
use rustpython_parser::Parse;
|
||||
|
||||
#[derive(is_macro::Is, Copy, Clone)]
|
||||
pub enum AnnotationKind {
|
||||
/// The annotation is defined as part a simple string literal,
|
||||
/// e.g. `x: "List[int]" = []`. Annotations within simple literals
|
||||
/// can be accurately located. For example, we can underline specific
|
||||
/// expressions within the annotation and apply automatic fixes, which is
|
||||
/// not possible for complex string literals.
|
||||
Simple,
|
||||
/// The annotation is defined as part of a complex string literal, such as
|
||||
/// a literal containing an implicit concatenation or escaped characters,
|
||||
/// e.g. `x: "List" "[int]" = []`. These are comparatively rare, but valid.
|
||||
Complex,
|
||||
}
|
||||
|
||||
/// Parse a type annotation from a string.
|
||||
pub fn parse_type_annotation(
|
||||
value: &str,
|
||||
range: TextRange,
|
||||
source: &str,
|
||||
) -> Result<(Expr, AnnotationKind)> {
|
||||
let expression = &source[range];
|
||||
|
||||
if str::raw_contents(expression).map_or(false, |body| body == value) {
|
||||
// The annotation is considered "simple" if and only if the raw representation (e.g.,
|
||||
// `List[int]` within "List[int]") exactly matches the parsed representation. This
|
||||
// isn't the case, e.g., for implicit concatenations, or for annotations that contain
|
||||
// escaped quotes.
|
||||
let leading_quote = str::leading_quote(expression).unwrap();
|
||||
let expr = Expr::parse_starts_at(
|
||||
value,
|
||||
"<filename>",
|
||||
range.start() + leading_quote.text_len(),
|
||||
)?;
|
||||
Ok((expr, AnnotationKind::Simple))
|
||||
} else {
|
||||
// Otherwise, consider this a "complex" annotation.
|
||||
let mut expr = Expr::parse(value, "<filename>")?;
|
||||
relocate_expr(&mut expr, range);
|
||||
Ok((expr, AnnotationKind::Complex))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue