Skip to content

Blocks cannot be formatted when they're top-level nodes #163

Closed
@kkuchta

Description

@kkuchta

If you parse a string like foo = bar { |x| x + 1 }, then traverse it down to the block node ({ |x| x + 1 }), trying to format that node throws an error. Here's a repro case:

require 'syntax_tree'

# Create a node visitor that walks the syntax tree looking for blocks.
class BlockFinder < SyntaxTree::Visitor
  attr_reader :first_block
  visit_method def visit_do_block(node)
    puts "found a brace block node!"
    @first_block ||= node
    # Don't traverse further
  end
  visit_method def visit_brace_block(node)
    puts "found a brace block node!"
    @first_block ||= node
    # Don't traverse further
  end
end

input_string = "foo = bar() { |x| x + 1}"
root = SyntaxTree.parse(input_string)

# use that visitor to find the first, outermost block
visitor = BlockFinder.new
visitor.visit(root)
block_node = visitor.first_block

formatter = SyntaxTree::Formatter.new(input_string, [], 80)

# !!! This throws an error:
# /Users/kevin/.rvm/gems/ruby-3.0.0/gems/syntax_tree-3.6.0/lib/syntax_tree/node.rb:1990:in `forced_do_end_bounds?': undefined method `call' for nil:NilClass
formatter.format(block_node)

# But if I comment that line out and then fake that this block node is nested
# within a parent node, it works:
formatter.instance_variable_set(:@stack, [proc {SyntaxTree::Program.new(statements: [], location: nil)}])
formatter.format(block_node)

formatter.flush
output_string = formatter.output.join
puts output_string # Prints  { |x| x + 1 }

The issue seems to be that forced_do_end_bounds in BlockFormatter inspects the parent node and doesn't handle when it doesn't exist.

PS: thanks for the great tool and, honestly, the very readable source!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions