@@ -258,8 +258,46 @@ fn process_node(
258258 | GDScriptNodeKind :: Dictionary
259259 | GDScriptNodeKind :: EnumeratorList
260260 | GDScriptNodeKind :: Parameters
261- | GDScriptNodeKind :: Arguments
262- | GDScriptNodeKind :: SubscriptArguments => process_container ( input, node, render_elements) ,
261+ | GDScriptNodeKind :: Arguments => process_container ( input, node, render_elements) ,
262+ GDScriptNodeKind :: SubscriptArguments => {
263+ // Anything like a[b] is parsed as a `subscript` node, but this may
264+ // be a dictionary access which can wrap across lines or a type hint
265+ // like `Dictionary[String, String]` which must stay on one line;
266+ // Official GDScript parser cannot parse line returns in there. So
267+ // we walk up the AST to check if we are inside a `type` node.
268+ // The type hint `Dictionary[String, String]` is parsed like this:
269+ //
270+ // ```text
271+ // (type
272+ // (subscript
273+ // (identifier) ; Dictionary
274+ // arguments: (subscript_arguments
275+ // (identifier) ; String
276+ // (identifier))) ; String
277+ // ```
278+ //
279+ // Which is why we walk up the AST to check if we are inside a `type` node.
280+ let mut is_type_with_subscript = false ;
281+ let mut ancestor = node. parent ( ) ;
282+ while let Some ( current) = ancestor {
283+ let current_kind = GDScriptNodeKind :: get_kind_from_ast_node ( current) ;
284+ if current_kind == GDScriptNodeKind :: Type {
285+ is_type_with_subscript = true ;
286+ break ;
287+ }
288+ if current_kind != GDScriptNodeKind :: Subscript
289+ && current_kind != GDScriptNodeKind :: Other
290+ {
291+ break ;
292+ }
293+ ancestor = current. parent ( ) ;
294+ }
295+ if is_type_with_subscript {
296+ process_children_with_spacing ( input, node, render_elements) ;
297+ } else {
298+ process_container ( input, node, render_elements) ;
299+ }
300+ }
263301 GDScriptNodeKind :: Body | GDScriptNodeKind :: ClassBody | GDScriptNodeKind :: MatchBody => {
264302 process_body ( input, node, render_elements)
265303 }
0 commit comments