prism 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
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