prism 0.15.1 → 0.16.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -1
  3. data/Makefile +6 -0
  4. data/README.md +2 -0
  5. data/config.yml +21 -20
  6. data/docs/configuration.md +2 -0
  7. data/docs/javascript.md +90 -0
  8. data/docs/releasing.md +27 -0
  9. data/docs/ruby_api.md +2 -0
  10. data/ext/prism/api_node.c +66 -68
  11. data/ext/prism/extension.c +73 -0
  12. data/ext/prism/extension.h +1 -1
  13. data/include/prism/ast.h +40 -40
  14. data/include/prism/defines.h +9 -0
  15. data/include/prism/enc/pm_encoding.h +1 -0
  16. data/include/prism/node.h +0 -17
  17. data/include/prism/parser.h +1 -0
  18. data/include/prism/prettyprint.h +15 -0
  19. data/include/prism/util/pm_buffer.h +10 -4
  20. data/include/prism/util/pm_constant_pool.h +1 -1
  21. data/include/prism/util/pm_newline_list.h +1 -1
  22. data/include/prism/version.h +3 -3
  23. data/include/prism.h +11 -11
  24. data/lib/prism/compiler.rb +0 -3
  25. data/lib/prism/debug.rb +20 -6
  26. data/lib/prism/desugar_compiler.rb +1 -1
  27. data/lib/prism/dispatcher.rb +0 -14
  28. data/lib/prism/dsl.rb +8 -13
  29. data/lib/prism/ffi.rb +25 -0
  30. data/lib/prism/lex_compat.rb +1 -1
  31. data/lib/prism/mutation_compiler.rb +3 -8
  32. data/lib/prism/node.rb +123 -159
  33. data/lib/prism/node_ext.rb +23 -16
  34. data/lib/prism/parse_result.rb +21 -5
  35. data/lib/prism/pattern.rb +3 -3
  36. data/lib/prism/serialize.rb +901 -305
  37. data/lib/prism/visitor.rb +0 -3
  38. data/prism.gemspec +8 -1
  39. data/rbi/prism.rbi +7261 -0
  40. data/rbi/prism_static.rbi +182 -0
  41. data/sig/prism.rbs +4439 -0
  42. data/sig/prism_static.rbs +110 -0
  43. data/src/enc/pm_unicode.c +1 -1
  44. data/src/node.c +28 -29
  45. data/src/prettyprint.c +7674 -1647
  46. data/src/prism.c +353 -300
  47. data/src/regexp.c +2 -0
  48. data/src/serialize.c +392 -381
  49. data/src/util/pm_buffer.c +47 -12
  50. data/src/util/pm_constant_pool.c +1 -1
  51. data/src/util/pm_newline_list.c +8 -54
  52. metadata +9 -2
data/lib/prism/node.rb CHANGED
@@ -462,9 +462,13 @@ module Prism
462
462
  # attr_reader arguments: Array[Node]
463
463
  attr_reader :arguments
464
464
 
465
- # def initialize: (arguments: Array[Node], location: Location) -> void
466
- def initialize(arguments, location)
465
+ # attr_reader flags: Integer
466
+ private attr_reader :flags
467
+
468
+ # def initialize: (arguments: Array[Node], flags: Integer, location: Location) -> void
469
+ def initialize(arguments, flags, location)
467
470
  @arguments = arguments
471
+ @flags = flags
468
472
  @location = location
469
473
  end
470
474
 
@@ -492,6 +496,7 @@ module Prism
492
496
  def copy(**params)
493
497
  ArgumentsNode.new(
494
498
  params.fetch(:arguments) { arguments },
499
+ params.fetch(:flags) { flags },
495
500
  params.fetch(:location) { location },
496
501
  )
497
502
  end
@@ -501,12 +506,19 @@ module Prism
501
506
 
502
507
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
503
508
  def deconstruct_keys(keys)
504
- { arguments: arguments, location: location }
509
+ { arguments: arguments, flags: flags, location: location }
510
+ end
511
+
512
+ # def keyword_splat?: () -> bool
513
+ def keyword_splat?
514
+ flags.anybits?(ArgumentsNodeFlags::KEYWORD_SPLAT)
505
515
  end
506
516
 
507
517
  def inspect(inspector = NodeInspector.new)
508
518
  inspector << inspector.header(self)
509
- inspector << "└── arguments: #{inspector.list("#{inspector.prefix} ", arguments)}"
519
+ inspector << "├── arguments: #{inspector.list("#{inspector.prefix}", arguments)}"
520
+ flags = [("keyword_splat" if keyword_splat?)].compact
521
+ inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
510
522
  inspector.to_str
511
523
  end
512
524
 
@@ -1642,7 +1654,11 @@ module Prism
1642
1654
 
1643
1655
  def inspect(inspector = NodeInspector.new)
1644
1656
  inspector << inspector.header(self)
1645
- inspector << "├── name: #{name.inspect}\n"
1657
+ if (name = self.name).nil?
1658
+ inspector << "├── name: ∅\n"
1659
+ else
1660
+ inspector << "├── name: #{name.inspect}\n"
1661
+ end
1646
1662
  inspector << "├── name_loc: #{inspector.location(name_loc)}\n"
1647
1663
  inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
1648
1664
  inspector.to_str
@@ -7166,11 +7182,11 @@ module Prism
7166
7182
  # attr_reader constant: Node?
7167
7183
  attr_reader :constant
7168
7184
 
7169
- # attr_reader assocs: Array[Node]
7170
- attr_reader :assocs
7185
+ # attr_reader elements: Array[Node]
7186
+ attr_reader :elements
7171
7187
 
7172
- # attr_reader kwrest: Node?
7173
- attr_reader :kwrest
7188
+ # attr_reader rest: Node?
7189
+ attr_reader :rest
7174
7190
 
7175
7191
  # attr_reader opening_loc: Location?
7176
7192
  attr_reader :opening_loc
@@ -7178,11 +7194,11 @@ module Prism
7178
7194
  # attr_reader closing_loc: Location?
7179
7195
  attr_reader :closing_loc
7180
7196
 
7181
- # def initialize: (constant: Node?, assocs: Array[Node], kwrest: Node?, opening_loc: Location?, closing_loc: Location?, location: Location) -> void
7182
- def initialize(constant, assocs, kwrest, opening_loc, closing_loc, location)
7197
+ # def initialize: (constant: Node?, elements: Array[Node], rest: Node?, opening_loc: Location?, closing_loc: Location?, location: Location) -> void
7198
+ def initialize(constant, elements, rest, opening_loc, closing_loc, location)
7183
7199
  @constant = constant
7184
- @assocs = assocs
7185
- @kwrest = kwrest
7200
+ @elements = elements
7201
+ @rest = rest
7186
7202
  @opening_loc = opening_loc
7187
7203
  @closing_loc = closing_loc
7188
7204
  @location = location
@@ -7195,29 +7211,29 @@ module Prism
7195
7211
 
7196
7212
  # def child_nodes: () -> Array[nil | Node]
7197
7213
  def child_nodes
7198
- [constant, *assocs, kwrest]
7214
+ [constant, *elements, rest]
7199
7215
  end
7200
7216
 
7201
7217
  # def compact_child_nodes: () -> Array[Node]
7202
7218
  def compact_child_nodes
7203
7219
  compact = []
7204
7220
  compact << constant if constant
7205
- compact.concat(assocs)
7206
- compact << kwrest if kwrest
7221
+ compact.concat(elements)
7222
+ compact << rest if rest
7207
7223
  compact
7208
7224
  end
7209
7225
 
7210
7226
  # def comment_targets: () -> Array[Node | Location]
7211
7227
  def comment_targets
7212
- [*constant, *assocs, *kwrest, *opening_loc, *closing_loc]
7228
+ [*constant, *elements, *rest, *opening_loc, *closing_loc]
7213
7229
  end
7214
7230
 
7215
7231
  # def copy: (**params) -> HashPatternNode
7216
7232
  def copy(**params)
7217
7233
  HashPatternNode.new(
7218
7234
  params.fetch(:constant) { constant },
7219
- params.fetch(:assocs) { assocs },
7220
- params.fetch(:kwrest) { kwrest },
7235
+ params.fetch(:elements) { elements },
7236
+ params.fetch(:rest) { rest },
7221
7237
  params.fetch(:opening_loc) { opening_loc },
7222
7238
  params.fetch(:closing_loc) { closing_loc },
7223
7239
  params.fetch(:location) { location },
@@ -7229,7 +7245,7 @@ module Prism
7229
7245
 
7230
7246
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
7231
7247
  def deconstruct_keys(keys)
7232
- { constant: constant, assocs: assocs, kwrest: kwrest, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
7248
+ { constant: constant, elements: elements, rest: rest, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
7233
7249
  end
7234
7250
 
7235
7251
  # def opening: () -> String?
@@ -7250,12 +7266,12 @@ module Prism
7250
7266
  inspector << "├── constant:\n"
7251
7267
  inspector << constant.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7252
7268
  end
7253
- inspector << "├── assocs: #{inspector.list("#{inspector.prefix}│ ", assocs)}"
7254
- if (kwrest = self.kwrest).nil?
7255
- inspector << "├── kwrest: ∅\n"
7269
+ inspector << "├── elements: #{inspector.list("#{inspector.prefix}│ ", elements)}"
7270
+ if (rest = self.rest).nil?
7271
+ inspector << "├── rest: ∅\n"
7256
7272
  else
7257
- inspector << "├── kwrest:\n"
7258
- inspector << kwrest.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7273
+ inspector << "├── rest:\n"
7274
+ inspector << rest.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7259
7275
  end
7260
7276
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
7261
7277
  inspector << "└── closing_loc: #{inspector.location(closing_loc)}\n"
@@ -9917,7 +9933,11 @@ module Prism
9917
9933
 
9918
9934
  def inspect(inspector = NodeInspector.new)
9919
9935
  inspector << inspector.header(self)
9920
- inspector << "├── name: #{name.inspect}\n"
9936
+ if (name = self.name).nil?
9937
+ inspector << "├── name: ∅\n"
9938
+ else
9939
+ inspector << "├── name: #{name.inspect}\n"
9940
+ end
9921
9941
  inspector << "├── name_loc: #{inspector.location(name_loc)}\n"
9922
9942
  inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
9923
9943
  inspector.to_str
@@ -11421,11 +11441,17 @@ module Prism
11421
11441
 
11422
11442
  # Represents a multi-target expression.
11423
11443
  #
11424
- # a, b, c = 1, 2, 3
11425
- # ^^^^^^^
11444
+ # a, (b, c) = 1, 2, 3
11445
+ # ^^^^^^
11426
11446
  class MultiTargetNode < Node
11427
- # attr_reader targets: Array[Node]
11428
- attr_reader :targets
11447
+ # attr_reader lefts: Array[Node]
11448
+ attr_reader :lefts
11449
+
11450
+ # attr_reader rest: Node?
11451
+ attr_reader :rest
11452
+
11453
+ # attr_reader rights: Array[Node]
11454
+ attr_reader :rights
11429
11455
 
11430
11456
  # attr_reader lparen_loc: Location?
11431
11457
  attr_reader :lparen_loc
@@ -11433,9 +11459,11 @@ module Prism
11433
11459
  # attr_reader rparen_loc: Location?
11434
11460
  attr_reader :rparen_loc
11435
11461
 
11436
- # def initialize: (targets: Array[Node], lparen_loc: Location?, rparen_loc: Location?, location: Location) -> void
11437
- def initialize(targets, lparen_loc, rparen_loc, location)
11438
- @targets = targets
11462
+ # def initialize: (lefts: Array[Node], rest: Node?, rights: Array[Node], lparen_loc: Location?, rparen_loc: Location?, location: Location) -> void
11463
+ def initialize(lefts, rest, rights, lparen_loc, rparen_loc, location)
11464
+ @lefts = lefts
11465
+ @rest = rest
11466
+ @rights = rights
11439
11467
  @lparen_loc = lparen_loc
11440
11468
  @rparen_loc = rparen_loc
11441
11469
  @location = location
@@ -11448,23 +11476,29 @@ module Prism
11448
11476
 
11449
11477
  # def child_nodes: () -> Array[nil | Node]
11450
11478
  def child_nodes
11451
- [*targets]
11479
+ [*lefts, rest, *rights]
11452
11480
  end
11453
11481
 
11454
11482
  # def compact_child_nodes: () -> Array[Node]
11455
11483
  def compact_child_nodes
11456
- [*targets]
11484
+ compact = []
11485
+ compact.concat(lefts)
11486
+ compact << rest if rest
11487
+ compact.concat(rights)
11488
+ compact
11457
11489
  end
11458
11490
 
11459
11491
  # def comment_targets: () -> Array[Node | Location]
11460
11492
  def comment_targets
11461
- [*targets, *lparen_loc, *rparen_loc]
11493
+ [*lefts, *rest, *rights, *lparen_loc, *rparen_loc]
11462
11494
  end
11463
11495
 
11464
11496
  # def copy: (**params) -> MultiTargetNode
11465
11497
  def copy(**params)
11466
11498
  MultiTargetNode.new(
11467
- params.fetch(:targets) { targets },
11499
+ params.fetch(:lefts) { lefts },
11500
+ params.fetch(:rest) { rest },
11501
+ params.fetch(:rights) { rights },
11468
11502
  params.fetch(:lparen_loc) { lparen_loc },
11469
11503
  params.fetch(:rparen_loc) { rparen_loc },
11470
11504
  params.fetch(:location) { location },
@@ -11476,7 +11510,7 @@ module Prism
11476
11510
 
11477
11511
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
11478
11512
  def deconstruct_keys(keys)
11479
- { targets: targets, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location }
11513
+ { lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location }
11480
11514
  end
11481
11515
 
11482
11516
  # def lparen: () -> String?
@@ -11491,7 +11525,14 @@ module Prism
11491
11525
 
11492
11526
  def inspect(inspector = NodeInspector.new)
11493
11527
  inspector << inspector.header(self)
11494
- inspector << "├── targets: #{inspector.list("#{inspector.prefix}│ ", targets)}"
11528
+ inspector << "├── lefts: #{inspector.list("#{inspector.prefix}│ ", lefts)}"
11529
+ if (rest = self.rest).nil?
11530
+ inspector << "├── rest: ∅\n"
11531
+ else
11532
+ inspector << "├── rest:\n"
11533
+ inspector << rest.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
11534
+ end
11535
+ inspector << "├── rights: #{inspector.list("#{inspector.prefix}│ ", rights)}"
11495
11536
  inspector << "├── lparen_loc: #{inspector.location(lparen_loc)}\n"
11496
11537
  inspector << "└── rparen_loc: #{inspector.location(rparen_loc)}\n"
11497
11538
  inspector.to_str
@@ -11531,8 +11572,14 @@ module Prism
11531
11572
  # a, b, c = 1, 2, 3
11532
11573
  # ^^^^^^^^^^^^^^^^^
11533
11574
  class MultiWriteNode < Node
11534
- # attr_reader targets: Array[Node]
11535
- attr_reader :targets
11575
+ # attr_reader lefts: Array[Node]
11576
+ attr_reader :lefts
11577
+
11578
+ # attr_reader rest: Node?
11579
+ attr_reader :rest
11580
+
11581
+ # attr_reader rights: Array[Node]
11582
+ attr_reader :rights
11536
11583
 
11537
11584
  # attr_reader lparen_loc: Location?
11538
11585
  attr_reader :lparen_loc
@@ -11546,9 +11593,11 @@ module Prism
11546
11593
  # attr_reader value: Node
11547
11594
  attr_reader :value
11548
11595
 
11549
- # def initialize: (targets: Array[Node], lparen_loc: Location?, rparen_loc: Location?, operator_loc: Location, value: Node, location: Location) -> void
11550
- def initialize(targets, lparen_loc, rparen_loc, operator_loc, value, location)
11551
- @targets = targets
11596
+ # def initialize: (lefts: Array[Node], rest: Node?, rights: Array[Node], lparen_loc: Location?, rparen_loc: Location?, operator_loc: Location, value: Node, location: Location) -> void
11597
+ def initialize(lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value, location)
11598
+ @lefts = lefts
11599
+ @rest = rest
11600
+ @rights = rights
11552
11601
  @lparen_loc = lparen_loc
11553
11602
  @rparen_loc = rparen_loc
11554
11603
  @operator_loc = operator_loc
@@ -11563,23 +11612,30 @@ module Prism
11563
11612
 
11564
11613
  # def child_nodes: () -> Array[nil | Node]
11565
11614
  def child_nodes
11566
- [*targets, value]
11615
+ [*lefts, rest, *rights, value]
11567
11616
  end
11568
11617
 
11569
11618
  # def compact_child_nodes: () -> Array[Node]
11570
11619
  def compact_child_nodes
11571
- [*targets, value]
11620
+ compact = []
11621
+ compact.concat(lefts)
11622
+ compact << rest if rest
11623
+ compact.concat(rights)
11624
+ compact << value
11625
+ compact
11572
11626
  end
11573
11627
 
11574
11628
  # def comment_targets: () -> Array[Node | Location]
11575
11629
  def comment_targets
11576
- [*targets, *lparen_loc, *rparen_loc, operator_loc, value]
11630
+ [*lefts, *rest, *rights, *lparen_loc, *rparen_loc, operator_loc, value]
11577
11631
  end
11578
11632
 
11579
11633
  # def copy: (**params) -> MultiWriteNode
11580
11634
  def copy(**params)
11581
11635
  MultiWriteNode.new(
11582
- params.fetch(:targets) { targets },
11636
+ params.fetch(:lefts) { lefts },
11637
+ params.fetch(:rest) { rest },
11638
+ params.fetch(:rights) { rights },
11583
11639
  params.fetch(:lparen_loc) { lparen_loc },
11584
11640
  params.fetch(:rparen_loc) { rparen_loc },
11585
11641
  params.fetch(:operator_loc) { operator_loc },
@@ -11593,7 +11649,7 @@ module Prism
11593
11649
 
11594
11650
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
11595
11651
  def deconstruct_keys(keys)
11596
- { targets: targets, lparen_loc: lparen_loc, rparen_loc: rparen_loc, operator_loc: operator_loc, value: value, location: location }
11652
+ { lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc, operator_loc: operator_loc, value: value, location: location }
11597
11653
  end
11598
11654
 
11599
11655
  # def lparen: () -> String?
@@ -11613,7 +11669,14 @@ module Prism
11613
11669
 
11614
11670
  def inspect(inspector = NodeInspector.new)
11615
11671
  inspector << inspector.header(self)
11616
- inspector << "├── targets: #{inspector.list("#{inspector.prefix}│ ", targets)}"
11672
+ inspector << "├── lefts: #{inspector.list("#{inspector.prefix}│ ", lefts)}"
11673
+ if (rest = self.rest).nil?
11674
+ inspector << "├── rest: ∅\n"
11675
+ else
11676
+ inspector << "├── rest:\n"
11677
+ inspector << rest.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
11678
+ end
11679
+ inspector << "├── rights: #{inspector.list("#{inspector.prefix}│ ", rights)}"
11617
11680
  inspector << "├── lparen_loc: #{inspector.location(lparen_loc)}\n"
11618
11681
  inspector << "├── rparen_loc: #{inspector.location(rparen_loc)}\n"
11619
11682
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
@@ -13514,114 +13577,6 @@ module Prism
13514
13577
  end
13515
13578
  end
13516
13579
 
13517
- # Represents a destructured required parameter node.
13518
- #
13519
- # def foo((bar, baz))
13520
- # ^^^^^^^^^^
13521
- # end
13522
- class RequiredDestructuredParameterNode < Node
13523
- # attr_reader parameters: Array[Node]
13524
- attr_reader :parameters
13525
-
13526
- # attr_reader opening_loc: Location
13527
- attr_reader :opening_loc
13528
-
13529
- # attr_reader closing_loc: Location
13530
- attr_reader :closing_loc
13531
-
13532
- # def initialize: (parameters: Array[Node], opening_loc: Location, closing_loc: Location, location: Location) -> void
13533
- def initialize(parameters, opening_loc, closing_loc, location)
13534
- @parameters = parameters
13535
- @opening_loc = opening_loc
13536
- @closing_loc = closing_loc
13537
- @location = location
13538
- end
13539
-
13540
- # def accept: (visitor: Visitor) -> void
13541
- def accept(visitor)
13542
- visitor.visit_required_destructured_parameter_node(self)
13543
- end
13544
-
13545
- # def child_nodes: () -> Array[nil | Node]
13546
- def child_nodes
13547
- [*parameters]
13548
- end
13549
-
13550
- # def compact_child_nodes: () -> Array[Node]
13551
- def compact_child_nodes
13552
- [*parameters]
13553
- end
13554
-
13555
- # def comment_targets: () -> Array[Node | Location]
13556
- def comment_targets
13557
- [*parameters, opening_loc, closing_loc]
13558
- end
13559
-
13560
- # def copy: (**params) -> RequiredDestructuredParameterNode
13561
- def copy(**params)
13562
- RequiredDestructuredParameterNode.new(
13563
- params.fetch(:parameters) { parameters },
13564
- params.fetch(:opening_loc) { opening_loc },
13565
- params.fetch(:closing_loc) { closing_loc },
13566
- params.fetch(:location) { location },
13567
- )
13568
- end
13569
-
13570
- # def deconstruct: () -> Array[nil | Node]
13571
- alias deconstruct child_nodes
13572
-
13573
- # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
13574
- def deconstruct_keys(keys)
13575
- { parameters: parameters, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
13576
- end
13577
-
13578
- # def opening: () -> String
13579
- def opening
13580
- opening_loc.slice
13581
- end
13582
-
13583
- # def closing: () -> String
13584
- def closing
13585
- closing_loc.slice
13586
- end
13587
-
13588
- def inspect(inspector = NodeInspector.new)
13589
- inspector << inspector.header(self)
13590
- inspector << "├── parameters: #{inspector.list("#{inspector.prefix}│ ", parameters)}"
13591
- inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
13592
- inspector << "└── closing_loc: #{inspector.location(closing_loc)}\n"
13593
- inspector.to_str
13594
- end
13595
-
13596
- # Sometimes you want to check an instance of a node against a list of
13597
- # classes to see what kind of behavior to perform. Usually this is done by
13598
- # calling `[cls1, cls2].include?(node.class)` or putting the node into a
13599
- # case statement and doing `case node; when cls1; when cls2; end`. Both of
13600
- # these approaches are relatively slow because of the constant lookups,
13601
- # method calls, and/or array allocations.
13602
- #
13603
- # Instead, you can call #type, which will return to you a symbol that you
13604
- # can use for comparison. This is faster than the other approaches because
13605
- # it uses a single integer comparison, but also because if you're on CRuby
13606
- # you can take advantage of the fact that case statements with all symbol
13607
- # keys will use a jump table.
13608
- #
13609
- # def type: () -> Symbol
13610
- def type
13611
- :required_destructured_parameter_node
13612
- end
13613
-
13614
- # Similar to #type, this method returns a symbol that you can use for
13615
- # splitting on the type of the node without having to do a long === chain.
13616
- # Note that like #type, it will still be slower than using == for a single
13617
- # class, but should be faster in a case statement or an array comparison.
13618
- #
13619
- # def self.type: () -> Symbol
13620
- def self.type
13621
- :required_destructured_parameter_node
13622
- end
13623
- end
13624
-
13625
13580
  # Represents a required parameter to a method, block, or lambda definition.
13626
13581
  #
13627
13582
  # def a(b)
@@ -14035,7 +13990,11 @@ module Prism
14035
13990
 
14036
13991
  def inspect(inspector = NodeInspector.new)
14037
13992
  inspector << inspector.header(self)
14038
- inspector << "├── name: #{name.inspect}\n"
13993
+ if (name = self.name).nil?
13994
+ inspector << "├── name: ∅\n"
13995
+ else
13996
+ inspector << "├── name: #{name.inspect}\n"
13997
+ end
14039
13998
  inspector << "├── name_loc: #{inspector.location(name_loc)}\n"
14040
13999
  inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
14041
14000
  inspector.to_str
@@ -16345,6 +16304,11 @@ module Prism
16345
16304
  end
16346
16305
  end
16347
16306
 
16307
+ module ArgumentsNodeFlags
16308
+ # if arguments contain keyword splat
16309
+ KEYWORD_SPLAT = 1 << 0
16310
+ end
16311
+
16348
16312
  module CallNodeFlags
16349
16313
  # &. operator
16350
16314
  SAFE_NAVIGATION = 1 << 0
@@ -3,6 +3,19 @@
3
3
  # Here we are reopening the prism module to provide methods on nodes that aren't
4
4
  # templated and are meant as convenience methods.
5
5
  module Prism
6
+ module RegularExpressionOptions
7
+ # Returns a numeric value that represents the flags that were used to create
8
+ # the regular expression.
9
+ def options
10
+ o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
11
+ o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
12
+ o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
13
+ o
14
+ end
15
+ end
16
+
17
+ private_constant :RegularExpressionOptions
18
+
6
19
  class FloatNode < Node
7
20
  # Returns the value of the node as a Ruby Float.
8
21
  def value
@@ -24,15 +37,16 @@ module Prism
24
37
  end
25
38
  end
26
39
 
40
+ class InterpolatedMatchLastLineNode < Node
41
+ include RegularExpressionOptions
42
+ end
43
+
27
44
  class InterpolatedRegularExpressionNode < Node
28
- # Returns a numeric value that represents the flags that were used to create
29
- # the regular expression.
30
- def options
31
- o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
32
- o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
33
- o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
34
- o
35
- end
45
+ include RegularExpressionOptions
46
+ end
47
+
48
+ class MatchLastLineNode < Node
49
+ include RegularExpressionOptions
36
50
  end
37
51
 
38
52
  class RationalNode < Node
@@ -43,14 +57,7 @@ module Prism
43
57
  end
44
58
 
45
59
  class RegularExpressionNode < Node
46
- # Returns a numeric value that represents the flags that were used to create
47
- # the regular expression.
48
- def options
49
- o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
50
- o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
51
- o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
52
- o
53
- end
60
+ include RegularExpressionOptions
54
61
  end
55
62
 
56
63
  class ConstantReadNode < Node
@@ -16,16 +16,32 @@ module Prism
16
16
  source.byteslice(offset, length)
17
17
  end
18
18
 
19
+ # Binary search through the offsets to find the line number for the given
20
+ # offset.
19
21
  def line(value)
20
- offsets.bsearch_index { |offset| offset > value } || offsets.length
22
+ left = 0
23
+ right = offsets.length - 1
24
+
25
+ while left <= right
26
+ mid = left + (right - left) / 2
27
+ return mid if offsets[mid] == value
28
+
29
+ if offsets[mid] < value
30
+ left = mid + 1
31
+ else
32
+ right = mid - 1
33
+ end
34
+ end
35
+
36
+ left - 1
21
37
  end
22
38
 
23
39
  def line_offset(value)
24
- offsets[line(value) - 1]
40
+ offsets[line(value)]
25
41
  end
26
42
 
27
43
  def column(value)
28
- value - offsets[line(value) - 1]
44
+ value - offsets[line(value)]
29
45
  end
30
46
 
31
47
  private
@@ -86,7 +102,7 @@ module Prism
86
102
 
87
103
  # The line number where this location starts.
88
104
  def start_line
89
- source.line(start_offset)
105
+ source.line(start_offset) + 1
90
106
  end
91
107
 
92
108
  # The content of the line where this location starts before this location.
@@ -97,7 +113,7 @@ module Prism
97
113
 
98
114
  # The line number where this location ends.
99
115
  def end_line
100
- source.line(end_offset - 1)
116
+ source.line(end_offset) + 1
101
117
  end
102
118
 
103
119
  # The column number in bytes where this location starts from the start of
data/lib/prism/pattern.rb CHANGED
@@ -158,12 +158,12 @@ module Prism
158
158
  # in InstanceVariableReadNode[name: Symbol]
159
159
  # in { name: Symbol }
160
160
  def compile_hash_pattern_node(node)
161
- compile_error(node) unless node.kwrest.nil?
161
+ compile_error(node) if node.rest
162
162
  compiled_constant = compile_node(node.constant) if node.constant
163
163
 
164
164
  preprocessed =
165
- node.assocs.to_h do |assoc|
166
- [assoc.key.unescaped.to_sym, compile_node(assoc.value)]
165
+ node.elements.to_h do |element|
166
+ [element.key.unescaped.to_sym, compile_node(element.value)]
167
167
  end
168
168
 
169
169
  compiled_keywords = ->(other) do