Group physical lines into logical lines. A prop/other line absorbs subsequent physical lines while EITHER: - bracket depth is still > 0 (unclosed `(`, `[`, or `{` in the value), - the last absorbed line ends with a trailing operator (`?`, `:`, `+`, …), - OR the next physical l
(raw_lines: list[str])
| 367 | |
| 368 | |
| 369 | def tokenize(raw_lines: list[str]) -> list[LogicalLine]: |
| 370 | """Group physical lines into logical lines. |
| 371 | |
| 372 | A prop/other line absorbs subsequent physical lines while EITHER: |
| 373 | - bracket depth is still > 0 (unclosed `(`, `[`, or `{` in the value), |
| 374 | - the last absorbed line ends with a trailing operator (`?`, `:`, `+`, …), |
| 375 | - OR the next physical line starts with a continuation operator. |
| 376 | |
| 377 | Comments and handlers are never absorbed into a property run. A `{` or `}` |
| 378 | that appears on the *absorbed* lines contributes to the bracket count, but |
| 379 | does not retrigger the `open`/`close` classification — the logical line is |
| 380 | still treated as a prop for run-sorting purposes, just an unsafe one. |
| 381 | """ |
| 382 | logical: list[LogicalLine] = [] |
| 383 | i = 0 |
| 384 | n = len(raw_lines) |
| 385 | |
| 386 | while i < n: |
| 387 | raw = raw_lines[i] |
| 388 | kind = physical_kind(raw) |
| 389 | line = LogicalLine(raws=[raw], kind=kind, start_idx=i) |
| 390 | i += 1 |
| 391 | |
| 392 | if kind not in ("prop", "other"): |
| 393 | logical.append(line) |
| 394 | continue |
| 395 | |
| 396 | # Track open-bracket balance across absorbed lines. If the property's |
| 397 | # value opens a list literal, object literal, or parenthesized group, |
| 398 | # keep absorbing physical lines until brackets rebalance. |
| 399 | depth = _bracket_delta(raw) |
| 400 | last = raw |
| 401 | inner = False # True once we've absorbed at least one continuation line |
| 402 | |
| 403 | while i < n: |
| 404 | next_raw = raw_lines[i] |
| 405 | next_kind = physical_kind(next_raw) |
| 406 | |
| 407 | # Blank line always terminates the run — even an open bracket |
| 408 | # followed by a blank line is malformed source we won't touch. |
| 409 | if next_kind == "blank": |
| 410 | break |
| 411 | |
| 412 | # A line whose net bracket delta is negative is a structural close |
| 413 | # of an OUTER block, not a continuation of this prop's value. |
| 414 | # Never absorb it, even if it happens to start with `)`, `]`, or `}`. |
| 415 | # Exception: when we're still inside an unclosed bracket run of our |
| 416 | # own — then the `)` / `]` / `}` closes our own literal. |
| 417 | next_bracket_delta = _bracket_delta(next_raw) |
| 418 | if next_bracket_delta < 0 and depth + next_bracket_delta < 0: |
| 419 | break |
| 420 | |
| 421 | # Decide whether `next_raw` continues `last`. |
| 422 | absorb = False |
| 423 | if depth > 0: |
| 424 | absorb = True |
| 425 | elif _has_trailing_operator(last, is_inner=inner): |
| 426 | absorb = True |
no test coverage detected