11use compact_str:: CompactString ;
22use core:: fmt;
3+ use ruff_python_ast:: whitespace:: indentation;
34use ruff_python_parser:: { TokenKind , Tokens } ;
4- use ruff_source_file:: LineRanges ;
55use std:: { error:: Error , fmt:: Formatter } ;
66use thiserror:: Error ;
77
8- use ruff_python_trivia:: { Cursor , is_python_whitespace } ;
8+ use ruff_python_trivia:: Cursor ;
99use ruff_text_size:: { Ranged , TextLen , TextRange , TextSize , TextSlice } ;
1010use smallvec:: { SmallVec , smallvec} ;
1111
@@ -138,34 +138,25 @@ impl<'a> SuppressionsBuilder<'a> {
138138 }
139139
140140 pub ( crate ) fn load_from_tokens ( mut self , tokens : & Tokens ) -> Suppressions {
141- let default_indent = String :: new ( ) ;
142- let mut current_indent: & String = & default_indent;
143- let mut indents: Vec < String > = vec ! [ ] ;
141+ let default_indent = "" ;
142+ let mut indents: Vec < & str > = vec ! [ ] ;
144143
145144 // Iterate through tokens, tracking indentation, filtering trailing comments, and then
146145 // looking for matching comments from the previous block when reaching a dedent token.
147146 for ( token_index, token) in tokens. iter ( ) . enumerate ( ) {
148147 match token. kind ( ) {
149148 TokenKind :: Indent => {
150- indents. push ( self . source . slice ( token) . to_string ( ) ) ;
151- current_indent = indents. last ( ) . unwrap_or ( & default_indent) ;
149+ indents. push ( self . source . slice ( token) ) ;
152150 }
153151 TokenKind :: Dedent => {
154- self . match_comments ( current_indent) ;
155-
152+ self . match_comments ( indents. last ( ) . copied ( ) . unwrap_or_default ( ) ) ;
156153 indents. pop ( ) ;
157- current_indent = indents. last ( ) . unwrap_or ( & default_indent) ;
158154 }
159155 TokenKind :: Comment => {
160156 let mut parser = SuppressionParser :: new ( self . source , token. range ( ) ) ;
161157 match parser. parse_comment ( ) {
162158 Ok ( comment) => {
163- let text_before = self . source . slice ( TextRange :: new (
164- self . source . line_start ( comment. range . start ( ) ) ,
165- comment. range . start ( ) ,
166- ) ) ;
167- let is_own_line = text_before. chars ( ) . all ( is_python_whitespace) ;
168- let indent = is_own_line. then_some ( text_before) ;
159+ let indent = indentation ( self . source , & comment. range ) ;
169160
170161 let Some ( indent) = indent else {
171162 // trailing suppressions are not supported
@@ -177,7 +168,7 @@ impl<'a> SuppressionsBuilder<'a> {
177168 } ;
178169
179170 // comment matches current block's indentation, or precedes an indent/dedent token
180- if indent == current_indent
171+ if indent == indents . last ( ) . copied ( ) . unwrap_or_default ( )
181172 || tokens[ token_index..]
182173 . iter ( )
183174 . find ( |t| !t. kind ( ) . is_trivia ( ) )
@@ -209,7 +200,7 @@ impl<'a> SuppressionsBuilder<'a> {
209200 }
210201 }
211202
212- self . match_comments ( & default_indent) ;
203+ self . match_comments ( default_indent) ;
213204
214205 Suppressions {
215206 valid : self . valid ,
@@ -218,7 +209,7 @@ impl<'a> SuppressionsBuilder<'a> {
218209 }
219210 }
220211
221- fn match_comments ( & mut self , current_indent : & String ) {
212+ fn match_comments ( & mut self , current_indent : & str ) {
222213 let mut comment_index = 0 ;
223214
224215 // for each pending comment, search for matching comments at the same indentation level,
0 commit comments