syntax_tree 5.3.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -1
  3. data/CHANGELOG.md +64 -1
  4. data/Gemfile.lock +2 -2
  5. data/README.md +28 -9
  6. data/Rakefile +12 -8
  7. data/bin/console +1 -0
  8. data/bin/whitequark +79 -0
  9. data/doc/changing_structure.md +16 -0
  10. data/lib/syntax_tree/basic_visitor.rb +44 -5
  11. data/lib/syntax_tree/cli.rb +2 -2
  12. data/lib/syntax_tree/dsl.rb +23 -11
  13. data/lib/syntax_tree/{visitor/field_visitor.rb → field_visitor.rb} +54 -55
  14. data/lib/syntax_tree/formatter.rb +1 -1
  15. data/lib/syntax_tree/index.rb +56 -54
  16. data/lib/syntax_tree/json_visitor.rb +55 -0
  17. data/lib/syntax_tree/language_server.rb +157 -2
  18. data/lib/syntax_tree/match_visitor.rb +120 -0
  19. data/lib/syntax_tree/mermaid.rb +177 -0
  20. data/lib/syntax_tree/mermaid_visitor.rb +69 -0
  21. data/lib/syntax_tree/{visitor/mutation_visitor.rb → mutation_visitor.rb} +27 -27
  22. data/lib/syntax_tree/node.rb +198 -107
  23. data/lib/syntax_tree/parser.rb +322 -118
  24. data/lib/syntax_tree/pretty_print_visitor.rb +83 -0
  25. data/lib/syntax_tree/reflection.rb +241 -0
  26. data/lib/syntax_tree/translation/parser.rb +3019 -0
  27. data/lib/syntax_tree/translation/rubocop_ast.rb +21 -0
  28. data/lib/syntax_tree/translation.rb +28 -0
  29. data/lib/syntax_tree/version.rb +1 -1
  30. data/lib/syntax_tree/with_scope.rb +244 -0
  31. data/lib/syntax_tree/yarv/basic_block.rb +53 -0
  32. data/lib/syntax_tree/yarv/calldata.rb +91 -0
  33. data/lib/syntax_tree/yarv/compiler.rb +110 -100
  34. data/lib/syntax_tree/yarv/control_flow_graph.rb +257 -0
  35. data/lib/syntax_tree/yarv/data_flow_graph.rb +338 -0
  36. data/lib/syntax_tree/yarv/decompiler.rb +1 -1
  37. data/lib/syntax_tree/yarv/disassembler.rb +104 -80
  38. data/lib/syntax_tree/yarv/instruction_sequence.rb +43 -18
  39. data/lib/syntax_tree/yarv/instructions.rb +203 -649
  40. data/lib/syntax_tree/yarv/legacy.rb +12 -24
  41. data/lib/syntax_tree/yarv/sea_of_nodes.rb +534 -0
  42. data/lib/syntax_tree/yarv.rb +18 -0
  43. data/lib/syntax_tree.rb +88 -56
  44. data/tasks/sorbet.rake +277 -0
  45. data/tasks/whitequark.rake +87 -0
  46. metadata +23 -11
  47. data/.gitmodules +0 -9
  48. data/lib/syntax_tree/language_server/inlay_hints.rb +0 -159
  49. data/lib/syntax_tree/visitor/environment.rb +0 -84
  50. data/lib/syntax_tree/visitor/json_visitor.rb +0 -55
  51. data/lib/syntax_tree/visitor/match_visitor.rb +0 -122
  52. data/lib/syntax_tree/visitor/pretty_print_visitor.rb +0 -85
  53. data/lib/syntax_tree/visitor/with_environment.rb +0 -140
@@ -126,18 +126,28 @@ module SyntaxTree
126
126
  raise NotImplementedError
127
127
  end
128
128
 
129
+ def start_char
130
+ location.start_char
131
+ end
132
+
133
+ def end_char
134
+ location.end_char
135
+ end
136
+
129
137
  def pretty_print(q)
130
- visitor = Visitor::PrettyPrintVisitor.new(q)
131
- visitor.visit(self)
138
+ accept(PrettyPrintVisitor.new(q))
132
139
  end
133
140
 
134
141
  def to_json(*opts)
135
- visitor = Visitor::JSONVisitor.new
136
- visitor.visit(self).to_json(*opts)
142
+ accept(JSONVisitor.new).to_json(*opts)
143
+ end
144
+
145
+ def to_mermaid
146
+ accept(MermaidVisitor.new)
137
147
  end
138
148
 
139
149
  def construct_keys
140
- PrettierPrint.format(+"") { |q| Visitor::MatchVisitor.new(q).visit(self) }
150
+ PrettierPrint.format(+"") { |q| accept(MatchVisitor.new(q)) }
141
151
  end
142
152
  end
143
153
 
@@ -555,7 +565,7 @@ module SyntaxTree
555
565
  # collection[]
556
566
  #
557
567
  class ARef < Node
558
- # [untyped] the value being indexed
568
+ # [Node] the value being indexed
559
569
  attr_reader :collection
560
570
 
561
571
  # [nil | Args] the value being passed within the brackets
@@ -633,7 +643,7 @@ module SyntaxTree
633
643
  # collection[index] = value
634
644
  #
635
645
  class ARefField < Node
636
- # [untyped] the value being indexed
646
+ # [Node] the value being indexed
637
647
  attr_reader :collection
638
648
 
639
649
  # [nil | Args] the value being passed within the brackets
@@ -808,7 +818,7 @@ module SyntaxTree
808
818
  # method(first, second, third)
809
819
  #
810
820
  class Args < Node
811
- # [Array[ untyped ]] the arguments that this node wraps
821
+ # [Array[ Node ]] the arguments that this node wraps
812
822
  attr_reader :parts
813
823
 
814
824
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -874,7 +884,7 @@ module SyntaxTree
874
884
  # method(&expression)
875
885
  #
876
886
  class ArgBlock < Node
877
- # [nil | untyped] the expression being turned into a block
887
+ # [nil | Node] the expression being turned into a block
878
888
  attr_reader :value
879
889
 
880
890
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -926,7 +936,7 @@ module SyntaxTree
926
936
  # method(*arguments)
927
937
  #
928
938
  class ArgStar < Node
929
- # [nil | untyped] the expression being splatted
939
+ # [nil | Node] the expression being splatted
930
940
  attr_reader :value
931
941
 
932
942
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -1129,7 +1139,8 @@ module SyntaxTree
1129
1139
  end
1130
1140
  end
1131
1141
 
1132
- # [LBracket] the bracket that opens this array
1142
+ # [nil | LBracket | QSymbolsBeg | QWordsBeg | SymbolsBeg | WordsBeg] the
1143
+ # bracket that opens this array
1133
1144
  attr_reader :lbracket
1134
1145
 
1135
1146
  # [nil | Args] the contents of the array
@@ -1287,7 +1298,7 @@ module SyntaxTree
1287
1298
  # [nil | VarRef] the optional constant wrapper
1288
1299
  attr_reader :constant
1289
1300
 
1290
- # [Array[ untyped ]] the regular positional arguments that this array
1301
+ # [Array[ Node ]] the regular positional arguments that this array
1291
1302
  # pattern is matching against
1292
1303
  attr_reader :requireds
1293
1304
 
@@ -1295,7 +1306,7 @@ module SyntaxTree
1295
1306
  # positional arguments
1296
1307
  attr_reader :rest
1297
1308
 
1298
- # [Array[ untyped ]] the list of positional arguments occurring after the
1309
+ # [Array[ Node ]] the list of positional arguments occurring after the
1299
1310
  # optional star if there is one
1300
1311
  attr_reader :posts
1301
1312
 
@@ -1405,7 +1416,7 @@ module SyntaxTree
1405
1416
  # to assign the result of the expression to
1406
1417
  attr_reader :target
1407
1418
 
1408
- # [untyped] the expression to be assigned
1419
+ # [Node] the expression to be assigned
1409
1420
  attr_reader :value
1410
1421
 
1411
1422
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -1480,10 +1491,10 @@ module SyntaxTree
1480
1491
  #
1481
1492
  # In the above example, the would be two Assoc nodes.
1482
1493
  class Assoc < Node
1483
- # [untyped] the key of this pair
1494
+ # [Node] the key of this pair
1484
1495
  attr_reader :key
1485
1496
 
1486
- # [untyped] the value of this pair
1497
+ # [nil | Node] the value of this pair
1487
1498
  attr_reader :value
1488
1499
 
1489
1500
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -1537,7 +1548,7 @@ module SyntaxTree
1537
1548
  private
1538
1549
 
1539
1550
  def format_contents(q)
1540
- q.parent.format_key(q, key)
1551
+ (q.parent || HashKeyFormatter::Identity.new).format_key(q, key)
1541
1552
  return unless value
1542
1553
 
1543
1554
  if key.comments.empty? && AssignFormatting.skip_indent?(value)
@@ -1558,7 +1569,7 @@ module SyntaxTree
1558
1569
  # { **pairs }
1559
1570
  #
1560
1571
  class AssocSplat < Node
1561
- # [nil | untyped] the expression that is being splatted
1572
+ # [nil | Node] the expression that is being splatted
1562
1573
  attr_reader :value
1563
1574
 
1564
1575
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -1754,6 +1765,20 @@ module SyntaxTree
1754
1765
  end
1755
1766
  end
1756
1767
 
1768
+ # When formatting a single assoc node without the context of the parent
1769
+ # hash, this formatter is used. It uses whatever is present in the node,
1770
+ # because there is nothing to be consistent with.
1771
+ class Identity
1772
+ def format_key(q, key)
1773
+ if key.is_a?(Label)
1774
+ q.format(key)
1775
+ else
1776
+ q.format(key)
1777
+ q.text(" =>")
1778
+ end
1779
+ end
1780
+ end
1781
+
1757
1782
  def self.for(container)
1758
1783
  labels =
1759
1784
  container.assocs.all? do |assoc|
@@ -1908,7 +1933,7 @@ module SyntaxTree
1908
1933
  # end
1909
1934
  #
1910
1935
  class PinnedBegin < Node
1911
- # [untyped] the expression being pinned
1936
+ # [Node] the expression being pinned
1912
1937
  attr_reader :statement
1913
1938
 
1914
1939
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -1989,13 +2014,13 @@ module SyntaxTree
1989
2014
  }
1990
2015
  end
1991
2016
 
1992
- # [untyped] the left-hand side of the expression
2017
+ # [Node] the left-hand side of the expression
1993
2018
  attr_reader :left
1994
2019
 
1995
2020
  # [Symbol] the operator used between the two expressions
1996
2021
  attr_reader :operator
1997
2022
 
1998
- # [untyped] the right-hand side of the expression
2023
+ # [Node] the right-hand side of the expression
1999
2024
  attr_reader :right
2000
2025
 
2001
2026
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -2149,6 +2174,14 @@ module SyntaxTree
2149
2174
  other.is_a?(BlockVar) && params === other.params &&
2150
2175
  ArrayMatch.call(locals, other.locals)
2151
2176
  end
2177
+
2178
+ # When a single required parameter is declared for a block, it gets
2179
+ # automatically expanded if the values being yielded into it are an array.
2180
+ def arg0?
2181
+ params.requireds.length == 1 && params.optionals.empty? &&
2182
+ params.rest.nil? && params.posts.empty? && params.keywords.empty? &&
2183
+ params.keyword_rest.nil? && params.block.nil?
2184
+ end
2152
2185
  end
2153
2186
 
2154
2187
  # BlockArg represents declaring a block parameter on a method definition.
@@ -2242,7 +2275,7 @@ module SyntaxTree
2242
2275
  @comments = []
2243
2276
  end
2244
2277
 
2245
- def bind(start_char, start_column, end_char, end_column)
2278
+ def bind(parser, start_char, start_column, end_char, end_column)
2246
2279
  @location =
2247
2280
  Location.new(
2248
2281
  start_line: location.start_line,
@@ -2256,6 +2289,7 @@ module SyntaxTree
2256
2289
  # Here we're going to determine the bounds for the statements
2257
2290
  consequent = rescue_clause || else_clause || ensure_clause
2258
2291
  statements.bind(
2292
+ parser,
2259
2293
  start_char,
2260
2294
  start_column,
2261
2295
  consequent ? consequent.location.start_char : end_char,
@@ -2646,7 +2680,7 @@ module SyntaxTree
2646
2680
  # Of course there are a lot of caveats to that, including trailing operators
2647
2681
  # when necessary, where comments are places, how blocks are aligned, etc.
2648
2682
  class CallChainFormatter
2649
- # [Call | MethodAddBlock] the top of the call chain
2683
+ # [CallNode | MethodAddBlock] the top of the call chain
2650
2684
  attr_reader :node
2651
2685
 
2652
2686
  def initialize(node)
@@ -2867,7 +2901,7 @@ module SyntaxTree
2867
2901
  # receiver.message
2868
2902
  #
2869
2903
  class CallNode < Node
2870
- # [nil | untyped] the receiver of the method call
2904
+ # [nil | Node] the receiver of the method call
2871
2905
  attr_reader :receiver
2872
2906
 
2873
2907
  # [nil | :"::" | Op | Period] the operator being used to send the message
@@ -3043,7 +3077,7 @@ module SyntaxTree
3043
3077
  # [Kw] the keyword that opens this expression
3044
3078
  attr_reader :keyword
3045
3079
 
3046
- # [nil | untyped] optional value being switched on
3080
+ # [nil | Node] optional value being switched on
3047
3081
  attr_reader :value
3048
3082
 
3049
3083
  # [In | When] the next clause in the chain
@@ -3122,14 +3156,14 @@ module SyntaxTree
3122
3156
  # value => pattern
3123
3157
  #
3124
3158
  class RAssign < Node
3125
- # [untyped] the left-hand expression
3159
+ # [Node] the left-hand expression
3126
3160
  attr_reader :value
3127
3161
 
3128
3162
  # [Kw | Op] the operator being used to match against the pattern, which is
3129
3163
  # either => or in
3130
3164
  attr_reader :operator
3131
3165
 
3132
- # [untyped] the pattern on the right-hand side of the expression
3166
+ # [Node] the pattern on the right-hand side of the expression
3133
3167
  attr_reader :pattern
3134
3168
 
3135
3169
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -3240,7 +3274,7 @@ module SyntaxTree
3240
3274
  # defined
3241
3275
  attr_reader :constant
3242
3276
 
3243
- # [nil | untyped] the optional superclass declaration
3277
+ # [nil | Node] the optional superclass declaration
3244
3278
  attr_reader :superclass
3245
3279
 
3246
3280
  # [BodyStmt] the expressions to execute within the context of the class
@@ -3378,7 +3412,7 @@ module SyntaxTree
3378
3412
  # [Args] the arguments being sent with the message
3379
3413
  attr_reader :arguments
3380
3414
 
3381
- # [nil | Block] the optional block being passed to the method
3415
+ # [nil | BlockNode] the optional block being passed to the method
3382
3416
  attr_reader :block
3383
3417
 
3384
3418
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -3484,19 +3518,19 @@ module SyntaxTree
3484
3518
  # object.method argument
3485
3519
  #
3486
3520
  class CommandCall < Node
3487
- # [untyped] the receiver of the message
3521
+ # [nil | Node] the receiver of the message
3488
3522
  attr_reader :receiver
3489
3523
 
3490
- # [:"::" | Op | Period] the operator used to send the message
3524
+ # [nil | :"::" | Op | Period] the operator used to send the message
3491
3525
  attr_reader :operator
3492
3526
 
3493
- # [Const | Ident | Op] the message being send
3527
+ # [:call | Const | Ident | Op] the message being send
3494
3528
  attr_reader :message
3495
3529
 
3496
- # [nil | Args] the arguments going along with the message
3530
+ # [nil | Args | ArgParen] the arguments going along with the message
3497
3531
  attr_reader :arguments
3498
3532
 
3499
- # [nil | Block] the block associated with this method call
3533
+ # [nil | BlockNode] the block associated with this method call
3500
3534
  attr_reader :block
3501
3535
 
3502
3536
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -3782,7 +3816,7 @@ module SyntaxTree
3782
3816
  # object::Const = value
3783
3817
  #
3784
3818
  class ConstPathField < Node
3785
- # [untyped] the source of the constant
3819
+ # [Node] the source of the constant
3786
3820
  attr_reader :parent
3787
3821
 
3788
3822
  # [Const] the constant itself
@@ -3846,7 +3880,7 @@ module SyntaxTree
3846
3880
  # object::Const
3847
3881
  #
3848
3882
  class ConstPathRef < Node
3849
- # [untyped] the source of the constant
3883
+ # [Node] the source of the constant
3850
3884
  attr_reader :parent
3851
3885
 
3852
3886
  # [Const] the constant itself
@@ -4015,7 +4049,7 @@ module SyntaxTree
4015
4049
  # def object.method(param) result end
4016
4050
  #
4017
4051
  class DefNode < Node
4018
- # [nil | untyped] the target where the method is being defined
4052
+ # [nil | Node] the target where the method is being defined
4019
4053
  attr_reader :target
4020
4054
 
4021
4055
  # [nil | Op | Period] the operator being used to declare the method
@@ -4027,7 +4061,7 @@ module SyntaxTree
4027
4061
  # [nil | Params | Paren] the parameter declaration for the method
4028
4062
  attr_reader :params
4029
4063
 
4030
- # [BodyStmt | untyped] the expressions to be executed by the method
4064
+ # [BodyStmt | Node] the expressions to be executed by the method
4031
4065
  attr_reader :bodystmt
4032
4066
 
4033
4067
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -4090,7 +4124,8 @@ module SyntaxTree
4090
4124
  def format(q)
4091
4125
  q.group do
4092
4126
  q.group do
4093
- q.text("def ")
4127
+ q.text("def")
4128
+ q.text(" ") if target || name.comments.empty?
4094
4129
 
4095
4130
  if target
4096
4131
  q.format(target)
@@ -4160,7 +4195,7 @@ module SyntaxTree
4160
4195
  # defined?(variable)
4161
4196
  #
4162
4197
  class Defined < Node
4163
- # [untyped] the value being sent to the keyword
4198
+ # [Node] the value being sent to the keyword
4164
4199
  attr_reader :value
4165
4200
 
4166
4201
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -4317,7 +4352,7 @@ module SyntaxTree
4317
4352
  # are no parentheses around the arguments to that command, so we need to
4318
4353
  # break the block.
4319
4354
  case q.parent
4320
- when Command, CommandCall
4355
+ when nil, Command, CommandCall
4321
4356
  q.break_parent
4322
4357
  format_break(q, break_opening, break_closing)
4323
4358
  return
@@ -4371,7 +4406,7 @@ module SyntaxTree
4371
4406
  # If we're a sibling of a control-flow keyword, then we're going to have to
4372
4407
  # use the do..end bounds.
4373
4408
  def forced_do_end_bounds?(q)
4374
- case q.parent.call
4409
+ case q.parent&.call
4375
4410
  when Break, Next, ReturnNode, Super
4376
4411
  true
4377
4412
  else
@@ -4451,13 +4486,13 @@ module SyntaxTree
4451
4486
  #
4452
4487
  # One of the sides of the expression may be nil, but not both.
4453
4488
  class RangeNode < Node
4454
- # [nil | untyped] the left side of the expression
4489
+ # [nil | Node] the left side of the expression
4455
4490
  attr_reader :left
4456
4491
 
4457
4492
  # [Op] the operator used for this range
4458
4493
  attr_reader :operator
4459
4494
 
4460
- # [nil | untyped] the right side of the expression
4495
+ # [nil | Node] the right side of the expression
4461
4496
  attr_reader :right
4462
4497
 
4463
4498
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -4578,7 +4613,7 @@ module SyntaxTree
4578
4613
  # dynamic symbol
4579
4614
  attr_reader :parts
4580
4615
 
4581
- # [String] the quote used to delimit the dynamic symbol
4616
+ # [nil | String] the quote used to delimit the dynamic symbol
4582
4617
  attr_reader :quote
4583
4618
 
4584
4619
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -4776,7 +4811,7 @@ module SyntaxTree
4776
4811
  # end
4777
4812
  #
4778
4813
  class Elsif < Node
4779
- # [untyped] the expression to be checked
4814
+ # [Node] the expression to be checked
4780
4815
  attr_reader :predicate
4781
4816
 
4782
4817
  # [Statements] the expressions to be executed
@@ -4872,6 +4907,25 @@ module SyntaxTree
4872
4907
  def initialize(value:, location:)
4873
4908
  @value = value
4874
4909
  @location = location
4910
+
4911
+ @leading = false
4912
+ @trailing = false
4913
+ end
4914
+
4915
+ def leading!
4916
+ @leading = true
4917
+ end
4918
+
4919
+ def leading?
4920
+ @leading
4921
+ end
4922
+
4923
+ def trailing!
4924
+ @trailing = true
4925
+ end
4926
+
4927
+ def trailing?
4928
+ @trailing
4875
4929
  end
4876
4930
 
4877
4931
  def inline?
@@ -4908,7 +4962,13 @@ module SyntaxTree
4908
4962
  end
4909
4963
 
4910
4964
  def format(q)
4911
- q.trim
4965
+ if (q.parent.is_a?(DefNode) && q.parent.endless?) ||
4966
+ q.parent.is_a?(Statements)
4967
+ q.trim
4968
+ else
4969
+ q.breakable_return
4970
+ end
4971
+
4912
4972
  q.text(value)
4913
4973
  end
4914
4974
 
@@ -5177,7 +5237,7 @@ module SyntaxTree
5177
5237
  # object.variable = value
5178
5238
  #
5179
5239
  class Field < Node
5180
- # [untyped] the parent object that owns the field being assigned
5240
+ # [Node] the parent object that owns the field being assigned
5181
5241
  attr_reader :parent
5182
5242
 
5183
5243
  # [:"::" | Op | Period] the operator being used for the assignment
@@ -5303,13 +5363,13 @@ module SyntaxTree
5303
5363
  # end
5304
5364
  #
5305
5365
  class FndPtn < Node
5306
- # [nil | untyped] the optional constant wrapper
5366
+ # [nil | Node] the optional constant wrapper
5307
5367
  attr_reader :constant
5308
5368
 
5309
5369
  # [VarField] the splat on the left-hand side
5310
5370
  attr_reader :left
5311
5371
 
5312
- # [Array[ untyped ]] the list of positional expressions in the pattern that
5372
+ # [Array[ Node ]] the list of positional expressions in the pattern that
5313
5373
  # are being matched
5314
5374
  attr_reader :values
5315
5375
 
@@ -5405,7 +5465,7 @@ module SyntaxTree
5405
5465
  # pull values out of the object being enumerated
5406
5466
  attr_reader :index
5407
5467
 
5408
- # [untyped] the object being enumerated in the loop
5468
+ # [Node] the object being enumerated in the loop
5409
5469
  attr_reader :collection
5410
5470
 
5411
5471
  # [Statements] the statements to be executed
@@ -5884,7 +5944,7 @@ module SyntaxTree
5884
5944
  # [Label] the keyword being used
5885
5945
  attr_reader :key
5886
5946
 
5887
- # [untyped] the optional value for the keyword
5947
+ # [Node] the optional value for the keyword
5888
5948
  attr_reader :value
5889
5949
 
5890
5950
  def initialize(key, value)
@@ -5897,7 +5957,7 @@ module SyntaxTree
5897
5957
  end
5898
5958
 
5899
5959
  def format(q)
5900
- q.format(key)
5960
+ HashKeyFormatter::Labels.new.format_key(q, key)
5901
5961
 
5902
5962
  if value
5903
5963
  q.text(" ")
@@ -5925,11 +5985,11 @@ module SyntaxTree
5925
5985
  end
5926
5986
  end
5927
5987
 
5928
- # [nil | untyped] the optional constant wrapper
5988
+ # [nil | Node] the optional constant wrapper
5929
5989
  attr_reader :constant
5930
5990
 
5931
- # [Array[ [Label, untyped] ]] the set of tuples representing the keywords
5932
- # that should be matched against in the pattern
5991
+ # [Array[ [DynaSymbol | Label, nil | Node] ]] the set of tuples
5992
+ # representing the keywords that should be matched against in the pattern
5933
5993
  attr_reader :keywords
5934
5994
 
5935
5995
  # [nil | VarField] an optional parameter to gather up all remaining keywords
@@ -6354,7 +6414,7 @@ module SyntaxTree
6354
6414
  # end
6355
6415
  #
6356
6416
  class IfNode < Node
6357
- # [untyped] the expression to be checked
6417
+ # [Node] the expression to be checked
6358
6418
  attr_reader :predicate
6359
6419
 
6360
6420
  # [Statements] the expressions to be executed
@@ -6427,13 +6487,13 @@ module SyntaxTree
6427
6487
  # predicate ? truthy : falsy
6428
6488
  #
6429
6489
  class IfOp < Node
6430
- # [untyped] the expression to be checked
6490
+ # [Node] the expression to be checked
6431
6491
  attr_reader :predicate
6432
6492
 
6433
- # [untyped] the expression to be executed if the predicate is truthy
6493
+ # [Node] the expression to be executed if the predicate is truthy
6434
6494
  attr_reader :truthy
6435
6495
 
6436
- # [untyped] the expression to be executed if the predicate is falsy
6496
+ # [Node] the expression to be executed if the predicate is falsy
6437
6497
  attr_reader :falsy
6438
6498
 
6439
6499
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -6617,7 +6677,7 @@ module SyntaxTree
6617
6677
  # end
6618
6678
  #
6619
6679
  class In < Node
6620
- # [untyped] the pattern to check against
6680
+ # [Node] the pattern to check against
6621
6681
  attr_reader :pattern
6622
6682
 
6623
6683
  # [Statements] the expressions to execute if the pattern matched
@@ -7400,7 +7460,7 @@ module SyntaxTree
7400
7460
  # [MLHS | MLHSParen] the target of the multiple assignment
7401
7461
  attr_reader :target
7402
7462
 
7403
- # [untyped] the value being assigned
7463
+ # [Node] the value being assigned
7404
7464
  attr_reader :value
7405
7465
 
7406
7466
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -7460,10 +7520,10 @@ module SyntaxTree
7460
7520
  # method {}
7461
7521
  #
7462
7522
  class MethodAddBlock < Node
7463
- # [Call | Command | CommandCall] the method call
7523
+ # [ARef | CallNode | Command | CommandCall | Super | ZSuper] the method call
7464
7524
  attr_reader :call
7465
7525
 
7466
- # [Block] the block being sent with the method call
7526
+ # [BlockNode] the block being sent with the method call
7467
7527
  attr_reader :block
7468
7528
 
7469
7529
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -7535,8 +7595,12 @@ module SyntaxTree
7535
7595
  # first, second, third = value
7536
7596
  #
7537
7597
  class MLHS < Node
7538
- # Array[ARefField | ArgStar | Field | Ident | MLHSParen | VarField] the
7539
- # parts of the left-hand side of a multiple assignment
7598
+ # [
7599
+ # Array[
7600
+ # ARefField | ArgStar | ConstPathField | Field | Ident | MLHSParen |
7601
+ # TopConstField | VarField
7602
+ # ]
7603
+ # ] the parts of the left-hand side of a multiple assignment
7540
7604
  attr_reader :parts
7541
7605
 
7542
7606
  # [boolean] whether or not there is a trailing comma at the end of this
@@ -7762,7 +7826,7 @@ module SyntaxTree
7762
7826
  # values = first, second, third
7763
7827
  #
7764
7828
  class MRHS < Node
7765
- # Array[untyped] the parts that are being assigned
7829
+ # [Array[Node]] the parts that are being assigned
7766
7830
  attr_reader :parts
7767
7831
 
7768
7832
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -7938,7 +8002,7 @@ module SyntaxTree
7938
8002
  # [Op] the operator being used for the assignment
7939
8003
  attr_reader :operator
7940
8004
 
7941
- # [untyped] the expression to be assigned
8005
+ # [Node] the expression to be assigned
7942
8006
  attr_reader :value
7943
8007
 
7944
8008
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -8095,7 +8159,7 @@ module SyntaxTree
8095
8159
  # [Ident] the name of the parameter
8096
8160
  attr_reader :name
8097
8161
 
8098
- # [untyped] the value of the parameter
8162
+ # [Node] the value of the parameter
8099
8163
  attr_reader :value
8100
8164
 
8101
8165
  def initialize(name, value)
@@ -8120,7 +8184,7 @@ module SyntaxTree
8120
8184
  # [Ident] the name of the parameter
8121
8185
  attr_reader :name
8122
8186
 
8123
- # [nil | untyped] the value of the parameter
8187
+ # [nil | Node] the value of the parameter
8124
8188
  attr_reader :value
8125
8189
 
8126
8190
  def initialize(name, value)
@@ -8161,10 +8225,10 @@ module SyntaxTree
8161
8225
  end
8162
8226
  end
8163
8227
 
8164
- # [Array[ Ident ]] any required parameters
8228
+ # [Array[ Ident | MLHSParen ]] any required parameters
8165
8229
  attr_reader :requireds
8166
8230
 
8167
- # [Array[ [ Ident, untyped ] ]] any optional parameters and their default
8231
+ # [Array[ [ Ident, Node ] ]] any optional parameters and their default
8168
8232
  # values
8169
8233
  attr_reader :optionals
8170
8234
 
@@ -8176,11 +8240,12 @@ module SyntaxTree
8176
8240
  # parameter
8177
8241
  attr_reader :posts
8178
8242
 
8179
- # [Array[ [ Ident, nil | untyped ] ]] any keyword parameters and their
8243
+ # [Array[ [ Label, nil | Node ] ]] any keyword parameters and their
8180
8244
  # optional default values
8181
8245
  attr_reader :keywords
8182
8246
 
8183
- # [nil | :nil | KwRestParam] the optional keyword rest parameter
8247
+ # [nil | :nil | ArgsForward | KwRestParam] the optional keyword rest
8248
+ # parameter
8184
8249
  attr_reader :keyword_rest
8185
8250
 
8186
8251
  # [nil | BlockArg] the optional block parameter
@@ -8369,7 +8434,7 @@ module SyntaxTree
8369
8434
  # [LParen] the left parenthesis that opened this statement
8370
8435
  attr_reader :lparen
8371
8436
 
8372
- # [nil | untyped] the expression inside the parentheses
8437
+ # [nil | Node] the expression inside the parentheses
8373
8438
  attr_reader :contents
8374
8439
 
8375
8440
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -9218,7 +9283,7 @@ module SyntaxTree
9218
9283
  # end
9219
9284
  #
9220
9285
  class RescueEx < Node
9221
- # [untyped] the list of exceptions being rescued
9286
+ # [nil | Node] the list of exceptions being rescued
9222
9287
  attr_reader :exceptions
9223
9288
 
9224
9289
  # [nil | Field | VarField] the expression being used to capture the raised
@@ -9296,7 +9361,7 @@ module SyntaxTree
9296
9361
  # [Kw] the rescue keyword
9297
9362
  attr_reader :keyword
9298
9363
 
9299
- # [RescueEx] the exceptions being rescued
9364
+ # [nil | RescueEx] the exceptions being rescued
9300
9365
  attr_reader :exception
9301
9366
 
9302
9367
  # [Statements] the expressions to evaluate when an error is rescued
@@ -9416,10 +9481,10 @@ module SyntaxTree
9416
9481
  # expression rescue value
9417
9482
  #
9418
9483
  class RescueMod < Node
9419
- # [untyped] the expression to execute
9484
+ # [Node] the expression to execute
9420
9485
  attr_reader :statement
9421
9486
 
9422
- # [untyped] the value to use if the executed expression raises an error
9487
+ # [Node] the value to use if the executed expression raises an error
9423
9488
  attr_reader :value
9424
9489
 
9425
9490
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -9678,7 +9743,7 @@ module SyntaxTree
9678
9743
  # end
9679
9744
  #
9680
9745
  class SClass < Node
9681
- # [untyped] the target of the singleton class to enter
9746
+ # [Node] the target of the singleton class to enter
9682
9747
  attr_reader :target
9683
9748
 
9684
9749
  # [BodyStmt] the expressions to be executed
@@ -9752,23 +9817,19 @@ module SyntaxTree
9752
9817
  # propagate that onto void_stmt nodes inside the stmts in order to make sure
9753
9818
  # all comments get printed appropriately.
9754
9819
  class Statements < Node
9755
- # [SyntaxTree] the parser that is generating this node
9756
- attr_reader :parser
9757
-
9758
- # [Array[ untyped ]] the list of expressions contained within this node
9820
+ # [Array[ Node ]] the list of expressions contained within this node
9759
9821
  attr_reader :body
9760
9822
 
9761
9823
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
9762
9824
  attr_reader :comments
9763
9825
 
9764
- def initialize(parser, body:, location:)
9765
- @parser = parser
9826
+ def initialize(body:, location:)
9766
9827
  @body = body
9767
9828
  @location = location
9768
9829
  @comments = []
9769
9830
  end
9770
9831
 
9771
- def bind(start_char, start_column, end_char, end_column)
9832
+ def bind(parser, start_char, start_column, end_char, end_column)
9772
9833
  @location =
9773
9834
  Location.new(
9774
9835
  start_line: location.start_line,
@@ -9794,7 +9855,7 @@ module SyntaxTree
9794
9855
  body[0] = VoidStmt.new(location: location)
9795
9856
  end
9796
9857
 
9797
- attach_comments(start_char, end_char)
9858
+ attach_comments(parser, start_char, end_char)
9798
9859
  end
9799
9860
 
9800
9861
  def bind_end(end_char, end_column)
@@ -9826,7 +9887,6 @@ module SyntaxTree
9826
9887
  def copy(body: nil, location: nil)
9827
9888
  node =
9828
9889
  Statements.new(
9829
- parser,
9830
9890
  body: body || self.body,
9831
9891
  location: location || self.location
9832
9892
  )
@@ -9838,7 +9898,7 @@ module SyntaxTree
9838
9898
  alias deconstruct child_nodes
9839
9899
 
9840
9900
  def deconstruct_keys(_keys)
9841
- { parser: parser, body: body, location: location, comments: comments }
9901
+ { body: body, location: location, comments: comments }
9842
9902
  end
9843
9903
 
9844
9904
  def format(q)
@@ -9898,7 +9958,7 @@ module SyntaxTree
9898
9958
  # As efficiently as possible, gather up all of the comments that have been
9899
9959
  # found while this statements list was being parsed and add them into the
9900
9960
  # body.
9901
- def attach_comments(start_char, end_char)
9961
+ def attach_comments(parser, start_char, end_char)
9902
9962
  parser_comments = parser.comments
9903
9963
 
9904
9964
  comment_index = 0
@@ -9945,9 +10005,13 @@ module SyntaxTree
9945
10005
  # string
9946
10006
  attr_reader :parts
9947
10007
 
10008
+ # [Array[ Comment | EmbDoc ]] the comments attached to this node
10009
+ attr_reader :comments
10010
+
9948
10011
  def initialize(parts:, location:)
9949
10012
  @parts = parts
9950
10013
  @location = location
10014
+ @comments = []
9951
10015
  end
9952
10016
 
9953
10017
  def accept(visitor)
@@ -9974,6 +10038,33 @@ module SyntaxTree
9974
10038
  def ===(other)
9975
10039
  other.is_a?(StringContent) && ArrayMatch.call(parts, other.parts)
9976
10040
  end
10041
+
10042
+ def format(q)
10043
+ q.text(q.quote)
10044
+ q.group do
10045
+ parts.each do |part|
10046
+ if part.is_a?(TStringContent)
10047
+ value = Quotes.normalize(part.value, q.quote)
10048
+ first = true
10049
+
10050
+ value.each_line(chomp: true) do |line|
10051
+ if first
10052
+ first = false
10053
+ else
10054
+ q.breakable_return
10055
+ end
10056
+
10057
+ q.text(line)
10058
+ end
10059
+
10060
+ q.breakable_return if value.end_with?("\n")
10061
+ else
10062
+ q.format(part)
10063
+ end
10064
+ end
10065
+ end
10066
+ q.text(q.quote)
10067
+ end
9977
10068
  end
9978
10069
 
9979
10070
  # StringConcat represents concatenating two strings together using a backward
@@ -9983,7 +10074,8 @@ module SyntaxTree
9983
10074
  # "second"
9984
10075
  #
9985
10076
  class StringConcat < Node
9986
- # [StringConcat | StringLiteral] the left side of the concatenation
10077
+ # [Heredoc | StringConcat | StringLiteral] the left side of the
10078
+ # concatenation
9987
10079
  attr_reader :left
9988
10080
 
9989
10081
  # [StringLiteral] the right side of the concatenation
@@ -10180,7 +10272,7 @@ module SyntaxTree
10180
10272
  # string literal
10181
10273
  attr_reader :parts
10182
10274
 
10183
- # [String] which quote was used by the string literal
10275
+ # [nil | String] which quote was used by the string literal
10184
10276
  attr_reader :quote
10185
10277
 
10186
10278
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -10425,8 +10517,8 @@ module SyntaxTree
10425
10517
  # :symbol
10426
10518
  #
10427
10519
  class SymbolLiteral < Node
10428
- # [Backtick | Const | CVar | GVar | Ident | IVar | Kw | Op] the value of the
10429
- # symbol
10520
+ # [Backtick | Const | CVar | GVar | Ident | IVar | Kw | Op | TStringContent]
10521
+ # the value of the symbol
10430
10522
  attr_reader :value
10431
10523
 
10432
10524
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -10465,6 +10557,7 @@ module SyntaxTree
10465
10557
 
10466
10558
  def format(q)
10467
10559
  q.text(":")
10560
+ q.text("\\") if value.comments.any?
10468
10561
  q.format(value)
10469
10562
  end
10470
10563
 
@@ -10934,7 +11027,7 @@ module SyntaxTree
10934
11027
  # not value
10935
11028
  #
10936
11029
  class Not < Node
10937
- # [nil | untyped] the statement on which to operate
11030
+ # [nil | Node] the statement on which to operate
10938
11031
  attr_reader :statement
10939
11032
 
10940
11033
  # [boolean] whether or not parentheses were used
@@ -11021,7 +11114,7 @@ module SyntaxTree
11021
11114
  # [String] the operator being used
11022
11115
  attr_reader :operator
11023
11116
 
11024
- # [untyped] the statement on which to operate
11117
+ # [Node] the statement on which to operate
11025
11118
  attr_reader :statement
11026
11119
 
11027
11120
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -11165,7 +11258,7 @@ module SyntaxTree
11165
11258
  # end
11166
11259
  #
11167
11260
  class UnlessNode < Node
11168
- # [untyped] the expression to be checked
11261
+ # [Node] the expression to be checked
11169
11262
  attr_reader :predicate
11170
11263
 
11171
11264
  # [Statements] the expressions to be executed
@@ -11311,7 +11404,7 @@ module SyntaxTree
11311
11404
  # end
11312
11405
  #
11313
11406
  class UntilNode < Node
11314
- # [untyped] the expression to be checked
11407
+ # [Node] the expression to be checked
11315
11408
  attr_reader :predicate
11316
11409
 
11317
11410
  # [Statements] the expressions to be executed
@@ -11379,7 +11472,7 @@ module SyntaxTree
11379
11472
  #
11380
11473
  # In the example above, the VarField node represents the +variable+ token.
11381
11474
  class VarField < Node
11382
- # [nil | Const | CVar | GVar | Ident | IVar] the target of this node
11475
+ # [nil | :nil | Const | CVar | GVar | Ident | IVar] the target of this node
11383
11476
  attr_reader :value
11384
11477
 
11385
11478
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -11490,8 +11583,9 @@ module SyntaxTree
11490
11583
  #
11491
11584
  # To be clear, this method should just not exist. It's not good. It's a
11492
11585
  # place of shame. But it's necessary for now, so I'm keeping it.
11493
- def pin(parent)
11494
- replace = PinnedVarRef.new(value: value, location: location)
11586
+ def pin(parent, pin)
11587
+ replace =
11588
+ PinnedVarRef.new(value: value, location: pin.location.to(location))
11495
11589
 
11496
11590
  parent
11497
11591
  .deconstruct_keys([])
@@ -11517,7 +11611,7 @@ module SyntaxTree
11517
11611
  # This can be a plain local variable like the example above. It can also be a
11518
11612
  # a class variable, a global variable, or an instance variable.
11519
11613
  class PinnedVarRef < Node
11520
- # [VarRef] the value of this node
11614
+ # [Const | CVar | GVar | Ident | IVar] the value of this node
11521
11615
  attr_reader :value
11522
11616
 
11523
11617
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
@@ -11631,9 +11725,6 @@ module SyntaxTree
11631
11725
  # ;;
11632
11726
  #
11633
11727
  class VoidStmt < Node
11634
- # [Location] the location of this node
11635
- attr_reader :location
11636
-
11637
11728
  # [Array[ Comment | EmbDoc ]] the comments attached to this node
11638
11729
  attr_reader :comments
11639
11730
 
@@ -11794,7 +11885,7 @@ module SyntaxTree
11794
11885
  # end
11795
11886
  #
11796
11887
  class WhileNode < Node
11797
- # [untyped] the expression to be checked
11888
+ # [Node] the expression to be checked
11798
11889
  attr_reader :predicate
11799
11890
 
11800
11891
  # [Statements] the expressions to be executed