src/black/ranges.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | """Functions related to Black's formatting by line ranges feature."""
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import difflib
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from dataclasses import dataclass
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from typing import Collection, Iterator, List, Sequence, Set, Tuple, Union
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from black.nodes import (
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | LN,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | STANDALONE_COMMENT,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Leaf,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Node,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Visitor,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | first_leaf,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | furthest_ancestor_with_last_leaf,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | last_leaf,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | syms,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | )
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from blib2to3.pgen2.token import ASYNC, NEWLINE
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def parse_line_ranges(line_ranges: Sequence[str]) -> List[Tuple[int, int]]:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines: List[Tuple[int, int]] = []
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | for lines_str in line_ranges:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | parts = lines_str.split("-")
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if len(parts) != 2:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | raise ValueError(
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | "Incorrect --line-ranges format, expect 'START-END', found"
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | f" {lines_str!r}"
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | )
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | start = int(parts[0])
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | end = int(parts[1])
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except ValueError:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | raise ValueError(
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | "Incorrect --line-ranges value, expect integer ranges, found"
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | f" {lines_str!r}"
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) from None
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | else:
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines.append((start, end))
0020 0015 0020 0000 0000 0000 0000 -- 05 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return lines
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0003 0003 0002 0000 0000 0000 0001 -- 02 003 005 003 005 008 008 0024.00 0036.00 0001.50 | def is_valid_line_range(lines: Tuple[int, int]) -> bool:
0003 0003 0002 0000 0000 0000 0001 -- 02 003 005 003 005 008 008 0024.00 0036.00 0001.50 | """Returns whether the line range is valid."""
0003 0003 0002 0000 0000 0000 0001 -- 02 003 005 003 005 008 008 0024.00 0036.00 0001.50 | return not lines or lines[0] <= lines[1]
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | def adjusted_lines(
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines: Collection[Tuple[int, int]],
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | original_source: str,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | modified_source: str,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | ) -> List[Tuple[int, int]]:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | """Returns the adjusted line ranges based on edits from the original code.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | This computes the new line ranges by diffing original_source and
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | modified_source, and adjust each range based on how the range overlaps with
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | the diffs.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | Note the diff can contain lines outside of the original line ranges. This can
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | happen when the formatting has to be done in adjacent to maintain consistent
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | local results. For example:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 1. def my_func(arg1, arg2,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 2. arg3,):
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 3. pass
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | If it restricts to line 2-2, it can't simply reformat line 2, it also has
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | to reformat line 1:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 1. def my_func(
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 2. arg1,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 3. arg2,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 4. arg3,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 5. ):
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | 6. pass
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | In this case, we will expand the line ranges to also include the whole diff
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | block.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | Args:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines: a collection of line ranges.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | original_source: the original source.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | modified_source: the modified source.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | """
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines_mappings = _calculate_lines_mappings(original_source, modified_source)
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 |
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_lines = []
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | # Keep an index of the current search. Since the lines and lines_mappings are
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | # sorted, this makes the search complexity linear.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | current_mapping_index = 0
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | for start, end in sorted(lines):
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | start_mapping_index = _find_lines_mapping_index(
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | start,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines_mappings,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | current_mapping_index,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | )
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | end_mapping_index = _find_lines_mapping_index(
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | end,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines_mappings,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | start_mapping_index,
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | )
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | current_mapping_index = start_mapping_index
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | if start_mapping_index >= len(lines_mappings) or end_mapping_index >= len(
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | lines_mappings
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | ):
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | # Protect against invalid inputs.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | continue
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | start_mapping = lines_mappings[start_mapping_index]
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | end_mapping = lines_mappings[end_mapping_index]
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | if start_mapping.is_changed_block:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | # When the line falls into a changed block, expands to the whole block.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_start = start_mapping.modified_start
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | else:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_start = (
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | start - start_mapping.original_start + start_mapping.modified_start
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | )
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | if end_mapping.is_changed_block:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | # When the line falls into a changed block, expands to the whole block.
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_end = end_mapping.modified_end
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | else:
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_end = end - end_mapping.original_start + end_mapping.modified_start
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_range = (new_start, new_end)
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | if is_valid_line_range(new_range):
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | new_lines.append(new_range)
0078 0025 0040 0005 0025 0008 0005 -- 07 004 012 007 014 016 021 0084.00 0196.00 0002.33 | return new_lines
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def convert_unchanged_lines(src_node: Node, lines: Collection[Tuple[int, int]]) -> None:
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Converts unchanged lines to STANDALONE_COMMENT.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | The idea is similar to how `# fmt: on/off` is implemented. It also converts the
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | nodes between those markers as a single `STANDALONE_COMMENT` leaf node with
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | the unformatted code as its value. `STANDALONE_COMMENT` is a "fake" token
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | that will be formatted as-is with its prefix normalized.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | Here we perform two passes:
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | 1. Visit the top-level statements, and convert them to a single
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | `STANDALONE_COMMENT` when unchanged. This speeds up formatting when some
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | of the top-level statements aren't changed.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | 2. Convert unchanged "unwrapped lines" to `STANDALONE_COMMENT` nodes line by
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | line. "unwrapped lines" are divided by the `NEWLINE` token. e.g. a
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | multi-line statement is *one* "unwrapped line" that ends with `NEWLINE`,
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | even though this statement itself can span multiple lines, and the
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | tokenizer only sees the last '\n' as the `NEWLINE` token.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | NOTE: During pass (2), comment prefixes and indentations are ALWAYS
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | normalized even when the lines aren't changed. This is fixable by moving
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | more formatting to pass (1). However, it's hard to get it correct when
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | incorrect indentations are used. So we defer this to future optimizations.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines_set: Set[int] = set()
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | for start, end in lines:
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines_set.update(range(start, end + 1))
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | visitor = _TopLevelStatementsVisitor(lines_set)
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | _ = list(visitor.visit(src_node)) # Consume all results.
0030 0009 0007 0001 0019 0004 0000 -- 02 001 002 001 002 003 003 0004.75 0002.38 0000.50 | _convert_unchanged_line_by_line(src_node, lines_set)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def _contains_standalone_comment(node: LN) -> bool:
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if isinstance(node, Leaf):
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return node.type == STANDALONE_COMMENT
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | else:
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | for child in node.children:
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if _contains_standalone_comment(child):
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return True
0008 0008 0008 0000 0000 0000 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return False
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | class _TopLevelStatementsVisitor(Visitor[None]):
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | """
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | A node visitor that converts unchanged top-level statements to
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | STANDALONE_COMMENT.
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | This is used in addition to _convert_unchanged_line_by_line, to
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | speed up formatting when there are unchanged top-level
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | classes/functions/statements.
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- | """
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- |
0002 0002 0002 0000 0000 0000 0000 05 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def __init__(self, lines_set: Set[int]):
0002 0002 0002 0000 0000 0000 0000 05 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self._lines_set = lines_set
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- |
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | def visit_simple_stmt(self, node: Node) -> Iterator[None]:
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | # This is only called for top-level statements, since `visit_suite`
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | # won't visit its children nodes.
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | yield from []
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | newline_leaf = last_leaf(node)
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | if not newline_leaf:
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | return
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | assert (
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | newline_leaf.type == NEWLINE
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | ), f"Unexpectedly found leaf.type={newline_leaf.type}"
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | # We need to find the furthest ancestor with the NEWLINE as the last
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | # leaf, since a `suite` can simply be a `simple_stmt` when it puts
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | # its body on the same line. Example: `if cond: pass`.
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | ancestor = furthest_ancestor_with_last_leaf(newline_leaf)
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | if not _get_line_range(ancestor).intersection(self._lines_set):
0016 0009 0011 0005 0000 0000 0005 05 03 002 004 003 004 006 007 0018.09 0018.09 0001.00 | _convert_node_to_standalone_comment(ancestor)
---- ---- ---- ---- ---- ---- ---- 05 -- --- --- --- --- --- --- ------- ------- ------- |
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | def visit_suite(self, node: Node) -> Iterator[None]:
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | yield from []
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # If there is a STANDALONE_COMMENT node, it means parts of the node tree
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # have fmt on/off/skip markers. Those STANDALONE_COMMENT nodes can't
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # be simply converted by calling str(node). So we just don't convert
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # here.
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | if _contains_standalone_comment(node):
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | return
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # Find the semantic parent of this suite. For `async_stmt` and
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # `async_funcdef`, the ASYNC token is defined on a separate level by the
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | # grammar.
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | semantic_parent = node.parent
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | if semantic_parent is not None:
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | if (
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | semantic_parent.prev_sibling is not None
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | and semantic_parent.prev_sibling.type == ASYNC
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | ):
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | semantic_parent = semantic_parent.parent
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | if semantic_parent is not None and not _get_line_range(
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | semantic_parent
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | ).intersection(self._lines_set):
0022 0010 0015 0007 0000 0000 0007 05 07 004 010 007 013 014 020 0076.15 0197.98 0002.60 | _convert_node_to_standalone_comment(semantic_parent)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | def _convert_unchanged_line_by_line(node: Node, lines_set: Set[int]) -> None:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | """Converts unchanged to STANDALONE_COMMENT line by line."""
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | for leaf in node.leaves():
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if leaf.type != NEWLINE:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # We only consider "unwrapped lines", which are divided by the NEWLINE
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # token.
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | continue
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if leaf.parent and leaf.parent.type == syms.match_stmt:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # The `suite` node is defined as:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # match_stmt: "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # Here we need to check `subject_expr`. The `case_block+` will be
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # checked by their own NEWLINEs.
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | nodes_to_ignore: List[LN] = []
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | prev_sibling = leaf.prev_sibling
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | while prev_sibling:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | nodes_to_ignore.insert(0, prev_sibling)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | prev_sibling = prev_sibling.prev_sibling
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if not _get_line_range(nodes_to_ignore).intersection(lines_set):
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | _convert_nodes_to_standalone_comment(nodes_to_ignore, newline=leaf)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | elif leaf.parent and leaf.parent.type == syms.suite:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # The `suite` node is defined as:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # We will check `simple_stmt` and `stmt+` separately against the lines set
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | parent_sibling = leaf.parent.prev_sibling
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | nodes_to_ignore = []
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | while parent_sibling and not parent_sibling.type == syms.suite:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # NOTE: Multiple suite nodes can exist as siblings in e.g. `if_stmt`.
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | nodes_to_ignore.insert(0, parent_sibling)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | parent_sibling = parent_sibling.prev_sibling
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # Special case for `async_stmt` and `async_funcdef` where the ASYNC
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # token is on the grandparent node.
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | grandparent = leaf.parent.parent
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if (
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | grandparent is not None
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | and grandparent.prev_sibling is not None
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | and grandparent.prev_sibling.type == ASYNC
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | ):
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | nodes_to_ignore.insert(0, grandparent.prev_sibling)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if not _get_line_range(nodes_to_ignore).intersection(lines_set):
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | _convert_nodes_to_standalone_comment(nodes_to_ignore, newline=leaf)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | else:
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | ancestor = furthest_ancestor_with_last_leaf(leaf)
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # Consider multiple decorators as a whole block, as their
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | # newlines have different behaviors than the rest of the grammar.
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if (
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | ancestor.type == syms.decorator
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | and ancestor.parent
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | and ancestor.parent.type == syms.decorators
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | ):
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | ancestor = ancestor.parent
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | if not _get_line_range(ancestor).intersection(lines_set):
0052 0031 0037 0014 0000 0000 0015 -- 19 005 024 018 034 029 052 0252.62 0894.68 0003.54 | _convert_node_to_standalone_comment(ancestor)
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | def _convert_node_to_standalone_comment(node: LN) -> None:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | """Convert node to STANDALONE_COMMENT by modifying the tree inline."""
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | parent = node.parent
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | if not parent:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | return
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | first = first_leaf(node)
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | last = last_leaf(node)
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | if not first or not last:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | return
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | if first is last:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # This can happen on the following edge cases:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # 1. A block of `# fmt: off/on` code except the `# fmt: on` is placed
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # on the end of the last line instead of on a new line.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # 2. A single backslash on its own line followed by a comment line.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # Ideally we don't want to format them when not requested, but fixing
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # isn't easy. These cases are also badly formatted code, so it isn't
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # too bad we reformat them.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | return
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # The prefix contains comments and indentation whitespaces. They are
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # reformatted accordingly to the correct indentation level.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # This also means the indentation will be changed on the unchanged lines, and
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # this is actually required to not break incremental reformatting.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | prefix = first.prefix
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | first.prefix = ""
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | index = node.remove()
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | if index is not None:
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # Remove the '\n', as STANDALONE_COMMENT will have '\n' appended when
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | # generating the formatted code.
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | value = str(node)[:-1]
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | parent.insert_child(
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | index,
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | Leaf(
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | STANDALONE_COMMENT,
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | value,
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | prefix=prefix,
0038 0018 0024 0013 0000 0000 0014 -- 06 005 008 007 010 013 017 0062.91 0196.59 0003.12 | fmt_pass_converted_first_leaf=first,
0038 0018 0024 0013 0000 0000 0014 -- -- 005 008 007 010 013 017 0062.91 0196.59 0003.12 | ),
0038 0018 0024 0013 0000 0000 0014 -- -- 005 008 007 010 013 017 0062.91 0196.59 0003.12 | )
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | def _convert_nodes_to_standalone_comment(nodes: Sequence[LN], *, newline: Leaf) -> None:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | """Convert nodes to STANDALONE_COMMENT by modifying the tree inline."""
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | if not nodes:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | return
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | parent = nodes[0].parent
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | first = first_leaf(nodes[0])
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | if not parent or not first:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | return
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | prefix = first.prefix
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | first.prefix = ""
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | value = "".join(str(node) for node in nodes)
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | # The prefix comment on the NEWLINE leaf is the trailing comment of the statement.
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | if newline.prefix:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | value += newline.prefix
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | newline.prefix = ""
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | index = nodes[0].remove()
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | for node in nodes[1:]:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | node.remove()
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | if index is not None:
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | parent.insert_child(
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | index,
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | Leaf(
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | STANDALONE_COMMENT,
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | value,
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | prefix=prefix,
0028 0019 0026 0001 0000 0000 0002 -- 08 004 009 006 009 013 015 0055.51 0111.01 0002.00 | fmt_pass_converted_first_leaf=first,
0028 0019 0026 0001 0000 0000 0002 -- -- 004 009 006 009 013 015 0055.51 0111.01 0002.00 | ),
0028 0019 0026 0001 0000 0000 0002 -- -- 004 009 006 009 013 015 0055.51 0111.01 0002.00 | )
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | def _leaf_line_end(leaf: Leaf) -> int:
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | """Returns the line number of the leaf node's last line."""
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if leaf.type == NEWLINE:
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | return leaf.lineno
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | else:
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | # Leaf nodes like multiline strings can occupy multiple lines.
0007 0006 0005 0001 0000 0000 0002 -- 02 002 004 002 004 006 006 0015.51 0015.51 0001.00 | return leaf.lineno + str(leaf).count("\n")
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | def _get_line_range(node_or_nodes: Union[LN, List[LN]]) -> Set[int]:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | """Returns the line range of this node or list of nodes."""
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | if isinstance(node_or_nodes, list):
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | nodes = node_or_nodes
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | if not nodes:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set()
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | first = first_leaf(nodes[0])
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | last = last_leaf(nodes[-1])
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | if first and last:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | line_start = first.lineno
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | line_end = _leaf_line_end(last)
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set(range(line_start, line_end + 1))
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | else:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set()
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | else:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | node = node_or_nodes
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | if isinstance(node, Leaf):
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set(range(node.lineno, _leaf_line_end(node) + 1))
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | else:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | first = first_leaf(node)
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | last = last_leaf(node)
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | if first and last:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set(range(first.lineno, _leaf_line_end(last) + 1))
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | else:
0025 0025 0024 0000 0000 0000 0001 -- 08 004 007 007 012 011 019 0065.73 0225.36 0003.43 | return set()
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @dataclass
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | class _LinesMapping:
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | """1-based lines mapping from original source to modified source.
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | Lines [original_start, original_end] from original source
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | are mapped to [modified_start, modified_end].
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | The ranges are inclusive on both ends.
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | """
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | original_start: int
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | original_end: int
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | modified_start: int
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | modified_end: int
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | # Whether this range corresponds to a changed block, or an unchanged block.
---- ---- ---- ---- ---- ---- ---- 01 -- --- --- --- --- --- --- ------- ------- ------- | is_changed_block: bool
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | def _calculate_lines_mappings(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_source: str,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_source: str,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | ) -> Sequence[_LinesMapping]:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | """Returns a sequence of _LinesMapping by diffing the sources.
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 |
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | For example, given the following diff:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | import re
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | - def func(arg1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | - arg2, arg3):
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | + def func(arg1, arg2, arg3):
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | pass
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | It returns the following mappings:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original -> modified
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (1, 1) -> (1, 1), is_changed_block=False (the "import re" line)
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (2, 3) -> (2, 2), is_changed_block=True (the diff)
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (4, 4) -> (3, 3), is_changed_block=False (the "pass" line)
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 |
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | You can think of this visually as if it brings up a side-by-side diff, and tries
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | to map the line ranges from the left side to the right side:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 |
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (1, 1)->(1, 1) 1. import re 1. import re
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (2, 3)->(2, 2) 2. def func(arg1, 2. def func(arg1, arg2, arg3):
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | 3. arg2, arg3):
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | (4, 4)->(3, 3) 4. pass 3. pass
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 |
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | Args:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_source: the original source.
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_source: the modified source.
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | """
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | matcher = difflib.SequenceMatcher(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | None,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_source.splitlines(keepends=True),
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_source.splitlines(keepends=True),
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | matching_blocks = matcher.get_matching_blocks()
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | lines_mappings: List[_LinesMapping] = []
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # matching_blocks is a sequence of "same block of code ranges", see
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.get_matching_blocks
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # Each block corresponds to a _LinesMapping with is_changed_block=False,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # and the ranges between two blocks corresponds to a _LinesMapping with
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # is_changed_block=True,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | # NOTE: matching_blocks is 0-based, but _LinesMapping is 1-based.
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | for i, block in enumerate(matching_blocks):
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | if i == 0:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | if block.a != 0 or block.b != 0:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | lines_mappings.append(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | _LinesMapping(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_start=1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_end=block.a,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_start=1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_end=block.b,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | is_changed_block=False,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | else:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | previous_block = matching_blocks[i - 1]
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | lines_mappings.append(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | _LinesMapping(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_start=previous_block.a + previous_block.size + 1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_end=block.a,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_start=previous_block.b + previous_block.size + 1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_end=block.b,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | is_changed_block=True,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | if i < len(matching_blocks) - 1:
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | lines_mappings.append(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | _LinesMapping(
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_start=block.a + 1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | original_end=block.a + block.size,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_start=block.b + 1,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | modified_end=block.b + block.size,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | is_changed_block=False,
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | )
0077 0016 0045 0006 0022 0004 0006 -- 06 006 012 015 030 018 045 0187.65 1407.35 0007.50 | return lines_mappings
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | def _find_lines_mapping_index(
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | original_line: int,
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | lines_mappings: Sequence[_LinesMapping],
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | start_index: int,
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | ) -> int:
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | """Returns the original index of the lines mappings for the original line."""
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | index = start_index
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | while index < len(lines_mappings):
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | mapping = lines_mappings[index]
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | if mapping.original_start <= original_line <= mapping.original_end:
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | return index
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | index += 1
0013 0009 0012 0000 0000 0000 0001 -- 03 003 006 004 007 009 011 0034.87 0061.02 0001.75 | return index