Skip to content

Commit b5d226b

Browse files
committed
Move lambdas into their own methods, smarter token finding in on_args_add_block
1 parent 840ebab commit b5d226b

File tree

2 files changed

+72
-55
lines changed

2 files changed

+72
-55
lines changed

lib/syntax_tree/node.rb

+58-44
Original file line numberDiff line numberDiff line change
@@ -2885,27 +2885,15 @@ def deconstruct_keys(_keys)
28852885
end
28862886

28872887
def format(q)
2888-
declaration = -> do
2889-
q.group do
2890-
q.text("class ")
2891-
q.format(constant)
2892-
2893-
if superclass
2894-
q.text(" < ")
2895-
q.format(superclass)
2896-
end
2897-
end
2898-
end
2899-
29002888
if bodystmt.empty?
29012889
q.group do
2902-
declaration.call
2890+
format_declaration(q)
29032891
q.breakable_force
29042892
q.text("end")
29052893
end
29062894
else
29072895
q.group do
2908-
declaration.call
2896+
format_declaration(q)
29092897

29102898
q.indent do
29112899
q.breakable_force
@@ -2917,6 +2905,20 @@ def format(q)
29172905
end
29182906
end
29192907
end
2908+
2909+
private
2910+
2911+
def format_declaration(q)
2912+
q.group do
2913+
q.text("class ")
2914+
q.format(constant)
2915+
2916+
if superclass
2917+
q.text(" < ")
2918+
q.format(superclass)
2919+
end
2920+
end
2921+
end
29202922
end
29212923

29222924
# Comma represents the use of the , operator.
@@ -5122,18 +5124,7 @@ def deconstruct_keys(_keys)
51225124
def format(q)
51235125
parts = keywords.map { |(key, value)| KeywordFormatter.new(key, value) }
51245126
parts << KeywordRestFormatter.new(keyword_rest) if keyword_rest
5125-
51265127
nested = PATTERNS.include?(q.parent.class)
5127-
contents = -> do
5128-
q.group { q.seplist(parts) { |part| q.format(part, stackable: false) } }
5129-
5130-
# If there isn't a constant, and there's a blank keyword_rest, then we
5131-
# have an plain ** that needs to have a `then` after it in order to
5132-
# parse correctly on the next parse.
5133-
if !constant && keyword_rest && keyword_rest.value.nil? && !nested
5134-
q.text(" then")
5135-
end
5136-
end
51375128

51385129
# If there is a constant, we're going to format to have the constant name
51395130
# first and then use brackets.
@@ -5143,7 +5134,7 @@ def format(q)
51435134
q.text("[")
51445135
q.indent do
51455136
q.breakable_empty
5146-
contents.call
5137+
format_contents(q, parts, nested)
51475138
end
51485139
q.breakable_empty
51495140
q.text("]")
@@ -5160,7 +5151,7 @@ def format(q)
51605151
# If there's only one pair, then we'll just print the contents provided
51615152
# we're not inside another pattern.
51625153
if !nested && parts.size == 1
5163-
contents.call
5154+
format_contents(q, parts, nested)
51645155
return
51655156
end
51665157

@@ -5170,7 +5161,7 @@ def format(q)
51705161
q.text("{")
51715162
q.indent do
51725163
q.breakable_space
5173-
contents.call
5164+
format_contents(q, parts, nested)
51745165
end
51755166

51765167
if q.target_ruby_version < Gem::Version.new("2.7.3")
@@ -5181,6 +5172,19 @@ def format(q)
51815172
end
51825173
end
51835174
end
5175+
5176+
private
5177+
5178+
def format_contents(q, parts, nested)
5179+
q.group { q.seplist(parts) { |part| q.format(part, stackable: false) } }
5180+
5181+
# If there isn't a constant, and there's a blank keyword_rest, then we
5182+
# have an plain ** that needs to have a `then` after it in order to
5183+
# parse correctly on the next parse.
5184+
if !constant && keyword_rest && keyword_rest.value.nil? && !nested
5185+
q.text(" then")
5186+
end
5187+
end
51845188
end
51855189

51865190
# The list of nodes that represent patterns inside of pattern matching so that
@@ -6543,22 +6547,15 @@ def deconstruct_keys(_keys)
65436547
end
65446548

65456549
def format(q)
6546-
declaration = -> do
6547-
q.group do
6548-
q.text("module ")
6549-
q.format(constant)
6550-
end
6551-
end
6552-
65536550
if bodystmt.empty?
65546551
q.group do
6555-
declaration.call
6552+
format_declaration(q)
65566553
q.breakable_force
65576554
q.text("end")
65586555
end
65596556
else
65606557
q.group do
6561-
declaration.call
6558+
format_declaration(q)
65626559

65636560
q.indent do
65646561
q.breakable_force
@@ -6570,6 +6567,15 @@ def format(q)
65706567
end
65716568
end
65726569
end
6570+
6571+
private
6572+
6573+
def format_declaration(q)
6574+
q.group do
6575+
q.text("module ")
6576+
q.format(constant)
6577+
end
6578+
end
65736579
end
65746580

65756581
# MRHS represents the values that are being assigned on the right-hand side of
@@ -7023,27 +7029,35 @@ def format(q)
70237029
parts << KeywordRestFormatter.new(keyword_rest) if keyword_rest
70247030
parts << block if block
70257031

7026-
contents = -> do
7027-
q.seplist(parts) { |part| q.format(part) }
7028-
q.format(rest) if rest.is_a?(ExcessedComma)
7032+
if parts.empty?
7033+
q.nest(0) { format_contents(q, parts) }
7034+
return
70297035
end
70307036

7031-
if ![Def, Defs, DefEndless].include?(q.parent.class) || parts.empty?
7032-
q.nest(0, &contents)
7033-
else
7037+
case q.parent
7038+
when Def, Defs, DefEndless
70347039
q.nest(0) do
70357040
q.text("(")
70367041
q.group do
70377042
q.indent do
70387043
q.breakable_empty
7039-
contents.call
7044+
format_contents(q, parts)
70407045
end
70417046
q.breakable_empty
70427047
end
70437048
q.text(")")
70447049
end
7050+
else
7051+
q.nest(0) { format_contents(q, parts) }
70457052
end
70467053
end
7054+
7055+
private
7056+
7057+
def format_contents(q, parts)
7058+
q.seplist(parts) { |part| q.format(part) }
7059+
q.format(rest) if rest.is_a?(ExcessedComma)
7060+
end
70477061
end
70487062

70497063
# Paren represents using balanced parentheses in a couple places in a Ruby

lib/syntax_tree/parser.rb

+14-11
Original file line numberDiff line numberDiff line change
@@ -513,23 +513,26 @@ def on_args_add(arguments, argument)
513513
# (false | untyped) block
514514
# ) -> Args
515515
def on_args_add_block(arguments, block)
516+
end_char = arguments.parts.any? && arguments.location.end_char
517+
516518
# First, see if there is an & operator that could potentially be
517519
# associated with the block part of this args_add_block. If there is not,
518520
# then just return the arguments.
519-
operator = find_operator(:&)
520-
return arguments unless operator
521-
522-
# If there are any arguments and the operator we found from the list is
523-
# not after them, then we're going to return the arguments as-is because
524-
# we're looking at an & that occurs before the arguments are done.
525-
if arguments.parts.any? &&
526-
operator.location.start_char < arguments.location.end_char
527-
return arguments
528-
end
521+
index =
522+
tokens.rindex do |token|
523+
# If there are any arguments and the operator we found from the list
524+
# is not after them, then we're going to return the arguments as-is
525+
# because we're looking at an & that occurs before the arguments are
526+
# done.
527+
return arguments if end_char && token.location.start_char < end_char
528+
token.is_a?(Op) && (token.name == :&)
529+
end
530+
531+
return arguments unless index
529532

530533
# Now we know we have an & operator, so we're going to delete it from the
531534
# list of tokens to make sure it doesn't get confused with anything else.
532-
tokens.delete(operator)
535+
operator = tokens.delete_at(index)
533536

534537
# Construct the location that represents the block argument.
535538
location = operator.location

0 commit comments

Comments
 (0)