prism 1.5.1 → 1.9.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 +74 -1
- data/Makefile +12 -5
- data/README.md +2 -1
- data/config.yml +34 -8
- data/docs/build_system.md +2 -2
- data/docs/cruby_compilation.md +1 -1
- data/docs/design.md +2 -2
- data/docs/parser_translation.md +1 -1
- data/docs/releasing.md +4 -25
- data/docs/ripper_translation.md +8 -17
- data/docs/ruby_api.md +1 -0
- data/ext/prism/api_node.c +7 -3
- data/ext/prism/extconf.rb +1 -1
- data/ext/prism/extension.c +10 -2
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +89 -25
- data/include/prism/diagnostic.h +3 -0
- data/include/prism/options.h +8 -2
- data/include/prism/parser.h +3 -0
- data/include/prism/version.h +3 -3
- data/include/prism.h +1 -1
- data/lib/prism/compiler.rb +152 -152
- data/lib/prism/dot_visitor.rb +5 -0
- data/lib/prism/dsl.rb +2 -2
- data/lib/prism/ffi.rb +11 -3
- data/lib/prism/inspect_visitor.rb +1 -0
- data/lib/prism/lex_compat.rb +133 -150
- data/lib/prism/node.rb +1184 -34
- data/lib/prism/parse_result.rb +11 -15
- data/lib/prism/polyfill/scan_byte.rb +1 -1
- data/lib/prism/polyfill/warn.rb +16 -22
- data/lib/prism/reflection.rb +1 -1
- data/lib/prism/serialize.rb +8 -5
- data/lib/prism/translation/parser/compiler.rb +16 -16
- data/lib/prism/translation/parser.rb +12 -3
- data/lib/prism/translation/parser_current.rb +5 -3
- data/lib/prism/translation/parser_versions.rb +36 -0
- data/lib/prism/translation/ripper/filter.rb +53 -0
- data/lib/prism/translation/ripper/lexer.rb +135 -0
- data/lib/prism/translation/ripper.rb +86 -40
- data/lib/prism/translation/ruby_parser.rb +55 -20
- data/lib/prism/translation.rb +5 -3
- data/lib/prism/visitor.rb +152 -152
- data/lib/prism.rb +21 -14
- data/prism.gemspec +5 -7
- data/rbi/prism/dsl.rbi +3 -3
- data/rbi/prism/node.rbi +24 -8
- data/rbi/prism/translation/parser_versions.rbi +23 -0
- data/rbi/prism.rbi +0 -3
- data/sig/prism/dsl.rbs +2 -2
- data/sig/prism/node.rbs +22 -8
- data/sig/prism/parse_result.rbs +1 -0
- data/sig/prism.rbs +58 -40
- data/src/diagnostic.c +7 -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 +1335 -1958
- data/src/serialize.c +7 -1
- data/src/token_type.c +2 -2
- data/src/util/pm_constant_pool.c +1 -1
- data/src/util/pm_string.c +6 -8
- metadata +7 -9
- data/lib/prism/translation/parser33.rb +0 -13
- data/lib/prism/translation/parser34.rb +0 -13
- data/lib/prism/translation/parser35.rb +0 -13
- data/rbi/prism/translation/parser33.rbi +0 -6
- data/rbi/prism/translation/parser34.rbi +0 -6
- data/rbi/prism/translation/parser35.rbi +0 -6
data/lib/prism/parse_result.rb
CHANGED
|
@@ -76,6 +76,15 @@ module Prism
|
|
|
76
76
|
source.byteslice(byte_offset, length) or raise
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
# Converts the line number and column in bytes to a byte offset.
|
|
80
|
+
def byte_offset(line, column)
|
|
81
|
+
normal = line - @start_line
|
|
82
|
+
raise IndexError if normal < 0
|
|
83
|
+
offsets.fetch(normal) + column
|
|
84
|
+
rescue IndexError
|
|
85
|
+
raise ArgumentError, "line #{line} is out of range"
|
|
86
|
+
end
|
|
87
|
+
|
|
79
88
|
# Binary search through the offsets to find the line number for the given
|
|
80
89
|
# byte offset.
|
|
81
90
|
def line(byte_offset)
|
|
@@ -155,21 +164,8 @@ module Prism
|
|
|
155
164
|
# Binary search through the offsets to find the line number for the given
|
|
156
165
|
# byte offset.
|
|
157
166
|
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
|
|
167
|
+
index = offsets.bsearch_index { |offset| offset > byte_offset } || offsets.length
|
|
168
|
+
index - 1
|
|
173
169
|
end
|
|
174
170
|
end
|
|
175
171
|
|
|
@@ -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/polyfill/warn.rb
CHANGED
|
@@ -7,17 +7,14 @@ if (method = Kernel.instance_method(:warn)).respond_to?(:parameters) ? method.pa
|
|
|
7
7
|
Kernel.prepend(
|
|
8
8
|
Module.new {
|
|
9
9
|
def warn(*msgs, uplevel: nil, category: nil) # :nodoc:
|
|
10
|
-
uplevel
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
super(*msgs, uplevel: uplevel)
|
|
10
|
+
case uplevel
|
|
11
|
+
when nil
|
|
12
|
+
super(*msgs)
|
|
13
|
+
when Integer
|
|
14
|
+
super(*msgs, uplevel: uplevel + 1)
|
|
15
|
+
else
|
|
16
|
+
super(*msgs, uplevel: uplevel.to_int + 1)
|
|
17
|
+
end
|
|
21
18
|
end
|
|
22
19
|
}
|
|
23
20
|
)
|
|
@@ -25,17 +22,14 @@ if (method = Kernel.instance_method(:warn)).respond_to?(:parameters) ? method.pa
|
|
|
25
22
|
Object.prepend(
|
|
26
23
|
Module.new {
|
|
27
24
|
def warn(*msgs, uplevel: nil, category: nil) # :nodoc:
|
|
28
|
-
uplevel
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
super(*msgs, uplevel: uplevel)
|
|
25
|
+
case uplevel
|
|
26
|
+
when nil
|
|
27
|
+
super(*msgs)
|
|
28
|
+
when Integer
|
|
29
|
+
super(*msgs, uplevel: uplevel + 1)
|
|
30
|
+
else
|
|
31
|
+
super(*msgs, uplevel: uplevel.to_int + 1)
|
|
32
|
+
end
|
|
39
33
|
end
|
|
40
34
|
}
|
|
41
35
|
)
|
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,11 +21,11 @@ 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 = 9
|
|
25
25
|
|
|
26
26
|
# The patch version of prism that we are expecting to find in the serialized
|
|
27
27
|
# strings.
|
|
28
|
-
PATCH_VERSION =
|
|
28
|
+
PATCH_VERSION = 0
|
|
29
29
|
|
|
30
30
|
# Deserialize the dumped output from a request to parse or parse_file.
|
|
31
31
|
#
|
|
@@ -397,6 +397,7 @@ module Prism
|
|
|
397
397
|
:conditional_while_predicate,
|
|
398
398
|
:constant_path_colon_colon_constant,
|
|
399
399
|
:def_endless,
|
|
400
|
+
:def_endless_parameters,
|
|
400
401
|
:def_endless_setter,
|
|
401
402
|
:def_name,
|
|
402
403
|
:def_params_term,
|
|
@@ -555,6 +556,7 @@ module Prism
|
|
|
555
556
|
:parameter_wild_loose_comma,
|
|
556
557
|
:pattern_array_multiple_rests,
|
|
557
558
|
:pattern_capture_duplicate,
|
|
559
|
+
:pattern_capture_in_alternative,
|
|
558
560
|
:pattern_expression_after_bracket,
|
|
559
561
|
:pattern_expression_after_comma,
|
|
560
562
|
:pattern_expression_after_hrocket,
|
|
@@ -616,6 +618,7 @@ module Prism
|
|
|
616
618
|
:unexpected_index_keywords,
|
|
617
619
|
:unexpected_label,
|
|
618
620
|
:unexpected_multi_write,
|
|
621
|
+
:unexpected_parameter_default_value,
|
|
619
622
|
:unexpected_range_operator,
|
|
620
623
|
:unexpected_safe_navigation,
|
|
621
624
|
:unexpected_token_close_context,
|
|
@@ -878,7 +881,7 @@ module Prism
|
|
|
878
881
|
when 18 then
|
|
879
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))
|
|
880
883
|
when 19 then
|
|
881
|
-
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))
|
|
882
885
|
when 20 then
|
|
883
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))
|
|
884
887
|
when 21 then
|
|
@@ -1286,7 +1289,7 @@ module Prism
|
|
|
1286
1289
|
-> (constant_pool, encoding, freeze) {
|
|
1287
1290
|
node_id = load_varuint
|
|
1288
1291
|
location = load_location(freeze)
|
|
1289
|
-
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))
|
|
1290
1293
|
value.freeze if freeze
|
|
1291
1294
|
value
|
|
1292
1295
|
},
|
|
@@ -2238,6 +2241,7 @@ module Prism
|
|
|
2238
2241
|
:KEYWORD_WHEN,
|
|
2239
2242
|
:NEWLINE,
|
|
2240
2243
|
:PARENTHESIS_RIGHT,
|
|
2244
|
+
:PIPE,
|
|
2241
2245
|
:SEMICOLON,
|
|
2242
2246
|
:AMPERSAND,
|
|
2243
2247
|
:AMPERSAND_AMPERSAND,
|
|
@@ -2354,7 +2358,6 @@ module Prism
|
|
|
2354
2358
|
:PERCENT_LOWER_X,
|
|
2355
2359
|
:PERCENT_UPPER_I,
|
|
2356
2360
|
:PERCENT_UPPER_W,
|
|
2357
|
-
:PIPE,
|
|
2358
2361
|
:PIPE_EQUAL,
|
|
2359
2362
|
:PIPE_PIPE,
|
|
2360
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
|
|
|
@@ -19,6 +19,13 @@ module Prism
|
|
|
19
19
|
# whitequark/parser gem's syntax tree. It inherits from the base parser for
|
|
20
20
|
# the parser gem, and overrides the parse* methods to parse with prism and
|
|
21
21
|
# then translate.
|
|
22
|
+
#
|
|
23
|
+
# Note that this version of the parser always parses using the latest
|
|
24
|
+
# version of Ruby syntax supported by Prism. If you want specific version
|
|
25
|
+
# support, use one of the version-specific subclasses, such as
|
|
26
|
+
# `Prism::Translation::Parser34`. If you want to parse using the same
|
|
27
|
+
# version of Ruby syntax as the currently running version of Ruby, use
|
|
28
|
+
# `Prism::Translation::ParserCurrent`.
|
|
22
29
|
class Parser < ::Parser::Base
|
|
23
30
|
Diagnostic = ::Parser::Diagnostic # :nodoc:
|
|
24
31
|
private_constant :Diagnostic
|
|
@@ -77,7 +84,7 @@ module Prism
|
|
|
77
84
|
end
|
|
78
85
|
|
|
79
86
|
def version # :nodoc:
|
|
80
|
-
|
|
87
|
+
41
|
|
81
88
|
end
|
|
82
89
|
|
|
83
90
|
# The default encoding for Ruby files is UTF-8.
|
|
@@ -349,8 +356,10 @@ module Prism
|
|
|
349
356
|
"3.3.1"
|
|
350
357
|
when 34
|
|
351
358
|
"3.4.0"
|
|
352
|
-
when 35
|
|
353
|
-
"
|
|
359
|
+
when 35, 40
|
|
360
|
+
"4.0.0"
|
|
361
|
+
when 41
|
|
362
|
+
"4.1.0"
|
|
354
363
|
else
|
|
355
364
|
"latest"
|
|
356
365
|
end
|
|
@@ -10,11 +10,13 @@ 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
|
-
parser =
|
|
19
|
+
parser = Parser40
|
|
18
20
|
major, minor, _patch = Gem::Version.new(RUBY_VERSION).segments
|
|
19
21
|
warn "warning: `Prism::Translation::Current` is loading #{parser.name}, " \
|
|
20
22
|
"but you are running #{major}.#{minor}."
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
|
|
4
|
+
module Prism
|
|
5
|
+
module Translation
|
|
6
|
+
# This class is the entry-point for Ruby 3.3 of `Prism::Translation::Parser`.
|
|
7
|
+
class Parser33 < Parser
|
|
8
|
+
def version # :nodoc:
|
|
9
|
+
33
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# This class is the entry-point for Ruby 3.4 of `Prism::Translation::Parser`.
|
|
14
|
+
class Parser34 < Parser
|
|
15
|
+
def version # :nodoc:
|
|
16
|
+
34
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# This class is the entry-point for Ruby 4.0 of `Prism::Translation::Parser`.
|
|
21
|
+
class Parser40 < Parser
|
|
22
|
+
def version # :nodoc:
|
|
23
|
+
40
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Parser35 = Parser40 # :nodoc:
|
|
28
|
+
|
|
29
|
+
# This class is the entry-point for Ruby 4.1 of `Prism::Translation::Parser`.
|
|
30
|
+
class Parser41 < Parser
|
|
31
|
+
def version # :nodoc:
|
|
32
|
+
41
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Prism
|
|
4
|
+
module Translation
|
|
5
|
+
class Ripper
|
|
6
|
+
class Filter # :nodoc:
|
|
7
|
+
# :stopdoc:
|
|
8
|
+
def initialize(src, filename = '-', lineno = 1)
|
|
9
|
+
@__lexer = Lexer.new(src, filename, lineno)
|
|
10
|
+
@__line = nil
|
|
11
|
+
@__col = nil
|
|
12
|
+
@__state = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def filename
|
|
16
|
+
@__lexer.filename
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def lineno
|
|
20
|
+
@__line
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def column
|
|
24
|
+
@__col
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def state
|
|
28
|
+
@__state
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def parse(init = nil)
|
|
32
|
+
data = init
|
|
33
|
+
@__lexer.lex.each do |pos, event, tok, state|
|
|
34
|
+
@__line, @__col = *pos
|
|
35
|
+
@__state = state
|
|
36
|
+
data = if respond_to?(event, true)
|
|
37
|
+
then __send__(event, tok, data)
|
|
38
|
+
else on_default(event, tok, data)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
data
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def on_default(event, token, data)
|
|
47
|
+
data
|
|
48
|
+
end
|
|
49
|
+
# :startdoc:
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# :markup: markdown
|
|
3
|
+
|
|
4
|
+
require_relative "../ripper"
|
|
5
|
+
|
|
6
|
+
module Prism
|
|
7
|
+
module Translation
|
|
8
|
+
class Ripper
|
|
9
|
+
class Lexer < Ripper # :nodoc:
|
|
10
|
+
# :stopdoc:
|
|
11
|
+
class State
|
|
12
|
+
|
|
13
|
+
attr_reader :to_int, :to_s
|
|
14
|
+
|
|
15
|
+
def initialize(i)
|
|
16
|
+
@to_int = i
|
|
17
|
+
@to_s = Ripper.lex_state_name(i)
|
|
18
|
+
freeze
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def [](index)
|
|
22
|
+
case index
|
|
23
|
+
when 0, :to_int
|
|
24
|
+
@to_int
|
|
25
|
+
when 1, :to_s
|
|
26
|
+
@to_s
|
|
27
|
+
else
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
alias to_i to_int
|
|
33
|
+
alias inspect to_s
|
|
34
|
+
def pretty_print(q) q.text(to_s) end
|
|
35
|
+
def ==(i) super or to_int == i end
|
|
36
|
+
def &(i) self.class.new(to_int & i) end
|
|
37
|
+
def |(i) self.class.new(to_int | i) end
|
|
38
|
+
def allbits?(i) to_int.allbits?(i) end
|
|
39
|
+
def anybits?(i) to_int.anybits?(i) end
|
|
40
|
+
def nobits?(i) to_int.nobits?(i) end
|
|
41
|
+
|
|
42
|
+
# Instances are frozen and there are only a handful of them so we cache them here.
|
|
43
|
+
STATES = Hash.new { |h,k| h[k] = State.new(k) }
|
|
44
|
+
|
|
45
|
+
def self.cached(i)
|
|
46
|
+
STATES[i]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Elem
|
|
51
|
+
attr_accessor :pos, :event, :tok, :state, :message
|
|
52
|
+
|
|
53
|
+
def initialize(pos, event, tok, state, message = nil)
|
|
54
|
+
@pos = pos
|
|
55
|
+
@event = event
|
|
56
|
+
@tok = tok
|
|
57
|
+
@state = State.cached(state)
|
|
58
|
+
@message = message
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def [](index)
|
|
62
|
+
case index
|
|
63
|
+
when 0, :pos
|
|
64
|
+
@pos
|
|
65
|
+
when 1, :event
|
|
66
|
+
@event
|
|
67
|
+
when 2, :tok
|
|
68
|
+
@tok
|
|
69
|
+
when 3, :state
|
|
70
|
+
@state
|
|
71
|
+
when 4, :message
|
|
72
|
+
@message
|
|
73
|
+
else
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def inspect
|
|
79
|
+
"#<#{self.class}: #{event}@#{pos[0]}:#{pos[1]}:#{state}: #{tok.inspect}#{": " if message}#{message}>"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
alias to_s inspect
|
|
83
|
+
|
|
84
|
+
def pretty_print(q)
|
|
85
|
+
q.group(2, "#<#{self.class}:", ">") {
|
|
86
|
+
q.breakable
|
|
87
|
+
q.text("#{event}@#{pos[0]}:#{pos[1]}")
|
|
88
|
+
q.breakable
|
|
89
|
+
state.pretty_print(q)
|
|
90
|
+
q.breakable
|
|
91
|
+
q.text("token: ")
|
|
92
|
+
tok.pretty_print(q)
|
|
93
|
+
if message
|
|
94
|
+
q.breakable
|
|
95
|
+
q.text("message: ")
|
|
96
|
+
q.text(message)
|
|
97
|
+
end
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def to_a
|
|
102
|
+
if @message
|
|
103
|
+
[@pos, @event, @tok, @state, @message]
|
|
104
|
+
else
|
|
105
|
+
[@pos, @event, @tok, @state]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Pretty much just the same as Prism.lex_compat.
|
|
111
|
+
def lex(raise_errors: false)
|
|
112
|
+
Ripper.lex(@source, filename, lineno, raise_errors: raise_errors)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns the lex_compat result wrapped in `Elem`. Errors are omitted.
|
|
116
|
+
# Since ripper is a streaming parser, tokens are expected to be emitted in the order
|
|
117
|
+
# that the parser encounters them. This is not implemented.
|
|
118
|
+
def parse(...)
|
|
119
|
+
lex(...).map do |position, event, token, state|
|
|
120
|
+
Elem.new(position, event, token, state.to_int)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Similar to parse but ripper sorts the elements by position in the source. Also
|
|
125
|
+
# includes errors. Since prism does error recovery, in cases of syntax errors
|
|
126
|
+
# the result may differ greatly compared to ripper.
|
|
127
|
+
def scan(...)
|
|
128
|
+
parse(...)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# :startdoc:
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|