prism 0.30.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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",
|