prism 0.30.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -1
- data/README.md +3 -1
- data/config.yml +185 -126
- data/docs/serialization.md +3 -0
- data/ext/prism/api_node.c +2843 -2085
- data/ext/prism/extconf.rb +1 -1
- data/ext/prism/extension.c +35 -25
- data/ext/prism/extension.h +2 -2
- data/include/prism/ast.h +1048 -69
- data/include/prism/defines.h +9 -0
- data/include/prism/diagnostic.h +11 -3
- data/include/prism/options.h +55 -1
- data/include/prism/parser.h +27 -3
- data/include/prism/regexp.h +2 -1
- data/include/prism/util/pm_integer.h +6 -6
- data/include/prism/util/pm_newline_list.h +11 -0
- data/include/prism/util/pm_string.h +1 -0
- data/include/prism/version.h +3 -3
- data/lib/prism/desugar_compiler.rb +111 -74
- data/lib/prism/dispatcher.rb +2 -1
- data/lib/prism/dot_visitor.rb +21 -31
- data/lib/prism/dsl.rb +656 -471
- data/lib/prism/ffi.rb +3 -0
- data/lib/prism/inspect_visitor.rb +285 -57
- data/lib/prism/mutation_compiler.rb +5 -5
- data/lib/prism/node.rb +2282 -4754
- data/lib/prism/node_ext.rb +72 -11
- data/lib/prism/parse_result/errors.rb +65 -0
- data/lib/prism/parse_result/newlines.rb +28 -28
- data/lib/prism/parse_result.rb +25 -2
- data/lib/prism/reflection.rb +7 -7
- data/lib/prism/serialize.rb +468 -610
- data/lib/prism/translation/parser/compiler.rb +18 -18
- data/lib/prism/translation/parser/lexer.rb +1 -1
- data/lib/prism/translation/parser.rb +3 -3
- data/lib/prism/translation/ripper.rb +14 -14
- data/lib/prism/translation/ruby_parser.rb +43 -7
- data/prism.gemspec +3 -1
- data/rbi/prism/dsl.rbi +521 -0
- data/rbi/prism/node.rbi +1456 -5616
- data/rbi/prism.rbi +16 -16
- data/sig/prism/dsl.rbs +189 -305
- data/sig/prism/node.rbs +702 -603
- data/sig/prism/parse_result.rbs +2 -0
- data/src/diagnostic.c +22 -6
- data/src/node.c +277 -284
- data/src/options.c +18 -0
- data/src/prettyprint.c +99 -108
- data/src/prism.c +1282 -760
- data/src/regexp.c +72 -4
- data/src/serialize.c +165 -50
- data/src/token_type.c +2 -2
- data/src/util/pm_integer.c +14 -14
- data/src/util/pm_newline_list.c +29 -0
- data/src/util/pm_string.c +9 -5
- metadata +4 -2
@@ -181,7 +181,7 @@ module Prism
|
|
181
181
|
if (rescue_clause = node.rescue_clause)
|
182
182
|
begin
|
183
183
|
find_start_offset = (rescue_clause.reference&.location || rescue_clause.exceptions.last&.location || rescue_clause.keyword_loc).end_offset
|
184
|
-
find_end_offset = (rescue_clause.statements&.location&.start_offset || rescue_clause.
|
184
|
+
find_end_offset = (rescue_clause.statements&.location&.start_offset || rescue_clause.subsequent&.location&.start_offset || (find_start_offset + 1))
|
185
185
|
|
186
186
|
rescue_bodies << builder.rescue_body(
|
187
187
|
token(rescue_clause.keyword_loc),
|
@@ -191,7 +191,7 @@ module Prism
|
|
191
191
|
srange_find(find_start_offset, find_end_offset, [";"]),
|
192
192
|
visit(rescue_clause.statements)
|
193
193
|
)
|
194
|
-
end until (rescue_clause = rescue_clause.
|
194
|
+
end until (rescue_clause = rescue_clause.subsequent).nil?
|
195
195
|
end
|
196
196
|
|
197
197
|
begin_body =
|
@@ -410,8 +410,8 @@ module Prism
|
|
410
410
|
token(node.case_keyword_loc),
|
411
411
|
visit(node.predicate),
|
412
412
|
visit_all(node.conditions),
|
413
|
-
token(node.
|
414
|
-
visit(node.
|
413
|
+
token(node.else_clause&.else_keyword_loc),
|
414
|
+
visit(node.else_clause),
|
415
415
|
token(node.end_keyword_loc)
|
416
416
|
)
|
417
417
|
end
|
@@ -423,8 +423,8 @@ module Prism
|
|
423
423
|
token(node.case_keyword_loc),
|
424
424
|
visit(node.predicate),
|
425
425
|
visit_all(node.conditions),
|
426
|
-
token(node.
|
427
|
-
visit(node.
|
426
|
+
token(node.else_clause&.else_keyword_loc),
|
427
|
+
visit(node.else_clause),
|
428
428
|
token(node.end_keyword_loc)
|
429
429
|
)
|
430
430
|
end
|
@@ -858,8 +858,8 @@ module Prism
|
|
858
858
|
visit(node.predicate),
|
859
859
|
token(node.then_keyword_loc),
|
860
860
|
visit(node.statements),
|
861
|
-
token(node.
|
862
|
-
visit(node.
|
861
|
+
token(node.subsequent.else_keyword_loc),
|
862
|
+
visit(node.subsequent)
|
863
863
|
)
|
864
864
|
elsif node.if_keyword_loc.start_offset == node.location.start_offset
|
865
865
|
builder.condition(
|
@@ -868,16 +868,16 @@ module Prism
|
|
868
868
|
if node.then_keyword_loc
|
869
869
|
token(node.then_keyword_loc)
|
870
870
|
else
|
871
|
-
srange_find(node.predicate.location.end_offset, (node.statements&.location || node.
|
871
|
+
srange_find(node.predicate.location.end_offset, (node.statements&.location || node.subsequent&.location || node.end_keyword_loc).start_offset, [";"])
|
872
872
|
end,
|
873
873
|
visit(node.statements),
|
874
|
-
case node.
|
874
|
+
case node.subsequent
|
875
875
|
when IfNode
|
876
|
-
token(node.
|
876
|
+
token(node.subsequent.if_keyword_loc)
|
877
877
|
when ElseNode
|
878
|
-
token(node.
|
878
|
+
token(node.subsequent.else_keyword_loc)
|
879
879
|
end,
|
880
|
-
visit(node.
|
880
|
+
visit(node.subsequent),
|
881
881
|
if node.if_keyword != "elsif"
|
882
882
|
token(node.end_keyword_loc)
|
883
883
|
end
|
@@ -885,7 +885,7 @@ module Prism
|
|
885
885
|
else
|
886
886
|
builder.condition_mod(
|
887
887
|
visit(node.statements),
|
888
|
-
visit(node.
|
888
|
+
visit(node.subsequent),
|
889
889
|
token(node.if_keyword_loc),
|
890
890
|
visit(node.predicate)
|
891
891
|
)
|
@@ -1784,16 +1784,16 @@ module Prism
|
|
1784
1784
|
if node.then_keyword_loc
|
1785
1785
|
token(node.then_keyword_loc)
|
1786
1786
|
else
|
1787
|
-
srange_find(node.predicate.location.end_offset, (node.statements&.location || node.
|
1787
|
+
srange_find(node.predicate.location.end_offset, (node.statements&.location || node.else_clause&.location || node.end_keyword_loc).start_offset, [";"])
|
1788
1788
|
end,
|
1789
|
-
visit(node.
|
1790
|
-
token(node.
|
1789
|
+
visit(node.else_clause),
|
1790
|
+
token(node.else_clause&.else_keyword_loc),
|
1791
1791
|
visit(node.statements),
|
1792
1792
|
token(node.end_keyword_loc)
|
1793
1793
|
)
|
1794
1794
|
else
|
1795
1795
|
builder.condition_mod(
|
1796
|
-
visit(node.
|
1796
|
+
visit(node.else_clause),
|
1797
1797
|
visit(node.statements),
|
1798
1798
|
token(node.keyword_loc),
|
1799
1799
|
visit(node.predicate)
|
@@ -339,7 +339,7 @@ module Prism
|
|
339
339
|
location = Range.new(source_buffer, offset_cache[token.location.start_offset], offset_cache[token.location.start_offset + 1])
|
340
340
|
end
|
341
341
|
when :tSYMBEG
|
342
|
-
if (next_token = lexed[index][0]) && next_token.type != :STRING_CONTENT && next_token.type != :EMBEXPR_BEGIN && next_token.type != :EMBVAR
|
342
|
+
if (next_token = lexed[index][0]) && next_token.type != :STRING_CONTENT && next_token.type != :EMBEXPR_BEGIN && next_token.type != :EMBVAR && next_token.type != :STRING_END
|
343
343
|
next_location = token.location.join(next_token.location)
|
344
344
|
type = :tSYMBOL
|
345
345
|
value = next_token.value
|
@@ -51,7 +51,7 @@ module Prism
|
|
51
51
|
source = source_buffer.source
|
52
52
|
|
53
53
|
offset_cache = build_offset_cache(source)
|
54
|
-
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]]), offset_cache)
|
54
|
+
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]], encoding: false), offset_cache)
|
55
55
|
|
56
56
|
build_ast(result.value, offset_cache)
|
57
57
|
ensure
|
@@ -64,7 +64,7 @@ module Prism
|
|
64
64
|
source = source_buffer.source
|
65
65
|
|
66
66
|
offset_cache = build_offset_cache(source)
|
67
|
-
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]]), offset_cache)
|
67
|
+
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]], encoding: false), offset_cache)
|
68
68
|
|
69
69
|
[
|
70
70
|
build_ast(result.value, offset_cache),
|
@@ -83,7 +83,7 @@ module Prism
|
|
83
83
|
offset_cache = build_offset_cache(source)
|
84
84
|
result =
|
85
85
|
begin
|
86
|
-
unwrap(Prism.parse_lex(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]]), offset_cache)
|
86
|
+
unwrap(Prism.parse_lex(source, filepath: source_buffer.name, version: convert_for_prism(version), scopes: [[]], encoding: false), offset_cache)
|
87
87
|
rescue ::Parser::SyntaxError
|
88
88
|
raise if !recover
|
89
89
|
end
|
@@ -1273,8 +1273,8 @@ module Prism
|
|
1273
1273
|
def visit_case_node(node)
|
1274
1274
|
predicate = visit(node.predicate)
|
1275
1275
|
clauses =
|
1276
|
-
node.conditions.reverse_each.inject(visit(node.
|
1277
|
-
on_when(*visit(condition),
|
1276
|
+
node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition|
|
1277
|
+
on_when(*visit(condition), current)
|
1278
1278
|
end
|
1279
1279
|
|
1280
1280
|
bounds(node.location)
|
@@ -1286,8 +1286,8 @@ module Prism
|
|
1286
1286
|
def visit_case_match_node(node)
|
1287
1287
|
predicate = visit(node.predicate)
|
1288
1288
|
clauses =
|
1289
|
-
node.conditions.reverse_each.inject(visit(node.
|
1290
|
-
on_in(*visit(condition),
|
1289
|
+
node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition|
|
1290
|
+
on_in(*visit(condition), current)
|
1291
1291
|
end
|
1292
1292
|
|
1293
1293
|
bounds(node.location)
|
@@ -1908,7 +1908,7 @@ module Prism
|
|
1908
1908
|
if node.then_keyword == "?"
|
1909
1909
|
predicate = visit(node.predicate)
|
1910
1910
|
truthy = visit(node.statements.body.first)
|
1911
|
-
falsy = visit(node.
|
1911
|
+
falsy = visit(node.subsequent.statements.body.first)
|
1912
1912
|
|
1913
1913
|
bounds(node.location)
|
1914
1914
|
on_ifop(predicate, truthy, falsy)
|
@@ -1921,13 +1921,13 @@ module Prism
|
|
1921
1921
|
else
|
1922
1922
|
visit(node.statements)
|
1923
1923
|
end
|
1924
|
-
|
1924
|
+
subsequent = visit(node.subsequent)
|
1925
1925
|
|
1926
1926
|
bounds(node.location)
|
1927
1927
|
if node.if_keyword == "if"
|
1928
|
-
on_if(predicate, statements,
|
1928
|
+
on_if(predicate, statements, subsequent)
|
1929
1929
|
else
|
1930
|
-
on_elsif(predicate, statements,
|
1930
|
+
on_elsif(predicate, statements, subsequent)
|
1931
1931
|
end
|
1932
1932
|
else
|
1933
1933
|
statements = visit(node.statements.body.first)
|
@@ -1960,7 +1960,7 @@ module Prism
|
|
1960
1960
|
# ^^^^^^^^^^^^^^^^^^^^^
|
1961
1961
|
def visit_in_node(node)
|
1962
1962
|
# This is a special case where we're not going to call on_in directly
|
1963
|
-
# because we don't have access to the
|
1963
|
+
# because we don't have access to the subsequent. Instead, we'll return
|
1964
1964
|
# the component parts and let the parent node handle it.
|
1965
1965
|
pattern = visit_pattern_node(node.pattern)
|
1966
1966
|
statements =
|
@@ -2808,10 +2808,10 @@ module Prism
|
|
2808
2808
|
visit(node.statements)
|
2809
2809
|
end
|
2810
2810
|
|
2811
|
-
|
2811
|
+
subsequent = visit(node.subsequent)
|
2812
2812
|
|
2813
2813
|
bounds(node.location)
|
2814
|
-
on_rescue(exceptions, reference, statements,
|
2814
|
+
on_rescue(exceptions, reference, statements, subsequent)
|
2815
2815
|
end
|
2816
2816
|
|
2817
2817
|
# def foo(*bar); end
|
@@ -3132,10 +3132,10 @@ module Prism
|
|
3132
3132
|
else
|
3133
3133
|
visit(node.statements)
|
3134
3134
|
end
|
3135
|
-
|
3135
|
+
else_clause = visit(node.else_clause)
|
3136
3136
|
|
3137
3137
|
bounds(node.location)
|
3138
|
-
on_unless(predicate, statements,
|
3138
|
+
on_unless(predicate, statements, else_clause)
|
3139
3139
|
else
|
3140
3140
|
statements = visit(node.statements.body.first)
|
3141
3141
|
predicate = visit(node.predicate)
|
@@ -3176,7 +3176,7 @@ module Prism
|
|
3176
3176
|
# ^^^^^^^^^^^^^
|
3177
3177
|
def visit_when_node(node)
|
3178
3178
|
# This is a special case where we're not going to call on_when directly
|
3179
|
-
# because we don't have access to the
|
3179
|
+
# because we don't have access to the subsequent. Instead, we'll return
|
3180
3180
|
# the component parts and let the parent node handle it.
|
3181
3181
|
conditions = visit_arguments(node.conditions)
|
3182
3182
|
statements =
|
@@ -55,7 +55,19 @@ module Prism
|
|
55
55
|
# a and b
|
56
56
|
# ^^^^^^^
|
57
57
|
def visit_and_node(node)
|
58
|
-
|
58
|
+
left = visit(node.left)
|
59
|
+
|
60
|
+
if left[0] == :and
|
61
|
+
# ruby_parser has the and keyword as right-associative as opposed to
|
62
|
+
# prism which has it as left-associative. We reverse that
|
63
|
+
# associativity here.
|
64
|
+
nest = left
|
65
|
+
nest = nest[2] while nest[2][0] == :and
|
66
|
+
nest[2] = s(node, :and, nest[2], visit(node.right))
|
67
|
+
left
|
68
|
+
else
|
69
|
+
s(node, :and, left, visit(node.right))
|
70
|
+
end
|
59
71
|
end
|
60
72
|
|
61
73
|
# []
|
@@ -135,7 +147,7 @@ module Prism
|
|
135
147
|
end
|
136
148
|
|
137
149
|
current = node.rescue_clause
|
138
|
-
until (current = current.
|
150
|
+
until (current = current.subsequent).nil?
|
139
151
|
result << visit(current)
|
140
152
|
end
|
141
153
|
end
|
@@ -251,6 +263,11 @@ module Prism
|
|
251
263
|
when RegularExpressionNode, InterpolatedRegularExpressionNode
|
252
264
|
return s(node, :match2, visit(node.receiver), visit(node.arguments.arguments.first))
|
253
265
|
end
|
266
|
+
|
267
|
+
case node.arguments.arguments.first
|
268
|
+
when RegularExpressionNode, InterpolatedRegularExpressionNode
|
269
|
+
return s(node, :match3, visit(node.arguments.arguments.first), visit(node.receiver))
|
270
|
+
end
|
254
271
|
end
|
255
272
|
end
|
256
273
|
|
@@ -330,13 +347,13 @@ module Prism
|
|
330
347
|
# case foo; when bar; end
|
331
348
|
# ^^^^^^^^^^^^^^^^^^^^^^^
|
332
349
|
def visit_case_node(node)
|
333
|
-
s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.
|
350
|
+
s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause)
|
334
351
|
end
|
335
352
|
|
336
353
|
# case foo; in bar; end
|
337
354
|
# ^^^^^^^^^^^^^^^^^^^^^
|
338
355
|
def visit_case_match_node(node)
|
339
|
-
s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.
|
356
|
+
s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause)
|
340
357
|
end
|
341
358
|
|
342
359
|
# class Foo; end
|
@@ -683,7 +700,7 @@ module Prism
|
|
683
700
|
# foo ? bar : baz
|
684
701
|
# ^^^^^^^^^^^^^^^
|
685
702
|
def visit_if_node(node)
|
686
|
-
s(node, :if, visit(node.predicate), visit(node.statements), visit(node.
|
703
|
+
s(node, :if, visit(node.predicate), visit(node.statements), visit(node.subsequent))
|
687
704
|
end
|
688
705
|
|
689
706
|
# 1i
|
@@ -876,6 +893,13 @@ module Prism
|
|
876
893
|
visited << result
|
877
894
|
end
|
878
895
|
elsif result[0] == :dstr
|
896
|
+
if !visited.empty? && part.parts[0].is_a?(StringNode)
|
897
|
+
# If we are in the middle of an implicitly concatenated string,
|
898
|
+
# we should not have a bare string as the first part. In this
|
899
|
+
# case we need to visit just that first part and then we can
|
900
|
+
# push the rest of the parts onto the visited array.
|
901
|
+
result[1] = visit(part.parts[0])
|
902
|
+
end
|
879
903
|
visited.concat(result[1..-1])
|
880
904
|
else
|
881
905
|
visited << result
|
@@ -1136,7 +1160,19 @@ module Prism
|
|
1136
1160
|
# a or b
|
1137
1161
|
# ^^^^^^
|
1138
1162
|
def visit_or_node(node)
|
1139
|
-
|
1163
|
+
left = visit(node.left)
|
1164
|
+
|
1165
|
+
if left[0] == :or
|
1166
|
+
# ruby_parser has the or keyword as right-associative as opposed to
|
1167
|
+
# prism which has it as left-associative. We reverse that
|
1168
|
+
# associativity here.
|
1169
|
+
nest = left
|
1170
|
+
nest = nest[2] while nest[2][0] == :or
|
1171
|
+
nest[2] = s(node, :or, nest[2], visit(node.right))
|
1172
|
+
left
|
1173
|
+
else
|
1174
|
+
s(node, :or, left, visit(node.right))
|
1175
|
+
end
|
1140
1176
|
end
|
1141
1177
|
|
1142
1178
|
# def foo(bar, *baz); end
|
@@ -1434,7 +1470,7 @@ module Prism
|
|
1434
1470
|
# bar unless foo
|
1435
1471
|
# ^^^^^^^^^^^^^^
|
1436
1472
|
def visit_unless_node(node)
|
1437
|
-
s(node, :if, visit(node.predicate), visit(node.
|
1473
|
+
s(node, :if, visit(node.predicate), visit(node.else_clause), visit(node.statements))
|
1438
1474
|
end
|
1439
1475
|
|
1440
1476
|
# until foo; bar end
|
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 = "0.
|
5
|
+
spec.version = "1.0.0"
|
6
6
|
spec.authors = ["Shopify"]
|
7
7
|
spec.email = ["ruby@shopify.com"]
|
8
8
|
|
@@ -82,6 +82,7 @@ Gem::Specification.new do |spec|
|
|
82
82
|
"lib/prism/pack.rb",
|
83
83
|
"lib/prism/parse_result.rb",
|
84
84
|
"lib/prism/parse_result/comments.rb",
|
85
|
+
"lib/prism/parse_result/errors.rb",
|
85
86
|
"lib/prism/parse_result/newlines.rb",
|
86
87
|
"lib/prism/pattern.rb",
|
87
88
|
"lib/prism/polyfill/byteindex.rb",
|
@@ -103,6 +104,7 @@ Gem::Specification.new do |spec|
|
|
103
104
|
"prism.gemspec",
|
104
105
|
"rbi/prism.rbi",
|
105
106
|
"rbi/prism/compiler.rbi",
|
107
|
+
"rbi/prism/dsl.rbi",
|
106
108
|
"rbi/prism/inspect_visitor.rbi",
|
107
109
|
"rbi/prism/node_ext.rbi",
|
108
110
|
"rbi/prism/node.rbi",
|