@@ -350,12 +350,19 @@ fn process_node(
350350 finish_group ( render_elements, group_index) ;
351351 }
352352 GDScriptNodeKind :: SetGet => process_setget ( input, node, render_elements) ,
353- GDScriptNodeKind :: ParenthesizedExpression => {
354- process_parenthesized_expression ( input, node, render_elements)
353+ GDScriptNodeKind :: ParenthesizedExpression
354+ | GDScriptNodeKind :: Attribute
355+ | GDScriptNodeKind :: Subscript
356+ | GDScriptNodeKind :: Call => {
357+ // Wrapping the entire expression in a group helps with calculating
358+ // the length of code segments and knowing where to break lines for
359+ // vertical spacing in the renderer.
360+ let group_index = begin_group ( render_elements) ;
361+ process_expression_content ( input, node, render_elements) ;
362+ finish_group ( render_elements, group_index) ;
355363 }
356364 GDScriptNodeKind :: BinaryOperator => process_binary_operator ( input, node, render_elements) ,
357365 GDScriptNodeKind :: Condition => process_conditional_expression ( input, node, render_elements) ,
358- GDScriptNodeKind :: Attribute => process_attribute ( input, node, render_elements) ,
359366 _ => process_children_with_spacing ( input, node, render_elements) ,
360367 }
361368}
@@ -1890,16 +1897,37 @@ fn process_container(
18901897 }
18911898}
18921899
1893- /// Formats ParenthesizedExpression nodes with a Group. The group lets a long
1894- /// expression use its parentheses as a safe break boundary instead of breaking
1895- /// an enclosing line at an operator inside the expression. Inner constructs
1896- /// that already handle their own indentation (lambdas, arrays, dicts) keep
1897- /// their specialized formatting .
1898- fn process_parenthesized_expression (
1900+ /// Processes part of an expression and appends render elements, without
1901+ /// creating a new group. This recursively processes child nodes as an
1902+ /// expression can contain sub-expressions, operators, lambda functions, etc.
1903+ ///
1904+ /// The IR for everything visited is added to `render_elements` .
1905+ fn process_expression_content (
18991906 input : & ParseInput ,
19001907 node : tree_sitter:: Node ,
19011908 render_elements : & mut Vec < RenderElement > ,
19021909) {
1910+ match GDScriptNodeKind :: get_kind_from_ast_node ( node) {
1911+ GDScriptNodeKind :: Attribute => {
1912+ process_attribute ( input, node, render_elements) ;
1913+ return ;
1914+ }
1915+ GDScriptNodeKind :: Subscript | GDScriptNodeKind :: Call => {
1916+ process_children_with_spacing ( input, node, render_elements) ;
1917+ return ;
1918+ }
1919+ GDScriptNodeKind :: ParenthesizedExpression => { }
1920+ // As we dive down the AST, we can stumble upon anything. For example,
1921+ // an attribute call can be a method call that within the arguments has
1922+ // a lambda function wrapped in parentheses or anything else. When we
1923+ // stumble upon something like that, we need to process those nodes
1924+ // recursively.
1925+ _ => {
1926+ process_node ( input, node, render_elements) ;
1927+ return ;
1928+ }
1929+ }
1930+
19031931 let child_count = node. child_count ( ) ;
19041932 if child_count < 3 {
19051933 process_children_with_spacing ( input, node, render_elements) ;
@@ -1944,8 +1972,6 @@ fn process_parenthesized_expression(
19441972 return ;
19451973 }
19461974
1947- let group_index = begin_group ( render_elements) ;
1948-
19491975 if let Some ( open) = node. child ( 0 ) {
19501976 process_node ( input, open, render_elements) ;
19511977 }
@@ -1979,8 +2005,6 @@ fn process_parenthesized_expression(
19792005 if let Some ( close) = node. child ( ( child_count - 1 ) as u32 ) {
19802006 process_node ( input, close, render_elements) ;
19812007 }
1982-
1983- finish_group ( render_elements, group_index) ;
19842008}
19852009
19862010/// Finds and returns the unnamed operator token between a binary expression's
@@ -2459,14 +2483,24 @@ fn process_attribute(
24592483 render_elements : & mut Vec < RenderElement > ,
24602484) {
24612485 let child_count = node. child_count ( ) ;
2462- // Only handle dot-access chains (child_count >= 5: at least 2 method calls).
2463- // Single method calls like a.foo() go through process_children_with_spacing.
2464- let is_dot_chain = if let Some ( c) = node. child ( 1 ) {
2465- GDScriptNodeKind :: get_kind_from_ast_node ( c) == GDScriptNodeKind :: TokenDot
2466- } else {
2467- false
2468- } ;
2469- if child_count < 5 || !is_dot_chain {
2486+ // An attribute node is an expression followed by dots using the dot
2487+ // accessor and accessing members or calling methods.
2488+ //
2489+ // If the chain has multiple dots, we need to specifically handle
2490+ // continuation lines. So we count the dots in the attribute chain and
2491+ // format accordingly.
2492+ let mut dot_count = 0 ;
2493+ let mut child_index = 0 ;
2494+ while child_index < child_count {
2495+ if let Some ( child) = node. child ( child_index as u32 )
2496+ && GDScriptNodeKind :: get_kind_from_ast_node ( child) == GDScriptNodeKind :: TokenDot
2497+ {
2498+ dot_count += 1 ;
2499+ }
2500+ child_index += 1 ;
2501+ }
2502+ let has_multiple_dot_accesses = dot_count >= 2 ;
2503+ if !has_multiple_dot_accesses {
24702504 process_children_with_spacing ( input, node, render_elements) ;
24712505 return ;
24722506 }
@@ -2530,8 +2564,6 @@ fn process_attribute(
25302564 child_index += 1 ;
25312565 }
25322566
2533- let group_index = begin_group ( render_elements) ;
2534-
25352567 if let Some ( expr) = node. child ( 0 ) {
25362568 process_node ( input, expr, render_elements) ;
25372569 }
@@ -2652,7 +2684,6 @@ fn process_attribute(
26522684
26532685 attribute_index += 2 ;
26542686 }
2655- finish_group ( render_elements, group_index) ;
26562687}
26572688
26582689/// Builds a method call inside a dot-access chain. Its argument container is
@@ -3046,7 +3077,18 @@ fn process_children_with_spacing(
30463077 index += 1 ;
30473078 continue ;
30483079 }
3049- process_node ( input, child, render_elements) ;
3080+ if index == 0
3081+ && matches ! (
3082+ parent_kind,
3083+ GDScriptNodeKind :: Attribute
3084+ | GDScriptNodeKind :: Subscript
3085+ | GDScriptNodeKind :: Call
3086+ )
3087+ {
3088+ process_expression_content ( input, child, render_elements) ;
3089+ } else {
3090+ process_node ( input, child, render_elements) ;
3091+ }
30503092 previous = Some ( child) ;
30513093 }
30523094 index += 1 ;
0 commit comments