1use std::ops::Deref;
2
3use bitflags::bitflags;
4use thin_vec::ThinVec;
5
6use ruff_python_ast::name::Name;
7use ruff_python_ast::token::TokenKind;
8use ruff_python_ast::{
9 self as ast, AnyStringFlags, AtomicNodeIndex, BoolOp, CmpOp, ConversionFlag, Expr, ExprContext,
10 FString, InterpolatedStringElement, InterpolatedStringElements, IpyEscapeKind, Number,
11 Operator, OperatorPrecedence, StringFlags, TString, UnaryOp,
12};
13use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
14
15use crate::error::{
16 ComprehensionUnpackingKind, FStringKind, StarTupleKind, UnparenthesizedNamedExprKind,
17};
18use crate::parser::progress::ParserProgress;
19use crate::parser::{FunctionKind, IpyEscapeContext, Parser, helpers};
20use crate::string::{
21 InterpolatedStringKind, StringType, parse_interpolated_string_literal_element,
22 parse_string_literal,
23};
24use crate::token_set::TokenSet;
25use crate::{
26 InterpolatedStringErrorType, Mode, ParseErrorType, UnsupportedSyntaxError,
27 UnsupportedSyntaxErrorKind,
28};
29
30use super::{InterpolatedStringElementsKind, Parenthesized, RecoveryContextKind};
31
32const NEWLINE_EOF_SET: TokenSet = TokenSet::new([TokenKind::Newline, TokenKind::EndOfFile]);
34
35const LITERAL_SET: TokenSet = TokenSet::new([
37 TokenKind::Int,
38 TokenKind::Float,
39 TokenKind::Complex,
40 TokenKind::String,
41 TokenKind::Ellipsis,
42 TokenKind::True,
43 TokenKind::False,
44 TokenKind::None,
45]);
46
47pub(super) const EXPR_SET: TokenSet = TokenSet::new([
49 TokenKind::Name,
50 TokenKind::Minus,
51 TokenKind::Plus,
52 TokenKind::Tilde,
53 TokenKind::Star,
54 TokenKind::DoubleStar,
55 TokenKind::Lpar,
56 TokenKind::Lbrace,
57 TokenKind::Lsqb,
58 TokenKind::Lambda,
59 TokenKind::Await,
60 TokenKind::Not,
61 TokenKind::Yield,
62 TokenKind::FStringStart,
63 TokenKind::TStringStart,
64 TokenKind::IpyEscapeCommand,
65])
66.union(LITERAL_SET);
67
68const END_EXPR_SET: TokenSet = TokenSet::new([
70 TokenKind::EndOfFile,
72 TokenKind::Newline,
74 TokenKind::Semi,
76 TokenKind::Colon,
80 TokenKind::Rbrace,
82 TokenKind::Rsqb,
84 TokenKind::Rpar,
86 TokenKind::Comma,
88 TokenKind::Dedent,
95 TokenKind::If,
97 TokenKind::Else,
98 TokenKind::As,
101 TokenKind::From,
103 TokenKind::For,
105 TokenKind::Async,
107 TokenKind::In,
109 TokenKind::Equal,
112 TokenKind::Exclamation,
114]);
115
116const END_SEQUENCE_SET: TokenSet = END_EXPR_SET.remove(TokenKind::Comma);
118
119impl<'src> Parser<'src> {
120 pub(super) fn at_name_or_keyword(&self) -> bool {
122 self.at(TokenKind::Name) || self.current_token_kind().is_keyword()
123 }
124
125 pub(super) fn at_name_or_soft_keyword(&self) -> bool {
127 self.at(TokenKind::Name) || self.at_soft_keyword()
128 }
129
130 pub(super) fn at_soft_keyword(&self) -> bool {
132 self.current_token_kind().is_soft_keyword()
133 }
134
135 pub(super) fn at_expr(&self) -> bool {
137 self.at_ts(EXPR_SET) || self.at_soft_keyword()
138 }
139
140 pub(super) fn at_sequence_end(&self) -> bool {
142 self.at_ts(END_SEQUENCE_SET)
143 }
144
145 pub(super) fn parse_expression_list(&mut self, context: ExpressionContext) -> ParsedExpr {
152 let start = self.node_start();
153 let parsed_expr = self.parse_conditional_expression_or_higher_impl(context);
154
155 if self.at(TokenKind::Comma) {
156 let subsequent_context = context.disallow_yield_expressions();
157 Expr::Tuple(self.parse_tuple_expression(
158 parsed_expr.expr,
159 start,
160 Parenthesized::No,
161 |p| p.parse_conditional_expression_or_higher_impl(subsequent_context),
162 ))
163 .into()
164 } else {
165 parsed_expr
166 }
167 }
168
169 pub(super) fn parse_named_expression_or_higher(
179 &mut self,
180 context: ExpressionContext,
181 ) -> ParsedExpr {
182 let start = self.node_start();
183 let parsed_expr = self.parse_conditional_expression_or_higher_impl(context);
184
185 if self.at(TokenKind::ColonEqual) {
186 Expr::Named(self.parse_named_expression(parsed_expr.expr, start)).into()
187 } else {
188 parsed_expr
189 }
190 }
191
192 pub(super) fn parse_conditional_expression_or_higher(&mut self) -> ParsedExpr {
205 self.parse_conditional_expression_or_higher_impl(ExpressionContext::default())
206 }
207
208 pub(super) fn parse_conditional_expression_or_higher_impl(
209 &mut self,
210 context: ExpressionContext,
211 ) -> ParsedExpr {
212 if self.at(TokenKind::Lambda) {
213 Expr::Lambda(self.parse_lambda_expr()).into()
214 } else {
215 let start = self.node_start();
216 let parsed_expr = self.parse_simple_expression(context);
217
218 if self.at(TokenKind::If) {
219 Expr::If(self.parse_if_expression(parsed_expr.expr, start)).into()
220 } else {
221 parsed_expr
222 }
223 }
224 }
225
226 fn parse_simple_expression(&mut self, context: ExpressionContext) -> ParsedExpr {
239 self.parse_binary_expression_or_higher(OperatorPrecedence::None, context)
240 }
241
242 fn parse_binary_expression_or_higher(
246 &mut self,
247 left_precedence: OperatorPrecedence,
248 context: ExpressionContext,
249 ) -> ParsedExpr {
250 self.with_recursion(|parser| {
251 let start = parser.node_start();
252 let lhs = parser.parse_lhs_expression(left_precedence, context);
253 parser.parse_binary_expression_or_higher_recursive(lhs, left_precedence, context, start)
254 })
255 }
256
257 fn parse_binary_expression_or_higher_recursive(
258 &mut self,
259 mut left: ParsedExpr,
260 left_precedence: OperatorPrecedence,
261 context: ExpressionContext,
262 start: TextSize,
263 ) -> ParsedExpr {
264 let mut progress = ParserProgress::default();
265
266 loop {
267 progress.assert_progressing(self);
268
269 let current_token = self.current_token_kind();
270
271 if matches!(current_token, TokenKind::In) && context.is_in_excluded() {
272 break;
275 }
276
277 let next_token =
278 matches!(current_token, TokenKind::Is | TokenKind::Not).then(|| self.peek());
279 let Some(operator) = BinaryLikeOperator::try_from_tokens(current_token, next_token)
280 else {
281 break;
283 };
284
285 let new_precedence = operator.precedence();
286
287 let stop_at_current_operator = if new_precedence.is_right_associative() {
288 new_precedence < left_precedence
289 } else {
290 new_precedence <= left_precedence
291 };
292
293 if stop_at_current_operator {
294 break;
295 }
296
297 left.expr = match operator {
298 BinaryLikeOperator::Boolean(bool_op) => {
299 Expr::BoolOp(self.parse_boolean_expression(left.expr, start, bool_op, context))
300 }
301 BinaryLikeOperator::Comparison(cmp_op) => Expr::Compare(
302 self.parse_comparison_expression(left.expr, start, cmp_op, context),
303 ),
304 BinaryLikeOperator::Binary(bin_op) => {
305 self.bump(TokenKind::from(bin_op));
306
307 let right = self.parse_binary_expression_or_higher(new_precedence, context);
308
309 Expr::BinOp(ast::ExprBinOp {
310 left: Box::new(left.expr),
311 op: bin_op,
312 right: Box::new(right.expr),
313 range: self.node_range(start),
314 node_index: AtomicNodeIndex::NONE,
315 })
316 }
317 };
318 }
319
320 left
321 }
322
323 fn parse_lhs_expression(
333 &mut self,
334 left_precedence: OperatorPrecedence,
335 context: ExpressionContext,
336 ) -> ParsedExpr {
337 let token = self.current_token_kind();
338 let start = self.node_start();
339
340 if let Some(unary_op) = token.as_unary_operator() {
341 let expr = self.parse_unary_expression(unary_op, context);
342
343 if matches!(unary_op, UnaryOp::Not) {
344 if left_precedence > OperatorPrecedence::Not {
345 self.add_error(
346 ParseErrorType::OtherError(
347 "Boolean 'not' expression cannot be used here".to_string(),
348 ),
349 &expr,
350 );
351 }
352 } else {
353 if left_precedence > OperatorPrecedence::PosNegBitNot
358 && left_precedence != OperatorPrecedence::Exponent
359 {
360 self.add_error(
361 ParseErrorType::OtherError(format!(
362 "Unary '{unary_op}' expression cannot be used here",
363 )),
364 &expr,
365 );
366 }
367 }
368
369 return Expr::UnaryOp(expr).into();
370 }
371
372 match token {
373 TokenKind::Star => {
374 let starred_expr = self.parse_starred_expression(context);
375
376 if left_precedence > OperatorPrecedence::None
377 || !context.is_starred_expression_allowed()
378 {
379 self.add_error(ParseErrorType::InvalidStarredExpressionUsage, &starred_expr);
380 }
381
382 return Expr::Starred(starred_expr).into();
383 }
384 TokenKind::Await => {
385 let await_expr = self.parse_await_expression();
386
387 if left_precedence >= OperatorPrecedence::Await {
389 self.add_error(
390 ParseErrorType::OtherError(
391 "Await expression cannot be used here".to_string(),
392 ),
393 &await_expr,
394 );
395 }
396
397 return Expr::Await(await_expr).into();
398 }
399 TokenKind::Lambda => {
400 let lambda_expr = self.parse_lambda_expr();
403 self.add_error(ParseErrorType::InvalidLambdaExpressionUsage, &lambda_expr);
404 return Expr::Lambda(lambda_expr).into();
405 }
406 TokenKind::Yield => {
407 let expr = self.parse_yield_expression();
408
409 if left_precedence > OperatorPrecedence::None
410 || !context.is_yield_expression_allowed()
411 {
412 self.add_error(ParseErrorType::InvalidYieldExpressionUsage, &expr);
413 }
414
415 return expr.into();
416 }
417 _ => {}
418 }
419
420 let lhs = self.parse_atom(context);
421
422 ParsedExpr {
423 expr: self.parse_postfix_expression(lhs.expr, start, context),
424 is_parenthesized: lhs.is_parenthesized,
425 }
426 }
427
428 fn parse_expression_with_bitwise_or_precedence(&mut self) -> ParsedExpr {
436 let parsed_expr = self.parse_conditional_expression_or_higher();
437
438 if parsed_expr.is_parenthesized {
439 return parsed_expr;
441 }
442
443 let expr_name = match parsed_expr.expr {
444 Expr::Compare(_) => "Comparison",
445 Expr::BoolOp(_)
446 | Expr::UnaryOp(ast::ExprUnaryOp {
447 op: ast::UnaryOp::Not,
448 ..
449 }) => "Boolean",
450 Expr::If(_) => "Conditional",
451 Expr::Lambda(_) => "Lambda",
452 _ => return parsed_expr,
453 };
454
455 self.add_error(
456 ParseErrorType::OtherError(format!("{expr_name} expression cannot be used here")),
457 &parsed_expr,
458 );
459
460 parsed_expr
461 }
462
463 pub(super) fn parse_name(&mut self, context: ExpressionContext) -> ast::ExprName {
470 let identifier = self.parse_identifier_with_context(context);
471
472 let ctx = if identifier.is_valid() {
473 ExprContext::Load
474 } else {
475 ExprContext::Invalid
476 };
477
478 ast::ExprName {
479 range: identifier.range,
480 id: identifier.id,
481 ctx,
482 node_index: AtomicNodeIndex::NONE,
483 }
484 }
485
486 pub(super) fn parse_missing_name(&mut self) -> ast::ExprName {
487 let identifier = self.parse_missing_identifier();
488
489 ast::ExprName {
490 range: identifier.range,
491 id: identifier.id,
492 ctx: ExprContext::Invalid,
493 node_index: AtomicNodeIndex::NONE,
494 }
495 }
496
497 pub(super) fn parse_identifier(&mut self) -> ast::Identifier {
503 self.parse_identifier_with_context(ExpressionContext::default())
504 }
505
506 fn parse_identifier_with_context(&mut self, context: ExpressionContext) -> ast::Identifier {
507 let range = self.current_token_range();
508
509 if self.at(TokenKind::Name) {
510 let name = self.bump_name();
511 return ast::Identifier {
512 id: name,
513 range,
514 node_index: AtomicNodeIndex::NONE,
515 };
516 }
517
518 if self.current_token_kind().is_soft_keyword() {
519 let text = self.src_text(range);
520 let id = self.intern_name(text);
521 self.bump_soft_keyword_as_name();
522 return ast::Identifier {
523 id,
524 range,
525 node_index: AtomicNodeIndex::NONE,
526 };
527 }
528
529 if (context.is_for_excluded())
537 && (self.at(TokenKind::For)
538 || (self.at(TokenKind::Async) && self.peek() == TokenKind::For))
539 || (context.is_in_excluded() && self.at(TokenKind::In))
540 {
541 return self.parse_missing_identifier();
542 }
543
544 if self.current_token_kind().is_keyword() {
545 self.add_error(
547 ParseErrorType::OtherError(format!(
548 "Expected an identifier, but found a keyword {} that cannot be used here",
549 self.current_token_kind()
550 )),
551 range,
552 );
553
554 let text = self.src_text(range);
555 let id = self.intern_name(text);
556 self.bump_any();
557 ast::Identifier {
558 id,
559 range,
560 node_index: AtomicNodeIndex::NONE,
561 }
562 } else {
563 self.parse_missing_identifier()
564 }
565 }
566
567 fn parse_missing_identifier(&mut self) -> ast::Identifier {
568 self.add_error(
569 ParseErrorType::OtherError("Expected an identifier".into()),
570 self.current_token_range(),
571 );
572
573 ast::Identifier {
574 id: Name::empty(),
575 range: self.missing_node_range(),
576 node_index: AtomicNodeIndex::NONE,
577 }
578 }
579
580 fn parse_atom(&mut self, context: ExpressionContext) -> ParsedExpr {
584 let start = self.node_start();
585
586 let lhs = match self.current_token_kind() {
587 TokenKind::Float => {
588 let value = self.bump_float();
589
590 Expr::NumberLiteral(ast::ExprNumberLiteral {
591 value: Number::Float(value),
592 range: self.node_range(start),
593 node_index: AtomicNodeIndex::NONE,
594 })
595 }
596 TokenKind::Complex => {
597 let (real, imag) = self.bump_complex();
598 Expr::NumberLiteral(ast::ExprNumberLiteral {
599 value: Number::Complex { real, imag },
600 range: self.node_range(start),
601 node_index: AtomicNodeIndex::NONE,
602 })
603 }
604 TokenKind::Int => {
605 let value = self.bump_int();
606 Expr::NumberLiteral(ast::ExprNumberLiteral {
607 value: Number::Int(value),
608 range: self.node_range(start),
609 node_index: AtomicNodeIndex::NONE,
610 })
611 }
612 TokenKind::True => {
613 self.bump(TokenKind::True);
614 Expr::BooleanLiteral(ast::ExprBooleanLiteral {
615 value: true,
616 range: self.node_range(start),
617 node_index: AtomicNodeIndex::NONE,
618 })
619 }
620 TokenKind::False => {
621 self.bump(TokenKind::False);
622 Expr::BooleanLiteral(ast::ExprBooleanLiteral {
623 value: false,
624 range: self.node_range(start),
625 node_index: AtomicNodeIndex::NONE,
626 })
627 }
628 TokenKind::None => {
629 self.bump(TokenKind::None);
630 Expr::NoneLiteral(ast::ExprNoneLiteral {
631 range: self.node_range(start),
632 node_index: AtomicNodeIndex::NONE,
633 })
634 }
635 TokenKind::Ellipsis => {
636 self.bump(TokenKind::Ellipsis);
637 Expr::EllipsisLiteral(ast::ExprEllipsisLiteral {
638 range: self.node_range(start),
639 node_index: AtomicNodeIndex::NONE,
640 })
641 }
642 TokenKind::Name => Expr::Name(self.parse_name(context)),
643 TokenKind::IpyEscapeCommand => {
644 Expr::IpyEscapeCommand(self.parse_ipython_escape_command_expression())
645 }
646 TokenKind::String | TokenKind::FStringStart | TokenKind::TStringStart => {
647 self.parse_strings()
648 }
649 TokenKind::Lpar => {
650 return self.parse_parenthesized_expression();
651 }
652 TokenKind::Lsqb => self.parse_list_like_expression(),
653 TokenKind::Lbrace => self.parse_set_or_dict_like_expression(),
654
655 kind => {
656 if kind.is_keyword() {
657 Expr::Name(self.parse_name(context))
658 } else {
659 self.add_error(
660 ParseErrorType::ExpectedExpression,
661 self.current_token_range(),
662 );
663 Expr::Name(ast::ExprName {
664 range: self.missing_node_range(),
665 id: Name::empty(),
666 ctx: ExprContext::Invalid,
667 node_index: AtomicNodeIndex::NONE,
668 })
669 }
670 }
671 };
672
673 lhs.into()
674 }
675
676 fn parse_postfix_expression(
683 &mut self,
684 mut lhs: Expr,
685 start: TextSize,
686 context: ExpressionContext,
687 ) -> Expr {
688 loop {
689 lhs = match self.current_token_kind() {
690 TokenKind::Lpar => Expr::Call(self.parse_call_expression(lhs, start)),
691 TokenKind::Lsqb => Expr::Subscript(self.parse_subscript_expression(lhs, start)),
692 TokenKind::Dot => {
693 Expr::Attribute(self.parse_attribute_expression(lhs, start, context))
694 }
695 _ => break lhs,
696 };
697 }
698 }
699
700 fn parse_call_expression(&mut self, func: Expr, start: TextSize) -> ast::ExprCall {
711 let arguments = self.parse_arguments(ArgumentsContext::Call);
712 debug_assert_eq!(self.node_range(start).end(), arguments.end());
713
714 ast::ExprCall {
715 func: Box::new(func),
716 arguments,
717 range_start: start,
718 node_index: AtomicNodeIndex::NONE,
719 }
720 }
721
722 pub(super) fn parse_arguments(&mut self, context: ArgumentsContext) -> ast::Arguments {
730 let start = self.node_start();
731 self.bump(TokenKind::Lpar);
732
733 if self.eat(TokenKind::Rpar) {
734 return ast::Arguments {
735 range: self.node_range(start),
736 node_index: AtomicNodeIndex::NONE,
737 args: Box::default(),
738 keywords: ThinVec::default(),
739 runtime_args: None,
740 runtime_bases: None,
741 };
742 }
743
744 let args_snapshot = self.expr_scratch.snapshot();
745 let keywords_snapshot = self.keyword_scratch.snapshot();
746 let mut seen_keyword_argument = false; let mut seen_keyword_unpacking = false; let has_trailing_comma =
750 self.parse_comma_separated_list(RecoveryContextKind::Arguments, |parser| {
751 let argument_start = parser.node_start();
752 if parser.eat(TokenKind::DoubleStar) {
753 let value = parser.parse_conditional_expression_or_higher();
754
755 parser.keyword_scratch.push(ast::Keyword {
756 arg: None,
757 value: value.expr,
758 range: parser.node_range(argument_start),
759 node_index: AtomicNodeIndex::NONE,
760 });
761
762 seen_keyword_unpacking = true;
763 } else {
764 let start = parser.node_start();
765 let mut parsed_expr = parser
766 .parse_named_expression_or_higher(ExpressionContext::starred_conditional());
767
768 match parser.current_token_kind() {
769 TokenKind::Async | TokenKind::For => {
770 if parsed_expr.is_unparenthesized_starred_expr() {
771 parser.add_unsupported_syntax_error(
772 UnsupportedSyntaxErrorKind::UnpackingInComprehension(
773 ComprehensionUnpackingKind::IterableInGenerator,
774 ),
775 parsed_expr.range(),
776 );
777 }
778
779 parsed_expr = Expr::Generator(parser.parse_generator_expression(
780 parsed_expr.expr,
781 start,
782 Parenthesized::No,
783 ))
784 .into();
785 }
786 _ => {
787 if seen_keyword_unpacking
788 && parsed_expr.is_unparenthesized_starred_expr()
789 {
790 parser.add_error(
791 ParseErrorType::InvalidArgumentUnpackingOrder,
792 &parsed_expr,
793 );
794 }
795 }
796 }
797
798 let arg_range = parser.node_range(start);
799 if parser.eat(TokenKind::Equal) {
800 seen_keyword_argument = true;
801 let arg = if let ParsedExpr {
802 expr: Expr::Name(ident_expr),
803 is_parenthesized,
804 } = parsed_expr
805 {
806 if is_parenthesized {
817 parser.add_unsupported_syntax_error(
818 UnsupportedSyntaxErrorKind::ParenthesizedKeywordArgumentName,
819 arg_range,
820 );
821 }
822
823 ast::Identifier {
824 id: ident_expr.id,
825 range: ident_expr.range,
826 node_index: AtomicNodeIndex::NONE,
827 }
828 } else {
829 parser.add_error(
833 ParseErrorType::OtherError("Expected a parameter name".to_string()),
834 &parsed_expr,
835 );
836 ast::Identifier {
837 id: Name::empty(),
838 range: parsed_expr.range(),
839 node_index: AtomicNodeIndex::NONE,
840 }
841 };
842
843 let value = parser.parse_conditional_expression_or_higher();
844
845 parser.keyword_scratch.push(ast::Keyword {
846 arg: Some(arg),
847 value: value.expr,
848 range: parser.node_range(argument_start),
849 node_index: AtomicNodeIndex::NONE,
850 });
851 } else {
852 if !parsed_expr.is_unparenthesized_starred_expr() {
853 if seen_keyword_unpacking {
854 parser.add_error(
855 ParseErrorType::PositionalAfterKeywordUnpacking,
856 &parsed_expr,
857 );
858 } else if seen_keyword_argument {
859 parser.add_error(
860 ParseErrorType::PositionalAfterKeywordArgument,
861 &parsed_expr,
862 );
863 }
864 }
865 parser.expr_scratch.push(parsed_expr.expr);
866 }
867 }
868 });
869
870 self.expect(TokenKind::Rpar);
871
872 let keywords = self.keyword_scratch.take_thin_vec(keywords_snapshot);
873 let arguments = ast::Arguments {
874 range: self.node_range(start),
875 node_index: AtomicNodeIndex::NONE,
876 args: self.expr_scratch.take(args_snapshot),
877 keywords,
878 runtime_args: None,
879 runtime_bases: None,
880 };
881
882 self.validate_arguments(&arguments, has_trailing_comma, context);
883
884 arguments
885 }
886
887 fn parse_subscript_expression(
895 &mut self,
896 mut value: Expr,
897 start: TextSize,
898 ) -> ast::ExprSubscript {
899 self.bump(TokenKind::Lsqb);
900
901 helpers::set_expr_ctx(&mut value, ExprContext::Load);
904
905 let slice_start = self.node_start();
907
908 if self.eat(TokenKind::Rsqb) {
910 let slice_range = self.node_range(slice_start);
911 self.add_error(ParseErrorType::EmptySlice, slice_range);
912
913 return ast::ExprSubscript {
914 value: Box::new(value),
915 slice: Box::new(Expr::Name(ast::ExprName {
916 range: slice_range,
917 id: Name::empty(),
918 ctx: ExprContext::Invalid,
919 node_index: AtomicNodeIndex::NONE,
920 })),
921 ctx: ExprContext::Load,
922 range: self.node_range(start),
923 node_index: AtomicNodeIndex::NONE,
924 };
925 }
926
927 let mut slice = self.parse_slice();
928
929 if self.eat(TokenKind::Comma) {
932 let slices_snapshot = self.expr_scratch.snapshot();
933 self.expr_scratch.push(slice);
934
935 self.parse_comma_separated_list(RecoveryContextKind::Slices, |parser| {
936 let slice = parser.parse_slice();
937 parser.expr_scratch.push(slice);
938 });
939
940 slice = Expr::Tuple(ast::ExprTuple {
941 elts: self.expr_scratch.take(slices_snapshot),
942 ctx: ExprContext::Load,
943 range: self.node_range(slice_start),
944 parenthesized: false,
945 node_index: AtomicNodeIndex::NONE,
946 runtime_elts: None,
947 });
948 } else if slice.is_starred_expr() {
949 slice = Expr::Tuple(ast::ExprTuple {
953 elts: vec![slice],
954 ctx: ExprContext::Load,
955 range: self.node_range(slice_start),
956 parenthesized: false,
957 node_index: AtomicNodeIndex::NONE,
958 runtime_elts: None,
959 });
960 }
961
962 self.expect(TokenKind::Rsqb);
963
964 if let Expr::Tuple(ast::ExprTuple {
989 elts,
990 parenthesized: false,
991 ..
992 }) = &slice
993 {
994 for elt in elts.iter().filter(|elt| elt.is_starred_expr()) {
995 self.add_unsupported_syntax_error(
996 UnsupportedSyntaxErrorKind::StarExpressionInIndex,
997 elt.range(),
998 );
999 }
1000 }
1001
1002 ast::ExprSubscript {
1003 value: Box::new(value),
1004 slice: Box::new(slice),
1005 ctx: ExprContext::Load,
1006 range: self.node_range(start),
1007 node_index: AtomicNodeIndex::NONE,
1008 }
1009 }
1010
1011 fn parse_slice(&mut self) -> Expr {
1015 const UPPER_END_SET: TokenSet =
1016 TokenSet::new([TokenKind::Comma, TokenKind::Colon, TokenKind::Rsqb])
1017 .union(NEWLINE_EOF_SET);
1018 const STEP_END_SET: TokenSet =
1019 TokenSet::new([TokenKind::Comma, TokenKind::Rsqb]).union(NEWLINE_EOF_SET);
1020
1021 let start = self.node_start();
1033
1034 let lower = if self.at_expr() {
1035 let lower =
1036 self.parse_named_expression_or_higher(ExpressionContext::starred_conditional());
1037
1038 if self.at_ts(NEWLINE_EOF_SET.union([TokenKind::Rsqb, TokenKind::Comma].into())) {
1040 if lower.is_unparenthesized_named_expr() {
1052 self.add_unsupported_syntax_error(
1053 UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
1054 UnparenthesizedNamedExprKind::SequenceIndex,
1055 ),
1056 lower.range(),
1057 );
1058 }
1059 return lower.expr;
1060 }
1061
1062 if !lower.is_parenthesized {
1064 match lower.expr {
1065 Expr::Starred(_) => {
1066 self.add_error(ParseErrorType::InvalidStarredExpressionUsage, &lower);
1067 }
1068 Expr::Named(_) => {
1069 self.add_error(ParseErrorType::UnparenthesizedNamedExpression, &lower);
1070 }
1071 _ => {}
1072 }
1073 }
1074
1075 Some(lower.expr)
1076 } else {
1077 None
1078 };
1079
1080 self.expect(TokenKind::Colon);
1081
1082 let lower = lower.map(Box::new);
1083 let upper = if self.at_ts(UPPER_END_SET) {
1084 None
1085 } else {
1086 Some(Box::new(self.parse_conditional_expression_or_higher().expr))
1087 };
1088
1089 let step = if self.eat(TokenKind::Colon) {
1090 if self.at_ts(STEP_END_SET) {
1091 None
1092 } else {
1093 Some(Box::new(self.parse_conditional_expression_or_higher().expr))
1094 }
1095 } else {
1096 None
1097 };
1098
1099 Expr::Slice(ast::ExprSlice {
1100 range: self.node_range(start),
1101 node_index: AtomicNodeIndex::NONE,
1102 lower,
1103 upper,
1104 step,
1105 })
1106 }
1107
1108 pub(super) fn parse_unary_expression(
1119 &mut self,
1120 op: UnaryOp,
1121 context: ExpressionContext,
1122 ) -> ast::ExprUnaryOp {
1123 let start = self.node_start();
1124 self.bump(TokenKind::from(op));
1125
1126 let operand = self.parse_binary_expression_or_higher(OperatorPrecedence::from(op), context);
1127
1128 ast::ExprUnaryOp {
1129 op,
1130 operand: Box::new(operand.expr),
1131 range: self.node_range(start),
1132 node_index: AtomicNodeIndex::NONE,
1133 }
1134 }
1135
1136 pub(super) fn parse_attribute_expression(
1144 &mut self,
1145 value: Expr,
1146 start: TextSize,
1147 context: ExpressionContext,
1148 ) -> ast::ExprAttribute {
1149 self.bump(TokenKind::Dot);
1150
1151 let attr = self.parse_identifier_with_context(context);
1152
1153 ast::ExprAttribute {
1154 value: Box::new(value),
1155 attr,
1156 ctx: ExprContext::Load,
1157 range: self.node_range(start),
1158 node_index: AtomicNodeIndex::NONE,
1159 }
1160 }
1161
1162 fn parse_boolean_expression(
1173 &mut self,
1174 lhs: Expr,
1175 start: TextSize,
1176 op: BoolOp,
1177 context: ExpressionContext,
1178 ) -> ast::ExprBoolOp {
1179 self.bump(TokenKind::from(op));
1180
1181 let values_snapshot = self.expr_scratch.snapshot();
1182 self.expr_scratch.push(lhs);
1183 let mut progress = ParserProgress::default();
1184
1185 loop {
1188 progress.assert_progressing(self);
1189
1190 let parsed_expr =
1191 self.parse_binary_expression_or_higher(OperatorPrecedence::from(op), context);
1192 self.expr_scratch.push(parsed_expr.expr);
1193
1194 if !self.eat(TokenKind::from(op)) {
1195 break;
1196 }
1197 }
1198
1199 ast::ExprBoolOp {
1200 values: self.expr_scratch.take(values_snapshot),
1201 op,
1202 range: self.node_range(start),
1203 node_index: AtomicNodeIndex::NONE,
1204 runtime_values: None,
1205 }
1206 }
1207
1208 fn bump_cmp_op(&mut self, op: CmpOp) {
1210 let (first, second) = match op {
1211 CmpOp::Eq => (TokenKind::EqEqual, None),
1212 CmpOp::NotEq => (TokenKind::NotEqual, None),
1213 CmpOp::Lt => (TokenKind::Less, None),
1214 CmpOp::LtE => (TokenKind::LessEqual, None),
1215 CmpOp::Gt => (TokenKind::Greater, None),
1216 CmpOp::GtE => (TokenKind::GreaterEqual, None),
1217 CmpOp::Is => (TokenKind::Is, None),
1218 CmpOp::IsNot => (TokenKind::Is, Some(TokenKind::Not)),
1219 CmpOp::In => (TokenKind::In, None),
1220 CmpOp::NotIn => (TokenKind::Not, Some(TokenKind::In)),
1221 };
1222
1223 self.bump(first);
1224 if let Some(second) = second {
1225 self.bump(second);
1226 }
1227 }
1228
1229 fn parse_comparison_expression(
1242 &mut self,
1243 lhs: Expr,
1244 start: TextSize,
1245 op: CmpOp,
1246 context: ExpressionContext,
1247 ) -> ast::ExprCompare {
1248 self.bump_cmp_op(op);
1249
1250 let comparators_snapshot = self.expr_scratch.snapshot();
1251 let mut operators = vec![op];
1252
1253 let mut progress = ParserProgress::default();
1254
1255 loop {
1256 progress.assert_progressing(self);
1257
1258 let comparator = self
1259 .parse_binary_expression_or_higher(
1260 OperatorPrecedence::ComparisonsMembershipIdentity,
1261 context,
1262 )
1263 .expr;
1264 self.expr_scratch.push(comparator);
1265
1266 let next_token = self.current_token_kind();
1267 if matches!(next_token, TokenKind::In) && context.is_in_excluded() {
1268 break;
1269 }
1270
1271 let next_next_token =
1272 matches!(next_token, TokenKind::Is | TokenKind::Not).then(|| self.peek());
1273 let Some(next_op) = helpers::token_kind_to_cmp_op(next_token, next_next_token) else {
1274 break;
1275 };
1276
1277 self.bump_cmp_op(next_op);
1278 operators.push(next_op);
1279 }
1280
1281 ast::ExprCompare {
1282 left: Box::new(lhs),
1283 ops: operators.into_boxed_slice(),
1284 comparators: self.expr_scratch.take(comparators_snapshot),
1285 range: self.node_range(start),
1286 node_index: AtomicNodeIndex::NONE,
1287 runtime_comparators: None,
1288 }
1289 }
1290
1291 pub(super) fn parse_strings(&mut self) -> Expr {
1299 const STRING_START_SET: TokenSet = TokenSet::new([
1300 TokenKind::String,
1301 TokenKind::FStringStart,
1302 TokenKind::TStringStart,
1303 ]);
1304
1305 let start = self.node_start();
1306 let first = self.parse_string();
1307
1308 if !self.at_ts(STRING_START_SET) {
1309 return first.into();
1310 }
1311
1312 let mut strings = Vec::with_capacity(2);
1313 strings.push(first);
1314
1315 let mut progress = ParserProgress::default();
1316
1317 while self.at_ts(STRING_START_SET) {
1318 progress.assert_progressing(self);
1319 strings.push(self.parse_string());
1320 }
1321
1322 let range = self.node_range(start);
1323 self.handle_implicitly_concatenated_strings(strings, range)
1324 }
1325
1326 fn parse_string(&mut self) -> StringType {
1328 if self.at(TokenKind::String) {
1329 self.parse_string_or_byte_literal()
1330 } else if self.at(TokenKind::FStringStart) {
1331 StringType::FString(
1332 self.parse_interpolated_string(InterpolatedStringKind::FString)
1333 .into(),
1334 )
1335 } else if self.at(TokenKind::TStringStart) {
1336 let string_type = StringType::TString(
1350 self.parse_interpolated_string(InterpolatedStringKind::TString)
1351 .into(),
1352 );
1353 self.add_unsupported_syntax_error(
1354 UnsupportedSyntaxErrorKind::TemplateStrings,
1355 string_type.range(),
1356 );
1357 string_type
1358 } else {
1359 unreachable!("Expected to parse a string")
1360 }
1361 }
1362
1363 fn handle_implicitly_concatenated_strings(
1369 &mut self,
1370 strings: Vec<StringType>,
1371 range: TextRange,
1372 ) -> Expr {
1373 assert!(strings.len() > 1);
1374
1375 let mut has_fstring = false;
1376 let mut byte_literal_count = 0;
1377 let mut tstring_count = 0;
1378 for string in &strings {
1379 match string {
1380 StringType::FString(_) => has_fstring = true,
1381 StringType::TString(_) => tstring_count += 1,
1382 StringType::Bytes(_) => byte_literal_count += 1,
1383 StringType::Str(_) => {}
1384 }
1385 }
1386 let has_bytes = byte_literal_count > 0;
1387 let has_tstring = tstring_count > 0;
1388
1389 if has_bytes {
1390 if byte_literal_count < strings.len() {
1391 self.report_mixed_string_literal_error(&strings, range);
1412 }
1413 else {
1417 let mut values = Vec::with_capacity(strings.len());
1418 for string in strings {
1419 values.push(match string {
1420 StringType::Bytes(value) => value,
1421 _ => unreachable!("Expected `StringType::Bytes`"),
1422 });
1423 }
1424 return Expr::from(ast::ExprBytesLiteral {
1425 value: ast::BytesLiteralValue::concatenated(values),
1426 range,
1427 node_index: AtomicNodeIndex::NONE,
1428 });
1429 }
1430 } else if has_tstring {
1431 if tstring_count < strings.len() {
1432 self.report_mixed_string_literal_error(&strings, range);
1433 }
1434 else {
1438 let mut values = Vec::with_capacity(strings.len());
1439 for string in strings {
1440 values.push(match string {
1441 StringType::TString(value) => value,
1442 _ => unreachable!("Expected `StringType::TString`"),
1443 });
1444 }
1445 return Expr::from(ast::ExprTString {
1446 value: ast::TStringValue::concatenated(values),
1447 range,
1448 node_index: AtomicNodeIndex::NONE,
1449 runtime_template_str: None,
1450 runtime_values: None,
1451 });
1452 }
1453 }
1454
1455 if !has_fstring && !has_tstring {
1478 let mut values = Vec::with_capacity(strings.len());
1479 for string in strings {
1480 values.push(match string {
1481 StringType::Str(value) => value,
1482 _ => ast::StringLiteral::invalid(string.range()),
1483 });
1484 }
1485 return Expr::from(ast::ExprStringLiteral {
1486 value: ast::StringLiteralValue::concatenated(values),
1487 range,
1488 node_index: AtomicNodeIndex::NONE,
1489 });
1490 }
1491
1492 let mut parts = Vec::with_capacity(strings.len());
1493 for string in strings {
1494 match string {
1495 StringType::FString(fstring) => parts.push(ast::FStringPart::FString(fstring)),
1496 StringType::Str(string) => parts.push(ast::FStringPart::Literal(string)),
1497 StringType::TString(tstring) => parts.push(ast::FStringPart::Literal(
1501 ast::StringLiteral::invalid(tstring.range()),
1502 )),
1503 StringType::Bytes(bytes) => parts.push(ast::FStringPart::Literal(
1504 ast::StringLiteral::invalid(bytes.range()),
1505 )),
1506 }
1507 }
1508
1509 Expr::from(ast::ExprFString {
1510 value: ast::FStringValue::concatenated(parts),
1511 range,
1512 node_index: AtomicNodeIndex::NONE,
1513 runtime_joined_str: None,
1514 runtime_values: None,
1515 })
1516 }
1517
1518 fn report_mixed_string_literal_error(&mut self, strings: &[StringType], range: TextRange) {
1519 for pair in strings.windows(2) {
1522 let message = match pair {
1523 [StringType::TString(_), StringType::TString(_)]
1524 | [StringType::Bytes(_), StringType::Bytes(_)] => continue,
1525 [StringType::TString(_), _] | [_, StringType::TString(_)] => {
1526 "Cannot mix t-string literals with string or bytes literals"
1527 }
1528 [StringType::Bytes(_), _] | [_, StringType::Bytes(_)] => {
1529 "Bytes literal cannot be mixed with non-bytes literals"
1530 }
1531 _ => continue,
1532 };
1533 self.add_error(ParseErrorType::OtherError(message.to_string()), range);
1534 break;
1535 }
1536 }
1537
1538 fn parse_string_or_byte_literal(&mut self) -> StringType {
1548 let range = self.current_token_range();
1549 let flags = self.tokens.current_flags().as_any_string_flags();
1550
1551 let value = self.bump_string_value();
1552
1553 match parse_string_literal(value, flags, range) {
1554 Ok(string) => string,
1555 Err(error) => {
1556 let location = error.location();
1557 self.add_error(ParseErrorType::Lexical(error.into_error()), location);
1558
1559 if flags.is_byte_string() {
1560 StringType::Bytes(ast::BytesLiteral {
1565 value: Box::new([]),
1566 range,
1567 flags: ast::BytesLiteralFlags::from(flags).with_invalid(),
1568 node_index: AtomicNodeIndex::NONE,
1569 })
1570 } else {
1571 StringType::Str(ast::StringLiteral {
1575 value: "".into(),
1576 range,
1577 flags: ast::StringLiteralFlags::from(flags).with_invalid(),
1578 node_index: AtomicNodeIndex::NONE,
1579 })
1580 }
1581 }
1582 }
1583 }
1584
1585 fn parse_interpolated_string(
1597 &mut self,
1598 kind: InterpolatedStringKind,
1599 ) -> InterpolatedStringData {
1600 let start = self.node_start();
1601 let mut flags = self.tokens.current_flags().as_any_string_flags();
1602
1603 self.bump(kind.start_token());
1604 let elements = self.parse_interpolated_string_elements(
1605 flags,
1606 InterpolatedStringElementsKind::Regular(kind),
1607 kind,
1608 );
1609
1610 if !self.expect(kind.end_token()) {
1611 flags = flags.with_unclosed(true);
1612 }
1613
1614 InterpolatedStringData {
1615 elements,
1616 range: self.node_range(start),
1617 flags,
1618 }
1619 }
1620
1621 fn check_fstring_comments(&mut self, range: TextRange) -> bool {
1624 let mut has_comments = false;
1625
1626 self.unsupported_syntax_errors.extend(
1627 self.tokens
1628 .in_range(range)
1629 .iter()
1630 .filter(|token| token.kind().is_comment())
1631 .map(|token| {
1632 has_comments = true;
1633 UnsupportedSyntaxError {
1634 kind: UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Comment),
1635 range: token.range(),
1636 target_version: self.options.target_version,
1637 }
1638 }),
1639 );
1640
1641 has_comments
1642 }
1643
1644 fn parse_interpolated_string_elements(
1651 &mut self,
1652 flags: ast::AnyStringFlags,
1653 elements_kind: InterpolatedStringElementsKind,
1654 string_kind: InterpolatedStringKind,
1655 ) -> ast::InterpolatedStringElements {
1656 let mut elements = vec![];
1657 let middle_token_kind = string_kind.middle_token();
1658
1659 self.parse_list(
1660 RecoveryContextKind::InterpolatedStringElements(elements_kind),
1661 |parser| {
1662 let element = match parser.current_token_kind() {
1663 TokenKind::Lbrace => ast::InterpolatedStringElement::from(
1664 parser.parse_interpolated_element(flags, string_kind),
1665 ),
1666 tok if tok == middle_token_kind => {
1667 let range = parser.current_token_range();
1668 let value = parser.current_token_text();
1669 parser.bump(middle_token_kind);
1670 InterpolatedStringElement::Literal(
1671 parse_interpolated_string_literal_element(value, flags, range)
1672 .unwrap_or_else(|lex_error| {
1673 let location = lex_error.location();
1677 parser.add_error(
1678 ParseErrorType::Lexical(lex_error.into_error()),
1679 location,
1680 );
1681 ast::InterpolatedStringLiteralElement {
1682 value: "".into(),
1683 range,
1684 node_index: AtomicNodeIndex::NONE,
1685 }
1686 }),
1687 )
1688 }
1689 TokenKind::Unknown => {
1692 parser.bump_any();
1693 return;
1694 }
1695 tok => {
1696 unreachable!(
1700 "{}: unexpected token `{tok:?}` at {:?}",
1701 string_kind,
1702 parser.current_token_range()
1703 );
1704 }
1705 };
1706 elements.push(element);
1707 },
1708 );
1709
1710 ast::InterpolatedStringElements::from(elements)
1711 }
1712
1713 fn parse_interpolated_element(
1719 &mut self,
1720 flags: ast::AnyStringFlags,
1721 string_kind: InterpolatedStringKind,
1722 ) -> ast::InterpolatedElement {
1723 let start = self.node_start();
1724 self.bump(TokenKind::Lbrace);
1725
1726 self.tokens
1727 .re_lex_string_token_in_interpolation_element(string_kind);
1728
1729 let value = self.parse_expression_list(ExpressionContext::yield_or_starred_bitwise_or());
1752
1753 if !value.is_parenthesized && value.expr.is_lambda_expr() {
1754 self.add_error(
1765 ParseErrorType::from_interpolated_string_error(
1766 InterpolatedStringErrorType::LambdaWithoutParentheses,
1767 string_kind,
1768 ),
1769 value.range(),
1770 );
1771 }
1772 let debug_text = if self.eat(TokenKind::Equal) {
1773 let leading_range = TextRange::new(start + "{".text_len(), value.start());
1774 let trailing_range = TextRange::new(value.end(), self.current_token_range().start());
1775 Some(ast::DebugText::new(
1776 self.src_text(leading_range),
1777 self.src_text(value.range()),
1778 self.src_text(trailing_range),
1779 ))
1780 } else {
1781 None
1782 };
1783
1784 let conversion = if self.eat(TokenKind::Exclamation) {
1785 self.tokens.re_lex_raw_string_in_format_spec();
1788
1789 let conversion_flag_range = self.current_token_range();
1790 if self.at(TokenKind::Name) {
1791 if self.prev_token_end != conversion_flag_range.start() {
1796 self.add_error(
1797 ParseErrorType::from_interpolated_string_error(
1798 InterpolatedStringErrorType::ConversionFlagNotImmediatelyAfterExclamation,
1799 string_kind,
1800 ),
1801 TextRange::new(self.prev_token_end, conversion_flag_range.start()),
1802 );
1803 }
1804 let name = self.bump_name();
1805 match &*name {
1806 "s" => ConversionFlag::Str,
1807 "r" => ConversionFlag::Repr,
1808 "a" => ConversionFlag::Ascii,
1809 _ => {
1810 self.add_error(
1817 ParseErrorType::from_interpolated_string_error(
1818 InterpolatedStringErrorType::InvalidConversionFlag,
1819 string_kind,
1820 ),
1821 conversion_flag_range,
1822 );
1823 ConversionFlag::None
1824 }
1825 }
1826 } else {
1827 self.add_error(
1836 ParseErrorType::from_interpolated_string_error(
1837 InterpolatedStringErrorType::InvalidConversionFlag,
1838 string_kind,
1839 ),
1840 conversion_flag_range,
1841 );
1842 self.bump_any();
1844 ConversionFlag::None
1845 }
1846 } else {
1847 ConversionFlag::None
1848 };
1849
1850 let format_spec = if self.eat(TokenKind::Colon) {
1851 let spec_start = self.node_start();
1852 let elements = self.with_recursion(|parser| {
1853 parser.parse_interpolated_string_elements(
1854 flags,
1855 InterpolatedStringElementsKind::FormatSpec(string_kind),
1856 string_kind,
1857 )
1858 });
1859 Some(Box::new(ast::InterpolatedStringFormatSpec {
1860 range: self.node_range(spec_start),
1861 elements,
1862 node_index: AtomicNodeIndex::NONE,
1863 }))
1864 } else {
1865 None
1866 };
1867
1868 self.tokens
1869 .re_lex_string_token_in_interpolation_element(string_kind);
1870
1871 if !self.eat(TokenKind::Rbrace) {
1873 self.add_error(
1903 ParseErrorType::from_interpolated_string_error(
1904 InterpolatedStringErrorType::UnclosedLbrace,
1905 string_kind,
1906 ),
1907 self.current_token_range(),
1908 );
1909 }
1910
1911 let range = self.node_range(start);
1983
1984 if !self.options.target_version.supports_pep_701()
1985 && matches!(string_kind, InterpolatedStringKind::FString)
1986 {
1987 let range = format_spec
1991 .as_ref()
1992 .map(|format_spec| TextRange::new(range.start(), format_spec.start()))
1993 .unwrap_or(range);
1994
1995 let quote_bytes = flags.quote_str().as_bytes();
1996 let quote_len = flags.quote_len();
1997 let mut has_backslash_or_comment = false;
1998
1999 for slash_position in memchr::memchr_iter(b'\\', self.source[range].as_bytes()) {
2000 has_backslash_or_comment = true;
2001 let slash_position = TextSize::try_from(slash_position).unwrap();
2002 self.add_unsupported_syntax_error(
2003 UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::Backslash),
2004 TextRange::at(range.start() + slash_position, '\\'.text_len()),
2005 );
2006 }
2007
2008 if let Some(quote_position) =
2009 memchr::memmem::find(self.source[range].as_bytes(), quote_bytes)
2010 {
2011 let quote_position = TextSize::try_from(quote_position).unwrap();
2012 self.add_unsupported_syntax_error(
2013 UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::NestedQuote),
2014 TextRange::at(range.start() + quote_position, quote_len),
2015 );
2016 }
2017
2018 has_backslash_or_comment |= self.check_fstring_comments(range);
2019
2020 if !flags.is_triple_quoted()
2023 && !has_backslash_or_comment
2024 && memchr::memchr2(b'\n', b'\r', self.source[range].as_bytes()).is_some()
2025 {
2026 self.add_unsupported_syntax_error(
2027 UnsupportedSyntaxErrorKind::Pep701FString(FStringKind::LineBreak),
2028 TextRange::at(range.start(), '{'.text_len()),
2029 );
2030 }
2031 }
2032
2033 ast::InterpolatedElement {
2034 expression: Box::new(value.expr),
2035 debug_text,
2036 conversion,
2037 format_spec,
2038 range,
2039 node_index: AtomicNodeIndex::NONE,
2040 runtime_str: None,
2041 runtime_interpolation_format_spec: None,
2042 runtime_formatted_value_format_spec: None,
2043 }
2044 }
2045
2046 fn parse_list_like_expression(&mut self) -> Expr {
2054 let start = self.node_start();
2055
2056 self.bump(TokenKind::Lsqb);
2057
2058 if self.at_ts(NEWLINE_EOF_SET) {
2060 self.add_error(
2061 ParseErrorType::OtherError("Missing closing bracket `]`".to_string()),
2062 self.current_token_range(),
2063 );
2064 }
2065
2066 if self.eat(TokenKind::Rsqb) {
2068 return Expr::List(ast::ExprList {
2069 elts: vec![],
2070 ctx: ExprContext::Load,
2071 range: self.node_range(start),
2072 node_index: AtomicNodeIndex::NONE,
2073 runtime_elts: None,
2074 });
2075 }
2076
2077 let first_element = self.parse_named_expression_or_higher(
2079 ExpressionContext::starred_bitwise_or().with_for_excluded(),
2080 );
2081
2082 match self.current_token_kind() {
2083 TokenKind::Async | TokenKind::For => {
2084 if first_element.is_unparenthesized_starred_expr() {
2096 self.add_unsupported_syntax_error(
2097 UnsupportedSyntaxErrorKind::UnpackingInComprehension(
2098 ComprehensionUnpackingKind::IterableInList,
2099 ),
2100 first_element.range(),
2101 );
2102 }
2103
2104 Expr::ListComp(self.parse_list_comprehension_expression(first_element.expr, start))
2105 }
2106 _ => Expr::List(self.parse_list_expression(first_element.expr, start)),
2107 }
2108 }
2109
2110 fn parse_set_or_dict_like_expression(&mut self) -> Expr {
2121 let start = self.node_start();
2149 self.bump(TokenKind::Lbrace);
2150
2151 if self.at_ts(NEWLINE_EOF_SET) {
2153 self.add_error(
2154 ParseErrorType::OtherError("Missing closing brace `}`".to_string()),
2155 self.current_token_range(),
2156 );
2157 }
2158
2159 if self.eat(TokenKind::Rbrace) {
2161 return Expr::Dict(ast::ExprDict {
2162 items: vec![],
2163 range: self.node_range(start),
2164 node_index: AtomicNodeIndex::NONE,
2165 runtime_values: None,
2166 });
2167 }
2168
2169 let after_brace = self.node_start();
2170
2171 if self.eat(TokenKind::DoubleStar) {
2172 let value = self.parse_expression_with_bitwise_or_precedence();
2175 let unpack_range = TextRange::new(after_brace, value.range().end());
2176
2177 if matches!(self.current_token_kind(), TokenKind::Async | TokenKind::For) {
2178 self.add_unsupported_syntax_error(
2179 UnsupportedSyntaxErrorKind::UnpackingInComprehension(
2180 ComprehensionUnpackingKind::DictInDict,
2181 ),
2182 unpack_range,
2183 );
2184
2185 return Expr::DictComp(
2186 self.parse_dictionary_comprehension_expression(None, value.expr, start),
2187 );
2188 }
2189
2190 if self.at(TokenKind::Colon) {
2191 self.add_error(ParseErrorType::InvalidStarredExpressionUsage, unpack_range);
2192
2193 self.bump(TokenKind::Colon);
2194 let dict_value = self.parse_conditional_expression_or_higher();
2195
2196 if matches!(self.current_token_kind(), TokenKind::Async | TokenKind::For) {
2197 return Expr::DictComp(self.parse_dictionary_comprehension_expression(
2198 Some(value.expr),
2199 dict_value.expr,
2200 start,
2201 ));
2202 }
2203
2204 return Expr::Dict(self.parse_dictionary_expression(
2205 Some(value.expr),
2206 dict_value.expr,
2207 start,
2208 ));
2209 }
2210
2211 return Expr::Dict(self.parse_dictionary_expression(None, value.expr, start));
2212 }
2213
2214 let key_or_element = self.parse_named_expression_or_higher(
2218 ExpressionContext::starred_bitwise_or().with_for_excluded(),
2219 );
2220
2221 match self.current_token_kind() {
2222 TokenKind::Async | TokenKind::For => {
2223 if key_or_element.is_unparenthesized_starred_expr() {
2224 self.add_unsupported_syntax_error(
2225 UnsupportedSyntaxErrorKind::UnpackingInComprehension(
2226 ComprehensionUnpackingKind::IterableInSet,
2227 ),
2228 key_or_element.range(),
2229 );
2230 } else if key_or_element.is_unparenthesized_named_expr() {
2231 self.add_unsupported_syntax_error(
2245 UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
2246 UnparenthesizedNamedExprKind::SetComprehension,
2247 ),
2248 key_or_element.range(),
2249 );
2250 }
2251
2252 Expr::SetComp(self.parse_set_comprehension_expression(key_or_element.expr, start))
2253 }
2254 TokenKind::Colon => {
2255 if !key_or_element.is_parenthesized {
2258 match key_or_element.expr {
2259 Expr::Starred(_) => self.add_error(
2260 ParseErrorType::InvalidStarredExpressionUsage,
2261 &key_or_element.expr,
2262 ),
2263 Expr::Named(_) => self.add_error(
2264 ParseErrorType::UnparenthesizedNamedExpression,
2265 &key_or_element,
2266 ),
2267 _ => {}
2268 }
2269 }
2270
2271 self.bump(TokenKind::Colon);
2272 let value = if self.at(TokenKind::DoubleStar) {
2273 let unpack_start = self.node_start();
2274 self.bump(TokenKind::DoubleStar);
2275 let value = self.parse_expression_with_bitwise_or_precedence();
2276 self.add_error(
2277 ParseErrorType::InvalidStarredExpressionUsage,
2278 TextRange::new(unpack_start, value.range().end()),
2279 );
2280 value
2281 } else {
2282 self.parse_conditional_expression_or_higher()
2283 };
2284
2285 if matches!(self.current_token_kind(), TokenKind::Async | TokenKind::For) {
2286 Expr::DictComp(self.parse_dictionary_comprehension_expression(
2287 Some(key_or_element.expr),
2288 value.expr,
2289 start,
2290 ))
2291 } else {
2292 Expr::Dict(self.parse_dictionary_expression(
2293 Some(key_or_element.expr),
2294 value.expr,
2295 start,
2296 ))
2297 }
2298 }
2299 _ => Expr::Set(self.parse_set_expression(key_or_element, start)),
2300 }
2301 }
2302
2303 fn parse_parenthesized_expression(&mut self) -> ParsedExpr {
2309 let start = self.node_start();
2310 self.bump(TokenKind::Lpar);
2311
2312 if self.at_ts(NEWLINE_EOF_SET) {
2314 let range = self.current_token_range();
2315 self.add_error(
2316 ParseErrorType::OtherError("Missing closing parenthesis `)`".to_string()),
2317 range,
2318 );
2319 }
2320
2321 if self.eat(TokenKind::Rpar) {
2323 return Expr::Tuple(ast::ExprTuple {
2324 elts: vec![],
2325 ctx: ExprContext::Load,
2326 range: self.node_range(start),
2327 node_index: AtomicNodeIndex::NONE,
2328 parenthesized: true,
2329 runtime_elts: None,
2330 })
2331 .into();
2332 }
2333
2334 let mut parsed_expr = self.parse_named_expression_or_higher(
2337 ExpressionContext::yield_or_starred_bitwise_or().with_for_excluded(),
2338 );
2339
2340 match self.current_token_kind() {
2341 TokenKind::Comma => {
2342 let tuple =
2344 self.parse_tuple_expression(parsed_expr.expr, start, Parenthesized::Yes, |p| {
2345 p.parse_named_expression_or_higher(ExpressionContext::starred_bitwise_or())
2346 });
2347
2348 ParsedExpr {
2349 expr: tuple.into(),
2350 is_parenthesized: false,
2351 }
2352 }
2353 TokenKind::Async | TokenKind::For => {
2354 if parsed_expr.is_unparenthesized_starred_expr() {
2356 self.add_unsupported_syntax_error(
2357 UnsupportedSyntaxErrorKind::UnpackingInComprehension(
2358 ComprehensionUnpackingKind::IterableInGenerator,
2359 ),
2360 parsed_expr.range(),
2361 );
2362 }
2363
2364 let generator = Expr::Generator(self.parse_generator_expression(
2365 parsed_expr.expr,
2366 start,
2367 Parenthesized::Yes,
2368 ));
2369
2370 ParsedExpr {
2371 expr: generator,
2372 is_parenthesized: false,
2373 }
2374 }
2375 _ => {
2376 if parsed_expr.expr.is_starred_expr() {
2378 self.add_error(ParseErrorType::InvalidStarredExpressionUsage, &parsed_expr);
2379 }
2380
2381 self.expect(TokenKind::Rpar);
2382
2383 parsed_expr.is_parenthesized = true;
2384 parsed_expr
2385 }
2386 }
2387 }
2388
2389 pub(super) fn parse_tuple_expression(
2393 &mut self,
2394 first_element: Expr,
2395 start: TextSize,
2396 parenthesized: Parenthesized,
2397 mut parse_func: impl FnMut(&mut Parser<'src>) -> ParsedExpr,
2398 ) -> ast::ExprTuple {
2399 if !self.at_sequence_end() {
2403 self.expect(TokenKind::Comma);
2404 }
2405
2406 let elts_snapshot = self.expr_scratch.snapshot();
2407 self.expr_scratch.push(first_element);
2408
2409 self.parse_comma_separated_list(RecoveryContextKind::TupleElements(parenthesized), |p| {
2410 let element = parse_func(p).expr;
2411 p.expr_scratch.push(element);
2412 });
2413
2414 if parenthesized.is_yes() {
2415 self.expect(TokenKind::Rpar);
2416 }
2417
2418 ast::ExprTuple {
2419 elts: self.expr_scratch.take(elts_snapshot),
2420 ctx: ExprContext::Load,
2421 range: self.node_range(start),
2422 node_index: AtomicNodeIndex::NONE,
2423 parenthesized: parenthesized.is_yes(),
2424 runtime_elts: None,
2425 }
2426 }
2427
2428 fn parse_list_expression(&mut self, first_element: Expr, start: TextSize) -> ast::ExprList {
2432 if !self.at_sequence_end() {
2433 self.expect(TokenKind::Comma);
2434 }
2435
2436 let elts_snapshot = self.expr_scratch.snapshot();
2437 self.expr_scratch.push(first_element);
2438
2439 self.parse_comma_separated_list(RecoveryContextKind::ListElements, |parser| {
2440 let element = parser
2441 .parse_named_expression_or_higher(ExpressionContext::starred_bitwise_or())
2442 .expr;
2443 parser.expr_scratch.push(element);
2444 });
2445
2446 self.expect(TokenKind::Rsqb);
2447
2448 ast::ExprList {
2449 elts: self.expr_scratch.take(elts_snapshot),
2450 ctx: ExprContext::Load,
2451 range: self.node_range(start),
2452 node_index: AtomicNodeIndex::NONE,
2453 runtime_elts: None,
2454 }
2455 }
2456
2457 fn parse_set_expression(&mut self, first_element: ParsedExpr, start: TextSize) -> ast::ExprSet {
2461 if !self.at_sequence_end() {
2462 self.expect(TokenKind::Comma);
2463 }
2464
2465 if first_element.is_unparenthesized_named_expr() {
2472 self.add_unsupported_syntax_error(
2473 UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
2474 UnparenthesizedNamedExprKind::SetLiteral,
2475 ),
2476 first_element.range(),
2477 );
2478 }
2479
2480 let elts_snapshot = self.expr_scratch.snapshot();
2481 self.expr_scratch.push(first_element.expr);
2482
2483 self.parse_comma_separated_list(RecoveryContextKind::SetElements, |parser| {
2484 let parsed_expr =
2485 parser.parse_named_expression_or_higher(ExpressionContext::starred_bitwise_or());
2486
2487 if parsed_expr.is_unparenthesized_named_expr() {
2488 parser.add_unsupported_syntax_error(
2489 UnsupportedSyntaxErrorKind::UnparenthesizedNamedExpr(
2490 UnparenthesizedNamedExprKind::SetLiteral,
2491 ),
2492 parsed_expr.range(),
2493 );
2494 }
2495
2496 parser.expr_scratch.push(parsed_expr.expr);
2497 });
2498
2499 self.expect(TokenKind::Rbrace);
2500
2501 ast::ExprSet {
2502 range: self.node_range(start),
2503 node_index: AtomicNodeIndex::NONE,
2504 elts: self.expr_scratch.take(elts_snapshot),
2505 runtime_elts: None,
2506 }
2507 }
2508
2509 fn parse_dictionary_expression(
2513 &mut self,
2514 key: Option<Expr>,
2515 value: Expr,
2516 start: TextSize,
2517 ) -> ast::ExprDict {
2518 if !self.at_sequence_end() {
2519 self.expect(TokenKind::Comma);
2520 }
2521
2522 let mut items = vec![ast::DictItem { key, value }];
2523
2524 self.parse_comma_separated_list(RecoveryContextKind::DictElements, |parser| {
2525 if parser.eat(TokenKind::DoubleStar) {
2526 items.push(ast::DictItem {
2529 key: None,
2530 value: parser.parse_expression_with_bitwise_or_precedence().expr,
2531 });
2532 } else {
2533 let key = parser.parse_conditional_expression_or_higher().expr;
2534 parser.expect(TokenKind::Colon);
2535
2536 items.push(ast::DictItem {
2537 key: Some(key),
2538 value: parser.parse_conditional_expression_or_higher().expr,
2539 });
2540 }
2541 });
2542
2543 self.expect(TokenKind::Rbrace);
2544
2545 items.shrink_to_fit();
2546
2547 ast::ExprDict {
2548 range: self.node_range(start),
2549 node_index: AtomicNodeIndex::NONE,
2550 items,
2551 runtime_values: None,
2552 }
2553 }
2554
2555 fn parse_generators(&mut self) -> Vec<ast::Comprehension> {
2562 const GENERATOR_SET: TokenSet = TokenSet::new([TokenKind::For, TokenKind::Async]);
2563
2564 let mut generators = Vec::with_capacity(1);
2565 let mut progress = ParserProgress::default();
2566
2567 while self.at_ts(GENERATOR_SET) {
2568 progress.assert_progressing(self);
2569 generators.push(self.parse_comprehension());
2570 }
2571
2572 generators.shrink_to_fit();
2573
2574 generators
2575 }
2576
2577 fn parse_comprehension(&mut self) -> ast::Comprehension {
2585 let start = self.node_start();
2586
2587 let is_async = self.eat(TokenKind::Async);
2588
2589 if is_async {
2590 self.expect(TokenKind::For);
2594 } else {
2595 self.bump(TokenKind::For);
2596 }
2597
2598 let mut target =
2599 self.parse_expression_list(ExpressionContext::starred_conditional().with_in_excluded());
2600
2601 helpers::set_expr_ctx(&mut target.expr, ExprContext::Store);
2602 self.validate_assignment_target(&target.expr);
2603
2604 self.expect(TokenKind::In);
2605 let iter = self.parse_simple_expression(ExpressionContext::default());
2606
2607 let ifs_snapshot = self.expr_scratch.snapshot();
2608 let mut progress = ParserProgress::default();
2609
2610 while self.eat(TokenKind::If) {
2611 progress.assert_progressing(self);
2612
2613 let parsed_expr = self.parse_simple_expression(ExpressionContext::default());
2614
2615 self.expr_scratch.push(parsed_expr.expr);
2616 }
2617
2618 ast::Comprehension {
2619 range: self.node_range(start),
2620 node_index: AtomicNodeIndex::NONE,
2621 target: target.expr,
2622 iter: iter.expr,
2623 ifs: self.expr_scratch.take(ifs_snapshot),
2624 is_async,
2625 runtime_ifs: None,
2626 runtime_is_async: None,
2627 }
2628 }
2629
2630 fn parse_generator_expression(
2637 &mut self,
2638 element: Expr,
2639 start: TextSize,
2640 parenthesized: Parenthesized,
2641 ) -> ast::ExprGenerator {
2642 let generators = self.parse_generators();
2643
2644 if parenthesized.is_yes() {
2645 self.expect(TokenKind::Rpar);
2646 }
2647
2648 ast::ExprGenerator {
2649 elt: Box::new(element),
2650 generators,
2651 range: self.node_range(start),
2652 node_index: AtomicNodeIndex::NONE,
2653 parenthesized: parenthesized.is_yes(),
2654 }
2655 }
2656
2657 fn parse_list_comprehension_expression(
2661 &mut self,
2662 element: Expr,
2663 start: TextSize,
2664 ) -> ast::ExprListComp {
2665 let generators = self.parse_generators();
2666
2667 self.expect(TokenKind::Rsqb);
2668
2669 ast::ExprListComp {
2670 elt: Box::new(element),
2671 generators,
2672 range: self.node_range(start),
2673 node_index: AtomicNodeIndex::NONE,
2674 }
2675 }
2676
2677 fn parse_dictionary_comprehension_expression(
2681 &mut self,
2682 key: Option<Expr>,
2683 value: Expr,
2684 start: TextSize,
2685 ) -> ast::ExprDictComp {
2686 let generators = self.parse_generators();
2687
2688 self.expect(TokenKind::Rbrace);
2689
2690 ast::ExprDictComp {
2691 key: key.map(Box::new),
2692 value: Box::new(value),
2693 generators,
2694 range: self.node_range(start),
2695 node_index: AtomicNodeIndex::NONE,
2696 }
2697 }
2698
2699 fn parse_set_comprehension_expression(
2703 &mut self,
2704 element: Expr,
2705 start: TextSize,
2706 ) -> ast::ExprSetComp {
2707 let generators = self.parse_generators();
2708
2709 self.expect(TokenKind::Rbrace);
2710
2711 ast::ExprSetComp {
2712 elt: Box::new(element),
2713 generators,
2714 range: self.node_range(start),
2715 node_index: AtomicNodeIndex::NONE,
2716 }
2717 }
2718
2719 fn parse_starred_expression(&mut self, context: ExpressionContext) -> ast::ExprStarred {
2736 let start = self.node_start();
2737 self.bump(TokenKind::Star);
2738
2739 let parsed_expr = match context.starred_expression_precedence() {
2740 StarredExpressionPrecedence::Conditional => self
2741 .parse_conditional_expression_or_higher_impl(
2742 context.disallow_starred_expressions(),
2747 ),
2748 StarredExpressionPrecedence::BitwiseOr => {
2749 self.parse_expression_with_bitwise_or_precedence()
2750 }
2751 };
2752
2753 ast::ExprStarred {
2754 value: Box::new(parsed_expr.expr),
2755 ctx: ExprContext::Load,
2756 range: self.node_range(start),
2757 node_index: AtomicNodeIndex::NONE,
2758 }
2759 }
2760
2761 fn parse_await_expression(&mut self) -> ast::ExprAwait {
2769 let start = self.node_start();
2770 self.bump(TokenKind::Await);
2771
2772 let parsed_expr = self.parse_binary_expression_or_higher(
2773 OperatorPrecedence::Await,
2774 ExpressionContext::default(),
2775 );
2776
2777 ast::ExprAwait {
2778 value: Box::new(parsed_expr.expr),
2779 range: self.node_range(start),
2780 node_index: AtomicNodeIndex::NONE,
2781 }
2782 }
2783
2784 fn parse_yield_expression(&mut self) -> Expr {
2792 let start = self.node_start();
2793 self.bump(TokenKind::Yield);
2794
2795 if self.eat(TokenKind::From) {
2796 return self.parse_yield_from_expression(start);
2797 }
2798
2799 let value = self.at_expr().then(|| {
2800 let parsed_expr = self.parse_expression_list(ExpressionContext::starred_bitwise_or());
2801
2802 self.check_tuple_unpacking(
2819 &parsed_expr,
2820 UnsupportedSyntaxErrorKind::StarTuple(StarTupleKind::Yield),
2821 );
2822
2823 Box::new(parsed_expr.expr)
2824 });
2825
2826 Expr::Yield(ast::ExprYield {
2827 value,
2828 range: self.node_range(start),
2829 node_index: AtomicNodeIndex::NONE,
2830 })
2831 }
2832
2833 fn parse_yield_from_expression(&mut self, start: TextSize) -> Expr {
2840 let expr = self
2856 .parse_expression_list(ExpressionContext::default())
2857 .expr;
2858
2859 match &expr {
2860 Expr::Tuple(tuple) if !tuple.parenthesized => {
2861 self.add_error(ParseErrorType::UnparenthesizedTupleExpression, &expr);
2862 }
2863 _ => {}
2864 }
2865
2866 Expr::YieldFrom(ast::ExprYieldFrom {
2867 value: Box::new(expr),
2868 range: self.node_range(start),
2869 node_index: AtomicNodeIndex::NONE,
2870 })
2871 }
2872
2873 fn parse_named_expression(&mut self, mut target: Expr, start: TextSize) -> ast::ExprNamed {
2881 self.bump(TokenKind::ColonEqual);
2882
2883 if !target.is_name_expr() {
2884 self.add_error(ParseErrorType::InvalidNamedAssignmentTarget, target.range());
2885 }
2886 helpers::set_expr_ctx(&mut target, ExprContext::Store);
2887
2888 let value = self.parse_conditional_expression_or_higher();
2889
2890 let range = self.node_range(start);
2891
2892 self.add_unsupported_syntax_error(UnsupportedSyntaxErrorKind::Walrus, range);
2901
2902 ast::ExprNamed {
2903 target: Box::new(target),
2904 value: Box::new(value.expr),
2905 range,
2906 node_index: AtomicNodeIndex::NONE,
2907 }
2908 }
2909
2910 fn parse_lambda_expr(&mut self) -> ast::ExprLambda {
2918 let start = self.node_start();
2919 self.bump(TokenKind::Lambda);
2920
2921 let parameters = if self.at(TokenKind::Colon) {
2922 None
2925 } else {
2926 Some(Box::new(self.parse_parameters(FunctionKind::Lambda)))
2927 };
2928
2929 self.expect(TokenKind::Colon);
2930
2931 let body = self.with_recursion(Self::parse_conditional_expression_or_higher);
2951
2952 ast::ExprLambda {
2953 body: Box::new(body.expr),
2954 parameters,
2955 range: self.node_range(start),
2956 node_index: AtomicNodeIndex::NONE,
2957 }
2958 }
2959
2960 fn parse_if_expression(&mut self, body: Expr, start: TextSize) -> ast::ExprIf {
2968 self.bump(TokenKind::If);
2969
2970 let test = self.parse_simple_expression(ExpressionContext::default());
2971
2972 self.expect(TokenKind::Else);
2973
2974 let orelse = self.with_recursion(Self::parse_conditional_expression_or_higher);
2976
2977 ast::ExprIf {
2978 body: Box::new(body),
2979 test: Box::new(test.expr),
2980 orelse: Box::new(orelse.expr),
2981 range: self.node_range(start),
2982 node_index: AtomicNodeIndex::NONE,
2983 }
2984 }
2985
2986 fn parse_ipython_escape_command_expression(&mut self) -> ast::ExprIpyEscapeCommand {
2993 let start = self.node_start();
2994
2995 let (value, kind) = self.bump_ipython_escape_command(IpyEscapeContext::Assignment);
2996
2997 if !matches!(kind, IpyEscapeKind::Magic | IpyEscapeKind::Shell) {
2998 unreachable!("IPython escape command expression is only allowed for % and !");
3000 }
3001
3002 let command = ast::ExprIpyEscapeCommand {
3003 range: self.node_range(start),
3004 node_index: AtomicNodeIndex::NONE,
3005 kind,
3006 value,
3007 };
3008
3009 if self.options.mode != Mode::Ipython {
3010 self.add_error(ParseErrorType::UnexpectedIpythonEscapeCommand, &command);
3011 }
3012
3013 command
3014 }
3015
3016 fn validate_arguments(
3019 &mut self,
3020 arguments: &ast::Arguments,
3021 has_trailing_comma: bool,
3022 context: ArgumentsContext,
3023 ) {
3024 let generator_must_be_parenthesized = match context {
3025 ArgumentsContext::Call => has_trailing_comma || arguments.len() > 1,
3026 ArgumentsContext::ClassDefinition => true,
3029 };
3030
3031 if generator_must_be_parenthesized {
3032 for arg in &*arguments.args {
3033 if let Some(ast::ExprGenerator {
3034 range,
3035 parenthesized: false,
3036 ..
3037 }) = arg.as_generator_expr()
3038 {
3039 let error = match context {
3049 ArgumentsContext::Call => {
3050 ParseErrorType::UnparenthesizedGeneratorExpression
3051 }
3052 ArgumentsContext::ClassDefinition => {
3053 ParseErrorType::OtherError("invalid syntax".to_owned())
3054 }
3055 };
3056 self.add_error(error, range);
3057 }
3058 }
3059 }
3060 }
3061}
3062
3063#[derive(Debug, Copy, Clone)]
3072pub(super) enum ArgumentsContext {
3073 Call,
3074 ClassDefinition,
3075}
3076
3077#[derive(Debug)]
3078pub(super) struct ParsedExpr {
3079 pub(super) expr: Expr,
3080 pub(super) is_parenthesized: bool,
3081}
3082
3083impl ParsedExpr {
3084 #[inline]
3085 pub(super) const fn is_unparenthesized_starred_expr(&self) -> bool {
3086 !self.is_parenthesized && self.expr.is_starred_expr()
3087 }
3088
3089 #[inline]
3090 const fn is_unparenthesized_named_expr(&self) -> bool {
3091 !self.is_parenthesized && self.expr.is_named_expr()
3092 }
3093}
3094
3095impl From<Expr> for ParsedExpr {
3096 #[inline]
3097 fn from(expr: Expr) -> Self {
3098 ParsedExpr {
3099 expr,
3100 is_parenthesized: false,
3101 }
3102 }
3103}
3104
3105impl Deref for ParsedExpr {
3106 type Target = Expr;
3107
3108 fn deref(&self) -> &Self::Target {
3109 &self.expr
3110 }
3111}
3112
3113impl Ranged for ParsedExpr {
3114 #[inline]
3115 fn range(&self) -> TextRange {
3116 self.expr.range()
3117 }
3118}
3119
3120#[derive(Debug)]
3121enum BinaryLikeOperator {
3122 Boolean(BoolOp),
3123 Comparison(CmpOp),
3124 Binary(Operator),
3125}
3126
3127impl BinaryLikeOperator {
3128 fn try_from_tokens(current: TokenKind, next: Option<TokenKind>) -> Option<BinaryLikeOperator> {
3132 if let Some(bool_op) = current.as_bool_operator() {
3133 Some(BinaryLikeOperator::Boolean(bool_op))
3134 } else if let Some(bin_op) = current.as_binary_operator() {
3135 Some(BinaryLikeOperator::Binary(bin_op))
3136 } else {
3137 helpers::token_kind_to_cmp_op(current, next).map(BinaryLikeOperator::Comparison)
3138 }
3139 }
3140
3141 fn precedence(&self) -> OperatorPrecedence {
3144 match self {
3145 BinaryLikeOperator::Boolean(bool_op) => OperatorPrecedence::from(*bool_op),
3146 BinaryLikeOperator::Comparison(_) => OperatorPrecedence::ComparisonsMembershipIdentity,
3147 BinaryLikeOperator::Binary(bin_op) => OperatorPrecedence::from(*bin_op),
3148 }
3149 }
3150}
3151
3152#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3154pub(super) enum StarredExpressionPrecedence {
3155 BitwiseOr,
3158
3159 Conditional,
3162}
3163
3164#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
3166pub(super) struct ExpressionContext(ExpressionContextFlags);
3167
3168bitflags! {
3169 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
3170 struct ExpressionContextFlags: u8 {
3171 const EXCLUDE_IN = 1 << 0;
3174
3175 const ALLOW_STARRED_EXPRESSION = 1 << 1;
3179
3180 const STARRED_BITWISE_OR_PRECEDENCE = 1 << 2;
3183
3184 const ALLOW_YIELD_EXPRESSION = 1 << 3;
3188
3189 const EXCLUDE_FOR = 1 << 4;
3192 }
3193}
3194
3195impl ExpressionContext {
3196 pub(super) fn starred_conditional() -> Self {
3198 ExpressionContext::default()
3199 .with_starred_expression_allowed(StarredExpressionPrecedence::Conditional)
3200 }
3201
3202 pub(super) fn starred_bitwise_or() -> Self {
3204 ExpressionContext::default()
3205 .with_starred_expression_allowed(StarredExpressionPrecedence::BitwiseOr)
3206 }
3207
3208 pub(super) fn yield_or_starred_bitwise_or() -> Self {
3211 ExpressionContext::starred_bitwise_or().with_yield_expression_allowed()
3212 }
3213
3214 fn disallow_starred_expressions(self) -> Self {
3215 let flags = self.0 & !ExpressionContextFlags::ALLOW_STARRED_EXPRESSION;
3216 ExpressionContext(flags)
3217 }
3218
3219 fn disallow_yield_expressions(self) -> Self {
3220 ExpressionContext(self.0 & !ExpressionContextFlags::ALLOW_YIELD_EXPRESSION)
3221 }
3222
3223 fn with_starred_expression_allowed(self, precedence: StarredExpressionPrecedence) -> Self {
3226 let mut flags = self.0 | ExpressionContextFlags::ALLOW_STARRED_EXPRESSION;
3227 match precedence {
3228 StarredExpressionPrecedence::BitwiseOr => {
3229 flags |= ExpressionContextFlags::STARRED_BITWISE_OR_PRECEDENCE;
3230 }
3231 StarredExpressionPrecedence::Conditional => {
3232 flags -= ExpressionContextFlags::STARRED_BITWISE_OR_PRECEDENCE;
3233 }
3234 }
3235 ExpressionContext(flags)
3236 }
3237
3238 fn with_yield_expression_allowed(self) -> Self {
3240 ExpressionContext(self.0 | ExpressionContextFlags::ALLOW_YIELD_EXPRESSION)
3241 }
3242
3243 pub(super) fn with_in_excluded(self) -> Self {
3245 ExpressionContext(self.0 | ExpressionContextFlags::EXCLUDE_IN)
3246 }
3247
3248 fn with_for_excluded(self) -> Self {
3250 ExpressionContext(self.0 | ExpressionContextFlags::EXCLUDE_FOR)
3251 }
3252
3253 const fn is_in_excluded(self) -> bool {
3255 self.0.contains(ExpressionContextFlags::EXCLUDE_IN)
3256 }
3257
3258 const fn is_starred_expression_allowed(self) -> bool {
3260 self.0
3261 .contains(ExpressionContextFlags::ALLOW_STARRED_EXPRESSION)
3262 }
3263
3264 const fn is_yield_expression_allowed(self) -> bool {
3266 self.0
3267 .contains(ExpressionContextFlags::ALLOW_YIELD_EXPRESSION)
3268 }
3269
3270 const fn is_for_excluded(self) -> bool {
3272 self.0.contains(ExpressionContextFlags::EXCLUDE_FOR)
3273 }
3274
3275 const fn starred_expression_precedence(self) -> StarredExpressionPrecedence {
3278 if self
3279 .0
3280 .contains(ExpressionContextFlags::STARRED_BITWISE_OR_PRECEDENCE)
3281 {
3282 StarredExpressionPrecedence::BitwiseOr
3283 } else {
3284 StarredExpressionPrecedence::Conditional
3285 }
3286 }
3287}
3288
3289#[derive(Debug)]
3290struct InterpolatedStringData {
3291 elements: InterpolatedStringElements,
3292 range: TextRange,
3293 flags: AnyStringFlags,
3294}
3295
3296impl From<InterpolatedStringData> for FString {
3297 fn from(value: InterpolatedStringData) -> Self {
3298 Self {
3299 elements: value.elements,
3300 range: value.range,
3301 flags: value.flags.into(),
3302 node_index: AtomicNodeIndex::NONE,
3303 }
3304 }
3305}
3306
3307impl From<InterpolatedStringData> for TString {
3308 fn from(value: InterpolatedStringData) -> Self {
3309 Self {
3310 elements: value.elements,
3311 range: value.range,
3312 flags: value.flags.into(),
3313 node_index: AtomicNodeIndex::NONE,
3314 }
3315 }
3316}