code: def simplify_tree(tree, unpack_lists=True, in_list=False):
      
      # TODO: copy (or (de)serialize)? outside this function?
      if isinstance(tree, BaseNode) and not isinstance(tree, Terminal):
          used_fields = [field for field in tree._fields if getattr(tree, field, False)]
          if len(used_fields) == 1:
              result = getattr(tree, used_fields[0])
          else:
              result = None
          if (
              len(used_fields) != 1
              or isinstance(tree, AliasNode)
              or (in_list and isinstance(result, list))
          ):
              result = tree
              for field in tree._fields:
                  old_value = getattr(tree, field, None)
                  if old_value:
                      setattr(
                          result,
                          field,
                          simplify_tree(old_value, unpack_lists=unpack_lists),
                      )
              return result
          assert result is not None
      elif isinstance(tree, list) and len(tree) == 1 and unpack_lists:
          result = tree[0]
      else:
          if isinstance(tree, list):
              result = [
                  simplify_tree(el, unpack_lists=unpack_lists, in_list=True)
                  for el in tree
              ]
          else:
              result = tree
          return result
  
      return simplify_tree(result, unpack_lists=unpack_lists)
docs: Recursively unpack single-item lists and objects where fields and labels only reference a single child
  
      :param tree: the tree to simplify (mutating!)
      :param unpack_lists: whether single-item lists should be replaced by that item
      :param in_list: this is used to prevent unpacking a node in a list as AST visit can't handle nested lists