Preserve comments on the final function parameter (#1519)

Buildifier currently moves a trailing comment on the final function
parameter past the closing `)` and any return annotation. For example:

```python
def f(
    x,  # @unused
) -> int:
    return 1
```

becomes:

```python
def f(
        x) -> int:  # @unused
    return 1
```

Since #1488, these two spellings have different AST attachments: the
first comment belongs to `x`, while the second belongs to the function
header's colon. #1518 intentionally interprets an `@unused` comment on
the header as applying to the final parameter, preserving the
longstanding behavior of existing files. However, buildifier should not
convert the preferred parameter-attached form into that legacy
header-attached form. Keeping the forms distinguishable lets users write
the clearer form today and leaves room to change or deprecate the legacy
interpretation in the future.

This PR keeps signatures with parameter suffix comments multiline and
emits a pending final parameter comment before the closing parenthesis:

```python
def f(
        x  # @unused
) -> int:
    return 1
```

Both forms remain supported, with `@unused` applying only to the final
parameter:

```python
# Preferred: the comment is attached to y.
def f(
        x,
        y  # @unused
):
    pass

# Legacy compatibility: a header comment applies to y, not x.
def g(x, y):  # @unused
    pass
```

The lexer previously treated a comment following a line containing only
`):` as a body comment. That exception was added in #276 before
block-header comments had their own AST node. Remove it so comments
visibly written after the colon remain attached to the header, including
multiline `def`, `if`, and `for` headers.

Finally, flush queued end-of-line comments before reducing the
indentation margin. This keeps continuation comments on a final
parameter aligned with that parameter and makes formatting idempotent.

The `unused-variable` documentation now recommends the
parameter-attached form and documents the header-attached form as
backward compatibility behavior.
9 files changed
tree: f8ebb25a966754956ca33e3e8c1d0aa79889f5a9
  1. .bazelci/
  2. .github/
  3. api_proto/
  4. build/
  5. build_proto/
  6. buildifier/
  7. buildozer/
  8. bzlenv/
  9. config/
  10. convertast/
  11. deps_proto/
  12. differ/
  13. edit/
  14. extra_actions_base_proto/
  15. file/
  16. generatetables/
  17. labels/
  18. lang/
  19. release/
  20. tables/
  21. testutils/
  22. unused_deps/
  23. warn/
  24. wspace/
  25. .bazelrc
  26. .bazelversion
  27. .gitignore
  28. .mailmap
  29. .pre-commit-config.yaml
  30. AGENTS.md
  31. BUILD.bazel
  32. CODEOWNERS
  33. CONTRIBUTING.md
  34. CONTRIBUTORS
  35. go.mod
  36. go.sum
  37. launcher.js
  38. LICENSE
  39. MODULE.bazel
  40. README.md
  41. status.py
  42. update_generated.sh
  43. WARNINGS.md
  44. WORKSPACE
  45. WORKSPACE.bzlmod
README.md

Buildtools for bazel

This repository contains developer tools for working with Google's bazel buildtool.

Build status

Setup

See instructions in each tool's directory.