1313use crate :: QuoteStyle ;
1414use crate :: node_kind:: GDScriptNodeKind ;
1515use crate :: parser:: { ParseInput , RegionWithDisabledFormatting } ;
16- use crate :: renderer:: { RangeRenderElement , RangeSourceBytes , RenderElement } ;
16+ use crate :: renderer:: { GroupParentFit , RangeRenderElement , RangeSourceBytes , RenderElement } ;
1717use crate :: reorder:: { self , DeclarationKind } ;
1818
1919fn begin_indent ( render_elements : & mut Vec < RenderElement > , level : u16 ) -> usize {
@@ -40,6 +40,7 @@ fn begin_group(render_elements: &mut Vec<RenderElement>) -> usize {
4040 let index = render_elements. len ( ) ;
4141 render_elements. push ( RenderElement :: Group {
4242 children : RangeRenderElement { start : 0 , end : 0 } ,
43+ parent_fit : GroupParentFit :: Full ,
4344 } ) ;
4445 index
4546}
@@ -55,6 +56,14 @@ fn finish_group(render_elements: &mut [RenderElement], group_index: usize) {
5556 }
5657}
5758
59+ fn begin_group_until_first_line_break ( render_elements : & mut Vec < RenderElement > ) -> usize {
60+ let group_index = begin_group ( render_elements) ;
61+ if let RenderElement :: Group { parent_fit, .. } = & mut render_elements[ group_index] {
62+ * parent_fit = GroupParentFit :: UntilFirstLineBreak ;
63+ }
64+ group_index
65+ }
66+
5867/// Returns the number of blank lines to output before a declaration of the given
5968/// kind, based on the user's config. Returns 0 for declarations that don't need
6069/// extra blank lines (normal spacing applies).
@@ -2031,7 +2040,6 @@ fn process_attribute(
20312040 } else {
20322041 input. continuation_indent_level
20332042 } ;
2034- let continuation_indent_index = begin_indent ( render_elements, chain_indent_level) ;
20352043 let mut attribute_index: u32 = 1 ;
20362044 while attribute_index < child_count as u32 {
20372045 let child = node. child ( attribute_index) ;
@@ -2061,18 +2069,28 @@ fn process_attribute(
20612069 if GDScriptNodeKind :: get_kind_from_ast_node ( call_node)
20622070 == GDScriptNodeKind :: AttributeCall
20632071 {
2064- process_method_call_flat ( input, call_node, render_elements) ;
2072+ process_method_call_name ( input, call_node, render_elements) ;
2073+ finish_indent ( render_elements, continuation_indent_index) ;
2074+ process_method_call_arguments (
2075+ input,
2076+ call_node,
2077+ attribute_index + 2 >= child_count as u32 ,
2078+ render_elements,
2079+ ) ;
20652080 } else {
20662081 process_node ( input, call_node, render_elements) ;
2082+ finish_indent ( render_elements, continuation_indent_index) ;
20672083 }
2084+ } else {
2085+ finish_indent ( render_elements, continuation_indent_index) ;
20682086 }
2069- finish_indent ( render_elements, continuation_indent_index) ;
20702087 }
20712088 attribute_index += 2 ;
20722089 continue ;
20732090 }
20742091
20752092 if !allows_implicit_continuation && !has_explicit_line_continuation {
2093+ let continuation_indent_index = begin_indent ( render_elements, chain_indent_level) ;
20762094 let continuation_index = render_elements. len ( ) + 1 ;
20772095 render_elements. push ( RenderElement :: Branch {
20782096 if_single_line : None ,
@@ -2083,6 +2101,31 @@ fn process_attribute(
20832101 } ) ;
20842102 render_elements. push ( RenderElement :: Space ) ;
20852103 render_elements. push ( RenderElement :: TextStatic ( "\\ " ) ) ;
2104+ render_elements. push ( RenderElement :: SoftLine ) ;
2105+ if let Some ( dot_node) = child {
2106+ process_node ( input, dot_node, render_elements) ;
2107+ }
2108+ if let Some ( call_node) = next {
2109+ if GDScriptNodeKind :: get_kind_from_ast_node ( call_node)
2110+ == GDScriptNodeKind :: AttributeCall
2111+ {
2112+ process_method_call_name ( input, call_node, render_elements) ;
2113+ finish_indent ( render_elements, continuation_indent_index) ;
2114+ process_method_call_arguments (
2115+ input,
2116+ call_node,
2117+ attribute_index + 2 >= child_count as u32 ,
2118+ render_elements,
2119+ ) ;
2120+ } else {
2121+ process_node ( input, call_node, render_elements) ;
2122+ finish_indent ( render_elements, continuation_indent_index) ;
2123+ }
2124+ } else {
2125+ finish_indent ( render_elements, continuation_indent_index) ;
2126+ }
2127+ attribute_index += 2 ;
2128+ continue ;
20862129 }
20872130 if !has_explicit_line_continuation {
20882131 render_elements. push ( RenderElement :: SoftLine ) ;
@@ -2095,82 +2138,118 @@ fn process_attribute(
20952138 if GDScriptNodeKind :: get_kind_from_ast_node ( call_node)
20962139 == GDScriptNodeKind :: AttributeCall
20972140 {
2098- process_method_call_flat ( input, call_node, render_elements) ;
2141+ process_method_call_flat (
2142+ input,
2143+ call_node,
2144+ attribute_index + 2 >= child_count as u32 ,
2145+ render_elements,
2146+ ) ;
20992147 } else {
21002148 process_node ( input, call_node, render_elements) ;
21012149 }
21022150 }
21032151
21042152 attribute_index += 2 ;
21052153 }
2106- finish_indent ( render_elements, continuation_indent_index) ;
21072154 finish_group ( render_elements, group_index) ;
21082155}
21092156
2110- /// Builds a method call (name + arguments) inline without extra indentation.
2111- /// Used inside a dot-access chain. Uses emit_inter_child_separator between
2112- /// arguments and between the last argument and the closing parenthesis.
2157+ /// Builds a method call inside a dot-access chain. Its argument container is
2158+ /// isolated so that long arguments do not force the whole chain to break.
21132159fn process_method_call_flat (
2160+ input : & ParseInput ,
2161+ attribute_call : tree_sitter:: Node ,
2162+ is_last_chain_call : bool ,
2163+ render_elements : & mut Vec < RenderElement > ,
2164+ ) {
2165+ process_method_call_name ( input, attribute_call, render_elements) ;
2166+ process_method_call_arguments ( input, attribute_call, is_last_chain_call, render_elements) ;
2167+ }
2168+
2169+ fn process_method_call_name (
21142170 input : & ParseInput ,
21152171 attribute_call : tree_sitter:: Node ,
21162172 render_elements : & mut Vec < RenderElement > ,
21172173) {
21182174 if let Some ( method_name) = attribute_call. child ( 0 ) {
21192175 process_node ( input, method_name, render_elements) ;
21202176 }
2177+ }
2178+
2179+ fn process_method_call_arguments (
2180+ input : & ParseInput ,
2181+ attribute_call : tree_sitter:: Node ,
2182+ is_last_chain_call : bool ,
2183+ render_elements : & mut Vec < RenderElement > ,
2184+ ) {
21212185 if let Some ( args) = attribute_call. child ( 1 ) {
2122- let argument_child_count = args. child_count ( ) ;
2123- if argument_child_count >= 2 {
2124- if let Some ( open) = args. child ( 0 ) {
2125- process_node ( input, open, render_elements) ;
2126- }
2127- let close_parenthesis_index = ( argument_child_count - 1 ) as u32 ;
2128- let args_kind = GDScriptNodeKind :: get_kind_from_ast_node ( args) ;
2129- let has_trailing_comma = if close_parenthesis_index >= 2 {
2130- if let Some ( node_before_close_paren) = args. child ( close_parenthesis_index - 1 ) {
2131- GDScriptNodeKind :: get_kind_from_ast_node ( node_before_close_paren)
2132- == GDScriptNodeKind :: TokenComma
2133- } else {
2134- false
2135- }
2136- } else {
2137- false
2138- } ;
2139- let body_end = if has_trailing_comma {
2140- close_parenthesis_index - 1
2141- } else {
2142- close_parenthesis_index
2143- } ;
2144- let mut previous_child: Option < tree_sitter:: Node > =
2145- Some ( args. child ( 0 ) . expect ( "argument_child_count>=2" ) ) ;
2146- let mut argument_index: u32 = 1 ;
2147- while argument_index < body_end {
2148- if let Some ( child_argument) = args. child ( argument_index) {
2149- if let Some ( ref previous_node) = previous_child {
2150- process_separator_between_sibling_nodes (
2151- args_kind,
2152- previous_node,
2153- & child_argument,
2154- render_elements,
2155- ) ;
2156- }
2157- process_node ( input, child_argument, render_elements) ;
2158- previous_child = Some ( child_argument) ;
2159- }
2160- argument_index += 1 ;
2161- }
2162- if let Some ( close) = args. child ( close_parenthesis_index) {
2163- if let Some ( ref previous_node) = previous_child {
2164- process_separator_between_sibling_nodes (
2165- args_kind,
2166- previous_node,
2167- & close,
2168- render_elements,
2169- ) ;
2170- }
2171- process_node ( input, close, render_elements) ;
2186+ if is_last_chain_call {
2187+ let group_index = begin_group_until_first_line_break ( render_elements) ;
2188+ process_node ( input, args, render_elements) ;
2189+ finish_group ( render_elements, group_index) ;
2190+ } else {
2191+ process_method_arguments_flat ( input, args, render_elements) ;
2192+ }
2193+ }
2194+ }
2195+
2196+ fn process_method_arguments_flat (
2197+ input : & ParseInput ,
2198+ args : tree_sitter:: Node ,
2199+ render_elements : & mut Vec < RenderElement > ,
2200+ ) {
2201+ let argument_child_count = args. child_count ( ) ;
2202+ if argument_child_count < 2 {
2203+ return ;
2204+ }
2205+ if let Some ( open) = args. child ( 0 ) {
2206+ process_node ( input, open, render_elements) ;
2207+ }
2208+ let close_parenthesis_index = ( argument_child_count - 1 ) as u32 ;
2209+ let args_kind = GDScriptNodeKind :: get_kind_from_ast_node ( args) ;
2210+ let has_trailing_comma = if close_parenthesis_index >= 2 {
2211+ if let Some ( node_before_close_paren) = args. child ( close_parenthesis_index - 1 ) {
2212+ GDScriptNodeKind :: get_kind_from_ast_node ( node_before_close_paren)
2213+ == GDScriptNodeKind :: TokenComma
2214+ } else {
2215+ false
2216+ }
2217+ } else {
2218+ false
2219+ } ;
2220+ let body_end = if has_trailing_comma {
2221+ close_parenthesis_index - 1
2222+ } else {
2223+ close_parenthesis_index
2224+ } ;
2225+ let mut previous_child: Option < tree_sitter:: Node > =
2226+ Some ( args. child ( 0 ) . expect ( "argument_child_count >= 2" ) ) ;
2227+ let mut argument_index: u32 = 1 ;
2228+ while argument_index < body_end {
2229+ if let Some ( child_argument) = args. child ( argument_index) {
2230+ if let Some ( ref previous_node) = previous_child {
2231+ process_separator_between_sibling_nodes (
2232+ args_kind,
2233+ previous_node,
2234+ & child_argument,
2235+ render_elements,
2236+ ) ;
21722237 }
2238+ process_node ( input, child_argument, render_elements) ;
2239+ previous_child = Some ( child_argument) ;
21732240 }
2241+ argument_index += 1 ;
2242+ }
2243+ if let Some ( close) = args. child ( close_parenthesis_index) {
2244+ if let Some ( ref previous_node) = previous_child {
2245+ process_separator_between_sibling_nodes (
2246+ args_kind,
2247+ previous_node,
2248+ & close,
2249+ render_elements,
2250+ ) ;
2251+ }
2252+ process_node ( input, close, render_elements) ;
21742253 }
21752254}
21762255
0 commit comments