prism 1.6.0 → 1.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -1
- data/Makefile +3 -3
- data/README.md +1 -1
- data/config.yml +28 -3
- data/docs/build_system.md +2 -2
- data/docs/cruby_compilation.md +1 -1
- data/docs/releasing.md +2 -2
- data/ext/prism/api_node.c +7 -3
- data/ext/prism/extconf.rb +1 -1
- data/ext/prism/extension.c +2 -3
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +54 -20
- data/include/prism/diagnostic.h +2 -0
- data/include/prism/options.h +8 -2
- data/include/prism/parser.h +3 -0
- data/include/prism/version.h +2 -2
- data/include/prism.h +1 -1
- data/lib/prism/dot_visitor.rb +5 -0
- data/lib/prism/dsl.rb +2 -2
- data/lib/prism/ffi.rb +3 -1
- data/lib/prism/inspect_visitor.rb +1 -0
- data/lib/prism/node.rb +52 -13
- data/lib/prism/parse_result.rb +2 -15
- data/lib/prism/polyfill/scan_byte.rb +1 -1
- data/lib/prism/reflection.rb +1 -1
- data/lib/prism/serialize.rb +6 -4
- data/lib/prism/translation/parser/compiler.rb +16 -16
- data/lib/prism/translation/parser.rb +5 -3
- data/lib/prism/translation/parser35.rb +1 -6
- data/lib/prism/translation/parser40.rb +13 -0
- data/lib/prism/translation/parser41.rb +13 -0
- data/lib/prism/translation/parser_current.rb +4 -2
- data/lib/prism/translation/ripper.rb +2 -2
- data/lib/prism/translation/ruby_parser.rb +53 -18
- data/lib/prism/translation.rb +2 -0
- data/lib/prism.rb +4 -5
- data/prism.gemspec +5 -1
- data/rbi/prism/dsl.rbi +3 -3
- data/rbi/prism/node.rbi +21 -8
- data/rbi/prism/translation/parser35.rbi +0 -2
- data/rbi/prism/translation/parser40.rbi +6 -0
- data/rbi/prism/translation/parser41.rbi +6 -0
- data/sig/prism/dsl.rbs +2 -2
- data/sig/prism/node.rbs +18 -8
- data/src/diagnostic.c +5 -1
- data/src/encoding.c +172 -67
- data/src/node.c +9 -0
- data/src/options.c +17 -7
- data/src/prettyprint.c +16 -0
- data/src/prism.c +1192 -1895
- data/src/serialize.c +7 -1
- data/src/token_type.c +2 -2
- data/src/util/pm_constant_pool.c +1 -1
- metadata +5 -1
data/lib/prism/node.rb
CHANGED
|
@@ -2605,7 +2605,7 @@ module Prism
|
|
|
2605
2605
|
# ^^^^^^^^
|
|
2606
2606
|
class CallNode < Node
|
|
2607
2607
|
# Initialize a new CallNode node.
|
|
2608
|
-
def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
|
|
2608
|
+
def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
|
|
2609
2609
|
@source = source
|
|
2610
2610
|
@node_id = node_id
|
|
2611
2611
|
@location = location
|
|
@@ -2617,6 +2617,7 @@ module Prism
|
|
|
2617
2617
|
@opening_loc = opening_loc
|
|
2618
2618
|
@arguments = arguments
|
|
2619
2619
|
@closing_loc = closing_loc
|
|
2620
|
+
@equal_loc = equal_loc
|
|
2620
2621
|
@block = block
|
|
2621
2622
|
end
|
|
2622
2623
|
|
|
@@ -2641,20 +2642,20 @@ module Prism
|
|
|
2641
2642
|
|
|
2642
2643
|
# def comment_targets: () -> Array[Node | Location]
|
|
2643
2644
|
def comment_targets
|
|
2644
|
-
[*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *block] #: Array[Prism::node | Location]
|
|
2645
|
+
[*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *equal_loc, *block] #: Array[Prism::node | Location]
|
|
2645
2646
|
end
|
|
2646
2647
|
|
|
2647
|
-
# def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode
|
|
2648
|
-
def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block)
|
|
2649
|
-
CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
|
|
2648
|
+
# def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?equal_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode
|
|
2649
|
+
def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, equal_loc: self.equal_loc, block: self.block)
|
|
2650
|
+
CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
|
|
2650
2651
|
end
|
|
2651
2652
|
|
|
2652
2653
|
# def deconstruct: () -> Array[Node?]
|
|
2653
2654
|
alias deconstruct child_nodes
|
|
2654
2655
|
|
|
2655
|
-
# def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: BlockNode | BlockArgumentNode | nil }
|
|
2656
|
+
# def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, equal_loc: Location?, block: BlockNode | BlockArgumentNode | nil }
|
|
2656
2657
|
def deconstruct_keys(keys)
|
|
2657
|
-
{ node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block }
|
|
2658
|
+
{ node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, equal_loc: equal_loc, block: block }
|
|
2658
2659
|
end
|
|
2659
2660
|
|
|
2660
2661
|
# def safe_navigation?: () -> bool
|
|
@@ -2791,6 +2792,31 @@ module Prism
|
|
|
2791
2792
|
repository.enter(node_id, :closing_loc) unless @closing_loc.nil?
|
|
2792
2793
|
end
|
|
2793
2794
|
|
|
2795
|
+
# Represents the location of the equal sign, in the case that this is an attribute write.
|
|
2796
|
+
#
|
|
2797
|
+
# foo.bar = value
|
|
2798
|
+
# ^
|
|
2799
|
+
#
|
|
2800
|
+
# foo[bar] = value
|
|
2801
|
+
# ^
|
|
2802
|
+
def equal_loc
|
|
2803
|
+
location = @equal_loc
|
|
2804
|
+
case location
|
|
2805
|
+
when nil
|
|
2806
|
+
nil
|
|
2807
|
+
when Location
|
|
2808
|
+
location
|
|
2809
|
+
else
|
|
2810
|
+
@equal_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF)
|
|
2811
|
+
end
|
|
2812
|
+
end
|
|
2813
|
+
|
|
2814
|
+
# Save the equal_loc location using the given saved source so that
|
|
2815
|
+
# it can be retrieved later.
|
|
2816
|
+
def save_equal_loc(repository)
|
|
2817
|
+
repository.enter(node_id, :equal_loc) unless @equal_loc.nil?
|
|
2818
|
+
end
|
|
2819
|
+
|
|
2794
2820
|
# Represents the block that is being passed to the method.
|
|
2795
2821
|
#
|
|
2796
2822
|
# foo { |a| a }
|
|
@@ -2817,6 +2843,11 @@ module Prism
|
|
|
2817
2843
|
closing_loc&.slice
|
|
2818
2844
|
end
|
|
2819
2845
|
|
|
2846
|
+
# def equal: () -> String?
|
|
2847
|
+
def equal
|
|
2848
|
+
equal_loc&.slice
|
|
2849
|
+
end
|
|
2850
|
+
|
|
2820
2851
|
# def inspect -> String
|
|
2821
2852
|
def inspect
|
|
2822
2853
|
InspectVisitor.compose(self)
|
|
@@ -2844,6 +2875,7 @@ module Prism
|
|
|
2844
2875
|
(opening_loc.nil? == other.opening_loc.nil?) &&
|
|
2845
2876
|
(arguments === other.arguments) &&
|
|
2846
2877
|
(closing_loc.nil? == other.closing_loc.nil?) &&
|
|
2878
|
+
(equal_loc.nil? == other.equal_loc.nil?) &&
|
|
2847
2879
|
(block === other.block)
|
|
2848
2880
|
end
|
|
2849
2881
|
end
|
|
@@ -7536,10 +7568,15 @@ module Prism
|
|
|
7536
7568
|
end
|
|
7537
7569
|
end
|
|
7538
7570
|
|
|
7539
|
-
# Represents the use of the `super` keyword without parentheses or arguments.
|
|
7571
|
+
# Represents the use of the `super` keyword without parentheses or arguments, but which might have a block.
|
|
7540
7572
|
#
|
|
7541
7573
|
# super
|
|
7542
7574
|
# ^^^^^
|
|
7575
|
+
#
|
|
7576
|
+
# super { 123 }
|
|
7577
|
+
# ^^^^^^^^^^^^^
|
|
7578
|
+
#
|
|
7579
|
+
# If it has any other arguments, it would be a `SuperNode` instead.
|
|
7543
7580
|
class ForwardingSuperNode < Node
|
|
7544
7581
|
# Initialize a new ForwardingSuperNode node.
|
|
7545
7582
|
def initialize(source, node_id, location, flags, block)
|
|
@@ -7585,7 +7622,7 @@ module Prism
|
|
|
7585
7622
|
{ node_id: node_id, location: location, block: block }
|
|
7586
7623
|
end
|
|
7587
7624
|
|
|
7588
|
-
#
|
|
7625
|
+
# All other arguments are forwarded as normal, except the original block is replaced with the new block.
|
|
7589
7626
|
attr_reader :block
|
|
7590
7627
|
|
|
7591
7628
|
# def inspect -> String
|
|
@@ -10951,7 +10988,7 @@ module Prism
|
|
|
10951
10988
|
[*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location]
|
|
10952
10989
|
end
|
|
10953
10990
|
|
|
10954
|
-
# def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], ?closing_loc: Location?) -> InterpolatedStringNode
|
|
10991
|
+
# def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode], ?closing_loc: Location?) -> InterpolatedStringNode
|
|
10955
10992
|
def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc)
|
|
10956
10993
|
InterpolatedStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc)
|
|
10957
10994
|
end
|
|
@@ -10959,7 +10996,7 @@ module Prism
|
|
|
10959
10996
|
# def deconstruct: () -> Array[Node?]
|
|
10960
10997
|
alias deconstruct child_nodes
|
|
10961
10998
|
|
|
10962
|
-
# def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], closing_loc: Location? }
|
|
10999
|
+
# def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode], closing_loc: Location? }
|
|
10963
11000
|
def deconstruct_keys(keys)
|
|
10964
11001
|
{ node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc }
|
|
10965
11002
|
end
|
|
@@ -10993,7 +11030,7 @@ module Prism
|
|
|
10993
11030
|
repository.enter(node_id, :opening_loc) unless @opening_loc.nil?
|
|
10994
11031
|
end
|
|
10995
11032
|
|
|
10996
|
-
# attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode]
|
|
11033
|
+
# attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode]
|
|
10997
11034
|
attr_reader :parts
|
|
10998
11035
|
|
|
10999
11036
|
# attr_reader closing_loc: Location?
|
|
@@ -17213,6 +17250,8 @@ module Prism
|
|
|
17213
17250
|
#
|
|
17214
17251
|
# super foo, bar
|
|
17215
17252
|
# ^^^^^^^^^^^^^^
|
|
17253
|
+
#
|
|
17254
|
+
# If no arguments are provided (except for a block), it would be a `ForwardingSuperNode` instead.
|
|
17216
17255
|
class SuperNode < Node
|
|
17217
17256
|
# Initialize a new SuperNode node.
|
|
17218
17257
|
def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block)
|
|
@@ -17295,7 +17334,7 @@ module Prism
|
|
|
17295
17334
|
repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil?
|
|
17296
17335
|
end
|
|
17297
17336
|
|
|
17298
|
-
#
|
|
17337
|
+
# Can be only `nil` when there are empty parentheses, like `super()`.
|
|
17299
17338
|
attr_reader :arguments
|
|
17300
17339
|
|
|
17301
17340
|
# attr_reader rparen_loc: Location?
|
data/lib/prism/parse_result.rb
CHANGED
|
@@ -155,21 +155,8 @@ module Prism
|
|
|
155
155
|
# Binary search through the offsets to find the line number for the given
|
|
156
156
|
# byte offset.
|
|
157
157
|
def find_line(byte_offset)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
while left <= right
|
|
162
|
-
mid = left + (right - left) / 2
|
|
163
|
-
return mid if (offset = offsets[mid]) == byte_offset
|
|
164
|
-
|
|
165
|
-
if offset < byte_offset
|
|
166
|
-
left = mid + 1
|
|
167
|
-
else
|
|
168
|
-
right = mid - 1
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
left - 1
|
|
158
|
+
index = offsets.bsearch_index { |offset| offset > byte_offset } || offsets.length
|
|
159
|
+
index - 1
|
|
173
160
|
end
|
|
174
161
|
end
|
|
175
162
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require "strscan"
|
|
4
4
|
|
|
5
5
|
# Polyfill for StringScanner#scan_byte, which didn't exist until Ruby 3.4.
|
|
6
|
-
if !(StringScanner.
|
|
6
|
+
if !(StringScanner.method_defined?(:scan_byte))
|
|
7
7
|
StringScanner.include(
|
|
8
8
|
Module.new {
|
|
9
9
|
def scan_byte # :nodoc:
|
data/lib/prism/reflection.rb
CHANGED
|
@@ -143,7 +143,7 @@ module Prism
|
|
|
143
143
|
when :call_and_write_node
|
|
144
144
|
[FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), OptionalLocationField.new(:message_loc), ConstantField.new(:read_name), ConstantField.new(:write_name), LocationField.new(:operator_loc), NodeField.new(:value)]
|
|
145
145
|
when :call_node
|
|
146
|
-
[FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), ConstantField.new(:name), OptionalLocationField.new(:message_loc), OptionalLocationField.new(:opening_loc), OptionalNodeField.new(:arguments), OptionalLocationField.new(:closing_loc), OptionalNodeField.new(:block)]
|
|
146
|
+
[FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), ConstantField.new(:name), OptionalLocationField.new(:message_loc), OptionalLocationField.new(:opening_loc), OptionalNodeField.new(:arguments), OptionalLocationField.new(:closing_loc), OptionalLocationField.new(:equal_loc), OptionalNodeField.new(:block)]
|
|
147
147
|
when :call_operator_write_node
|
|
148
148
|
[FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), OptionalLocationField.new(:message_loc), ConstantField.new(:read_name), ConstantField.new(:write_name), ConstantField.new(:binary_operator), LocationField.new(:binary_operator_loc), NodeField.new(:value)]
|
|
149
149
|
when :call_or_write_node
|
data/lib/prism/serialize.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Prism
|
|
|
21
21
|
|
|
22
22
|
# The minor version of prism that we are expecting to find in the serialized
|
|
23
23
|
# strings.
|
|
24
|
-
MINOR_VERSION =
|
|
24
|
+
MINOR_VERSION = 7
|
|
25
25
|
|
|
26
26
|
# The patch version of prism that we are expecting to find in the serialized
|
|
27
27
|
# strings.
|
|
@@ -556,6 +556,7 @@ module Prism
|
|
|
556
556
|
:parameter_wild_loose_comma,
|
|
557
557
|
:pattern_array_multiple_rests,
|
|
558
558
|
:pattern_capture_duplicate,
|
|
559
|
+
:pattern_capture_in_alternative,
|
|
559
560
|
:pattern_expression_after_bracket,
|
|
560
561
|
:pattern_expression_after_comma,
|
|
561
562
|
:pattern_expression_after_hrocket,
|
|
@@ -617,6 +618,7 @@ module Prism
|
|
|
617
618
|
:unexpected_index_keywords,
|
|
618
619
|
:unexpected_label,
|
|
619
620
|
:unexpected_multi_write,
|
|
621
|
+
:unexpected_parameter_default_value,
|
|
620
622
|
:unexpected_range_operator,
|
|
621
623
|
:unexpected_safe_navigation,
|
|
622
624
|
:unexpected_token_close_context,
|
|
@@ -879,7 +881,7 @@ module Prism
|
|
|
879
881
|
when 18 then
|
|
880
882
|
CallAndWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze))
|
|
881
883
|
when 19 then
|
|
882
|
-
CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze))
|
|
884
|
+
CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze))
|
|
883
885
|
when 20 then
|
|
884
886
|
CallOperatorWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze))
|
|
885
887
|
when 21 then
|
|
@@ -1287,7 +1289,7 @@ module Prism
|
|
|
1287
1289
|
-> (constant_pool, encoding, freeze) {
|
|
1288
1290
|
node_id = load_varuint
|
|
1289
1291
|
location = load_location(freeze)
|
|
1290
|
-
value = CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze))
|
|
1292
|
+
value = CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze))
|
|
1291
1293
|
value.freeze if freeze
|
|
1292
1294
|
value
|
|
1293
1295
|
},
|
|
@@ -2239,6 +2241,7 @@ module Prism
|
|
|
2239
2241
|
:KEYWORD_WHEN,
|
|
2240
2242
|
:NEWLINE,
|
|
2241
2243
|
:PARENTHESIS_RIGHT,
|
|
2244
|
+
:PIPE,
|
|
2242
2245
|
:SEMICOLON,
|
|
2243
2246
|
:AMPERSAND,
|
|
2244
2247
|
:AMPERSAND_AMPERSAND,
|
|
@@ -2355,7 +2358,6 @@ module Prism
|
|
|
2355
2358
|
:PERCENT_LOWER_X,
|
|
2356
2359
|
:PERCENT_UPPER_I,
|
|
2357
2360
|
:PERCENT_UPPER_W,
|
|
2358
|
-
:PIPE,
|
|
2359
2361
|
:PIPE_EQUAL,
|
|
2360
2362
|
:PIPE_PIPE,
|
|
2361
2363
|
:PIPE_PIPE_EQUAL,
|
|
@@ -217,7 +217,7 @@ module Prism
|
|
|
217
217
|
rescue_clause.exceptions.any? ? builder.array(nil, visit_all(rescue_clause.exceptions), nil) : nil,
|
|
218
218
|
token(rescue_clause.operator_loc),
|
|
219
219
|
visit(rescue_clause.reference),
|
|
220
|
-
|
|
220
|
+
srange_semicolon(find_start_offset, find_end_offset),
|
|
221
221
|
visit(rescue_clause.statements)
|
|
222
222
|
)
|
|
223
223
|
end until (rescue_clause = rescue_clause.subsequent).nil?
|
|
@@ -323,7 +323,7 @@ module Prism
|
|
|
323
323
|
visit_all(arguments),
|
|
324
324
|
token(node.closing_loc),
|
|
325
325
|
),
|
|
326
|
-
|
|
326
|
+
token(node.equal_loc),
|
|
327
327
|
visit(node.arguments.arguments.last)
|
|
328
328
|
),
|
|
329
329
|
block
|
|
@@ -340,7 +340,7 @@ module Prism
|
|
|
340
340
|
if name.end_with?("=") && !message_loc.slice.end_with?("=") && node.arguments && block.nil?
|
|
341
341
|
builder.assign(
|
|
342
342
|
builder.attr_asgn(visit(node.receiver), call_operator, token(message_loc)),
|
|
343
|
-
|
|
343
|
+
token(node.equal_loc),
|
|
344
344
|
visit(node.arguments.arguments.last)
|
|
345
345
|
)
|
|
346
346
|
else
|
|
@@ -789,7 +789,7 @@ module Prism
|
|
|
789
789
|
if (do_keyword_loc = node.do_keyword_loc)
|
|
790
790
|
token(do_keyword_loc)
|
|
791
791
|
else
|
|
792
|
-
|
|
792
|
+
srange_semicolon(node.collection.location.end_offset, (node.statements&.location || node.end_keyword_loc).start_offset)
|
|
793
793
|
end,
|
|
794
794
|
visit(node.statements),
|
|
795
795
|
token(node.end_keyword_loc)
|
|
@@ -921,7 +921,7 @@ module Prism
|
|
|
921
921
|
if (then_keyword_loc = node.then_keyword_loc)
|
|
922
922
|
token(then_keyword_loc)
|
|
923
923
|
else
|
|
924
|
-
|
|
924
|
+
srange_semicolon(node.predicate.location.end_offset, (node.statements&.location || node.subsequent&.location || node.end_keyword_loc).start_offset)
|
|
925
925
|
end,
|
|
926
926
|
visit(node.statements),
|
|
927
927
|
case node.subsequent
|
|
@@ -987,7 +987,7 @@ module Prism
|
|
|
987
987
|
if (then_loc = node.then_loc)
|
|
988
988
|
token(then_loc)
|
|
989
989
|
else
|
|
990
|
-
|
|
990
|
+
srange_semicolon(node.pattern.location.end_offset, node.statements&.location&.start_offset)
|
|
991
991
|
end,
|
|
992
992
|
visit(node.statements)
|
|
993
993
|
)
|
|
@@ -1808,7 +1808,7 @@ module Prism
|
|
|
1808
1808
|
if (then_keyword_loc = node.then_keyword_loc)
|
|
1809
1809
|
token(then_keyword_loc)
|
|
1810
1810
|
else
|
|
1811
|
-
|
|
1811
|
+
srange_semicolon(node.predicate.location.end_offset, (node.statements&.location || node.else_clause&.location || node.end_keyword_loc).start_offset)
|
|
1812
1812
|
end,
|
|
1813
1813
|
visit(node.else_clause),
|
|
1814
1814
|
token(node.else_clause&.else_keyword_loc),
|
|
@@ -1839,7 +1839,7 @@ module Prism
|
|
|
1839
1839
|
if (do_keyword_loc = node.do_keyword_loc)
|
|
1840
1840
|
token(do_keyword_loc)
|
|
1841
1841
|
else
|
|
1842
|
-
|
|
1842
|
+
srange_semicolon(node.predicate.location.end_offset, (node.statements&.location || node.closing_loc).start_offset)
|
|
1843
1843
|
end,
|
|
1844
1844
|
visit(node.statements),
|
|
1845
1845
|
token(node.closing_loc)
|
|
@@ -1863,7 +1863,7 @@ module Prism
|
|
|
1863
1863
|
if (then_keyword_loc = node.then_keyword_loc)
|
|
1864
1864
|
token(then_keyword_loc)
|
|
1865
1865
|
else
|
|
1866
|
-
|
|
1866
|
+
srange_semicolon(node.conditions.last.location.end_offset, node.statements&.location&.start_offset)
|
|
1867
1867
|
end,
|
|
1868
1868
|
visit(node.statements)
|
|
1869
1869
|
)
|
|
@@ -1883,7 +1883,7 @@ module Prism
|
|
|
1883
1883
|
if (do_keyword_loc = node.do_keyword_loc)
|
|
1884
1884
|
token(do_keyword_loc)
|
|
1885
1885
|
else
|
|
1886
|
-
|
|
1886
|
+
srange_semicolon(node.predicate.location.end_offset, (node.statements&.location || node.closing_loc).start_offset)
|
|
1887
1887
|
end,
|
|
1888
1888
|
visit(node.statements),
|
|
1889
1889
|
token(node.closing_loc)
|
|
@@ -2012,16 +2012,16 @@ module Prism
|
|
|
2012
2012
|
Range.new(source_buffer, offset_cache[start_offset], offset_cache[end_offset])
|
|
2013
2013
|
end
|
|
2014
2014
|
|
|
2015
|
-
# Constructs a new source range by finding the given
|
|
2016
|
-
#
|
|
2017
|
-
#
|
|
2015
|
+
# Constructs a new source range by finding a semicolon between the given
|
|
2016
|
+
# start offset and end offset. If the semicolon is not found, it returns
|
|
2017
|
+
# nil. Importantly it does not search past newlines or comments.
|
|
2018
2018
|
#
|
|
2019
2019
|
# Note that end_offset is allowed to be nil, in which case this will
|
|
2020
2020
|
# search until the end of the string.
|
|
2021
|
-
def
|
|
2022
|
-
if (match = source_buffer.source.byteslice(start_offset...end_offset)[/\A\s
|
|
2021
|
+
def srange_semicolon(start_offset, end_offset)
|
|
2022
|
+
if (match = source_buffer.source.byteslice(start_offset...end_offset)[/\A\s*;/])
|
|
2023
2023
|
final_offset = start_offset + match.bytesize
|
|
2024
|
-
[
|
|
2024
|
+
[";", Range.new(source_buffer, offset_cache[final_offset - 1], offset_cache[final_offset])]
|
|
2025
2025
|
end
|
|
2026
2026
|
end
|
|
2027
2027
|
|
|
@@ -84,7 +84,7 @@ module Prism
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def version # :nodoc:
|
|
87
|
-
|
|
87
|
+
41
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# The default encoding for Ruby files is UTF-8.
|
|
@@ -356,8 +356,10 @@ module Prism
|
|
|
356
356
|
"3.3.1"
|
|
357
357
|
when 34
|
|
358
358
|
"3.4.0"
|
|
359
|
-
when 35
|
|
360
|
-
"
|
|
359
|
+
when 35, 40
|
|
360
|
+
"4.0.0"
|
|
361
|
+
when 41
|
|
362
|
+
"4.1.0"
|
|
361
363
|
else
|
|
362
364
|
"latest"
|
|
363
365
|
end
|
|
@@ -10,8 +10,10 @@ module Prism
|
|
|
10
10
|
ParserCurrent = Parser33
|
|
11
11
|
when /^3\.4\./
|
|
12
12
|
ParserCurrent = Parser34
|
|
13
|
-
when /^3\.5\./
|
|
14
|
-
ParserCurrent =
|
|
13
|
+
when /^3\.5\./, /^4\.0\./
|
|
14
|
+
ParserCurrent = Parser40
|
|
15
|
+
when /^4\.1\./
|
|
16
|
+
ParserCurrent = Parser41
|
|
15
17
|
else
|
|
16
18
|
# Keep this in sync with released Ruby.
|
|
17
19
|
parser = Parser34
|
|
@@ -71,7 +71,7 @@ module Prism
|
|
|
71
71
|
# [[1, 13], :on_kw, "end", END ]]
|
|
72
72
|
#
|
|
73
73
|
def self.lex(src, filename = "-", lineno = 1, raise_errors: false)
|
|
74
|
-
result = Prism.lex_compat(src, filepath: filename, line: lineno)
|
|
74
|
+
result = Prism.lex_compat(src, filepath: filename, line: lineno, version: "current")
|
|
75
75
|
|
|
76
76
|
if result.failure? && raise_errors
|
|
77
77
|
raise SyntaxError, result.errors.first.message
|
|
@@ -3295,7 +3295,7 @@ module Prism
|
|
|
3295
3295
|
|
|
3296
3296
|
# Lazily initialize the parse result.
|
|
3297
3297
|
def result
|
|
3298
|
-
@result ||= Prism.parse(source, partial_script: true)
|
|
3298
|
+
@result ||= Prism.parse(source, partial_script: true, version: "current")
|
|
3299
3299
|
end
|
|
3300
3300
|
|
|
3301
3301
|
##########################################################################
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
# :markup: markdown
|
|
3
3
|
|
|
4
4
|
begin
|
|
5
|
-
require "
|
|
5
|
+
require "sexp"
|
|
6
6
|
rescue LoadError
|
|
7
|
-
warn(%q{Error: Unable to load
|
|
7
|
+
warn(%q{Error: Unable to load sexp. Add `gem "sexp_processor"` to your Gemfile.})
|
|
8
8
|
exit(1)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
class RubyParser # :nodoc:
|
|
12
|
+
class SyntaxError < RuntimeError # :nodoc:
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
11
16
|
module Prism
|
|
12
17
|
module Translation
|
|
13
18
|
# This module is the entry-point for converting a prism syntax tree into the
|
|
@@ -415,14 +420,18 @@ module Prism
|
|
|
415
420
|
visit(node.constant_path)
|
|
416
421
|
end
|
|
417
422
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
423
|
+
result =
|
|
424
|
+
if node.body.nil?
|
|
425
|
+
s(node, :class, name, visit(node.superclass))
|
|
426
|
+
elsif node.body.is_a?(StatementsNode)
|
|
427
|
+
compiler = copy_compiler(in_def: false)
|
|
428
|
+
s(node, :class, name, visit(node.superclass)).concat(node.body.body.map { |child| child.accept(compiler) })
|
|
429
|
+
else
|
|
430
|
+
s(node, :class, name, visit(node.superclass), node.body.accept(copy_compiler(in_def: false)))
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
attach_comments(result, node)
|
|
434
|
+
result
|
|
426
435
|
end
|
|
427
436
|
|
|
428
437
|
# ```
|
|
@@ -611,7 +620,9 @@ module Prism
|
|
|
611
620
|
s(node, :defs, visit(node.receiver), name)
|
|
612
621
|
end
|
|
613
622
|
|
|
623
|
+
attach_comments(result, node)
|
|
614
624
|
result.line(node.name_loc.start_line)
|
|
625
|
+
|
|
615
626
|
if node.parameters.nil?
|
|
616
627
|
result << s(node, :args).line(node.name_loc.start_line)
|
|
617
628
|
else
|
|
@@ -1270,14 +1281,18 @@ module Prism
|
|
|
1270
1281
|
visit(node.constant_path)
|
|
1271
1282
|
end
|
|
1272
1283
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1284
|
+
result =
|
|
1285
|
+
if node.body.nil?
|
|
1286
|
+
s(node, :module, name)
|
|
1287
|
+
elsif node.body.is_a?(StatementsNode)
|
|
1288
|
+
compiler = copy_compiler(in_def: false)
|
|
1289
|
+
s(node, :module, name).concat(node.body.body.map { |child| child.accept(compiler) })
|
|
1290
|
+
else
|
|
1291
|
+
s(node, :module, name, node.body.accept(copy_compiler(in_def: false)))
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
attach_comments(result, node)
|
|
1295
|
+
result
|
|
1281
1296
|
end
|
|
1282
1297
|
|
|
1283
1298
|
# ```
|
|
@@ -1820,6 +1835,17 @@ module Prism
|
|
|
1820
1835
|
|
|
1821
1836
|
private
|
|
1822
1837
|
|
|
1838
|
+
# Attach prism comments to the given sexp.
|
|
1839
|
+
def attach_comments(sexp, node)
|
|
1840
|
+
return unless node.comments
|
|
1841
|
+
return if node.comments.empty?
|
|
1842
|
+
|
|
1843
|
+
extra = node.location.start_line - node.comments.last.location.start_line
|
|
1844
|
+
comments = node.comments.map(&:slice)
|
|
1845
|
+
comments.concat([nil] * [0, extra].max)
|
|
1846
|
+
sexp.comments = comments.join("\n")
|
|
1847
|
+
end
|
|
1848
|
+
|
|
1823
1849
|
# Create a new compiler with the given options.
|
|
1824
1850
|
def copy_compiler(in_def: self.in_def, in_pattern: self.in_pattern)
|
|
1825
1851
|
Compiler.new(file, in_def: in_def, in_pattern: in_pattern)
|
|
@@ -1898,6 +1924,14 @@ module Prism
|
|
|
1898
1924
|
translate(Prism.parse_file(filepath, partial_script: true), filepath)
|
|
1899
1925
|
end
|
|
1900
1926
|
|
|
1927
|
+
# Parse the give file and translate it into the
|
|
1928
|
+
# seattlerb/ruby_parser gem's Sexp format. This method is
|
|
1929
|
+
# provided for API compatibility to RubyParser and takes an
|
|
1930
|
+
# optional +timeout+ argument.
|
|
1931
|
+
def process(ruby, file = "(string)", timeout = nil)
|
|
1932
|
+
Timeout.timeout(timeout) { parse(ruby, file) }
|
|
1933
|
+
end
|
|
1934
|
+
|
|
1901
1935
|
class << self
|
|
1902
1936
|
# Parse the given source and translate it into the seattlerb/ruby_parser
|
|
1903
1937
|
# gem's Sexp format.
|
|
@@ -1922,6 +1956,7 @@ module Prism
|
|
|
1922
1956
|
raise ::RubyParser::SyntaxError, "#{filepath}:#{error.location.start_line} :: #{error.message}"
|
|
1923
1957
|
end
|
|
1924
1958
|
|
|
1959
|
+
result.attach_comments!
|
|
1925
1960
|
result.value.accept(Compiler.new(filepath))
|
|
1926
1961
|
end
|
|
1927
1962
|
end
|
data/lib/prism/translation.rb
CHANGED
|
@@ -10,6 +10,8 @@ module Prism
|
|
|
10
10
|
autoload :Parser33, "prism/translation/parser33"
|
|
11
11
|
autoload :Parser34, "prism/translation/parser34"
|
|
12
12
|
autoload :Parser35, "prism/translation/parser35"
|
|
13
|
+
autoload :Parser40, "prism/translation/parser40"
|
|
14
|
+
autoload :Parser41, "prism/translation/parser41"
|
|
13
15
|
autoload :Ripper, "prism/translation/ripper"
|
|
14
16
|
autoload :RubyParser, "prism/translation/ruby_parser"
|
|
15
17
|
end
|
data/lib/prism.rb
CHANGED
|
@@ -42,13 +42,12 @@ module Prism
|
|
|
42
42
|
# Initialize a new exception for the given ruby version string.
|
|
43
43
|
def initialize(version)
|
|
44
44
|
message = +"invalid version: Requested to parse as `version: 'current'`; "
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
rescue ArgumentError
|
|
45
|
+
segments =
|
|
46
|
+
if version.match?(/\A\d+\.\d+.\d+\z/)
|
|
47
|
+
version.split(".").map(&:to_i)
|
|
49
48
|
end
|
|
50
49
|
|
|
51
|
-
if
|
|
50
|
+
if segments && ((segments[0] < 3) || (segments[0] == 3 && segments[1] < 3))
|
|
52
51
|
message << " #{version} is below the minimum supported syntax."
|
|
53
52
|
else
|
|
54
53
|
message << " #{version} is unknown. Please update the `prism` gem."
|
data/prism.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = "prism"
|
|
5
|
-
spec.version = "1.
|
|
5
|
+
spec.version = "1.7.0"
|
|
6
6
|
spec.authors = ["Shopify"]
|
|
7
7
|
spec.email = ["ruby@shopify.com"]
|
|
8
8
|
|
|
@@ -101,6 +101,8 @@ Gem::Specification.new do |spec|
|
|
|
101
101
|
"lib/prism/translation/parser33.rb",
|
|
102
102
|
"lib/prism/translation/parser34.rb",
|
|
103
103
|
"lib/prism/translation/parser35.rb",
|
|
104
|
+
"lib/prism/translation/parser40.rb",
|
|
105
|
+
"lib/prism/translation/parser41.rb",
|
|
104
106
|
"lib/prism/translation/parser/builder.rb",
|
|
105
107
|
"lib/prism/translation/parser/compiler.rb",
|
|
106
108
|
"lib/prism/translation/parser/lexer.rb",
|
|
@@ -123,6 +125,8 @@ Gem::Specification.new do |spec|
|
|
|
123
125
|
"rbi/prism/translation/parser33.rbi",
|
|
124
126
|
"rbi/prism/translation/parser34.rbi",
|
|
125
127
|
"rbi/prism/translation/parser35.rbi",
|
|
128
|
+
"rbi/prism/translation/parser40.rbi",
|
|
129
|
+
"rbi/prism/translation/parser41.rbi",
|
|
126
130
|
"rbi/prism/translation/ripper.rbi",
|
|
127
131
|
"rbi/prism/visitor.rbi",
|
|
128
132
|
"sig/prism.rbs",
|