Fix formatter blank line and over-indent for union template argument#11010
Conversation
When a `union` expression was used directly as one of multiple template arguments and the argument list wrapped, the formatter inserted a blank line before the union and indented its `|`-prefixed variants one level deeper than the sibling arguments. The argument list already supplies a line break and an indentation level before each argument, so `printUnion` no longer adds its own leading line and indent when the union is a direct argument of a multi-argument template reference. Fixes microsoft#11009 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@microsoft-github-policy-service agree |
commit: |
|
All changed packages have been documented.
Show changes
|
Address review feedback: the previous fix dropped align(2) on union variants when the union is a multi-argument template argument, which de-indented a nested template inside a variant. Keep align(2) unconditionally (matching prettier's union printer) so a breaking variant stays aligned under its "| " prefix, and add a regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the careful review — you're right, fixed in And to your question: this does follow prettier's union printer — indent-or-not depends on the parent ( |
Reformatting arm.tsp/response.tsp (union template arguments) changed the tcgc crossLanguageVersion hash of the generated metadata. Update the two *_metadata.json files to the regenerated hashes so the Java RegenCheck passes, and add an internal changeset for @typespec/http-client-java so the changelog check passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A TemplateArgument node only ever exists as an element of TypeReference.arguments (the sole TemplateArgumentNode[] in the AST), so when the parent is a TemplateArgument the owning TypeReference is always the next node ancestor. Replace the variable-depth loop with a direct getParentNode(1) check; behavior is unchanged and all formatter tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
yeah we investigated with Allen, I believe the issue is that the crossVersionId hashes the file content which the formatting affect. Should be good now |
…osoft#11011) Fixes the `is`-breaking part of microsoft#11009 (the blank-line/over-indent part is addressed separately in microsoft#11010). ## Problem When a model/scalar heritage clause (`is X` / `extends X`) references a template with multiple arguments, the formatter wrapped the keyword and the template reference in a single `group(indent(...))`. Prettier measures that group against the full flat width of the template argument list, so the group broke and pushed the keyword onto its own indented line — even when the declaration line itself was short: ```tsp model Picked is PickProperties< Sample, ... >; ``` ## Fix `printHeritageClause` now keeps the keyword on the declaration line when the base is a template reference with multiple (breakable) arguments, and lets the template argument list control the line break: ```tsp model Picked is PickProperties< Sample, ... >; ``` Single-argument (hugged) and non-template bases keep the previous behavior of breaking the keyword onto its own line when the declaration is too long. ## Tests - Added regression tests for the multi-argument case on `model is`, `model extends`, and `scalar extends` in `formatter.test.ts`. - Reformatted one committed `http-client-java` test spec (`arm-customization.tsp`) that contained the old output (whitespace only, no semantic change). - Formatter test suite, eslint, tsc, and `prettier --check "**/*.tsp"` all pass locally. > Note: the `crossLanguageVersion` hash in the corresponding `*_metadata.json` is whitespace-sensitive; it will be updated from the RegenCheck output once CI runs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the formatter fixes @oha-4 |
|
@oha-4 it seems like tests need to be updated as seems to conflict with your other pr I merged |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…' into fix/formatter-union-template-arg
…oft#11093) Fixes microsoft#11092 ## Problem PR microsoft#11010 fixed a blank-line / over-indent issue when a `union` expression is used as one of several **positional** template arguments. That fix made `printUnion` suppress its own leading line + indent when the union is a direct argument of a multi-argument template reference (the surrounding argument list already supplies them). This regressed the **named** template argument case (`Name = <union>`). For a named argument the union is printed *after* `Name = `, so the argument list's line break / indent does **not** apply to the union variants. Suppressing the union's own break + indent collapsed the variants: ```tsp alias Alias = Test< A = "Some long value", TakesALongUnion = | string | int32 | int64 | "Some very long string that split line" >; ``` ## Fix `isInMultiTemplateArgumentList` now returns `false` when the parent `TemplateArgument` has a `name`. Named-argument unions fall back to the standalone behavior (their own leading `line` + `| ` + indent): ```tsp alias Alias = Test< A = "Some long value", TakesALongUnion = | string | int32 | int64 | "Some very long string that split line" >; ``` The single-argument case and the positional multi-argument case (microsoft#11009) are unchanged. ## Tests - Added a regression test for the named-union multi-argument case (microsoft#11092). - Existing microsoft#11009 positional tests still pass; full formatter suite (216 tests) passes. - `prettier --check "**/*.tsp"` clean; compiler builds.
Fixes #11009
Problem
When a
unionexpression is used directly as one of multiple template arguments and the argument list is long enough to wrap,tsp formatinserts a blank line before the union and indents its leading-|variants one level deeper than the sibling arguments:Fix
printTemplateParametersalready emits asoftline+ anindentlevel before each argument in a multi-argument list.printUnionwas also emitting its own leadingline+indent(+align(2)), so the two stacked, producing the blank line and the extra indentation level.printUnionnow detects when the union is a direct argument of a multi-argument template reference (isInMultiTemplateArgumentList) and, in that case, lets the surrounding argument list control the line break and indentation. Result:The standalone/value-position cases (e.g.
alias X = "a" | "b" | ...) and the single-template-argument (shouldHug) case are unchanged, since there the surrounding context does not supply the line break/indent.Tests
unionused as a template argument #11009) and a test pinning the single-argument behavior informatter.test.ts.http-client-javatest fixtures that contained the buggy output (whitespace only; no semantic change).pnpm prettier --check "**/*.tsp", formatter test suite, tsc, and eslint all pass.