From 41bcd55978f6ec28a612643db9b4a94635b4da6f Mon Sep 17 00:00:00 2001 From: Ryan Atkinson Date: Wed, 5 Aug 2026 00:32:19 -0400 Subject: [PATCH] fix: keep the first call's argument hug in short chains --- benches/js/diagnostics/corpus_stats.ts | 7 +- .../src/printer/calls/arg_predicates.rs | 118 - .../tsv_ts/src/printer/chain/builder/mod.rs | 47 +- .../expected.json | 1971 +++++++++++++++++ .../input.svelte | 22 + .../unformatted_flat.svelte | 15 + .../expected.json | 863 ++++++++ .../input.svelte | 18 + .../unformatted_compact.svelte | 9 + .../expected.json | 627 +++++- .../input.svelte | 14 + .../unformatted_compact.svelte | 7 + 12 files changed, 3553 insertions(+), 165 deletions(-) create mode 100644 tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/expected.json create mode 100644 tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/input.svelte create mode 100644 tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/unformatted_flat.svelte create mode 100644 tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/expected.json create mode 100644 tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/input.svelte create mode 100644 tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/unformatted_compact.svelte diff --git a/benches/js/diagnostics/corpus_stats.ts b/benches/js/diagnostics/corpus_stats.ts index 05b41eabd..8fe94c278 100644 --- a/benches/js/diagnostics/corpus_stats.ts +++ b/benches/js/diagnostics/corpus_stats.ts @@ -234,9 +234,10 @@ function main(): void { if (files.length === 0) throw new Error(`No in-scope files found for ${title}`); const overall = stats_of(files); - const per_lang = LANGUAGES.map( - (l) => ({ language: l, stats: stats_of(files.filter((f) => f.language === l)) }) - ).filter((r) => r.stats.files > 0); + const per_lang = LANGUAGES.map((l) => ({ + language: l, + stats: stats_of(files.filter((f) => f.language === l)) + })).filter((r) => r.stats.files > 0); const groups = dir ? [] : group_by_entry(files, entry_paths); const conc = dir ? concentration(files, root, largest_n) : []; const big_files = files.filter((f) => f.bytes > big).sort((a, b) => b.bytes - a.bytes); diff --git a/crates/tsv_ts/src/printer/calls/arg_predicates.rs b/crates/tsv_ts/src/printer/calls/arg_predicates.rs index 9b31f9277..32e1ee596 100644 --- a/crates/tsv_ts/src/printer/calls/arg_predicates.rs +++ b/crates/tsv_ts/src/printer/calls/arg_predicates.rs @@ -396,109 +396,6 @@ pub fn is_simple_call_argument(expr: &Expression<'_>, depth: usize) -> bool { } } -/// Check if an expression contains a call expression with arguments (recursively). -/// -/// Used to determine if a chain's first call has an argument that may need to -/// break independently. When the first call's arg contains a call WITH arguments, -/// that inner call might break, so we let each group format independently rather -/// than forcing expansion on the last call. -/// -/// Empty calls like `a.b()` don't count because they won't break. -pub fn contains_call_expression(expr: &Expression<'_>) -> bool { - match expr { - // A call with arguments might break - return true - // Empty calls (no args) won't break - continue checking inside - Expression::CallExpression(call) => { - !call.arguments.is_empty() || contains_call_expression(call.callee) - } - Expression::NewExpression(new_expr) => { - !new_expr.arguments.is_empty() || contains_call_expression(new_expr.callee) - } - - // Recurse into common wrapper types - Expression::MemberExpression(member) => { - contains_call_expression(member.object) - || (member.computed && contains_call_expression(member.property)) - } - Expression::TSAsExpression(e) => contains_call_expression(e.expression), - Expression::TSSatisfiesExpression(e) => contains_call_expression(e.expression), - Expression::TSTypeAssertion(e) => contains_call_expression(e.expression), - Expression::TSNonNullExpression(e) => contains_call_expression(e.expression), - Expression::TSInstantiationExpression(e) => contains_call_expression(e.expression), - Expression::AwaitExpression(e) => contains_call_expression(e.argument), - Expression::UnaryExpression(e) => contains_call_expression(e.argument), - Expression::UpdateExpression(e) => contains_call_expression(e.argument), - Expression::SpreadElement(e) => contains_call_expression(e.argument), - Expression::JsdocCast(cast) => contains_call_expression(cast.inner), - Expression::ParenthesizedExpression(paren) => contains_call_expression(paren.expression), - - // Binary expressions (includes logical operators in internal AST) - Expression::BinaryExpression(e) => { - contains_call_expression(e.left) || contains_call_expression(e.right) - } - Expression::AssignmentExpression(e) => { - contains_call_expression(e.left) || contains_call_expression(e.right) - } - - // Conditional expression - Expression::ConditionalExpression(e) => { - contains_call_expression(e.test) - || contains_call_expression(e.consequent) - || contains_call_expression(e.alternate) - } - - // Sequence expression - Expression::SequenceExpression(e) => e.expressions.iter().any(contains_call_expression), - - // Template literal expressions - Expression::TemplateLiteral(t) => t.expressions.iter().any(contains_call_expression), - Expression::TaggedTemplateExpression(t) => { - contains_call_expression(t.tag) - || t.quasi.expressions.iter().any(contains_call_expression) - } - - // Array/object literals - Expression::ArrayExpression(arr) => arr - .elements - .iter() - .any(|el| el.as_ref().is_some_and(contains_call_expression)), - Expression::ObjectExpression(obj) => obj.properties.iter().any(|prop| match prop { - internal::ObjectProperty::Property(p) => { - (p.computed && contains_call_expression(&p.key)) - || contains_call_expression(&p.value) - } - internal::ObjectProperty::SpreadElement(s) => contains_call_expression(s.argument), - }), - - // Arrow/function expressions - check body for expression arrows - Expression::ArrowFunctionExpression(arr) => { - if let internal::ArrowFunctionBody::Expression(body) = &arr.body { - contains_call_expression(body) - } else { - false - } - } - - // Simple expressions that don't contain calls - Expression::Identifier(_) - | Expression::Literal(_) - | Expression::RegexLiteral(_) - | Expression::ThisExpression(_) - | Expression::Super(_) - | Expression::MetaProperty(_) - | Expression::FunctionExpression(_) - | Expression::ClassExpression(_) - | Expression::YieldExpression(_) - | Expression::ImportExpression(_) - | Expression::ArrayPattern(_) - | Expression::ObjectPattern(_) - | Expression::AssignmentPattern(_) - | Expression::RestElement(_) - | Expression::PrivateIdentifier(_) - | Expression::TSParameterProperty(_) => false, - } -} - /// Check if arguments form a "function composition" pattern that forces expansion. /// /// Matches Prettier's `isFunctionCompositionArgs` logic: @@ -594,21 +491,6 @@ mod tests { assert!(!is_simple_call_argument(&parse_expr(&arena, "[...x]"), 2)); } - #[test] - fn contains_call_expression_recursion() { - let arena = Bump::new(); - // An empty call does not count, but we recurse into the callee. - assert!(!contains_call_expression(&parse_expr(&arena, "a.b()"))); - // A call WITH arguments counts. - assert!(contains_call_expression(&parse_expr(&arena, "a.b(x)"))); - // Recurse through a binary expression. - assert!(contains_call_expression(&parse_expr(&arena, "a + f(x)"))); - // A computed member recurses into the property. - assert!(contains_call_expression(&parse_expr(&arena, "a[f(x)]"))); - // No call anywhere. - assert!(!contains_call_expression(&parse_expr(&arena, "a + b"))); - } - #[test] fn function_composition_args_detection() { let arena = Bump::new(); diff --git a/crates/tsv_ts/src/printer/chain/builder/mod.rs b/crates/tsv_ts/src/printer/chain/builder/mod.rs index 5a1064c8c..3e31e5057 100644 --- a/crates/tsv_ts/src/printer/chain/builder/mod.rs +++ b/crates/tsv_ts/src/printer/chain/builder/mod.rs @@ -35,7 +35,6 @@ use super::printing::{ use super::types::{ChainGroup, ChainNode, ChainNodeRefVec}; use crate::ast::internal::Expression; use crate::printer::Printer; -use crate::printer::calls::arg_predicates::contains_call_expression; use smallvec::smallvec; use tsv_lang::Span; use tsv_lang::doc::{DocBuf, arena::DocId}; @@ -360,19 +359,6 @@ fn build_short_chain_doc<'a>( ); } - // Check if chain ends with member (for callback arg breaking preference) - let chain_ends_with_member = ends_with_member(rest_groups, first_groups); - - // When chain ends with member and first groups have calls, prefer expanding - // first groups' call args over breaking the chain. - if first_has_calls && chain_ends_with_member { - let first_expanded_doc = build_first_groups_expanded_doc(first_groups, printer); - let mut state_first_expanded_parts: DocBuf = smallvec![first_expanded_doc]; - state_first_expanded_parts.extend(rest_docs.iter().copied()); - let state_first_expanded = d.concat(&state_first_expanded_parts); - return d.conditional_group(&[on_line, state_first_expanded]); - } - // Prettier's short chain behavior (member-chain.js lines 351-360): // For chains with groups.length <= cutoff, just return group(oneLine). if !first_has_calls { @@ -412,32 +398,13 @@ fn build_short_chain_doc<'a>( return d.group(on_line); } - // Check for nested calls in first call's args - let first_call_arg_contains_call = first_groups - .iter() - .flat_map(|g| g.nodes.iter()) - .filter_map(ChainNode::as_call_expression) - .any(|call| call.arguments.iter().any(contains_call_expression)); - - if !first_call_arg_contains_call { - // Prettier: group(printedGroups.flat()) for short chains (member-chain.js:351-359). - // group() lets hardlines in the first call (e.g., multiline array) render - // naturally while the second call's inner group handles its own arg layout. - return d.group(on_line); - } - - // When first call's arg contains calls, try both expansion directions - let rest_expanded = build_rest_expanded_docs(rest_groups, printer); - let mut state_last_expanded_parts: DocBuf = smallvec![first_doc]; - state_last_expanded_parts.extend(rest_expanded); - let state_last_expanded = d.concat(&state_last_expanded_parts); - - let first_expanded_doc = build_first_groups_expanded_doc(first_groups, printer); - let mut state_first_expanded_parts: DocBuf = smallvec![first_expanded_doc]; - state_first_expanded_parts.extend(rest_docs.iter().copied()); - let state_first_expanded = d.concat(&state_first_expanded_parts); - - d.conditional_group(&[on_line, state_last_expanded, state_first_expanded]) + // Prettier: group(printedGroups.flat()) for short chains (member-chain.js:351-359). + // group() lets hardlines in the first call (e.g., multiline array) render + // naturally while each call's inner args group handles its own layout — including + // the last-argument hug of a first call whose argument breaks (`X.map((x) => ({`). + // A chain-level conditional_group here would measure the whole line flat and + // pre-empt that inner hug, force-expanding the first call's argument list instead. + d.group(on_line) } /// Whether the chain is `base_call(args).a.b...` — a bare base call followed by ONLY diff --git a/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/expected.json b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/expected.json new file mode 100644 index 000000000..63f576563 --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/expected.json @@ -0,0 +1,1971 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 812, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " 100 visual on the flat line - whole chain stays inline", + "start": 38, + "end": 95, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 59 + } + } + }, + { + "type": "Line", + "value": " 101 visual flat - the last call's args expand, the head stays merged and flat", + "start": 198, + "end": 278, + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 82 + } + } + }, + { + "type": "Line", + "value": " head segment through `.filter(` at exactly 100 - the last-call expansion still fits", + "start": 389, + "end": 475, + "loc": { + "start": { + "line": 11, + "column": 2 + }, + "end": { + "line": 11, + "column": 88 + } + } + }, + { + "type": "Line", + "value": " head segment through `.filter(` at 101 - the object hugs the callback parens instead", + "start": 594, + "end": 681, + "loc": { + "start": { + "line": 16, + "column": 2 + }, + "end": { + "line": 16, + "column": 89 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 811, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 802, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 22, + "column": 9 + } + }, + "body": [ + { + "type": "FunctionDeclaration", + "start": 20, + "end": 801, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 29, + "end": 31, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "name": "fn" + }, + "expression": false, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 34, + "end": 801, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 98, + "end": 194, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 98 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 104, + "end": 193, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 97 + } + }, + "id": { + "type": "Identifier", + "start": 104, + "end": 105, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 9 + } + }, + "name": "a" + }, + "init": { + "type": "CallExpression", + "start": 108, + "end": 193, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 97 + } + }, + "callee": { + "type": "MemberExpression", + "start": 108, + "end": 184, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 88 + } + }, + "object": { + "type": "CallExpression", + "start": 108, + "end": 177, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 81 + } + }, + "callee": { + "type": "MemberExpression", + "start": 108, + "end": 117, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 108, + "end": 113, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 17 + } + }, + "name": "Items" + }, + "property": { + "type": "Identifier", + "start": 114, + "end": 117, + "loc": { + "start": { + "line": 4, + "column": 18 + }, + "end": { + "line": 4, + "column": 21 + } + }, + "name": "map" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 118, + "end": 176, + "loc": { + "start": { + "line": 4, + "column": 22 + }, + "end": { + "line": 4, + "column": 80 + } + }, + "id": null, + "expression": true, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 119, + "end": 120, + "loc": { + "start": { + "line": 4, + "column": 23 + }, + "end": { + "line": 4, + "column": 24 + } + }, + "name": "x" + } + ], + "body": { + "type": "ObjectExpression", + "start": 126, + "end": 175, + "loc": { + "start": { + "line": 4, + "column": 30 + }, + "end": { + "line": 4, + "column": 79 + } + }, + "properties": [ + { + "type": "Property", + "start": 128, + "end": 134, + "loc": { + "start": { + "line": 4, + "column": 32 + }, + "end": { + "line": 4, + "column": 38 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 128, + "end": 129, + "loc": { + "start": { + "line": 4, + "column": 32 + }, + "end": { + "line": 4, + "column": 33 + } + }, + "name": "a" + }, + "value": { + "type": "MemberExpression", + "start": 131, + "end": 134, + "loc": { + "start": { + "line": 4, + "column": 35 + }, + "end": { + "line": 4, + "column": 38 + } + }, + "object": { + "type": "Identifier", + "start": 131, + "end": 132, + "loc": { + "start": { + "line": 4, + "column": 35 + }, + "end": { + "line": 4, + "column": 36 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 133, + "end": 134, + "loc": { + "start": { + "line": 4, + "column": 37 + }, + "end": { + "line": 4, + "column": 38 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + }, + "kind": "init" + }, + { + "type": "Property", + "start": 136, + "end": 173, + "loc": { + "start": { + "line": 4, + "column": 40 + }, + "end": { + "line": 4, + "column": 77 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 136, + "end": 137, + "loc": { + "start": { + "line": 4, + "column": 40 + }, + "end": { + "line": 4, + "column": 41 + } + }, + "name": "b" + }, + "value": { + "type": "CallExpression", + "start": 139, + "end": 173, + "loc": { + "start": { + "line": 4, + "column": 43 + }, + "end": { + "line": 4, + "column": 77 + } + }, + "callee": { + "type": "Identifier", + "start": 139, + "end": 142, + "loc": { + "start": { + "line": 4, + "column": 43 + }, + "end": { + "line": 4, + "column": 46 + } + }, + "name": "fn1" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 143, + "end": 172, + "loc": { + "start": { + "line": 4, + "column": 47 + }, + "end": { + "line": 4, + "column": 76 + } + }, + "object": { + "type": "Identifier", + "start": 143, + "end": 144, + "loc": { + "start": { + "line": 4, + "column": 47 + }, + "end": { + "line": 4, + "column": 48 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 145, + "end": 172, + "loc": { + "start": { + "line": 4, + "column": 49 + }, + "end": { + "line": 4, + "column": 76 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "computed": false, + "optional": false + } + ], + "optional": false + }, + "kind": "init" + } + ] + } + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 178, + "end": 184, + "loc": { + "start": { + "line": 4, + "column": 82 + }, + "end": { + "line": 4, + "column": 88 + } + }, + "name": "filter" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 185, + "end": 192, + "loc": { + "start": { + "line": 4, + "column": 89 + }, + "end": { + "line": 4, + "column": 96 + } + }, + "name": "Boolean" + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " 100 visual on the flat line - whole chain stays inline", + "start": 38, + "end": 95 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 281, + "end": 385, + "loc": { + "start": { + "line": 7, + "column": 2 + }, + "end": { + "line": 9, + "column": 4 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 287, + "end": 384, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 9, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 287, + "end": 288, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 9 + } + }, + "name": "b" + }, + "init": { + "type": "CallExpression", + "start": 291, + "end": 384, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 9, + "column": 3 + } + }, + "callee": { + "type": "MemberExpression", + "start": 291, + "end": 368, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 7, + "column": 89 + } + }, + "object": { + "type": "CallExpression", + "start": 291, + "end": 361, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 7, + "column": 82 + } + }, + "callee": { + "type": "MemberExpression", + "start": 291, + "end": 300, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 7, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 291, + "end": 296, + "loc": { + "start": { + "line": 7, + "column": 12 + }, + "end": { + "line": 7, + "column": 17 + } + }, + "name": "Items" + }, + "property": { + "type": "Identifier", + "start": 297, + "end": 300, + "loc": { + "start": { + "line": 7, + "column": 18 + }, + "end": { + "line": 7, + "column": 21 + } + }, + "name": "map" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 301, + "end": 360, + "loc": { + "start": { + "line": 7, + "column": 22 + }, + "end": { + "line": 7, + "column": 81 + } + }, + "id": null, + "expression": true, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 302, + "end": 303, + "loc": { + "start": { + "line": 7, + "column": 23 + }, + "end": { + "line": 7, + "column": 24 + } + }, + "name": "x" + } + ], + "body": { + "type": "ObjectExpression", + "start": 309, + "end": 359, + "loc": { + "start": { + "line": 7, + "column": 30 + }, + "end": { + "line": 7, + "column": 80 + } + }, + "properties": [ + { + "type": "Property", + "start": 311, + "end": 317, + "loc": { + "start": { + "line": 7, + "column": 32 + }, + "end": { + "line": 7, + "column": 38 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 311, + "end": 312, + "loc": { + "start": { + "line": 7, + "column": 32 + }, + "end": { + "line": 7, + "column": 33 + } + }, + "name": "a" + }, + "value": { + "type": "MemberExpression", + "start": 314, + "end": 317, + "loc": { + "start": { + "line": 7, + "column": 35 + }, + "end": { + "line": 7, + "column": 38 + } + }, + "object": { + "type": "Identifier", + "start": 314, + "end": 315, + "loc": { + "start": { + "line": 7, + "column": 35 + }, + "end": { + "line": 7, + "column": 36 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 316, + "end": 317, + "loc": { + "start": { + "line": 7, + "column": 37 + }, + "end": { + "line": 7, + "column": 38 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + }, + "kind": "init" + }, + { + "type": "Property", + "start": 319, + "end": 357, + "loc": { + "start": { + "line": 7, + "column": 40 + }, + "end": { + "line": 7, + "column": 78 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 319, + "end": 320, + "loc": { + "start": { + "line": 7, + "column": 40 + }, + "end": { + "line": 7, + "column": 41 + } + }, + "name": "b" + }, + "value": { + "type": "CallExpression", + "start": 322, + "end": 357, + "loc": { + "start": { + "line": 7, + "column": 43 + }, + "end": { + "line": 7, + "column": 78 + } + }, + "callee": { + "type": "Identifier", + "start": 322, + "end": 325, + "loc": { + "start": { + "line": 7, + "column": 43 + }, + "end": { + "line": 7, + "column": 46 + } + }, + "name": "fn1" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 326, + "end": 356, + "loc": { + "start": { + "line": 7, + "column": 47 + }, + "end": { + "line": 7, + "column": 77 + } + }, + "object": { + "type": "Identifier", + "start": 326, + "end": 327, + "loc": { + "start": { + "line": 7, + "column": 47 + }, + "end": { + "line": 7, + "column": 48 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 328, + "end": 356, + "loc": { + "start": { + "line": 7, + "column": 49 + }, + "end": { + "line": 7, + "column": 77 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "computed": false, + "optional": false + } + ], + "optional": false + }, + "kind": "init" + } + ] + } + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 362, + "end": 368, + "loc": { + "start": { + "line": 7, + "column": 83 + }, + "end": { + "line": 7, + "column": 89 + } + }, + "name": "filter" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 373, + "end": 380, + "loc": { + "start": { + "line": 8, + "column": 3 + }, + "end": { + "line": 8, + "column": 10 + } + }, + "name": "Boolean" + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " 101 visual flat - the last call's args expand, the head stays merged and flat", + "start": 198, + "end": 278 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 478, + "end": 590, + "loc": { + "start": { + "line": 12, + "column": 2 + }, + "end": { + "line": 14, + "column": 4 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 484, + "end": 589, + "loc": { + "start": { + "line": 12, + "column": 8 + }, + "end": { + "line": 14, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 484, + "end": 485, + "loc": { + "start": { + "line": 12, + "column": 8 + }, + "end": { + "line": 12, + "column": 9 + } + }, + "name": "c" + }, + "init": { + "type": "CallExpression", + "start": 488, + "end": 589, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 14, + "column": 3 + } + }, + "callee": { + "type": "MemberExpression", + "start": 488, + "end": 573, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 12, + "column": 97 + } + }, + "object": { + "type": "CallExpression", + "start": 488, + "end": 566, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 12, + "column": 90 + } + }, + "callee": { + "type": "MemberExpression", + "start": 488, + "end": 497, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 12, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 488, + "end": 493, + "loc": { + "start": { + "line": 12, + "column": 12 + }, + "end": { + "line": 12, + "column": 17 + } + }, + "name": "Items" + }, + "property": { + "type": "Identifier", + "start": 494, + "end": 497, + "loc": { + "start": { + "line": 12, + "column": 18 + }, + "end": { + "line": 12, + "column": 21 + } + }, + "name": "map" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 498, + "end": 565, + "loc": { + "start": { + "line": 12, + "column": 22 + }, + "end": { + "line": 12, + "column": 89 + } + }, + "id": null, + "expression": true, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 499, + "end": 500, + "loc": { + "start": { + "line": 12, + "column": 23 + }, + "end": { + "line": 12, + "column": 24 + } + }, + "name": "x" + } + ], + "body": { + "type": "ObjectExpression", + "start": 506, + "end": 564, + "loc": { + "start": { + "line": 12, + "column": 30 + }, + "end": { + "line": 12, + "column": 88 + } + }, + "properties": [ + { + "type": "Property", + "start": 508, + "end": 514, + "loc": { + "start": { + "line": 12, + "column": 32 + }, + "end": { + "line": 12, + "column": 38 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 508, + "end": 509, + "loc": { + "start": { + "line": 12, + "column": 32 + }, + "end": { + "line": 12, + "column": 33 + } + }, + "name": "a" + }, + "value": { + "type": "MemberExpression", + "start": 511, + "end": 514, + "loc": { + "start": { + "line": 12, + "column": 35 + }, + "end": { + "line": 12, + "column": 38 + } + }, + "object": { + "type": "Identifier", + "start": 511, + "end": 512, + "loc": { + "start": { + "line": 12, + "column": 35 + }, + "end": { + "line": 12, + "column": 36 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 513, + "end": 514, + "loc": { + "start": { + "line": 12, + "column": 37 + }, + "end": { + "line": 12, + "column": 38 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + }, + "kind": "init" + }, + { + "type": "Property", + "start": 516, + "end": 562, + "loc": { + "start": { + "line": 12, + "column": 40 + }, + "end": { + "line": 12, + "column": 86 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 516, + "end": 517, + "loc": { + "start": { + "line": 12, + "column": 40 + }, + "end": { + "line": 12, + "column": 41 + } + }, + "name": "b" + }, + "value": { + "type": "CallExpression", + "start": 519, + "end": 562, + "loc": { + "start": { + "line": 12, + "column": 43 + }, + "end": { + "line": 12, + "column": 86 + } + }, + "callee": { + "type": "Identifier", + "start": 519, + "end": 522, + "loc": { + "start": { + "line": 12, + "column": 43 + }, + "end": { + "line": 12, + "column": 46 + } + }, + "name": "fn1" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 523, + "end": 561, + "loc": { + "start": { + "line": 12, + "column": 47 + }, + "end": { + "line": 12, + "column": 85 + } + }, + "object": { + "type": "Identifier", + "start": 523, + "end": 524, + "loc": { + "start": { + "line": 12, + "column": 47 + }, + "end": { + "line": 12, + "column": 48 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 525, + "end": 561, + "loc": { + "start": { + "line": 12, + "column": 49 + }, + "end": { + "line": 12, + "column": 85 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "computed": false, + "optional": false + } + ], + "optional": false + }, + "kind": "init" + } + ] + } + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 567, + "end": 573, + "loc": { + "start": { + "line": 12, + "column": 91 + }, + "end": { + "line": 12, + "column": 97 + } + }, + "name": "filter" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 578, + "end": 585, + "loc": { + "start": { + "line": 13, + "column": 3 + }, + "end": { + "line": 13, + "column": 10 + } + }, + "name": "Boolean" + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " head segment through `.filter(` at exactly 100 - the last-call expansion still fits", + "start": 389, + "end": 475 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 684, + "end": 798, + "loc": { + "start": { + "line": 17, + "column": 2 + }, + "end": { + "line": 20, + "column": 22 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 690, + "end": 797, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 20, + "column": 21 + } + }, + "id": { + "type": "Identifier", + "start": 690, + "end": 691, + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 9 + } + }, + "name": "d" + }, + "init": { + "type": "CallExpression", + "start": 694, + "end": 797, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 20, + "column": 21 + } + }, + "callee": { + "type": "MemberExpression", + "start": 694, + "end": 788, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 20, + "column": 12 + } + }, + "object": { + "type": "CallExpression", + "start": 694, + "end": 781, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 20, + "column": 5 + } + }, + "callee": { + "type": "MemberExpression", + "start": 694, + "end": 703, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 694, + "end": 699, + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 17, + "column": 17 + } + }, + "name": "Items" + }, + "property": { + "type": "Identifier", + "start": 700, + "end": 703, + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 21 + } + }, + "name": "map" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 704, + "end": 780, + "loc": { + "start": { + "line": 17, + "column": 22 + }, + "end": { + "line": 20, + "column": 4 + } + }, + "id": null, + "expression": true, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 705, + "end": 706, + "loc": { + "start": { + "line": 17, + "column": 23 + }, + "end": { + "line": 17, + "column": 24 + } + }, + "name": "x" + } + ], + "body": { + "type": "ObjectExpression", + "start": 712, + "end": 779, + "loc": { + "start": { + "line": 17, + "column": 30 + }, + "end": { + "line": 20, + "column": 3 + } + }, + "properties": [ + { + "type": "Property", + "start": 717, + "end": 723, + "loc": { + "start": { + "line": 18, + "column": 3 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 717, + "end": 718, + "loc": { + "start": { + "line": 18, + "column": 3 + }, + "end": { + "line": 18, + "column": 4 + } + }, + "name": "a" + }, + "value": { + "type": "MemberExpression", + "start": 720, + "end": 723, + "loc": { + "start": { + "line": 18, + "column": 6 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "object": { + "type": "Identifier", + "start": 720, + "end": 721, + "loc": { + "start": { + "line": 18, + "column": 6 + }, + "end": { + "line": 18, + "column": 7 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 722, + "end": 723, + "loc": { + "start": { + "line": 18, + "column": 8 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "name": "a" + }, + "computed": false, + "optional": false + }, + "kind": "init" + }, + { + "type": "Property", + "start": 728, + "end": 775, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 50 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 728, + "end": 729, + "loc": { + "start": { + "line": 19, + "column": 3 + }, + "end": { + "line": 19, + "column": 4 + } + }, + "name": "b" + }, + "value": { + "type": "CallExpression", + "start": 731, + "end": 775, + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 19, + "column": 50 + } + }, + "callee": { + "type": "Identifier", + "start": 731, + "end": 734, + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 19, + "column": 9 + } + }, + "name": "fn1" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 735, + "end": 774, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 49 + } + }, + "object": { + "type": "Identifier", + "start": 735, + "end": 736, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 11 + } + }, + "name": "x" + }, + "property": { + "type": "Identifier", + "start": 737, + "end": 774, + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 49 + } + }, + "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + "computed": false, + "optional": false + } + ], + "optional": false + }, + "kind": "init" + } + ] + } + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 782, + "end": 788, + "loc": { + "start": { + "line": 20, + "column": 6 + }, + "end": { + "line": 20, + "column": 12 + } + }, + "name": "filter" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 789, + "end": 796, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 20, + "column": 20 + } + }, + "name": "Boolean" + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " head segment through `.filter(` at 101 - the object hugs the callback parens instead", + "start": 594, + "end": 681 + } + ] + } + ] + } + } + ], + "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/expressions/calls/chained/merged_head_object_return_trailing_call_long/input.svelte b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/input.svelte new file mode 100644 index 000000000..df9027727 --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/input.svelte @@ -0,0 +1,22 @@ + diff --git a/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/unformatted_flat.svelte b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/unformatted_flat.svelte new file mode 100644 index 000000000..64d5d3c9e --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/merged_head_object_return_trailing_call_long/unformatted_flat.svelte @@ -0,0 +1,15 @@ + diff --git a/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/expected.json b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/expected.json new file mode 100644 index 000000000..abdaf6688 --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/expected.json @@ -0,0 +1,863 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 384, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [] + }, + "options": null, + "comments": [ + { + "type": "Line", + "value": " source-multiline object head arg stays broken, so ALL args break out -", + "start": 20, + "end": 93, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 74 + } + } + }, + { + "type": "Line", + "value": " the hug states can't hold a head arg that already breaks", + "start": 95, + "end": 154, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 60 + } + } + }, + { + "type": "Line", + "value": " contrast: a flat object head arg stays inline and the block arrow hugs", + "start": 240, + "end": 313, + "loc": { + "start": { + "line": 14, + "column": 1 + }, + "end": { + "line": 14, + "column": 74 + } + } + } + ], + "instance": { + "type": "Script", + "start": 0, + "end": 383, + "context": "default", + "content": { + "type": "Program", + "start": 18, + "end": 374, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 18, + "column": 9 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 156, + "end": 237, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 12, + "column": 3 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 162, + "end": 236, + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 12, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 162, + "end": 163, + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 4, + "column": 8 + } + }, + "name": "a" + }, + "init": { + "type": "CallExpression", + "start": 166, + "end": 236, + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 12, + "column": 2 + } + }, + "callee": { + "type": "MemberExpression", + "start": 166, + "end": 178, + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 23 + } + }, + "object": { + "type": "CallExpression", + "start": 166, + "end": 175, + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 20 + } + }, + "callee": { + "type": "MemberExpression", + "start": 166, + "end": 172, + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 166, + "end": 169, + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 14 + } + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 170, + "end": 172, + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 17 + } + }, + "name": "aa" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 173, + "end": 174, + "loc": { + "start": { + "line": 4, + "column": 18 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "name": "x" + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 176, + "end": 178, + "loc": { + "start": { + "line": 4, + "column": 21 + }, + "end": { + "line": 4, + "column": 23 + } + }, + "name": "bb" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ObjectExpression", + "start": 182, + "end": 204, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 8, + "column": 3 + } + }, + "properties": [ + { + "type": "Property", + "start": 187, + "end": 191, + "loc": { + "start": { + "line": 6, + "column": 3 + }, + "end": { + "line": 6, + "column": 7 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 187, + "end": 188, + "loc": { + "start": { + "line": 6, + "column": 3 + }, + "end": { + "line": 6, + "column": 4 + } + }, + "name": "a" + }, + "value": { + "type": "Literal", + "start": 190, + "end": 191, + "loc": { + "start": { + "line": 6, + "column": 6 + }, + "end": { + "line": 6, + "column": 7 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + }, + { + "type": "Property", + "start": 196, + "end": 200, + "loc": { + "start": { + "line": 7, + "column": 3 + }, + "end": { + "line": 7, + "column": 7 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 196, + "end": 197, + "loc": { + "start": { + "line": 7, + "column": 3 + }, + "end": { + "line": 7, + "column": 4 + } + }, + "name": "b" + }, + "value": { + "type": "Literal", + "start": 199, + "end": 200, + "loc": { + "start": { + "line": 7, + "column": 6 + }, + "end": { + "line": 7, + "column": 7 + } + }, + "value": 2, + "raw": "2" + }, + "kind": "init" + } + ] + }, + { + "type": "ArrowFunctionExpression", + "start": 208, + "end": 233, + "loc": { + "start": { + "line": 9, + "column": 2 + }, + "end": { + "line": 11, + "column": 3 + } + }, + "id": null, + "expression": false, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 209, + "end": 210, + "loc": { + "start": { + "line": 9, + "column": 3 + }, + "end": { + "line": 9, + "column": 4 + } + }, + "name": "y" + } + ], + "body": { + "type": "BlockStatement", + "start": 215, + "end": 233, + "loc": { + "start": { + "line": 9, + "column": 9 + }, + "end": { + "line": 11, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 220, + "end": 229, + "loc": { + "start": { + "line": 10, + "column": 3 + }, + "end": { + "line": 10, + "column": 12 + } + }, + "argument": { + "type": "Identifier", + "start": 227, + "end": 228, + "loc": { + "start": { + "line": 10, + "column": 10 + }, + "end": { + "line": 10, + "column": 11 + } + }, + "name": "y" + } + } + ] + } + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " source-multiline object head arg stays broken, so ALL args break out -", + "start": 20, + "end": 93 + }, + { + "type": "Line", + "value": " the hug states can't hold a head arg that already breaks", + "start": 95, + "end": 154 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 315, + "end": 373, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 17, + "column": 4 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 321, + "end": 372, + "loc": { + "start": { + "line": 15, + "column": 7 + }, + "end": { + "line": 17, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 321, + "end": 322, + "loc": { + "start": { + "line": 15, + "column": 7 + }, + "end": { + "line": 15, + "column": 8 + } + }, + "name": "b" + }, + "init": { + "type": "CallExpression", + "start": 325, + "end": 372, + "loc": { + "start": { + "line": 15, + "column": 11 + }, + "end": { + "line": 17, + "column": 3 + } + }, + "callee": { + "type": "MemberExpression", + "start": 325, + "end": 337, + "loc": { + "start": { + "line": 15, + "column": 11 + }, + "end": { + "line": 15, + "column": 23 + } + }, + "object": { + "type": "CallExpression", + "start": 325, + "end": 334, + "loc": { + "start": { + "line": 15, + "column": 11 + }, + "end": { + "line": 15, + "column": 20 + } + }, + "callee": { + "type": "MemberExpression", + "start": 325, + "end": 331, + "loc": { + "start": { + "line": 15, + "column": 11 + }, + "end": { + "line": 15, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 325, + "end": 328, + "loc": { + "start": { + "line": 15, + "column": 11 + }, + "end": { + "line": 15, + "column": 14 + } + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 329, + "end": 331, + "loc": { + "start": { + "line": 15, + "column": 15 + }, + "end": { + "line": 15, + "column": 17 + } + }, + "name": "aa" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 332, + "end": 333, + "loc": { + "start": { + "line": 15, + "column": 18 + }, + "end": { + "line": 15, + "column": 19 + } + }, + "name": "x" + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 335, + "end": 337, + "loc": { + "start": { + "line": 15, + "column": 21 + }, + "end": { + "line": 15, + "column": 23 + } + }, + "name": "bb" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ObjectExpression", + "start": 338, + "end": 346, + "loc": { + "start": { + "line": 15, + "column": 24 + }, + "end": { + "line": 15, + "column": 32 + } + }, + "properties": [ + { + "type": "Property", + "start": 340, + "end": 344, + "loc": { + "start": { + "line": 15, + "column": 26 + }, + "end": { + "line": 15, + "column": 30 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 340, + "end": 341, + "loc": { + "start": { + "line": 15, + "column": 26 + }, + "end": { + "line": 15, + "column": 27 + } + }, + "name": "a" + }, + "value": { + "type": "Literal", + "start": 343, + "end": 344, + "loc": { + "start": { + "line": 15, + "column": 29 + }, + "end": { + "line": 15, + "column": 30 + } + }, + "value": 1, + "raw": "1" + }, + "kind": "init" + } + ] + }, + { + "type": "ArrowFunctionExpression", + "start": 348, + "end": 371, + "loc": { + "start": { + "line": 15, + "column": 34 + }, + "end": { + "line": 17, + "column": 2 + } + }, + "id": null, + "expression": false, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 349, + "end": 350, + "loc": { + "start": { + "line": 15, + "column": 35 + }, + "end": { + "line": 15, + "column": 36 + } + }, + "name": "y" + } + ], + "body": { + "type": "BlockStatement", + "start": 355, + "end": 371, + "loc": { + "start": { + "line": 15, + "column": 41 + }, + "end": { + "line": 17, + "column": 2 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 359, + "end": 368, + "loc": { + "start": { + "line": 16, + "column": 2 + }, + "end": { + "line": 16, + "column": 11 + } + }, + "argument": { + "type": "Identifier", + "start": 366, + "end": 367, + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 16, + "column": 10 + } + }, + "name": "y" + } + } + ] + } + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " contrast: a flat object head arg stays inline and the block arrow hugs", + "start": 240, + "end": 313 + } + ] + } + ], + "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/expressions/calls/chained/multiline_object_before_callback/input.svelte b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/input.svelte new file mode 100644 index 000000000..e214b1239 --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/input.svelte @@ -0,0 +1,18 @@ + diff --git a/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/unformatted_compact.svelte b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/unformatted_compact.svelte new file mode 100644 index 000000000..f226ad6f4 --- /dev/null +++ b/tests/fixtures/typescript/expressions/calls/chained/multiline_object_before_callback/unformatted_compact.svelte @@ -0,0 +1,9 @@ + diff --git a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/expected.json b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/expected.json index c3f36766c..470a4b70b 100644 --- a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/expected.json +++ b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/expected.json @@ -2,7 +2,7 @@ "css": null, "js": [], "start": 0, - "end": 796, + "end": 1227, "type": "Root", "fragment": { "type": "Fragment", @@ -89,24 +89,56 @@ "column": 62 } } + }, + { + "type": "Line", + "value": " direct multiline object in the last call - authored broken, stays broken, chain stays flat", + "start": 788, + "end": 881, + "loc": { + "start": { + "line": 25, + "column": 1 + }, + "end": { + "line": 25, + "column": 94 + } + } + }, + { + "type": "Line", + "value": " direct array in the last call - no preserved break: the chain overflows and expands per method", + "start": 968, + "end": 1065, + "loc": { + "start": { + "line": 31, + "column": 1 + }, + "end": { + "line": 31, + "column": 98 + } + } } ], "instance": { "type": "Script", "start": 0, - "end": 795, + "end": 1226, "context": "default", "content": { "type": "Program", "start": 18, - "end": 786, + "end": 1217, "loc": { "start": { "line": 1, "column": 0 }, "end": { - "line": 24, + "line": 38, "column": 9 } }, @@ -1168,6 +1200,593 @@ "end": 590 } ] + }, + { + "type": "VariableDeclaration", + "start": 883, + "end": 965, + "loc": { + "start": { + "line": 26, + "column": 1 + }, + "end": { + "line": 29, + "column": 4 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 889, + "end": 964, + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 29, + "column": 3 + } + }, + "id": { + "type": "Identifier", + "start": 889, + "end": 895, + "loc": { + "start": { + "line": 26, + "column": 7 + }, + "end": { + "line": 26, + "column": 13 + } + }, + "name": "objArg" + }, + "init": { + "type": "CallExpression", + "start": 898, + "end": 964, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 29, + "column": 3 + } + }, + "callee": { + "type": "MemberExpression", + "start": 898, + "end": 917, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 35 + } + }, + "object": { + "type": "CallExpression", + "start": 898, + "end": 913, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 31 + } + }, + "callee": { + "type": "MemberExpression", + "start": 898, + "end": 905, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 898, + "end": 901, + "loc": { + "start": { + "line": 26, + "column": 16 + }, + "end": { + "line": 26, + "column": 19 + } + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 902, + "end": 905, + "loc": { + "start": { + "line": 26, + "column": 20 + }, + "end": { + "line": 26, + "column": 23 + } + }, + "name": "fn1" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 906, + "end": 907, + "loc": { + "start": { + "line": 26, + "column": 24 + }, + "end": { + "line": 26, + "column": 25 + } + }, + "name": "g" + }, + { + "type": "Literal", + "start": 909, + "end": 912, + "loc": { + "start": { + "line": 26, + "column": 27 + }, + "end": { + "line": 26, + "column": 30 + } + }, + "value": "f", + "raw": "'f'" + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 914, + "end": 917, + "loc": { + "start": { + "line": 26, + "column": 32 + }, + "end": { + "line": 26, + "column": 35 + } + }, + "name": "fn2" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ObjectExpression", + "start": 918, + "end": 963, + "loc": { + "start": { + "line": 26, + "column": 36 + }, + "end": { + "line": 29, + "column": 2 + } + }, + "properties": [ + { + "type": "Property", + "start": 922, + "end": 933, + "loc": { + "start": { + "line": 27, + "column": 2 + }, + "end": { + "line": 27, + "column": 13 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 922, + "end": 928, + "loc": { + "start": { + "line": 27, + "column": 2 + }, + "end": { + "line": 27, + "column": 8 + } + }, + "name": "status" + }, + "value": { + "type": "Literal", + "start": 930, + "end": 933, + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 13 + } + }, + "value": 200, + "raw": "200" + }, + "kind": "init" + }, + { + "type": "Property", + "start": 937, + "end": 960, + "loc": { + "start": { + "line": 28, + "column": 2 + }, + "end": { + "line": 28, + "column": 25 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 937, + "end": 944, + "loc": { + "start": { + "line": 28, + "column": 2 + }, + "end": { + "line": 28, + "column": 9 + } + }, + "name": "headers" + }, + "value": { + "type": "Identifier", + "start": 946, + "end": 960, + "loc": { + "start": { + "line": 28, + "column": 11 + }, + "end": { + "line": 28, + "column": 25 + } + }, + "name": "defaultHeaders" + }, + "kind": "init" + } + ] + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " direct multiline object in the last call - authored broken, stays broken, chain stays flat", + "start": 788, + "end": 881 + } + ] + }, + { + "type": "VariableDeclaration", + "start": 1067, + "end": 1216, + "loc": { + "start": { + "line": 32, + "column": 1 + }, + "end": { + "line": 37, + "column": 5 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 1073, + "end": 1215, + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 37, + "column": 4 + } + }, + "id": { + "type": "Identifier", + "start": 1073, + "end": 1079, + "loc": { + "start": { + "line": 32, + "column": 7 + }, + "end": { + "line": 32, + "column": 13 + } + }, + "name": "arrArg" + }, + "init": { + "type": "CallExpression", + "start": 1082, + "end": 1215, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 37, + "column": 4 + } + }, + "callee": { + "type": "MemberExpression", + "start": 1082, + "end": 1107, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 34, + "column": 6 + } + }, + "object": { + "type": "CallExpression", + "start": 1082, + "end": 1100, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 33, + "column": 14 + } + }, + "callee": { + "type": "MemberExpression", + "start": 1082, + "end": 1092, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 33, + "column": 6 + } + }, + "object": { + "type": "Identifier", + "start": 1082, + "end": 1085, + "loc": { + "start": { + "line": 32, + "column": 16 + }, + "end": { + "line": 32, + "column": 19 + } + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 1089, + "end": 1092, + "loc": { + "start": { + "line": 33, + "column": 3 + }, + "end": { + "line": 33, + "column": 6 + } + }, + "name": "fn1" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 1093, + "end": 1094, + "loc": { + "start": { + "line": 33, + "column": 7 + }, + "end": { + "line": 33, + "column": 8 + } + }, + "name": "g" + }, + { + "type": "Literal", + "start": 1096, + "end": 1099, + "loc": { + "start": { + "line": 33, + "column": 10 + }, + "end": { + "line": 33, + "column": 13 + } + }, + "value": "f", + "raw": "'f'" + } + ], + "optional": false + }, + "property": { + "type": "Identifier", + "start": 1104, + "end": 1107, + "loc": { + "start": { + "line": 34, + "column": 3 + }, + "end": { + "line": 34, + "column": 6 + } + }, + "name": "fn2" + }, + "computed": false, + "optional": false + }, + "arguments": [ + { + "type": "ArrayExpression", + "start": 1108, + "end": 1214, + "loc": { + "start": { + "line": 34, + "column": 7 + }, + "end": { + "line": 37, + "column": 3 + } + }, + "elements": [ + { + "type": "Literal", + "start": 1113, + "end": 1159, + "loc": { + "start": { + "line": 35, + "column": 3 + }, + "end": { + "line": 35, + "column": 49 + } + }, + "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "raw": "'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'" + }, + { + "type": "Literal", + "start": 1164, + "end": 1210, + "loc": { + "start": { + "line": 36, + "column": 3 + }, + "end": { + "line": 36, + "column": 49 + } + }, + "value": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw": "'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'" + } + ] + } + ], + "optional": false + } + } + ], + "kind": "const", + "leadingComments": [ + { + "type": "Line", + "value": " direct array in the last call - no preserved break: the chain overflows and expands per method", + "start": 968, + "end": 1065 + } + ] } ], "sourceType": "module" diff --git a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/input.svelte b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/input.svelte index 915e274bd..0faf91ff2 100644 --- a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/input.svelte +++ b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/input.svelte @@ -21,4 +21,18 @@ headers: defaultHeaders }) ); + + // direct multiline object in the last call - authored broken, stays broken, chain stays flat + const objArg = obj.fn1(g, 'f').fn2({ + status: 200, + headers: defaultHeaders + }); + + // direct array in the last call - no preserved break: the chain overflows and expands per method + const arrArg = obj + .fn1(g, 'f') + .fn2([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + ]); diff --git a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/unformatted_compact.svelte b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/unformatted_compact.svelte index 8291481c2..49c674da8 100644 --- a/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/unformatted_compact.svelte +++ b/tests/fixtures/typescript/expressions/chain/call_chain_last_arg_breaks_long/unformatted_compact.svelte @@ -11,4 +11,11 @@ status:200,headers:defaultHeaders})); // breaks per method; the last call's `new` arg still expands const chainAaaaa=obj.fn1(scope,'pathValueSegmentLiteralAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa').fn2(new Ctor(serialize(input),{ status:200,headers:defaultHeaders})); + +// direct multiline object in the last call - authored broken, stays broken, chain stays flat +const objArg=obj.fn1(g,'f').fn2({ +status:200,headers:defaultHeaders}); + +// direct array in the last call - no preserved break: the chain overflows and expands per method +const arrArg=obj.fn1(g,'f').fn2(['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb']);