@@ -360,16 +360,21 @@ CompoundStatement: ast::Stmt = {
360360};
361361
362362IfStatement: ast::Stmt = {
363- <location:@L> "if" <test:NamedExpressionTest> ":" <body:Suite> <s2:(@L "elif" NamedExpressionTest ":" Suite @R )*> <s3:("else" ":" Suite)?> <end_location:@R > => {
363+ <location:@L> "if" <test:NamedExpressionTest> ":" <body:Suite> <s2:(@L "elif" NamedExpressionTest ":" Suite)*> <s3:("else" ":" Suite)?> => {
364364 // Determine last else:
365365 let mut last = s3.map(|s| s.2).unwrap_or_default();
366-
366+ let end_location = last
367+ .last()
368+ .or_else(|| s2.last().and_then(|last| last.4.last()))
369+ .or_else(|| body.last())
370+ .unwrap()
371+ .end_location;
367372 // handle elif:
368373 for i in s2.into_iter().rev() {
369374 let x = ast::Stmt {
370375 custom: (),
371376 location: i.0,
372- end_location: Some(i.5) ,
377+ end_location: i.4.last().unwrap().end_location ,
373378 node: ast::StmtKind::If { test: Box::new(i.2), body: i.4, orelse: last },
374379 };
375380 last = vec![x];
@@ -378,19 +383,24 @@ IfStatement: ast::Stmt = {
378383 ast::Stmt {
379384 custom: (),
380385 location,
381- end_location: Some(end_location) ,
386+ end_location,
382387 node: ast::StmtKind::If { test: Box::new(test), body, orelse: last }
383388 }
384389 },
385390};
386391
387392WhileStatement: ast::Stmt = {
388- <location:@L> "while" <test:NamedExpressionTest> ":" <body:Suite> <s2:("else" ":" Suite)?> <end_location:@R> => {
393+ <location:@L> "while" <test:NamedExpressionTest> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
389394 let orelse = s2.map(|s| s.2).unwrap_or_default();
395+ let end_location = orelse
396+ .last()
397+ .or_else(|| body.last())
398+ .unwrap()
399+ .end_location;
390400 ast::Stmt {
391401 custom: (),
392402 location,
393- end_location: Some(end_location) ,
403+ end_location,
394404 node: ast::StmtKind::While {
395405 test: Box::new(test),
396406 body,
@@ -401,8 +411,14 @@ WhileStatement: ast::Stmt = {
401411};
402412
403413ForStatement: ast::Stmt = {
404- <location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:TestList> ":" <body:Suite> <s2:("else" ":" Suite)?> <end_location:@R> => {
414+ <location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:TestList> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
405415 let orelse = s2.map(|s| s.2).unwrap_or_default();
416+ let end_location = orelse
417+ .last()
418+ .or_else(|| body.last())
419+ .unwrap()
420+ .end_location
421+ .unwrap();
406422 let target = Box::new(set_context(target, ast::ExprContext::Store));
407423 let iter = Box::new(iter);
408424 let type_comment = None;
@@ -419,10 +435,16 @@ TryStatement: ast::Stmt = {
419435 <location:@L> "try" ":" <body:Suite> <handlers:ExceptClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> <end_location:@R> => {
420436 let orelse = else_suite.map(|s| s.2).unwrap_or_default();
421437 let finalbody = finally.map(|s| s.2).unwrap_or_default();
438+ let end_location = finalbody
439+ .last()
440+ .map(|last| last.end_location)
441+ .or_else(|| orelse.last().map(|last| last.end_location))
442+ .or_else(|| handlers.last().map(|last| last.end_location))
443+ .unwrap();
422444 ast::Stmt {
423445 custom: (),
424446 location,
425- end_location: Some(end_location) ,
447+ end_location,
426448 node: ast::StmtKind::Try {
427449 body,
428450 handlers,
@@ -431,14 +453,15 @@ TryStatement: ast::Stmt = {
431453 },
432454 }
433455 },
434- <location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> <end_location:@R> => {
456+ <location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> => {
435457 let handlers = vec![];
436458 let orelse = vec![];
437459 let finalbody = finally.2;
460+ let end_location = finalbody.last().unwrap().end_location;
438461 ast::Stmt {
439462 custom: (),
440463 location,
441- end_location: Some(end_location) ,
464+ end_location,
442465 node: ast::StmtKind::Try {
443466 body,
444467 handlers,
@@ -450,7 +473,8 @@ TryStatement: ast::Stmt = {
450473};
451474
452475ExceptClause: ast::Excepthandler = {
453- <location:@L> "except" <typ:Test?> ":" <body:Suite> <end_location:@R> => {
476+ <location:@L> "except" <typ:Test?> ":" <body:Suite> => {
477+ let end_location = body.last().unwrap().end_location.unwrap();
454478 ast::Excepthandler::new(
455479 location,
456480 end_location,
@@ -461,7 +485,8 @@ ExceptClause: ast::Excepthandler = {
461485 },
462486 )
463487 },
464- <location:@L> "except" <x:(Test "as" Identifier)> ":" <body:Suite> <end_location:@R> => {
488+ <location:@L> "except" <x:(Test "as" Identifier)> ":" <body:Suite> => {
489+ let end_location = body.last().unwrap().end_location.unwrap();
465490 ast::Excepthandler::new(
466491 location,
467492 end_location,
@@ -475,7 +500,8 @@ ExceptClause: ast::Excepthandler = {
475500};
476501
477502WithStatement: ast::Stmt = {
478- <location:@L> <is_async:"async"?> "with" <items:WithItems> ":" <body:Suite> <end_location:@R> => {
503+ <location:@L> <is_async:"async"?> "with" <items:WithItems> ":" <body:Suite> => {
504+ let end_location = body.last().unwrap().end_location.unwrap();
479505 let type_comment = None;
480506 let node = if is_async.is_some() {
481507 ast::StmtKind::AsyncWith { items, body, type_comment }
@@ -514,9 +540,10 @@ WithItem: ast::Withitem = {
514540};
515541
516542FuncDef: ast::Stmt = {
517- <decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <body:Suite> <end_location:@R> => {
543+ <decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <body:Suite> => {
518544 let args = Box::new(args);
519545 let returns = r.map(|x| Box::new(x.1));
546+ let end_location = body.last().unwrap().end_location.unwrap();
520547 let type_comment = None;
521548 let node = if is_async.is_some() {
522549 ast::StmtKind::AsyncFunctionDef { name, args, body, decorator_list, returns, type_comment }
@@ -668,15 +695,16 @@ KwargParameter<ArgType>: Option<Box<ast::Arg>> = {
668695};
669696
670697ClassDef: ast::Stmt = {
671- <decorator_list:Decorator*> <location:@L> "class" <name:Identifier> <a:("(" ArgumentList ")")?> ":" <body:Suite> <end_location:@R> => {
698+ <decorator_list:Decorator*> <location:@L> "class" <name:Identifier> <a:("(" ArgumentList ")")?> ":" <body:Suite> => {
672699 let (bases, keywords) = match a {
673700 Some((_, arg, _)) => (arg.args, arg.keywords),
674701 None => (vec![], vec![]),
675702 };
703+ let end_location = body.last().unwrap().end_location;
676704 ast::Stmt {
677705 custom: (),
678706 location,
679- end_location: Some(end_location) ,
707+ end_location,
680708 node: ast::StmtKind::ClassDef {
681709 name,
682710 bases,
0 commit comments