Use correct start location for class/function clause header (#7802)

## Summary

This PR fixes the bug where the formatter would panic if a class/function with
decorators had a suppression comment.

The fix is to use to correct start location to find the `async`/`def`/`class`
keyword when decorators are present which is the end of the last
decorator.

## Test Plan

Add test cases for the fix and update the snapshots.
This commit is contained in:
Dhruv Manilawala 2023-10-04 13:25:01 +05:30 committed by GitHub
parent 7b4fb4fb5d
commit a1509dfc7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 2 deletions

View file

@ -203,15 +203,23 @@ impl<'a> ClauseHeader<'a> {
fn first_keyword_range(self, source: &str) -> FormatResult<TextRange> {
match self {
ClauseHeader::Class(header) => {
find_keyword(header.start(), SimpleTokenKind::Class, source)
let start_position = header
.decorator_list
.last()
.map_or_else(|| header.start(), Ranged::end);
find_keyword(start_position, SimpleTokenKind::Class, source)
}
ClauseHeader::Function(header) => {
let start_position = header
.decorator_list
.last()
.map_or_else(|| header.start(), Ranged::end);
let keyword = if header.is_async {
SimpleTokenKind::Async
} else {
SimpleTokenKind::Def
};
find_keyword(header.start(), keyword, source)
find_keyword(start_position, keyword, source)
}
ClauseHeader::If(header) => find_keyword(header.start(), SimpleTokenKind::If, source),
ClauseHeader::ElifElse(ElifElseClause {