From 8ee08fd77cb05490e5cb084f6480212ca1b362a3 Mon Sep 17 00:00:00 2001 From: Ryan Atkinson Date: Wed, 15 Jul 2026 16:33:00 -0400 Subject: [PATCH 1/2] fix: break non-hugging single type arguments --- .../src/cli/commands/gap_audit_known.txt | 2 + crates/tsv_ts/src/printer/class_common.rs | 4 +- .../src/printer/comments/declarations.rs | 2 +- crates/tsv_ts/src/printer/expressions/mod.rs | 8 +- .../printer/statements/type_declarations.rs | 2 +- .../src/printer/types/function_types.rs | 5 +- crates/tsv_ts/src/printer/types/mod.rs | 29 +- .../src/printer/types/type_annotation.rs | 8 +- .../src/printer/types/type_arguments.rs | 130 +- .../tsv_ts/src/printer/types/type_literal.rs | 2 +- .../tsv_ts/src/printer/types/type_params.rs | 4 +- .../expected.json | 1709 +++++++++++++++ .../input.svelte | 32 + .../type_argument_nonhug_long/expected.json | 1948 +++++++++++++++++ .../type_argument_nonhug_long/input.svelte | 35 + 15 files changed, 3809 insertions(+), 111 deletions(-) create mode 100644 tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/expected.json create mode 100644 tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/input.svelte create mode 100644 tests/fixtures/typescript/types/type_argument_nonhug_long/expected.json create mode 100644 tests/fixtures/typescript/types/type_argument_nonhug_long/input.svelte diff --git a/crates/tsv_debug/src/cli/commands/gap_audit_known.txt b/crates/tsv_debug/src/cli/commands/gap_audit_known.txt index e3c8e203..e221fe1d 100644 --- a/crates/tsv_debug/src/cli/commands/gap_audit_known.txt +++ b/crates/tsv_debug/src/cli/commands/gap_audit_known.txt @@ -271,6 +271,7 @@ DROPPED >(⟨⟩␣ line DROPPED >)⟨⟩␣ annotation,jsdoc_cast DROPPED >,⟨⟩>() annotation,block,jsdoc_cast,multiline DROPPED >?(⟨⟩IDENT annotation,block,jsdoc_cast,multiline +DROPPED >[⟨⟩]; annotation,block,jsdoc_cast,line,multiline DROPPED >[⟨⟩]]> annotation,block,jsdoc_cast,line,multiline DROPPED >}}⟨⟩␣ annotation,block,jsdoc_cast DROPPED >}⟨⟩>() annotation,block,jsdoc_cast,multiline @@ -278,6 +279,7 @@ DROPPED >⟨⟩( line DROPPED >⟨⟩(() line DROPPED >⟨⟩) annotation,jsdoc_cast DROPPED >⟨⟩,>( annotation,block,jsdoc_cast,multiline +DROPPED >⟨⟩[]; annotation,block,jsdoc_cast DROPPED >⟨⟩[]] annotation,block,jsdoc_cast DROPPED >⟨⟩␣ annotation,block,jsdoc_cast,multiline DROPPED ?(⟨⟩// annotation,block,jsdoc_cast,multiline diff --git a/crates/tsv_ts/src/printer/class_common.rs b/crates/tsv_ts/src/printer/class_common.rs index 93575322..bd00be78 100644 --- a/crates/tsv_ts/src/printer/class_common.rs +++ b/crates/tsv_ts/src/printer/class_common.rs @@ -147,7 +147,7 @@ impl<'a> Printer<'a> { ) { value_parts.push(doc); } - value_parts.push(self.build_type_arguments_doc_wrapping(type_args)); + value_parts.push(self.build_type_arguments_doc(type_args)); } let value_doc = d.concat(&value_parts); let mut ext_parts = smallvec![d.text("extends")]; @@ -181,7 +181,7 @@ impl<'a> Printer<'a> { ) { ext_parts.push(doc); } - ext_parts.push(self.build_type_arguments_doc_wrapping(type_args)); + ext_parts.push(self.build_type_arguments_doc(type_args)); } Some(d.concat(&ext_parts)) } diff --git a/crates/tsv_ts/src/printer/comments/declarations.rs b/crates/tsv_ts/src/printer/comments/declarations.rs index 282c2850..149bf386 100644 --- a/crates/tsv_ts/src/printer/comments/declarations.rs +++ b/crates/tsv_ts/src/printer/comments/declarations.rs @@ -936,7 +936,7 @@ impl<'a> Printer<'a> { ) { h_parts.push(doc); } - h_parts.push(self.build_type_arguments_doc_wrapping(type_args)); + h_parts.push(self.build_type_arguments_doc(type_args)); } if let Some(next) = items.get(i + 1) { let item_end = heritage_item_end(heritage); diff --git a/crates/tsv_ts/src/printer/expressions/mod.rs b/crates/tsv_ts/src/printer/expressions/mod.rs index 25e6abf6..580c5cd0 100644 --- a/crates/tsv_ts/src/printer/expressions/mod.rs +++ b/crates/tsv_ts/src/printer/expressions/mod.rs @@ -409,7 +409,7 @@ impl<'a> Printer<'a> { let type_end = type_assert.type_annotation.span().end; let expr_start = type_assert.expression.span().start; let close_angle = self.find_assertion_close_angle(type_end, expr_start); - let type_doc = self.build_type_doc_with_wrapping_type_args(type_assert.type_annotation); + let type_doc = self.build_type_doc(type_assert.type_annotation); // Comments in the cast stay where the author wrote them. Block comments hug // inline (``, ``, `/* c */ expr`); a `//` runs to @@ -620,7 +620,7 @@ impl<'a> Printer<'a> { if self.comments_force_own_line_between(kw_end, type_start) { parts.push(d.text(" ")); parts.push(d.text(keyword)); - let type_doc = self.build_type_doc_with_wrapping_type_args(type_annotation); + let type_doc = self.build_type_doc(type_annotation); self.append_keyword_value_line_comments(&mut parts, kw_end, type_start, type_doc); return d.concat(&parts); } @@ -663,9 +663,9 @@ impl<'a> Printer<'a> { CommentSpacing::Trailing, )); } - parts.push(self.build_type_doc_with_wrapping_type_args(type_annotation)); + parts.push(self.build_type_doc(type_annotation)); } else { - parts.push(self.build_type_doc_with_wrapping_type_args(type_annotation)); + parts.push(self.build_type_doc(type_annotation)); } d.concat(&parts) diff --git a/crates/tsv_ts/src/printer/statements/type_declarations.rs b/crates/tsv_ts/src/printer/statements/type_declarations.rs index 143c0bd3..66ca4095 100644 --- a/crates/tsv_ts/src/printer/statements/type_declarations.rs +++ b/crates/tsv_ts/src/printer/statements/type_declarations.rs @@ -332,7 +332,7 @@ impl<'a> Printer<'a> { } else if type_has_internal_breaking(value_type) { // Types with internal breaking (braces, brackets, parens, angle brackets) stay hugged // Use wrapping version so TypeReference type args break internally when too long - let type_doc = self.build_type_doc_with_wrapping_type_args(value_type); + let type_doc = self.build_type_doc(value_type); parts.push(d.text(" ")); parts.push(type_doc); } else if has_complex_params { diff --git a/crates/tsv_ts/src/printer/types/function_types.rs b/crates/tsv_ts/src/printer/types/function_types.rs index 0adf9191..56213fd3 100644 --- a/crates/tsv_ts/src/printer/types/function_types.rs +++ b/crates/tsv_ts/src/printer/types/function_types.rs @@ -218,9 +218,8 @@ impl<'a> Printer<'a> { .as_ref() .is_some_and(type_args_should_wrap_for_return_type) => { - // Use build_type_doc_inner with wrap_type_args=true to enable - // wrapping inside the type reference's type arguments - let type_doc = self.build_type_doc_inner(return_type.type_annotation, true); + // The type reference's own type arguments wrap internally when too wide. + let type_doc = self.build_type_doc(return_type.type_annotation); joined(d.text(arrow_sp), type_doc) } _ => joined( diff --git a/crates/tsv_ts/src/printer/types/mod.rs b/crates/tsv_ts/src/printer/types/mod.rs index 7ac1066f..01536547 100644 --- a/crates/tsv_ts/src/printer/types/mod.rs +++ b/crates/tsv_ts/src/printer/types/mod.rs @@ -52,25 +52,12 @@ impl<'a> Printer<'a> { // Main Type Doc Builders // - /// Build a Doc for a TypeScript type expression - pub(in crate::printer) fn build_type_doc(&self, ts_type: &TSType<'_>) -> DocId { - self.build_type_doc_inner(ts_type, false) - } - - /// Build a Doc for a TypeScript type expression with wrapping type arguments. + /// Build a Doc for a TypeScript type expression. /// - /// Used in type alias RHS where TypeReference type arguments should break - /// internally (e.g., `Promise` breaks inside `<>`). - pub(in crate::printer) fn build_type_doc_with_wrapping_type_args( - &self, - ts_type: &TSType<'_>, - ) -> DocId { - self.build_type_doc_inner(ts_type, true) - } - - /// Inner implementation for type doc building. - /// When `wrap_type_args` is true, TypeReference uses wrapping type arguments. - pub(super) fn build_type_doc_inner(&self, ts_type: &TSType<'_>, wrap_type_args: bool) -> DocId { + /// A `TypeReference`'s own type arguments always break internally when too wide + /// (`Promise` breaks inside the `<>`) — `build_type_arguments_doc` is the + /// single builder for every type-argument position, so no caller has to opt into that. + pub(in crate::printer) fn build_type_doc(&self, ts_type: &TSType<'_>) -> DocId { let d = self.d(); match ts_type { TSType::Keyword(kw) => d.text(kw.kind.as_str()), @@ -89,11 +76,7 @@ impl<'a> Printer<'a> { ) { parts.push(doc); } - if wrap_type_args { - parts.push(self.build_type_arguments_doc_wrapping(type_args)); - } else { - parts.push(self.build_type_arguments_doc(type_args)); - } + parts.push(self.build_type_arguments_doc(type_args)); } d.concat(&parts) } diff --git a/crates/tsv_ts/src/printer/types/type_annotation.rs b/crates/tsv_ts/src/printer/types/type_annotation.rs index cabbdd27..0f092676 100644 --- a/crates/tsv_ts/src/printer/types/type_annotation.rs +++ b/crates/tsv_ts/src/printer/types/type_annotation.rs @@ -140,8 +140,8 @@ impl<'a> Printer<'a> { /// Build type annotation doc with width-aware type argument wrapping. /// - /// For `TypeReference`, uses `build_type_arguments_doc_wrapping` so - /// type arguments wrap at width boundary. + /// For `TypeReference`, `build_type_arguments_doc` wraps the type + /// arguments at the width boundary. /// /// For Union types, uses break-after-colon layout: /// ```text @@ -229,7 +229,7 @@ impl<'a> Printer<'a> { { parts.push(name_ta_comments); } - parts.push(self.build_type_arguments_doc_wrapping(type_args)); + parts.push(self.build_type_arguments_doc(type_args)); return d.concat(&parts); } @@ -360,7 +360,7 @@ impl<'a> Printer<'a> { { parts.push(comments_doc); } - parts.push(self.build_type_doc_with_wrapping_type_args(&intersection.types[0])); + parts.push(self.build_type_doc(&intersection.types[0])); return d.concat(&parts); } diff --git a/crates/tsv_ts/src/printer/types/type_arguments.rs b/crates/tsv_ts/src/printer/types/type_arguments.rs index 3ba81675..7fe44592 100644 --- a/crates/tsv_ts/src/printer/types/type_arguments.rs +++ b/crates/tsv_ts/src/printer/types/type_arguments.rs @@ -1,7 +1,7 @@ // Type-argument instantiation (``) rendering use super::Printer; -use super::helpers::{is_simple_type_arg, unwrap_parenthesized}; +use super::helpers::{is_huggable_type, is_simple_type_arg, unwrap_parenthesized}; use crate::ast::internal::{self, TSType}; use smallvec::smallvec; use tsv_lang::doc::DocBuf; @@ -30,11 +30,13 @@ impl<'a> Printer<'a> { /// arguments, the assignment `=`) rather than inside it; any brace-delimited member /// carries its own group and still breaks block-style within the hugged `<…>`. /// - /// Assumes `args.params.len() == 1`; the caller gates on its own single-arg inline - /// predicate (`is_simple_type_arg`, `union_type_arg_hug_shape`, a huggable object, - /// or always-inline). Own-line and line comments are routed to the multiline path - /// before this runs, so only inline block comments remain to preserve here. Shared by - /// the type-position builder and the call/`new`/instantiation builder. + /// Assumes `args.params.len() == 1` **and** that the caller has gated on the argument + /// actually hugging — [`Self::type_arg_hugs`] for both builders here, and its split + /// spelling in `type_params.rs` (whose object case routes through + /// `try_build_hugging_curly_type_doc`, a documented divergence). Own-line and line + /// comments are routed to the multiline path before this runs, so only inline block + /// comments remain to preserve here. Shared by the type-position builder and the + /// call/`new`/instantiation builder. /// `has_comments` is the caller's whole-`<…>` window answer: `false` proves both /// gaps below are comment-free, so neither is searched. pub(in crate::printer) fn build_single_type_arg_inline( @@ -58,6 +60,30 @@ impl<'a> Printer<'a> { d.concat(&parts) } + /// Whether a **single type argument** hugs — i.e. whether `` inlines atomically. + /// Prettier's `shouldHugType` (`print/type-annotation.js`), and the whole answer, so no + /// type-argument site re-derives it from parts. Three clauses: + /// + /// 1. a **simple** type ([`is_simple_type_arg`]) — atomic, never benefits from breaking; + /// 2. an **object** type ([`is_huggable_type`] — `TypeLiteral`/`Mapped`), which carries + /// its own group and breaks block-style *inside* the hugged `<…>`; + /// 3. a **hugged union** ([`Self::type_arg_union_prints_hugged`] — `{ … } | null`), whose + /// object member likewise owns the expansion. + /// + /// For TypeScript this *is* prettier's `shouldInline` at `len == 1`: its remaining + /// disjunct, `NullableTypeAnnotation`, is Flow-only, and its `isParameterInTestCall` / + /// `isArrowFunctionVariable` clauses gate call-site `<…>`, not a type-position one. + /// + /// ⚠️ A non-hugging argument (an intersection, a function type, a conditional) must + /// **not** inline: `build_single_type_arg_inline` emits no group and no softlines, so an + /// inlined `<…>` has no break point and an overflowing head breaks *around* the brackets + /// (the enclosing operand, or the assignment `=`) instead of inside them. + pub(in crate::printer) fn type_arg_hugs(&self, ty: &TSType<'_>) -> bool { + is_simple_type_arg(ty) + || is_huggable_type(unwrap_parenthesized(ty)) + || self.type_arg_union_prints_hugged(ty) + } + /// Comments that force the `<...>` list to the multiline layout: line /// comments anywhere (including before the first argument, e.g. /// `Foo`) or own-line block comments — neither can render @@ -96,50 +122,23 @@ impl<'a> Printer<'a> { /// Build doc for type arguments: ``. /// - /// Single arg: always inline. Multi-arg: group-based breaking via shared helper. - /// Use `build_type_arguments_doc_wrapping` for single-arg hugging (e.g., `Array<{...}>`). - pub(crate) fn build_type_arguments_doc( - &self, - args: &internal::TSTypeParameterInstantiation<'_>, - ) -> DocId { - let d = self.d(); - if args.params.is_empty() { - return d.text("<>"); - } - - // One window search over the `<…>`, threaded into everything below it. - let has_comments = self.has_comments_on_page_between(args.span.start, args.span.end); - - if self.type_arguments_force_expansion(args, has_comments) { - return self.build_type_arguments_doc_with_line_comments(args); - } - - // Single type argument: inline (matches Prettier's shouldInline for len==1) - if args.params.len() == 1 { - return self.build_single_type_arg_inline(args, has_comments); - } - - // Multiple type arguments: use group so they can break at print width. - // Matches Prettier's group([<, indent([softline, join([",", line], args)]), softline, >]) - self.build_type_arguments_doc_multi_arg(args, has_comments) - } - - /// Build doc for type arguments with width-based wrapping support. + /// One builder for every type-argument position — there is no "wrapping" variant, because + /// there is nothing for one to do differently. A single **hugging** argument inlines + /// atomically ([`Self::type_arg_hugs`]); everything else — a non-hugging single argument + /// and every multi-argument list alike — gets the group, so the `<…>` breaks at print + /// width independently of its parent: /// - /// Inline: `` - /// Wrapped: `<\n\tT,\n\tU,\n\tV\n>` - /// - /// Special case: single TypeLiteral argument hugs the opening `<`: - /// `Array<{prop: string}>` stays hugged, and when broken: /// ```text - /// Array<{ - /// prop: string; - /// }> + /// Array<{ Promise< + /// prop: T; A & B & C + /// }> > /// ``` /// - /// Use this when type arguments should break independently of parent context, - /// such as in property type annotations. - pub(crate) fn build_type_arguments_doc_wrapping( + /// Inlining a hugging argument matters beyond layout taste: the group/softlines it avoids + /// would create Break-mode Line nodes in `fits()` rest_commands, causing upstream groups + /// (like arrays in Fluid assignment layout) to incorrectly appear to "fit" — Line in Break + /// mode returns true from `fits()`, short-circuiting the width check. + pub(crate) fn build_type_arguments_doc( &self, args: &internal::TSTypeParameterInstantiation<'_>, ) -> DocId { @@ -148,43 +147,34 @@ impl<'a> Printer<'a> { return d.text("<>"); } - // One window search over the `<…>`, threaded into everything below it. - let has_comments = self.has_comments_to_emit_between(args.span.start, args.span.end); + // One window search over the `<…>`, threaded into everything below it. **On-page**: + // this is the builder's zero-comment fast gate, so it short-circuits the layout gates + // below (`type_arguments_force_expansion` above all) — an emit-keyed answer would make + // every one of them blind to an owned comment. Sound today either way (ownership is + // set only in expression position, and a `<…>` window holds types), but the question + // asked here is "does a comment occupy the page", so that is the axis it asks. + let has_comments = self.has_comments_on_page_between(args.span.start, args.span.end); if self.type_arguments_force_expansion(args, has_comments) { return self.build_type_arguments_doc_with_line_comments(args); } - // Single type argument inlining, matching Prettier's `shouldInline` logic. - // Three categories are inlined (no group/softlines): - // - // 1. Simple types (`is_simple_type_arg`): keywords, literals, `this`, and a - // bare TypeReference without type args. Atomic — never need breaking. - // 2. Object types: TypeLiteral and Mapped types handle their own breaking. - // 3. Hugged unions: unions with a brace-delimited member like `{...} | null`. - // - // Without inlining, the group/softlines create Break-mode Line nodes in - // `fits()` rest_commands, causing upstream groups (like arrays in Fluid - // assignment layout) to incorrectly appear to "fit" — Line in Break mode - // returns true from `fits()`, short-circuiting the width check. - if args.params.len() == 1 { - let unwrapped = unwrap_parenthesized(&args.params[0]); - let is_huggable = is_simple_type_arg(&args.params[0]) - || matches!(unwrapped, TSType::TypeLiteral(_) | TSType::Mapped(_)) - || self.type_arg_union_prints_hugged(&args.params[0]); - if is_huggable { - return self.build_single_type_arg_inline(args, has_comments); - } + // A single argument inlines only when it hugs; a non-hugging one (an intersection, a + // function type, a conditional) falls through to the group below, which is what gives + // the `<…>` a break point of its own. + if args.params.len() == 1 && self.type_arg_hugs(&args.params[0]) { + return self.build_single_type_arg_inline(args, has_comments); } + // Matches Prettier's group([<, indent([softline, join([",", line], args)]), softline, >]) self.build_type_arguments_doc_multi_arg(args, has_comments) } /// Build multi-arg type arguments with group-based breaking. /// /// Matches Prettier's `group([<, indent([softline, join([",", line], args)]), softline, >])`. - /// Used by both `build_type_arguments_doc` and `build_type_arguments_doc_wrapping` - /// for 2+ type arguments (and non-huggable single args in the wrapping variant). + /// Used by `build_type_arguments_doc` for 2+ type arguments and for a non-hugging + /// single argument. /// `has_comments` is the caller's whole-`<…>` window answer. When `false` the whole /// per-argument comment apparatus is dead: every gap is provably comment-free, so /// neither the leading/trailing searches nor the `find_list_comma` byte scan that diff --git a/crates/tsv_ts/src/printer/types/type_literal.rs b/crates/tsv_ts/src/printer/types/type_literal.rs index 70b75977..70ade926 100644 --- a/crates/tsv_ts/src/printer/types/type_literal.rs +++ b/crates/tsv_ts/src/printer/types/type_literal.rs @@ -218,7 +218,7 @@ impl<'a> Printer<'a> { // wrapping type-args path so a nested non-huggable generic like // `Outer>` wraps the outer `Outer<>` instead of force-inlining // the single arg and breaking only the inner `Inner<>`. - self.build_type_doc_with_wrapping_type_args(ts_type) + self.build_type_doc(ts_type) } } diff --git a/crates/tsv_ts/src/printer/types/type_params.rs b/crates/tsv_ts/src/printer/types/type_params.rs index b7b0be9d..256cbb40 100644 --- a/crates/tsv_ts/src/printer/types/type_params.rs +++ b/crates/tsv_ts/src/printer/types/type_params.rs @@ -558,7 +558,7 @@ impl<'a> Printer<'a> { // (`union_type_arg_hug_shape`), whose object member carries its own group and // breaks block-style inside the hugged `<…>` rather than breaking the `<…>` onto // its own lines. Matches Prettier's `shouldInline`/`shouldHugType` and tsv's own - // type-position builder (`build_type_arguments_doc_wrapping`), via the shared + // type-position builder (`build_type_arguments_doc`), via the shared // predicates. Without it the fall-through group below gives the argument a // softline break point, so an overflowing call head (`callee(`) breaks the // `` instead of the arguments (and, as an assignment RHS, keeps the RHS on @@ -768,7 +768,7 @@ impl<'a> Printer<'a> { /// The object/mapped type carries its own width-aware group, so an inline /// `<{ ... }>` that overflows breaks block-style (members on their own lines) /// rather than spilling an inner union/intersection — matching the type-reference - /// type-argument path (`build_type_arguments_doc_wrapping`). + /// type-argument path (`build_type_arguments_doc`). fn try_build_hugging_curly_type_doc(&self, ty: &TSType<'_>) -> Option { match ty { // Object type literal: { a: number; b: string } or { /* comment */ } diff --git a/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/expected.json b/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/expected.json new file mode 100644 index 00000000..ad1120ce --- /dev/null +++ b/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/expected.json @@ -0,0 +1,1709 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 1079, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " Every context that reaches the non-wrapping type-argument builder applies the same", + "start": 20, + "end": 105, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 86 + } + } + }, + { + "type": "Line", + "value": " hug rule, so a non-hugging single type arg breaks the `<...>` in each of them.", + "start": 107, + "end": 188, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 82 + } + } + }, + { + "type": "Line", + "value": " 100 chars - fits inline at the boundary, so the `<...>` stays put", + "start": 191, + "end": 259, + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 69 + } + } + }, + { + "type": "Line", + "value": " 101 chars - array element type breaks", + "start": 362, + "end": 402, + "loc": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 8, + "column": 41 + } + } + }, + { + "type": "Line", + "value": " `typeof` query:", + "start": 513, + "end": 531, + "loc": { + "start": { + "line": 13, + "column": 1 + }, + "end": { + "line": 13, + "column": 19 + } + } + }, + { + "type": "Line", + "value": " `import(...)` type with a qualifier:", + "start": 645, + "end": 684, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 40 + } + } + }, + { + "type": "Line", + "value": " `keyof` operand:", + "start": 800, + "end": 819, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + { + "type": "Line", + "value": " Indexed-access object:", + "start": 932, + "end": 957, + "loc": { + "start": { + "line": 28, + "column": 1 + }, + "end": { + "line": 28, + "column": 26 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 1078, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 1069, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 32, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 261, + "end": 359, + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 99 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 275, + "end": 358, + "loc": { + "start": { + "line": 6, + "column": 15 + }, + "end": { + "line": 6, + "column": 98 + } + }, + "id": { + "type": "Identifier", + "start": 275, + "end": 358, + "loc": { + "start": { + "line": 6, + "column": 15 + }, + "end": { + "line": 6, + "column": 98 + } + }, + "name": "at100", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 280, + "end": 358, + "loc": { + "start": { + "line": 6, + "column": 20 + }, + "end": { + "line": 6, + "column": 98 + } + }, + "typeAnnotation": { + "type": "TSArrayType", + "start": 282, + "end": 358, + "loc": { + "start": { + "line": 6, + "column": 22 + }, + "end": { + "line": 6, + "column": 98 + } + }, + "elementType": { + "type": "TSTypeReference", + "start": 282, + "end": 356, + "loc": { + "start": { + "line": 6, + "column": 22 + }, + "end": { + "line": 6, + "column": 96 + } + }, + "typeName": { + "type": "Identifier", + "start": 282, + "end": 285, + "loc": { + "start": { + "line": 6, + "column": 22 + }, + "end": { + "line": 6, + "column": 25 + } + }, + "name": "Ref" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 285, + "end": 356, + "loc": { + "start": { + "line": 6, + "column": 25 + }, + "end": { + "line": 6, + "column": 96 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 286, + "end": 355, + "loc": { + "start": { + "line": 6, + "column": 26 + }, + "end": { + "line": 6, + "column": 95 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 286, + "end": 308, + "loc": { + "start": { + "line": 6, + "column": 26 + }, + "end": { + "line": 6, + "column": 48 + } + }, + "typeName": { + "type": "Identifier", + "start": 286, + "end": 308, + "loc": { + "start": { + "line": 6, + "column": 26 + }, + "end": { + "line": 6, + "column": 48 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 311, + "end": 332, + "loc": { + "start": { + "line": 6, + "column": 51 + }, + "end": { + "line": 6, + "column": 72 + } + }, + "typeName": { + "type": "Identifier", + "start": 311, + "end": 332, + "loc": { + "start": { + "line": 6, + "column": 51 + }, + "end": { + "line": 6, + "column": 72 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 335, + "end": 355, + "loc": { + "start": { + "line": 6, + "column": 75 + }, + "end": { + "line": 6, + "column": 95 + } + }, + "typeName": { + "type": "Identifier", + "start": 335, + "end": 355, + "loc": { + "start": { + "line": 6, + "column": 75 + }, + "end": { + "line": 6, + "column": 95 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " Every context that reaches the non-wrapping type-argument builder applies the same", + "start": 20, + "end": 105 + }, + { + "type": "Line", + "value": " hug rule, so a non-hugging single type arg breaks the `<...>` in each of them.", + "start": 107, + "end": 188 + }, + { + "type": "Line", + "value": " 100 chars - fits inline at the boundary, so the `<...>` stays put", + "start": 191, + "end": 259 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 404, + "end": 510, + "loc": { + "start": { + "line": 9, + "column": 1 + }, + "end": { + "line": 11, + "column": 5 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 418, + "end": 509, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 11, + "column": 4 + } + }, + "id": { + "type": "Identifier", + "start": 418, + "end": 509, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 11, + "column": 4 + } + }, + "name": "arr", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 421, + "end": 509, + "loc": { + "start": { + "line": 9, + "column": 18 + }, + "end": { + "line": 11, + "column": 4 + } + }, + "typeAnnotation": { + "type": "TSArrayType", + "start": 423, + "end": 509, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 11, + "column": 4 + } + }, + "elementType": { + "type": "TSTypeReference", + "start": 423, + "end": 507, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 11, + "column": 2 + } + }, + "typeName": { + "type": "Identifier", + "start": 423, + "end": 426, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 23 + } + }, + "name": "Ref" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 426, + "end": 507, + "loc": { + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 11, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 430, + "end": 504, + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 76 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 430, + "end": 455, + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 27 + } + }, + "typeName": { + "type": "Identifier", + "start": 430, + "end": 455, + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 27 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 458, + "end": 479, + "loc": { + "start": { + "line": 10, + "column": 30 + }, + "end": { + "line": 10, + "column": 51 + } + }, + "typeName": { + "type": "Identifier", + "start": 458, + "end": 479, + "loc": { + "start": { + "line": 10, + "column": 30 + }, + "end": { + "line": 10, + "column": 51 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 482, + "end": 504, + "loc": { + "start": { + "line": 10, + "column": 54 + }, + "end": { + "line": 10, + "column": 76 + } + }, + "typeName": { + "type": "Identifier", + "start": 482, + "end": 504, + "loc": { + "start": { + "line": 10, + "column": 54 + }, + "end": { + "line": 10, + "column": 76 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " 101 chars - array element type breaks", + "start": 362, + "end": 402 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 533, + "end": 642, + "loc": { + "start": { + "line": 14, + "column": 1 + }, + "end": { + "line": 16, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 547, + "end": 641, + "loc": { + "start": { + "line": 14, + "column": 15 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 547, + "end": 641, + "loc": { + "start": { + "line": 14, + "column": 15 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "name": "query", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 552, + "end": 641, + "loc": { + "start": { + "line": 14, + "column": 20 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 554, + "end": 641, + "loc": { + "start": { + "line": 14, + "column": 22 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "exprName": { + "type": "Identifier", + "start": 561, + "end": 563, + "loc": { + "start": { + "line": 14, + "column": 29 + }, + "end": { + "line": 14, + "column": 31 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 563, + "end": 641, + "loc": { + "start": { + "line": 14, + "column": 31 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 567, + "end": 638, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 73 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 567, + "end": 592, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 27 + } + }, + "typeName": { + "type": "Identifier", + "start": 567, + "end": 592, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 27 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 595, + "end": 615, + "loc": { + "start": { + "line": 15, + "column": 30 + }, + "end": { + "line": 15, + "column": 50 + } + }, + "typeName": { + "type": "Identifier", + "start": 595, + "end": 615, + "loc": { + "start": { + "line": 15, + "column": 30 + }, + "end": { + "line": 15, + "column": 50 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 618, + "end": 638, + "loc": { + "start": { + "line": 15, + "column": 53 + }, + "end": { + "line": 15, + "column": 73 + } + }, + "typeName": { + "type": "Identifier", + "start": 618, + "end": 638, + "loc": { + "start": { + "line": 15, + "column": 53 + }, + "end": { + "line": 15, + "column": 73 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " `typeof` query:", + "start": 513, + "end": 531 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 686, + "end": 797, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 21, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 700, + "end": 796, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 700, + "end": 796, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "name": "imp", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 703, + "end": 796, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSImportType", + "start": 705, + "end": 796, + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "argument": { + "type": "Literal", + "start": 712, + "end": 717, + "loc": { + "start": { + "line": 19, + "column": 27 + }, + "end": { + "line": 19, + "column": 32 + } + }, + "value": "./a", + "raw": "'./a'" + }, + "qualifier": { + "type": "Identifier", + "start": 719, + "end": 720, + "loc": { + "start": { + "line": 19, + "column": 34 + }, + "end": { + "line": 19, + "column": 35 + } + }, + "name": "Q" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 720, + "end": 796, + "loc": { + "start": { + "line": 19, + "column": 35 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 724, + "end": 793, + "loc": { + "start": { + "line": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 71 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 724, + "end": 747, + "loc": { + "start": { + "line": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 25 + } + }, + "typeName": { + "type": "Identifier", + "start": 724, + "end": 747, + "loc": { + "start": { + "line": 20, + "column": 2 + }, + "end": { + "line": 20, + "column": 25 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 750, + "end": 770, + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 48 + } + }, + "typeName": { + "type": "Identifier", + "start": 750, + "end": 770, + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 48 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 773, + "end": 793, + "loc": { + "start": { + "line": 20, + "column": 51 + }, + "end": { + "line": 20, + "column": 71 + } + }, + "typeName": { + "type": "Identifier", + "start": 773, + "end": 793, + "loc": { + "start": { + "line": 20, + "column": 51 + }, + "end": { + "line": 20, + "column": 71 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " `import(...)` type with a qualifier:", + "start": 645, + "end": 684 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 821, + "end": 929, + "loc": { + "start": { + "line": 24, + "column": 1 + }, + "end": { + "line": 26, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 835, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 15 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 835, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 15 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "name": "key", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 838, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 18 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSTypeOperator", + "start": 840, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "operator": "keyof", + "typeAnnotation": { + "type": "TSTypeReference", + "start": 846, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 26 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "typeName": { + "type": "Identifier", + "start": 846, + "end": 849, + "loc": { + "start": { + "line": 24, + "column": 26 + }, + "end": { + "line": 24, + "column": 29 + } + }, + "name": "Ref" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 849, + "end": 928, + "loc": { + "start": { + "line": 24, + "column": 29 + }, + "end": { + "line": 26, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 853, + "end": 925, + "loc": { + "start": { + "line": 25, + "column": 2 + }, + "end": { + "line": 25, + "column": 74 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 853, + "end": 879, + "loc": { + "start": { + "line": 25, + "column": 2 + }, + "end": { + "line": 25, + "column": 28 + } + }, + "typeName": { + "type": "Identifier", + "start": 853, + "end": 879, + "loc": { + "start": { + "line": 25, + "column": 2 + }, + "end": { + "line": 25, + "column": 28 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 882, + "end": 902, + "loc": { + "start": { + "line": 25, + "column": 31 + }, + "end": { + "line": 25, + "column": 51 + } + }, + "typeName": { + "type": "Identifier", + "start": 882, + "end": 902, + "loc": { + "start": { + "line": 25, + "column": 31 + }, + "end": { + "line": 25, + "column": 51 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 905, + "end": 925, + "loc": { + "start": { + "line": 25, + "column": 54 + }, + "end": { + "line": 25, + "column": 74 + } + }, + "typeName": { + "type": "Identifier", + "start": 905, + "end": 925, + "loc": { + "start": { + "line": 25, + "column": 54 + }, + "end": { + "line": 25, + "column": 74 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " `keyof` operand:", + "start": 800, + "end": 819 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 959, + "end": 1068, + "loc": { + "start": { + "line": 29, + "column": 1 + }, + "end": { + "line": 31, + "column": 8 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 973, + "end": 1067, + "loc": { + "start": { + "line": 29, + "column": 15 + }, + "end": { + "line": 31, + "column": 7 + } + }, + "id": { + "type": "Identifier", + "start": 973, + "end": 1067, + "loc": { + "start": { + "line": 29, + "column": 15 + }, + "end": { + "line": 31, + "column": 7 + } + }, + "name": "idx", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 976, + "end": 1067, + "loc": { + "start": { + "line": 29, + "column": 18 + }, + "end": { + "line": 31, + "column": 7 + } + }, + "typeAnnotation": { + "type": "TSIndexedAccessType", + "start": 978, + "end": 1067, + "loc": { + "start": { + "line": 29, + "column": 20 + }, + "end": { + "line": 31, + "column": 7 + } + }, + "objectType": { + "type": "TSTypeReference", + "start": 978, + "end": 1062, + "loc": { + "start": { + "line": 29, + "column": 20 + }, + "end": { + "line": 31, + "column": 2 + } + }, + "typeName": { + "type": "Identifier", + "start": 978, + "end": 981, + "loc": { + "start": { + "line": 29, + "column": 20 + }, + "end": { + "line": 29, + "column": 23 + } + }, + "name": "Ref" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 981, + "end": 1062, + "loc": { + "start": { + "line": 29, + "column": 23 + }, + "end": { + "line": 31, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 985, + "end": 1059, + "loc": { + "start": { + "line": 30, + "column": 2 + }, + "end": { + "line": 30, + "column": 76 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 985, + "end": 1017, + "loc": { + "start": { + "line": 30, + "column": 2 + }, + "end": { + "line": 30, + "column": 34 + } + }, + "typeName": { + "type": "Identifier", + "start": 985, + "end": 1017, + "loc": { + "start": { + "line": 30, + "column": 2 + }, + "end": { + "line": 30, + "column": 34 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 1020, + "end": 1040, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 57 + } + }, + "typeName": { + "type": "Identifier", + "start": 1020, + "end": 1040, + "loc": { + "start": { + "line": 30, + "column": 37 + }, + "end": { + "line": 30, + "column": 57 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 1043, + "end": 1059, + "loc": { + "start": { + "line": 30, + "column": 60 + }, + "end": { + "line": 30, + "column": 76 + } + }, + "typeName": { + "type": "Identifier", + "start": 1043, + "end": 1059, + "loc": { + "start": { + "line": 30, + "column": 60 + }, + "end": { + "line": 30, + "column": 76 + } + }, + "name": "CCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + }, + "indexType": { + "type": "TSLiteralType", + "start": 1063, + "end": 1066, + "loc": { + "start": { + "line": 31, + "column": 3 + }, + "end": { + "line": 31, + "column": 6 + } + }, + "literal": { + "type": "Literal", + "start": 1063, + "end": 1066, + "loc": { + "start": { + "line": 31, + "column": 3 + }, + "end": { + "line": 31, + "column": 6 + } + }, + "value": "k", + "raw": "'k'" + } + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " Indexed-access object:", + "start": 932, + "end": 957 + } + ] + } + ], + "sourceType": "module" + }, + "attributes": [ + { + "type": "Attribute", + "start": 8, + "end": 17, + "name": "lang", + "name_loc": { + "start": { + "line": 1, + "column": 8, + "character": 8 + }, + "end": { + "line": 1, + "column": 12, + "character": 12 + } + }, + "value": [ + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "ts", + "data": "ts" + } + ] + } + ] + } +} diff --git a/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/input.svelte b/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/input.svelte new file mode 100644 index 00000000..5f191ddf --- /dev/null +++ b/tests/fixtures/typescript/types/type_argument_nonhug_contexts_long/input.svelte @@ -0,0 +1,32 @@ + diff --git a/tests/fixtures/typescript/types/type_argument_nonhug_long/expected.json b/tests/fixtures/typescript/types/type_argument_nonhug_long/expected.json new file mode 100644 index 00000000..da0f583a --- /dev/null +++ b/tests/fixtures/typescript/types/type_argument_nonhug_long/expected.json @@ -0,0 +1,1948 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 1369, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " A single type argument inlines only when it HUGS (prettier's `shouldHugType`): a", + "start": 20, + "end": 103, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 84 + } + } + }, + { + "type": "Line", + "value": " simple type, an object type, or a hugged union. A simple type arg stays inline:", + "start": 105, + "end": 187, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 83 + } + } + }, + { + "type": "Line", + "value": " An object type arg hugs the `<` and expands block-style inside it:", + "start": 243, + "end": 312, + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 70 + } + } + }, + { + "type": "Line", + "value": " A union with an object member hugs too - the object expands, the `<` stays glued:", + "start": 426, + "end": 510, + "loc": { + "start": { + "line": 12, + "column": 1 + }, + "end": { + "line": 12, + "column": 85 + } + } + }, + { + "type": "Line", + "value": " 100 chars - an intersection type arg does not hug, but fits inline (at boundary)", + "start": 627, + "end": 710, + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 84 + } + } + }, + { + "type": "Line", + "value": " 101 chars - does not fit, and an intersection is not huggable, so the `<...>` breaks", + "start": 813, + "end": 900, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 21, + "column": 88 + } + } + }, + { + "type": "Line", + "value": " A function type arg does not hug - the `<...>` breaks", + "start": 1009, + "end": 1065, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 26, + "column": 57 + } + } + }, + { + "type": "Line", + "value": " A conditional type arg does not hug - the `<...>` breaks", + "start": 1183, + "end": 1242, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 60 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 1368, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 1359, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 35, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 189, + "end": 240, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 4, + "column": 52 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 203, + "end": 239, + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 51 + } + }, + "id": { + "type": "Identifier", + "start": 203, + "end": 239, + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 51 + } + }, + "name": "simple", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 209, + "end": 239, + "loc": { + "start": { + "line": 4, + "column": 21 + }, + "end": { + "line": 4, + "column": 51 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 211, + "end": 239, + "loc": { + "start": { + "line": 4, + "column": 23 + }, + "end": { + "line": 4, + "column": 51 + } + }, + "exprName": { + "type": "Identifier", + "start": 218, + "end": 220, + "loc": { + "start": { + "line": 4, + "column": 30 + }, + "end": { + "line": 4, + "column": 32 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 220, + "end": 239, + "loc": { + "start": { + "line": 4, + "column": 32 + }, + "end": { + "line": 4, + "column": 51 + } + }, + "params": [ + { + "type": "TSTypeReference", + "start": 221, + "end": 238, + "loc": { + "start": { + "line": 4, + "column": 33 + }, + "end": { + "line": 4, + "column": 50 + } + }, + "typeName": { + "type": "Identifier", + "start": 221, + "end": 238, + "loc": { + "start": { + "line": 4, + "column": 33 + }, + "end": { + "line": 4, + "column": 50 + } + }, + "name": "AaaaTypeReference" + } + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A single type argument inlines only when it HUGS (prettier's `shouldHugType`): a", + "start": 20, + "end": 103 + }, + { + "type": "Line", + "value": " simple type, an object type, or a hugged union. A simple type arg stays inline:", + "start": 105, + "end": 187 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 314, + "end": 423, + "loc": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 10, + "column": 4 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 328, + "end": 422, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 328, + "end": 422, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "name": "obj", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 331, + "end": 422, + "loc": { + "start": { + "line": 7, + "column": 18 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 333, + "end": 422, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "exprName": { + "type": "Identifier", + "start": 340, + "end": 342, + "loc": { + "start": { + "line": 7, + "column": 27 + }, + "end": { + "line": 7, + "column": 29 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 342, + "end": 422, + "loc": { + "start": { + "line": 7, + "column": 29 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "params": [ + { + "type": "TSTypeLiteral", + "start": 343, + "end": 421, + "loc": { + "start": { + "line": 7, + "column": 30 + }, + "end": { + "line": 10, + "column": 2 + } + }, + "members": [ + { + "type": "TSPropertySignature", + "start": 347, + "end": 396, + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 51 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 347, + "end": 373, + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 28 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 373, + "end": 395, + "loc": { + "start": { + "line": 8, + "column": 28 + }, + "end": { + "line": 8, + "column": 50 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 375, + "end": 395, + "loc": { + "start": { + "line": 8, + "column": 30 + }, + "end": { + "line": 8, + "column": 50 + } + }, + "typeName": { + "type": "Identifier", + "start": 375, + "end": 395, + "loc": { + "start": { + "line": 8, + "column": 30 + }, + "end": { + "line": 8, + "column": 50 + } + }, + "name": "Aaaaaaaaaaaaaaaaaaaa" + } + } + } + }, + { + "type": "TSPropertySignature", + "start": 399, + "end": 418, + "loc": { + "start": { + "line": 9, + "column": 2 + }, + "end": { + "line": 9, + "column": 21 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 399, + "end": 409, + "loc": { + "start": { + "line": 9, + "column": 2 + }, + "end": { + "line": 9, + "column": 12 + } + }, + "name": "bbbbbbbbbb" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 409, + "end": 417, + "loc": { + "start": { + "line": 9, + "column": 12 + }, + "end": { + "line": 9, + "column": 20 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 411, + "end": 417, + "loc": { + "start": { + "line": 9, + "column": 14 + }, + "end": { + "line": 9, + "column": 20 + } + }, + "typeName": { + "type": "Identifier", + "start": 411, + "end": 417, + "loc": { + "start": { + "line": 9, + "column": 14 + }, + "end": { + "line": 9, + "column": 20 + } + }, + "name": "Bbbbbb" + } + } + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " An object type arg hugs the `<` and expands block-style inside it:", + "start": 243, + "end": 312 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 512, + "end": 624, + "loc": { + "start": { + "line": 13, + "column": 1 + }, + "end": { + "line": 16, + "column": 11 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 526, + "end": 623, + "loc": { + "start": { + "line": 13, + "column": 15 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "id": { + "type": "Identifier", + "start": 526, + "end": 623, + "loc": { + "start": { + "line": 13, + "column": 15 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "name": "uni", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 529, + "end": 623, + "loc": { + "start": { + "line": 13, + "column": 18 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 531, + "end": 623, + "loc": { + "start": { + "line": 13, + "column": 20 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "exprName": { + "type": "Identifier", + "start": 538, + "end": 540, + "loc": { + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 13, + "column": 29 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 540, + "end": 623, + "loc": { + "start": { + "line": 13, + "column": 29 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "params": [ + { + "type": "TSUnionType", + "start": 541, + "end": 622, + "loc": { + "start": { + "line": 13, + "column": 30 + }, + "end": { + "line": 16, + "column": 9 + } + }, + "types": [ + { + "type": "TSTypeLiteral", + "start": 541, + "end": 615, + "loc": { + "start": { + "line": 13, + "column": 30 + }, + "end": { + "line": 16, + "column": 2 + } + }, + "members": [ + { + "type": "TSPropertySignature", + "start": 545, + "end": 594, + "loc": { + "start": { + "line": 14, + "column": 2 + }, + "end": { + "line": 14, + "column": 51 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 545, + "end": 571, + "loc": { + "start": { + "line": 14, + "column": 2 + }, + "end": { + "line": 14, + "column": 28 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 571, + "end": 593, + "loc": { + "start": { + "line": 14, + "column": 28 + }, + "end": { + "line": 14, + "column": 50 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 573, + "end": 593, + "loc": { + "start": { + "line": 14, + "column": 30 + }, + "end": { + "line": 14, + "column": 50 + } + }, + "typeName": { + "type": "Identifier", + "start": 573, + "end": 593, + "loc": { + "start": { + "line": 14, + "column": 30 + }, + "end": { + "line": 14, + "column": 50 + } + }, + "name": "Aaaaaaaaaaaaaaaaaaaa" + } + } + } + }, + { + "type": "TSPropertySignature", + "start": 597, + "end": 612, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 17 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 597, + "end": 603, + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 8 + } + }, + "name": "bbbbbb" + }, + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 603, + "end": 611, + "loc": { + "start": { + "line": 15, + "column": 8 + }, + "end": { + "line": 15, + "column": 16 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 605, + "end": 611, + "loc": { + "start": { + "line": 15, + "column": 10 + }, + "end": { + "line": 15, + "column": 16 + } + }, + "typeName": { + "type": "Identifier", + "start": 605, + "end": 611, + "loc": { + "start": { + "line": 15, + "column": 10 + }, + "end": { + "line": 15, + "column": 16 + } + }, + "name": "Bbbbbb" + } + } + } + } + ] + }, + { + "type": "TSNullKeyword", + "start": 618, + "end": 622, + "loc": { + "start": { + "line": 16, + "column": 5 + }, + "end": { + "line": 16, + "column": 9 + } + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A union with an object member hugs too - the object expands, the `<` stays glued:", + "start": 426, + "end": 510 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 712, + "end": 810, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 99 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 726, + "end": 809, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "id": { + "type": "Identifier", + "start": 726, + "end": 809, + "loc": { + "start": { + "line": 19, + "column": 15 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "name": "t100", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 730, + "end": 809, + "loc": { + "start": { + "line": 19, + "column": 19 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 732, + "end": 809, + "loc": { + "start": { + "line": 19, + "column": 21 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "exprName": { + "type": "Identifier", + "start": 739, + "end": 741, + "loc": { + "start": { + "line": 19, + "column": 28 + }, + "end": { + "line": 19, + "column": 30 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 741, + "end": 809, + "loc": { + "start": { + "line": 19, + "column": 30 + }, + "end": { + "line": 19, + "column": 98 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 742, + "end": 808, + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 742, + "end": 762, + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 51 + } + }, + "typeName": { + "type": "Identifier", + "start": 742, + "end": 762, + "loc": { + "start": { + "line": 19, + "column": 31 + }, + "end": { + "line": 19, + "column": 51 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 765, + "end": 785, + "loc": { + "start": { + "line": 19, + "column": 54 + }, + "end": { + "line": 19, + "column": 74 + } + }, + "typeName": { + "type": "Identifier", + "start": 765, + "end": 785, + "loc": { + "start": { + "line": 19, + "column": 54 + }, + "end": { + "line": 19, + "column": 74 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 788, + "end": 808, + "loc": { + "start": { + "line": 19, + "column": 77 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "typeName": { + "type": "Identifier", + "start": 788, + "end": 808, + "loc": { + "start": { + "line": 19, + "column": 77 + }, + "end": { + "line": 19, + "column": 97 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " 100 chars - an intersection type arg does not hug, but fits inline (at boundary)", + "start": 627, + "end": 710 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 902, + "end": 1006, + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 24, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 916, + "end": 1005, + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 24, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 916, + "end": 1005, + "loc": { + "start": { + "line": 22, + "column": 15 + }, + "end": { + "line": 24, + "column": 2 + } + }, + "name": "t101", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 920, + "end": 1005, + "loc": { + "start": { + "line": 22, + "column": 19 + }, + "end": { + "line": 24, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 922, + "end": 1005, + "loc": { + "start": { + "line": 22, + "column": 21 + }, + "end": { + "line": 24, + "column": 2 + } + }, + "exprName": { + "type": "Identifier", + "start": 929, + "end": 931, + "loc": { + "start": { + "line": 22, + "column": 28 + }, + "end": { + "line": 22, + "column": 30 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 931, + "end": 1005, + "loc": { + "start": { + "line": 22, + "column": 30 + }, + "end": { + "line": 24, + "column": 2 + } + }, + "params": [ + { + "type": "TSIntersectionType", + "start": 935, + "end": 1002, + "loc": { + "start": { + "line": 23, + "column": 2 + }, + "end": { + "line": 23, + "column": 69 + } + }, + "types": [ + { + "type": "TSTypeReference", + "start": 935, + "end": 956, + "loc": { + "start": { + "line": 23, + "column": 2 + }, + "end": { + "line": 23, + "column": 23 + } + }, + "typeName": { + "type": "Identifier", + "start": 935, + "end": 956, + "loc": { + "start": { + "line": 23, + "column": 2 + }, + "end": { + "line": 23, + "column": 23 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "type": "TSTypeReference", + "start": 959, + "end": 979, + "loc": { + "start": { + "line": 23, + "column": 26 + }, + "end": { + "line": 23, + "column": 46 + } + }, + "typeName": { + "type": "Identifier", + "start": 959, + "end": 979, + "loc": { + "start": { + "line": 23, + "column": 26 + }, + "end": { + "line": 23, + "column": 46 + } + }, + "name": "BBBBBBBBBBBBBBBBBBBB" + } + }, + { + "type": "TSTypeReference", + "start": 982, + "end": 1002, + "loc": { + "start": { + "line": 23, + "column": 49 + }, + "end": { + "line": 23, + "column": 69 + } + }, + "typeName": { + "type": "Identifier", + "start": 982, + "end": 1002, + "loc": { + "start": { + "line": 23, + "column": 49 + }, + "end": { + "line": 23, + "column": 69 + } + }, + "name": "CCCCCCCCCCCCCCCCCCCC" + } + } + ] + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " 101 chars - does not fit, and an intersection is not huggable, so the `<...>` breaks", + "start": 813, + "end": 900 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1067, + "end": 1180, + "loc": { + "start": { + "line": 27, + "column": 1 + }, + "end": { + "line": 29, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1081, + "end": 1179, + "loc": { + "start": { + "line": 27, + "column": 15 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 1081, + "end": 1179, + "loc": { + "start": { + "line": 27, + "column": 15 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "name": "fnType", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 1087, + "end": 1179, + "loc": { + "start": { + "line": 27, + "column": 21 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 1089, + "end": 1179, + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "exprName": { + "type": "Identifier", + "start": 1096, + "end": 1098, + "loc": { + "start": { + "line": 27, + "column": 30 + }, + "end": { + "line": 27, + "column": 32 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 1098, + "end": 1179, + "loc": { + "start": { + "line": 27, + "column": 32 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "params": [ + { + "type": "TSFunctionType", + "start": 1102, + "end": 1176, + "loc": { + "start": { + "line": 28, + "column": 2 + }, + "end": { + "line": 28, + "column": 76 + } + }, + "parameters": [ + { + "type": "Identifier", + "start": 1103, + "end": 1159, + "loc": { + "start": { + "line": 28, + "column": 3 + }, + "end": { + "line": 28, + "column": 59 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 1133, + "end": 1159, + "loc": { + "start": { + "line": 28, + "column": 33 + }, + "end": { + "line": 28, + "column": 59 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 1135, + "end": 1159, + "loc": { + "start": { + "line": 28, + "column": 35 + }, + "end": { + "line": 28, + "column": 59 + } + }, + "typeName": { + "type": "Identifier", + "start": 1135, + "end": 1159, + "loc": { + "start": { + "line": 28, + "column": 35 + }, + "end": { + "line": 28, + "column": 59 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAA" + } + } + } + } + ], + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 1161, + "end": 1176, + "loc": { + "start": { + "line": 28, + "column": 61 + }, + "end": { + "line": 28, + "column": 76 + } + }, + "typeAnnotation": { + "type": "TSTypeReference", + "start": 1164, + "end": 1176, + "loc": { + "start": { + "line": 28, + "column": 64 + }, + "end": { + "line": 28, + "column": 76 + } + }, + "typeName": { + "type": "Identifier", + "start": 1164, + "end": 1176, + "loc": { + "start": { + "line": 28, + "column": 64 + }, + "end": { + "line": 28, + "column": 76 + } + }, + "name": "BBBBBBBBBBBB" + } + } + } + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A function type arg does not hug - the `<...>` breaks", + "start": 1009, + "end": 1065 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1244, + "end": 1358, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 34, + "column": 3 + } + }, + "declare": true, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1258, + "end": 1357, + "loc": { + "start": { + "line": 32, + "column": 15 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 1258, + "end": 1357, + "loc": { + "start": { + "line": 32, + "column": 15 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "name": "cond", + "typeAnnotation": { + "type": "TSTypeAnnotation", + "start": 1262, + "end": 1357, + "loc": { + "start": { + "line": 32, + "column": 19 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "typeAnnotation": { + "type": "TSTypeQuery", + "start": 1264, + "end": 1357, + "loc": { + "start": { + "line": 32, + "column": 21 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "exprName": { + "type": "Identifier", + "start": 1271, + "end": 1273, + "loc": { + "start": { + "line": 32, + "column": 28 + }, + "end": { + "line": 32, + "column": 30 + } + }, + "name": "fn" + }, + "typeArguments": { + "type": "TSTypeParameterInstantiation", + "start": 1273, + "end": 1357, + "loc": { + "start": { + "line": 32, + "column": 30 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "params": [ + { + "type": "TSConditionalType", + "start": 1277, + "end": 1354, + "loc": { + "start": { + "line": 33, + "column": 2 + }, + "end": { + "line": 33, + "column": 79 + } + }, + "checkType": { + "type": "TSTypeReference", + "start": 1277, + "end": 1301, + "loc": { + "start": { + "line": 33, + "column": 2 + }, + "end": { + "line": 33, + "column": 26 + } + }, + "typeName": { + "type": "Identifier", + "start": 1277, + "end": 1301, + "loc": { + "start": { + "line": 33, + "column": 2 + }, + "end": { + "line": 33, + "column": 26 + } + }, + "name": "AAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + "extendsType": { + "type": "TSTypeReference", + "start": 1310, + "end": 1326, + "loc": { + "start": { + "line": 33, + "column": 35 + }, + "end": { + "line": 33, + "column": 51 + } + }, + "typeName": { + "type": "Identifier", + "start": 1310, + "end": 1326, + "loc": { + "start": { + "line": 33, + "column": 35 + }, + "end": { + "line": 33, + "column": 51 + } + }, + "name": "BBBBBBBBBBBBBBBB" + } + }, + "trueType": { + "type": "TSTypeReference", + "start": 1329, + "end": 1341, + "loc": { + "start": { + "line": 33, + "column": 54 + }, + "end": { + "line": 33, + "column": 66 + } + }, + "typeName": { + "type": "Identifier", + "start": 1329, + "end": 1341, + "loc": { + "start": { + "line": 33, + "column": 54 + }, + "end": { + "line": 33, + "column": 66 + } + }, + "name": "CCCCCCCCCCCC" + } + }, + "falseType": { + "type": "TSTypeReference", + "start": 1344, + "end": 1354, + "loc": { + "start": { + "line": 33, + "column": 69 + }, + "end": { + "line": 33, + "column": 79 + } + }, + "typeName": { + "type": "Identifier", + "start": 1344, + "end": 1354, + "loc": { + "start": { + "line": 33, + "column": 69 + }, + "end": { + "line": 33, + "column": 79 + } + }, + "name": "DDDDDDDDDD" + } + } + } + ] + } + } + } + }, + "init": null + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " A conditional type arg does not hug - the `<...>` breaks", + "start": 1183, + "end": 1242 + } + ] + } + ], + "sourceType": "module" + }, + "attributes": [ + { + "type": "Attribute", + "start": 8, + "end": 17, + "name": "lang", + "name_loc": { + "start": { + "line": 1, + "column": 8, + "character": 8 + }, + "end": { + "line": 1, + "column": 12, + "character": 12 + } + }, + "value": [ + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "ts", + "data": "ts" + } + ] + } + ] + } +} diff --git a/tests/fixtures/typescript/types/type_argument_nonhug_long/input.svelte b/tests/fixtures/typescript/types/type_argument_nonhug_long/input.svelte new file mode 100644 index 00000000..767ca6e6 --- /dev/null +++ b/tests/fixtures/typescript/types/type_argument_nonhug_long/input.svelte @@ -0,0 +1,35 @@ + From e01decc32fe0dd8c74b03dc1bf6c9689e70dec36 Mon Sep 17 00:00:00 2001 From: Ryan Atkinson Date: Wed, 15 Jul 2026 16:39:14 -0400 Subject: [PATCH 2/2] refactor --- crates/tsv_ts/src/printer/expressions/conditional.rs | 7 +++++-- crates/tsv_ts/src/printer/expressions/mod.rs | 4 +--- .../src/printer/statements/control_flow/if_else.rs | 10 +++++----- .../statements/control_flow/loops/while_loop.rs | 10 +--------- .../src/printer/statements/control_flow/switch.rs | 11 +---------- 5 files changed, 13 insertions(+), 29 deletions(-) diff --git a/crates/tsv_ts/src/printer/expressions/conditional.rs b/crates/tsv_ts/src/printer/expressions/conditional.rs index 3c9b7065..507c8341 100644 --- a/crates/tsv_ts/src/printer/expressions/conditional.rs +++ b/crates/tsv_ts/src/printer/expressions/conditional.rs @@ -86,8 +86,11 @@ impl<'a> Printer<'a> { } } - /// Build a Doc for a conditional expression with wrapping support - pub(in crate::printer) fn build_conditional_doc_with_wrapping( + /// Build a Doc for a conditional expression — the default layout. + /// + /// The paired [`Self::build_conditional_doc_with_binary_test_indent`] is the same + /// thing with `indent_binary_test`, which is the only axis between them. + pub(in crate::printer) fn build_conditional_doc( &self, cond: &internal::ConditionalExpression<'_>, ) -> DocId { diff --git a/crates/tsv_ts/src/printer/expressions/mod.rs b/crates/tsv_ts/src/printer/expressions/mod.rs index 580c5cd0..1adec6b3 100644 --- a/crates/tsv_ts/src/printer/expressions/mod.rs +++ b/crates/tsv_ts/src/printer/expressions/mod.rs @@ -138,9 +138,7 @@ impl<'a> Printer<'a> { self.is_expression_statement.set(was_expr_stmt); self.build_member_doc(member) } - Expression::ConditionalExpression(cond) => { - self.build_conditional_doc_with_wrapping(cond) - } + Expression::ConditionalExpression(cond) => self.build_conditional_doc(cond), Expression::ArrowFunctionExpression(arrow) => self.build_arrow_doc(arrow), Expression::FunctionExpression(func) => { self.maybe_wrap_expr_stmt_paren(func.span, self.build_function_doc(func)) diff --git a/crates/tsv_ts/src/printer/statements/control_flow/if_else.rs b/crates/tsv_ts/src/printer/statements/control_flow/if_else.rs index 012f68d5..a54c2f5e 100644 --- a/crates/tsv_ts/src/printer/statements/control_flow/if_else.rs +++ b/crates/tsv_ts/src/printer/statements/control_flow/if_else.rs @@ -191,7 +191,7 @@ impl<'a> Printer<'a> { /// adjustClause(consequent), // body handling /// ]) /// ``` - fn build_if_statement_with_wrapping_doc(&self, stmt: &internal::IfStatement<'_>) -> DocId { + fn build_if_statement_plain_doc(&self, stmt: &internal::IfStatement<'_>) -> DocId { let d = self.d(); // Find paren positions for comment handling let open_paren = self.find_open_paren_after(stmt.span.start); @@ -288,19 +288,19 @@ impl<'a> Printer<'a> { self.has_comments_to_emit_between(consequent_end, alternate_start) }); + // A comment in the consequent→alternate gap is the only axis here; both paths + // group and wrap the condition identically. if has_if_else_comments { - // Build doc with inline comments between } and else self.build_if_statement_with_comments_doc(stmt) } else { - // Delegate to the sophisticated version that handles width-based wrapping - self.build_if_statement_with_wrapping_doc(stmt) + self.build_if_statement_plain_doc(stmt) } } /// Build if statement doc with comments between consequent and alternate fn build_if_statement_with_comments_doc(&self, stmt: &internal::IfStatement<'_>) -> DocId { let d = self.d(); - // Build condition group (same as build_if_statement_with_wrapping_doc) + // Build condition group (same as build_if_statement_plain_doc) let open_paren = self.find_open_paren_after(stmt.span.start); let close_paren = open_paren.and_then(|o| self.matching_close_paren(o)); let if_keyword_end = stmt.span.start + "if".len() as u32; diff --git a/crates/tsv_ts/src/printer/statements/control_flow/loops/while_loop.rs b/crates/tsv_ts/src/printer/statements/control_flow/loops/while_loop.rs index 508011b6..4703daf4 100644 --- a/crates/tsv_ts/src/printer/statements/control_flow/loops/while_loop.rs +++ b/crates/tsv_ts/src/printer/statements/control_flow/loops/while_loop.rs @@ -14,7 +14,7 @@ impl<'a> Printer<'a> { /// /// Matches Prettier's architecture: the condition wraps to multiple lines /// when the `while (condition)` line exceeds print width. - fn build_while_statement_with_wrapping_doc( + pub(in crate::printer::statements) fn build_while_statement_doc( &self, stmt: &internal::WhileStatement<'_>, ) -> DocId { @@ -74,14 +74,6 @@ impl<'a> Printer<'a> { } } - pub(in crate::printer::statements) fn build_while_statement_doc( - &self, - stmt: &internal::WhileStatement<'_>, - ) -> DocId { - // Delegate to the wrapping version for proper condition grouping - self.build_while_statement_with_wrapping_doc(stmt) - } - pub(in crate::printer::statements) fn build_do_while_statement_doc( &self, stmt: &internal::DoWhileStatement<'_>, diff --git a/crates/tsv_ts/src/printer/statements/control_flow/switch.rs b/crates/tsv_ts/src/printer/statements/control_flow/switch.rs index ed5ab4cd..42113a38 100644 --- a/crates/tsv_ts/src/printer/statements/control_flow/switch.rs +++ b/crates/tsv_ts/src/printer/statements/control_flow/switch.rs @@ -15,7 +15,7 @@ impl<'a> Printer<'a> { /// /// Matches Prettier's architecture: the discriminant wraps to multiple lines /// when the `switch (discriminant) {` line exceeds print width. - fn build_switch_statement_with_wrapping_doc( + pub(in crate::printer::statements) fn build_switch_statement_doc( &self, stmt: &internal::SwitchStatement<'_>, ) -> DocId { @@ -409,13 +409,4 @@ impl<'a> Printer<'a> { d.concat(&parts) } - - #[inline] - pub(in crate::printer::statements) fn build_switch_statement_doc( - &self, - stmt: &internal::SwitchStatement<'_>, - ) -> DocId { - // Delegate to the wrapping version which handles proper indentation structure - self.build_switch_statement_with_wrapping_doc(stmt) - } }