@@ -1173,7 +1173,7 @@ def on_args_add(arguments, argument)
1173
1173
# method(&expression)
1174
1174
#
1175
1175
class ArgBlock
1176
- # [untyped] the expression being turned into a block
1176
+ # [nil | untyped] the expression being turned into a block
1177
1177
attr_reader :value
1178
1178
1179
1179
# [Location] the location of this node
@@ -1194,15 +1194,17 @@ def child_nodes
1194
1194
1195
1195
def format ( q )
1196
1196
q . text ( "&" )
1197
- q . format ( value )
1197
+ q . format ( value ) if value
1198
1198
end
1199
1199
1200
1200
def pretty_print ( q )
1201
1201
q . group ( 2 , "(" , ")" ) do
1202
1202
q . text ( "arg_block" )
1203
1203
1204
- q . breakable
1205
- q . pp ( value )
1204
+ if value
1205
+ q . breakable
1206
+ q . pp ( value )
1207
+ end
1206
1208
1207
1209
q . pp ( Comment ::List . new ( comments ) )
1208
1210
end
@@ -1221,13 +1223,14 @@ def to_json(*opts)
1221
1223
# (false | untyped) block
1222
1224
# ) -> Args
1223
1225
def on_args_add_block ( arguments , block )
1224
- return arguments unless block
1226
+ operator = find_token ( Op , "&" , consume : false )
1227
+ return arguments unless operator
1225
1228
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 )
1231
1234
1232
1235
Args . new (
1233
1236
parts : arguments . parts << arg_block ,
@@ -1896,7 +1899,7 @@ def child_nodes
1896
1899
end
1897
1900
1898
1901
def format ( q )
1899
- if value . is_a? ( HashLiteral )
1902
+ if value & .is_a? ( HashLiteral )
1900
1903
format_contents ( q )
1901
1904
else
1902
1905
q . group { format_contents ( q ) }
@@ -1910,8 +1913,10 @@ def pretty_print(q)
1910
1913
q . breakable
1911
1914
q . pp ( key )
1912
1915
1913
- q . breakable
1914
- q . pp ( value )
1916
+ if value
1917
+ q . breakable
1918
+ q . pp ( value )
1919
+ end
1915
1920
1916
1921
q . pp ( Comment ::List . new ( comments ) )
1917
1922
end
@@ -1931,6 +1936,7 @@ def to_json(*opts)
1931
1936
1932
1937
def format_contents ( q )
1933
1938
q . parent . format_key ( q , key )
1939
+ return unless value
1934
1940
1935
1941
if key . comments . empty? && AssignFormatting . skip_indent? ( value )
1936
1942
q . text ( " " )
@@ -1947,7 +1953,10 @@ def format_contents(q)
1947
1953
# :call-seq:
1948
1954
# on_assoc_new: (untyped key, untyped value) -> Assoc
1949
1955
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 )
1951
1960
end
1952
1961
1953
1962
# AssocSplat represents double-splatting a value into a hash (either a hash
@@ -2578,7 +2587,7 @@ def on_block_var(params, locals)
2578
2587
# def method(&block); end
2579
2588
#
2580
2589
class BlockArg
2581
- # [Ident] the name of the block argument
2590
+ # [nil | Ident] the name of the block argument
2582
2591
attr_reader :name
2583
2592
2584
2593
# [Location] the location of this node
@@ -2599,15 +2608,17 @@ def child_nodes
2599
2608
2600
2609
def format ( q )
2601
2610
q . text ( "&" )
2602
- q . format ( name )
2611
+ q . format ( name ) if name
2603
2612
end
2604
2613
2605
2614
def pretty_print ( q )
2606
2615
q . group ( 2 , "(" , ")" ) do
2607
2616
q . text ( "blockarg" )
2608
2617
2609
- q . breakable
2610
- q . pp ( name )
2618
+ if name
2619
+ q . breakable
2620
+ q . pp ( name )
2621
+ end
2611
2622
2612
2623
q . pp ( Comment ::List . new ( comments ) )
2613
2624
end
@@ -2625,7 +2636,10 @@ def to_json(*opts)
2625
2636
def on_blockarg ( name )
2626
2637
operator = find_token ( Op , "&" )
2627
2638
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 )
2629
2643
end
2630
2644
2631
2645
# bodystmt can't actually determine its bounds appropriately because it
@@ -4419,7 +4433,7 @@ class DefEndless
4419
4433
# [Backtick | Const | Ident | Kw | Op] the name of the method
4420
4434
attr_reader :name
4421
4435
4422
- # [nil | Paren] the parameter declaration for the method
4436
+ # [nil | Params | Paren] the parameter declaration for the method
4423
4437
attr_reader :paren
4424
4438
4425
4439
# [untyped] the expression to be executed by the method
@@ -4463,7 +4477,12 @@ def format(q)
4463
4477
end
4464
4478
4465
4479
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
4467
4486
4468
4487
q . text ( " =" )
4469
4488
q . group do
@@ -4529,21 +4548,6 @@ def on_def(name, params, bodystmt)
4529
4548
# and normal method definitions.
4530
4549
beginning = find_token ( Kw , "def" )
4531
4550
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
-
4547
4551
# If there aren't any params then we need to correct the params node
4548
4552
# location information
4549
4553
if params . is_a? ( Params ) && params . empty?
@@ -4559,18 +4563,35 @@ def on_def(name, params, bodystmt)
4559
4563
params = Params . new ( location : location )
4560
4564
end
4561
4565
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 )
4567
4567
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
4574
4595
end
4575
4596
4576
4597
# 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)
4778
4799
end
4779
4800
4780
4801
beginning = find_token ( Kw , "def" )
4802
+ ending = find_token ( Kw , "end" , consume : false )
4781
4803
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
+ )
4798
4810
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
4803
4823
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
4812
4833
end
4813
4834
4814
4835
# DoBlock represents passing a block to a method call using the +do+ and +end+
@@ -8927,7 +8948,7 @@ def format(q)
8927
8948
end
8928
8949
8929
8950
class KeywordRestFormatter
8930
- # [:nil | KwRestParam] the value of the parameter
8951
+ # [:nil | ArgsForward | KwRestParam] the value of the parameter
8931
8952
attr_reader :value
8932
8953
8933
8954
def initialize ( value )
@@ -9042,7 +9063,7 @@ def format(q)
9042
9063
q . format ( rest ) if rest && rest . is_a? ( ExcessedComma )
9043
9064
end
9044
9065
9045
- if [ Def , Defs ] . include? ( q . parent . class )
9066
+ if [ Def , Defs , DefEndless ] . include? ( q . parent . class )
9046
9067
q . group ( 0 , "(" , ")" ) do
9047
9068
q . indent do
9048
9069
q . breakable ( "" )
@@ -9142,8 +9163,8 @@ def to_json(*opts)
9142
9163
# (nil | ArgsForward | ExcessedComma | RestParam) rest,
9143
9164
# (nil | Array[Ident]) posts,
9144
9165
# (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
9147
9168
# ) -> Params
9148
9169
def on_params (
9149
9170
requireds ,
@@ -9161,7 +9182,7 @@ def on_params(
9161
9182
*posts ,
9162
9183
*keywords &.flat_map { |( key , value ) | [ key , value || nil ] } ,
9163
9184
( keyword_rest if keyword_rest != :nil ) ,
9164
- block
9185
+ ( block if block != :& )
9165
9186
] . compact
9166
9187
9167
9188
location =
@@ -9178,7 +9199,7 @@ def on_params(
9178
9199
posts : posts || [ ] ,
9179
9200
keywords : keywords || [ ] ,
9180
9201
keyword_rest : keyword_rest ,
9181
- block : block ,
9202
+ block : ( block if block != :& ) ,
9182
9203
location : location
9183
9204
)
9184
9205
end
0 commit comments