ruff_python_parser/
typing.rs1use ruff_python_ast::relocate::relocate_expr;
4use ruff_python_ast::{Expr, ExprStringLiteral, ModExpression, StringLiteral};
5use ruff_text_size::Ranged;
6
7use crate::{ParseError, Parsed, parse_expression, parse_string_annotation};
8
9type AnnotationParseResult = Result<ParsedAnnotation, ParseError>;
10
11#[derive(Debug)]
12pub struct ParsedAnnotation {
13 parsed: Parsed<ModExpression>,
14 kind: AnnotationKind,
15}
16
17impl ParsedAnnotation {
18 pub fn parsed(&self) -> &Parsed<ModExpression> {
19 &self.parsed
20 }
21
22 pub fn expression(&self) -> &Expr {
23 self.parsed.expr()
24 }
25
26 pub fn kind(&self) -> AnnotationKind {
27 self.kind
28 }
29}
30
31#[derive(Copy, Clone, Debug)]
32pub enum AnnotationKind {
33 Simple,
39
40 Complex,
44}
45
46impl AnnotationKind {
47 pub const fn is_simple(self) -> bool {
49 matches!(self, AnnotationKind::Simple)
50 }
51}
52
53pub fn parse_type_annotation(
56 string_expr: &ExprStringLiteral,
57 source: &str,
58) -> AnnotationParseResult {
59 if let Some(string_literal) = string_expr.as_single_part_string() {
60 if &source[string_literal.content_range()] == string_literal.as_str() {
63 parse_simple_type_annotation(string_literal, source)
64 } else {
65 parse_complex_type_annotation(string_expr)
68 }
69 } else {
70 parse_complex_type_annotation(string_expr)
72 }
73}
74
75fn parse_simple_type_annotation(
76 string_literal: &StringLiteral,
77 source: &str,
78) -> AnnotationParseResult {
79 Ok(ParsedAnnotation {
80 parsed: parse_string_annotation(source, string_literal)?,
81 kind: AnnotationKind::Simple,
82 })
83}
84
85fn parse_complex_type_annotation(string_expr: &ExprStringLiteral) -> AnnotationParseResult {
86 let mut parsed = parse_expression(string_expr.value.to_str())?;
87 relocate_expr(parsed.expr_mut(), string_expr.range());
88 Ok(ParsedAnnotation {
89 parsed,
90 kind: AnnotationKind::Complex,
91 })
92}