@@ -1173,7 +1173,7 @@ def on_args_add(arguments, argument)
11731173 # method(&expression)
11741174 #
11751175 class ArgBlock
1176- # [untyped] the expression being turned into a block
1176+ # [nil | untyped] the expression being turned into a block
11771177 attr_reader :value
11781178
11791179 # [Location] the location of this node
@@ -1194,15 +1194,17 @@ def child_nodes
11941194
11951195 def format ( q )
11961196 q . text ( "&" )
1197- q . format ( value )
1197+ q . format ( value ) if value
11981198 end
11991199
12001200 def pretty_print ( q )
12011201 q . group ( 2 , "(" , ")" ) do
12021202 q . text ( "arg_block" )
12031203
1204- q . breakable
1205- q . pp ( value )
1204+ if value
1205+ q . breakable
1206+ q . pp ( value )
1207+ end
12061208
12071209 q . pp ( Comment ::List . new ( comments ) )
12081210 end
@@ -1221,13 +1223,14 @@ def to_json(*opts)
12211223 # (false | untyped) block
12221224 # ) -> Args
12231225 def on_args_add_block ( arguments , block )
1224- return arguments unless block
1226+ operator = find_token ( Op , "&" , consume : false )
1227+ return arguments unless operator
12251228
1226- arg_block =
1227- ArgBlock . new (
1228- value : block ,
1229- location : find_token ( Op , "&" ) . location . to ( block . location )
1230- )
1229+ tokens . delete ( operator )
1230+ location = operator . location
1231+ location = operator . location . to ( block . location ) if block
1232+
1233+ arg_block = ArgBlock . new ( value : block , location : location )
12311234
12321235 Args . new (
12331236 parts : arguments . parts << arg_block ,
@@ -1896,7 +1899,7 @@ def child_nodes
18961899 end
18971900
18981901 def format ( q )
1899- if value . is_a? ( HashLiteral )
1902+ if value & .is_a? ( HashLiteral )
19001903 format_contents ( q )
19011904 else
19021905 q . group { format_contents ( q ) }
@@ -1910,8 +1913,10 @@ def pretty_print(q)
19101913 q . breakable
19111914 q . pp ( key )
19121915
1913- q . breakable
1914- q . pp ( value )
1916+ if value
1917+ q . breakable
1918+ q . pp ( value )
1919+ end
19151920
19161921 q . pp ( Comment ::List . new ( comments ) )
19171922 end
@@ -1931,6 +1936,7 @@ def to_json(*opts)
19311936
19321937 def format_contents ( q )
19331938 q . parent . format_key ( q , key )
1939+ return unless value
19341940
19351941 if key . comments . empty? && AssignFormatting . skip_indent? ( value )
19361942 q . text ( " " )
@@ -1947,7 +1953,10 @@ def format_contents(q)
19471953 # :call-seq:
19481954 # on_assoc_new: (untyped key, untyped value) -> Assoc
19491955 def on_assoc_new ( key , value )
1950- Assoc . new ( key : key , value : value , location : key . location . to ( value . location ) )
1956+ location = key . location
1957+ location = location . to ( value . location ) if value
1958+
1959+ Assoc . new ( key : key , value : value , location : location )
19511960 end
19521961
19531962 # AssocSplat represents double-splatting a value into a hash (either a hash
@@ -2578,7 +2587,7 @@ def on_block_var(params, locals)
25782587 # def method(&block); end
25792588 #
25802589 class BlockArg
2581- # [Ident] the name of the block argument
2590+ # [nil | Ident] the name of the block argument
25822591 attr_reader :name
25832592
25842593 # [Location] the location of this node
@@ -2599,15 +2608,17 @@ def child_nodes
25992608
26002609 def format ( q )
26012610 q . text ( "&" )
2602- q . format ( name )
2611+ q . format ( name ) if name
26032612 end
26042613
26052614 def pretty_print ( q )
26062615 q . group ( 2 , "(" , ")" ) do
26072616 q . text ( "blockarg" )
26082617
2609- q . breakable
2610- q . pp ( name )
2618+ if name
2619+ q . breakable
2620+ q . pp ( name )
2621+ end
26112622
26122623 q . pp ( Comment ::List . new ( comments ) )
26132624 end
@@ -2625,7 +2636,10 @@ def to_json(*opts)
26252636 def on_blockarg ( name )
26262637 operator = find_token ( Op , "&" )
26272638
2628- BlockArg . new ( name : name , location : operator . location . to ( name . location ) )
2639+ location = operator . location
2640+ location = location . to ( name . location ) if name
2641+
2642+ BlockArg . new ( name : name , location : location )
26292643 end
26302644
26312645 # bodystmt can't actually determine its bounds appropriately because it
@@ -4419,7 +4433,7 @@ class DefEndless
44194433 # [Backtick | Const | Ident | Kw | Op] the name of the method
44204434 attr_reader :name
44214435
4422- # [nil | Paren] the parameter declaration for the method
4436+ # [nil | Params | Paren] the parameter declaration for the method
44234437 attr_reader :paren
44244438
44254439 # [untyped] the expression to be executed by the method
@@ -4463,7 +4477,12 @@ def format(q)
44634477 end
44644478
44654479 q . format ( name )
4466- q . format ( paren ) if paren && !paren . contents . empty?
4480+
4481+ if paren
4482+ params = paren
4483+ params = params . contents if params . is_a? ( Paren )
4484+ q . format ( paren ) unless params . empty?
4485+ end
44674486
44684487 q . text ( " =" )
44694488 q . group do
@@ -4529,21 +4548,6 @@ def on_def(name, params, bodystmt)
45294548 # and normal method definitions.
45304549 beginning = find_token ( Kw , "def" )
45314550
4532- # If we don't have a bodystmt node, then we have a single-line method
4533- unless bodystmt . is_a? ( BodyStmt )
4534- node =
4535- DefEndless . new (
4536- target : nil ,
4537- operator : nil ,
4538- name : name ,
4539- paren : params ,
4540- statement : bodystmt ,
4541- location : beginning . location . to ( bodystmt . location )
4542- )
4543-
4544- return node
4545- end
4546-
45474551 # If there aren't any params then we need to correct the params node
45484552 # location information
45494553 if params . is_a? ( Params ) && params . empty?
@@ -4559,18 +4563,35 @@ def on_def(name, params, bodystmt)
45594563 params = Params . new ( location : location )
45604564 end
45614565
4562- ending = find_token ( Kw , "end" )
4563- bodystmt . bind (
4564- find_next_statement_start ( params . location . end_char ) ,
4565- ending . location . start_char
4566- )
4566+ ending = find_token ( Kw , "end" , consume : false )
45674567
4568- Def . new (
4569- name : name ,
4570- params : params ,
4571- bodystmt : bodystmt ,
4572- location : beginning . location . to ( ending . location )
4573- )
4568+ if ending
4569+ tokens . delete ( ending )
4570+ bodystmt . bind (
4571+ find_next_statement_start ( params . location . end_char ) ,
4572+ ending . location . start_char
4573+ )
4574+
4575+ Def . new (
4576+ name : name ,
4577+ params : params ,
4578+ bodystmt : bodystmt ,
4579+ location : beginning . location . to ( ending . location )
4580+ )
4581+ else
4582+ # In Ruby >= 3.1.0, this is a BodyStmt that wraps a single statement in
4583+ # the statements list. Before, it was just the individual statement.
4584+ statement = bodystmt . is_a? ( BodyStmt ) ? bodystmt . statements : bodystmt
4585+
4586+ DefEndless . new (
4587+ target : nil ,
4588+ operator : nil ,
4589+ name : name ,
4590+ paren : params ,
4591+ statement : statement ,
4592+ location : beginning . location . to ( bodystmt . location )
4593+ )
4594+ end
45744595 end
45754596
45764597 # Defined represents the use of the +defined?+ operator. It can be used with
@@ -4778,37 +4799,37 @@ def on_defs(target, operator, name, params, bodystmt)
47784799 end
47794800
47804801 beginning = find_token ( Kw , "def" )
4802+ ending = find_token ( Kw , "end" , consume : false )
47814803
4782- # If we don't have a bodystmt node, then we have a single-line method
4783- unless bodystmt . is_a? ( BodyStmt )
4784- node =
4785- DefEndless . new (
4786- target : target ,
4787- operator : operator ,
4788- name : name ,
4789- paren : params ,
4790- statement : bodystmt ,
4791- location : beginning . location . to ( bodystmt . location )
4792- )
4793-
4794- return node
4795- end
4796-
4797- ending = find_token ( Kw , "end" )
4804+ if ending
4805+ tokens . delete ( ending )
4806+ bodystmt . bind (
4807+ find_next_statement_start ( params . location . end_char ) ,
4808+ ending . location . start_char
4809+ )
47984810
4799- bodystmt . bind (
4800- find_next_statement_start ( params . location . end_char ) ,
4801- ending . location . start_char
4802- )
4811+ Defs . new (
4812+ target : target ,
4813+ operator : operator ,
4814+ name : name ,
4815+ params : params ,
4816+ bodystmt : bodystmt ,
4817+ location : beginning . location . to ( ending . location )
4818+ )
4819+ else
4820+ # In Ruby >= 3.1.0, this is a BodyStmt that wraps a single statement in
4821+ # the statements list. Before, it was just the individual statement.
4822+ statement = bodystmt . is_a? ( BodyStmt ) ? bodystmt . statements : bodystmt
48034823
4804- Defs . new (
4805- target : target ,
4806- operator : operator ,
4807- name : name ,
4808- params : params ,
4809- bodystmt : bodystmt ,
4810- location : beginning . location . to ( ending . location )
4811- )
4824+ DefEndless . new (
4825+ target : target ,
4826+ operator : operator ,
4827+ name : name ,
4828+ paren : params ,
4829+ statement : statement ,
4830+ location : beginning . location . to ( bodystmt . location )
4831+ )
4832+ end
48124833 end
48134834
48144835 # DoBlock represents passing a block to a method call using the +do+ and +end+
@@ -8927,7 +8948,7 @@ def format(q)
89278948 end
89288949
89298950 class KeywordRestFormatter
8930- # [:nil | KwRestParam] the value of the parameter
8951+ # [:nil | ArgsForward | KwRestParam] the value of the parameter
89318952 attr_reader :value
89328953
89338954 def initialize ( value )
@@ -9042,7 +9063,7 @@ def format(q)
90429063 q . format ( rest ) if rest && rest . is_a? ( ExcessedComma )
90439064 end
90449065
9045- if [ Def , Defs ] . include? ( q . parent . class )
9066+ if [ Def , Defs , DefEndless ] . include? ( q . parent . class )
90469067 q . group ( 0 , "(" , ")" ) do
90479068 q . indent do
90489069 q . breakable ( "" )
@@ -9142,8 +9163,8 @@ def to_json(*opts)
91429163 # (nil | ArgsForward | ExcessedComma | RestParam) rest,
91439164 # (nil | Array[Ident]) posts,
91449165 # (nil | Array[[Ident, nil | untyped]]) keywords,
9145- # (nil | :nil | KwRestParam) keyword_rest,
9146- # (nil | BlockArg) block
9166+ # (nil | :nil | ArgsForward | KwRestParam) keyword_rest,
9167+ # (nil | :& | BlockArg) block
91479168 # ) -> Params
91489169 def on_params (
91499170 requireds ,
@@ -9161,7 +9182,7 @@ def on_params(
91619182 *posts ,
91629183 *keywords &.flat_map { |( key , value ) | [ key , value || nil ] } ,
91639184 ( keyword_rest if keyword_rest != :nil ) ,
9164- block
9185+ ( block if block != :& )
91659186 ] . compact
91669187
91679188 location =
@@ -9178,7 +9199,7 @@ def on_params(
91789199 posts : posts || [ ] ,
91799200 keywords : keywords || [ ] ,
91809201 keyword_rest : keyword_rest ,
9181- block : block ,
9202+ block : ( block if block != :& ) ,
91829203 location : location
91839204 )
91849205 end
0 commit comments