prism 0.24.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BSDmakefile +58 -0
- data/CHANGELOG.md +50 -1
- data/Makefile +5 -2
- data/README.md +45 -6
- data/config.yml +499 -4
- data/docs/build_system.md +31 -0
- data/docs/configuration.md +2 -0
- data/docs/cruby_compilation.md +1 -1
- data/docs/parser_translation.md +14 -9
- data/docs/releasing.md +2 -2
- data/docs/ripper_translation.md +50 -0
- data/docs/ruby_api.md +1 -0
- data/docs/serialization.md +26 -5
- data/ext/prism/api_node.c +911 -815
- data/ext/prism/api_pack.c +9 -0
- data/ext/prism/extconf.rb +27 -11
- data/ext/prism/extension.c +313 -66
- data/ext/prism/extension.h +5 -4
- data/include/prism/ast.h +213 -64
- data/include/prism/defines.h +106 -2
- data/include/prism/diagnostic.h +134 -71
- data/include/prism/encoding.h +22 -4
- data/include/prism/node.h +93 -0
- data/include/prism/options.h +82 -7
- data/include/prism/pack.h +11 -0
- data/include/prism/parser.h +198 -53
- data/include/prism/prettyprint.h +8 -0
- data/include/prism/static_literals.h +118 -0
- data/include/prism/util/pm_buffer.h +65 -2
- data/include/prism/util/pm_constant_pool.h +18 -1
- data/include/prism/util/pm_integer.h +119 -0
- data/include/prism/util/pm_list.h +1 -1
- data/include/prism/util/pm_newline_list.h +8 -0
- data/include/prism/util/pm_string.h +26 -2
- data/include/prism/version.h +2 -2
- data/include/prism.h +59 -1
- data/lib/prism/compiler.rb +8 -1
- data/lib/prism/debug.rb +46 -3
- data/lib/prism/desugar_compiler.rb +1 -1
- data/lib/prism/dispatcher.rb +29 -0
- data/lib/prism/dot_visitor.rb +87 -16
- data/lib/prism/dsl.rb +24 -12
- data/lib/prism/ffi.rb +67 -12
- data/lib/prism/lex_compat.rb +17 -15
- data/lib/prism/mutation_compiler.rb +11 -0
- data/lib/prism/node.rb +2096 -2499
- data/lib/prism/node_ext.rb +77 -29
- data/lib/prism/pack.rb +4 -0
- data/lib/prism/parse_result/comments.rb +34 -17
- data/lib/prism/parse_result/newlines.rb +3 -1
- data/lib/prism/parse_result.rb +78 -32
- data/lib/prism/pattern.rb +16 -4
- data/lib/prism/polyfill/string.rb +12 -0
- data/lib/prism/serialize.rb +439 -102
- data/lib/prism/translation/parser/compiler.rb +152 -50
- data/lib/prism/translation/parser/lexer.rb +103 -22
- data/lib/prism/translation/parser/rubocop.rb +41 -13
- data/lib/prism/translation/parser.rb +119 -7
- data/lib/prism/translation/parser33.rb +1 -1
- data/lib/prism/translation/parser34.rb +1 -1
- data/lib/prism/translation/ripper/sexp.rb +125 -0
- data/lib/prism/translation/ripper/shim.rb +5 -0
- data/lib/prism/translation/ripper.rb +3212 -462
- data/lib/prism/translation/ruby_parser.rb +35 -18
- data/lib/prism/translation.rb +3 -1
- data/lib/prism/visitor.rb +10 -0
- data/lib/prism.rb +8 -2
- data/prism.gemspec +33 -4
- data/rbi/prism/compiler.rbi +14 -0
- data/rbi/prism/desugar_compiler.rbi +5 -0
- data/rbi/prism/mutation_compiler.rbi +5 -0
- data/rbi/prism/node.rbi +8221 -0
- data/rbi/prism/node_ext.rbi +102 -0
- data/rbi/prism/parse_result.rbi +304 -0
- data/rbi/prism/translation/parser/compiler.rbi +13 -0
- data/rbi/prism/translation/ripper/ripper_compiler.rbi +5 -0
- data/rbi/prism/translation/ripper.rbi +25 -0
- data/rbi/prism/translation/ruby_parser.rbi +11 -0
- data/rbi/prism/visitor.rbi +470 -0
- data/rbi/prism.rbi +39 -7749
- data/sig/prism/compiler.rbs +9 -0
- data/sig/prism/dispatcher.rbs +16 -0
- data/sig/prism/dot_visitor.rbs +6 -0
- data/sig/prism/dsl.rbs +462 -0
- data/sig/prism/mutation_compiler.rbs +158 -0
- data/sig/prism/node.rbs +3529 -0
- data/sig/prism/node_ext.rbs +78 -0
- data/sig/prism/pack.rbs +43 -0
- data/sig/prism/parse_result.rbs +127 -0
- data/sig/prism/pattern.rbs +13 -0
- data/sig/prism/serialize.rbs +7 -0
- data/sig/prism/visitor.rbs +168 -0
- data/sig/prism.rbs +188 -4767
- data/src/diagnostic.c +575 -230
- data/src/encoding.c +211 -108
- data/src/node.c +7526 -447
- data/src/options.c +36 -12
- data/src/pack.c +33 -17
- data/src/prettyprint.c +1294 -1385
- data/src/prism.c +3628 -1099
- data/src/regexp.c +17 -2
- data/src/serialize.c +47 -28
- data/src/static_literals.c +552 -0
- data/src/token_type.c +1 -0
- data/src/util/pm_buffer.c +147 -20
- data/src/util/pm_char.c +4 -4
- data/src/util/pm_constant_pool.c +35 -11
- data/src/util/pm_integer.c +629 -0
- data/src/util/pm_list.c +1 -1
- data/src/util/pm_newline_list.c +14 -5
- data/src/util/pm_string.c +134 -5
- data/src/util/pm_string_list.c +2 -2
- metadata +35 -6
- data/docs/ripper.md +0 -36
- data/rbi/prism_static.rbi +0 -207
- data/sig/prism_static.rbs +0 -201
data/lib/prism/dot_visitor.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
=begin
|
3
4
|
This file is generated by the templates/template.rb script and should not be
|
4
5
|
modified manually. See templates/lib/prism/dot_visitor.rb.erb
|
@@ -24,7 +25,7 @@ module Prism
|
|
24
25
|
if port
|
25
26
|
"<tr><td align=\"left\" colspan=\"2\" port=\"#{name}\">#{name}</td></tr>"
|
26
27
|
else
|
27
|
-
"<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value)}</td></tr>"
|
28
|
+
"<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value || raise)}</td></tr>"
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
@@ -1155,9 +1156,7 @@ module Prism
|
|
1155
1156
|
digraph.edge("#{id}:value -> #{node_id(node.value)};")
|
1156
1157
|
|
1157
1158
|
# operator_loc
|
1158
|
-
|
1159
|
-
table.field("operator_loc", location_inspect(operator_loc))
|
1160
|
-
end
|
1159
|
+
table.field("operator_loc", location_inspect(node.operator_loc))
|
1161
1160
|
|
1162
1161
|
digraph.nodes << <<~DOT
|
1163
1162
|
#{id} [
|
@@ -1773,6 +1772,9 @@ module Prism
|
|
1773
1772
|
table = Table.new("FloatNode")
|
1774
1773
|
id = node_id(node)
|
1775
1774
|
|
1775
|
+
# value
|
1776
|
+
table.field("value", node.value.inspect)
|
1777
|
+
|
1776
1778
|
digraph.nodes << <<~DOT
|
1777
1779
|
#{id} [
|
1778
1780
|
label=<#{table.to_dot.gsub(/\n/, "\n ")}>
|
@@ -2580,6 +2582,9 @@ module Prism
|
|
2580
2582
|
# flags
|
2581
2583
|
table.field("flags", integer_base_flags_inspect(node))
|
2582
2584
|
|
2585
|
+
# value
|
2586
|
+
table.field("value", node.value.inspect)
|
2587
|
+
|
2583
2588
|
digraph.nodes << <<~DOT
|
2584
2589
|
#{id} [
|
2585
2590
|
label=<#{table.to_dot.gsub(/\n/, "\n ")}>
|
@@ -2666,6 +2671,9 @@ module Prism
|
|
2666
2671
|
table = Table.new("InterpolatedStringNode")
|
2667
2672
|
id = node_id(node)
|
2668
2673
|
|
2674
|
+
# flags
|
2675
|
+
table.field("flags", interpolated_string_node_flags_inspect(node))
|
2676
|
+
|
2669
2677
|
# opening_loc
|
2670
2678
|
unless (opening_loc = node.opening_loc).nil?
|
2671
2679
|
table.field("opening_loc", location_inspect(opening_loc))
|
@@ -2768,6 +2776,20 @@ module Prism
|
|
2768
2776
|
super
|
2769
2777
|
end
|
2770
2778
|
|
2779
|
+
# Visit a ItParametersNode node.
|
2780
|
+
def visit_it_parameters_node(node)
|
2781
|
+
table = Table.new("ItParametersNode")
|
2782
|
+
id = node_id(node)
|
2783
|
+
|
2784
|
+
digraph.nodes << <<~DOT
|
2785
|
+
#{id} [
|
2786
|
+
label=<#{table.to_dot.gsub(/\n/, "\n ")}>
|
2787
|
+
];
|
2788
|
+
DOT
|
2789
|
+
|
2790
|
+
super
|
2791
|
+
end
|
2792
|
+
|
2771
2793
|
# Visit a KeywordHashNode node.
|
2772
2794
|
def visit_keyword_hash_node(node)
|
2773
2795
|
table = Table.new("KeywordHashNode")
|
@@ -4009,6 +4031,27 @@ module Prism
|
|
4009
4031
|
super
|
4010
4032
|
end
|
4011
4033
|
|
4034
|
+
# Visit a ShareableConstantNode node.
|
4035
|
+
def visit_shareable_constant_node(node)
|
4036
|
+
table = Table.new("ShareableConstantNode")
|
4037
|
+
id = node_id(node)
|
4038
|
+
|
4039
|
+
# flags
|
4040
|
+
table.field("flags", shareable_constant_node_flags_inspect(node))
|
4041
|
+
|
4042
|
+
# write
|
4043
|
+
table.field("write", port: true)
|
4044
|
+
digraph.edge("#{id}:write -> #{node_id(node.write)};")
|
4045
|
+
|
4046
|
+
digraph.nodes << <<~DOT
|
4047
|
+
#{id} [
|
4048
|
+
label=<#{table.to_dot.gsub(/\n/, "\n ")}>
|
4049
|
+
];
|
4050
|
+
DOT
|
4051
|
+
|
4052
|
+
super
|
4053
|
+
end
|
4054
|
+
|
4012
4055
|
# Visit a SingletonClassNode node.
|
4013
4056
|
def visit_singleton_class_node(node)
|
4014
4057
|
table = Table.new("SingletonClassNode")
|
@@ -4064,6 +4107,9 @@ module Prism
|
|
4064
4107
|
table = Table.new("SourceFileNode")
|
4065
4108
|
id = node_id(node)
|
4066
4109
|
|
4110
|
+
# flags
|
4111
|
+
table.field("flags", string_flags_inspect(node))
|
4112
|
+
|
4067
4113
|
# filepath
|
4068
4114
|
table.field("filepath", node.filepath.inspect)
|
4069
4115
|
|
@@ -4390,6 +4436,11 @@ module Prism
|
|
4390
4436
|
table.field("conditions", "[]")
|
4391
4437
|
end
|
4392
4438
|
|
4439
|
+
# then_keyword_loc
|
4440
|
+
unless (then_keyword_loc = node.then_keyword_loc).nil?
|
4441
|
+
table.field("then_keyword_loc", location_inspect(then_keyword_loc))
|
4442
|
+
end
|
4443
|
+
|
4393
4444
|
# statements
|
4394
4445
|
unless (statements = node.statements).nil?
|
4395
4446
|
table.field("statements", port: true)
|
@@ -4517,7 +4568,7 @@ module Prism
|
|
4517
4568
|
# Inspect a node that has arguments_node_flags flags to display the flags as a
|
4518
4569
|
# comma-separated list.
|
4519
4570
|
def arguments_node_flags_inspect(node)
|
4520
|
-
flags = []
|
4571
|
+
flags = [] #: Array[String]
|
4521
4572
|
flags << "contains_keyword_splat" if node.contains_keyword_splat?
|
4522
4573
|
flags.join(", ")
|
4523
4574
|
end
|
@@ -4525,7 +4576,7 @@ module Prism
|
|
4525
4576
|
# Inspect a node that has array_node_flags flags to display the flags as a
|
4526
4577
|
# comma-separated list.
|
4527
4578
|
def array_node_flags_inspect(node)
|
4528
|
-
flags = []
|
4579
|
+
flags = [] #: Array[String]
|
4529
4580
|
flags << "contains_splat" if node.contains_splat?
|
4530
4581
|
flags.join(", ")
|
4531
4582
|
end
|
@@ -4533,7 +4584,7 @@ module Prism
|
|
4533
4584
|
# Inspect a node that has call_node_flags flags to display the flags as a
|
4534
4585
|
# comma-separated list.
|
4535
4586
|
def call_node_flags_inspect(node)
|
4536
|
-
flags = []
|
4587
|
+
flags = [] #: Array[String]
|
4537
4588
|
flags << "safe_navigation" if node.safe_navigation?
|
4538
4589
|
flags << "variable_call" if node.variable_call?
|
4539
4590
|
flags << "attribute_write" if node.attribute_write?
|
@@ -4544,7 +4595,7 @@ module Prism
|
|
4544
4595
|
# Inspect a node that has encoding_flags flags to display the flags as a
|
4545
4596
|
# comma-separated list.
|
4546
4597
|
def encoding_flags_inspect(node)
|
4547
|
-
flags = []
|
4598
|
+
flags = [] #: Array[String]
|
4548
4599
|
flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
|
4549
4600
|
flags << "forced_binary_encoding" if node.forced_binary_encoding?
|
4550
4601
|
flags.join(", ")
|
@@ -4553,7 +4604,7 @@ module Prism
|
|
4553
4604
|
# Inspect a node that has integer_base_flags flags to display the flags as a
|
4554
4605
|
# comma-separated list.
|
4555
4606
|
def integer_base_flags_inspect(node)
|
4556
|
-
flags = []
|
4607
|
+
flags = [] #: Array[String]
|
4557
4608
|
flags << "binary" if node.binary?
|
4558
4609
|
flags << "decimal" if node.decimal?
|
4559
4610
|
flags << "octal" if node.octal?
|
@@ -4561,10 +4612,19 @@ module Prism
|
|
4561
4612
|
flags.join(", ")
|
4562
4613
|
end
|
4563
4614
|
|
4615
|
+
# Inspect a node that has interpolated_string_node_flags flags to display the flags as a
|
4616
|
+
# comma-separated list.
|
4617
|
+
def interpolated_string_node_flags_inspect(node)
|
4618
|
+
flags = [] #: Array[String]
|
4619
|
+
flags << "frozen" if node.frozen?
|
4620
|
+
flags << "mutable" if node.mutable?
|
4621
|
+
flags.join(", ")
|
4622
|
+
end
|
4623
|
+
|
4564
4624
|
# Inspect a node that has keyword_hash_node_flags flags to display the flags as a
|
4565
4625
|
# comma-separated list.
|
4566
4626
|
def keyword_hash_node_flags_inspect(node)
|
4567
|
-
flags = []
|
4627
|
+
flags = [] #: Array[String]
|
4568
4628
|
flags << "symbol_keys" if node.symbol_keys?
|
4569
4629
|
flags.join(", ")
|
4570
4630
|
end
|
@@ -4572,7 +4632,7 @@ module Prism
|
|
4572
4632
|
# Inspect a node that has loop_flags flags to display the flags as a
|
4573
4633
|
# comma-separated list.
|
4574
4634
|
def loop_flags_inspect(node)
|
4575
|
-
flags = []
|
4635
|
+
flags = [] #: Array[String]
|
4576
4636
|
flags << "begin_modifier" if node.begin_modifier?
|
4577
4637
|
flags.join(", ")
|
4578
4638
|
end
|
@@ -4580,7 +4640,7 @@ module Prism
|
|
4580
4640
|
# Inspect a node that has parameter_flags flags to display the flags as a
|
4581
4641
|
# comma-separated list.
|
4582
4642
|
def parameter_flags_inspect(node)
|
4583
|
-
flags = []
|
4643
|
+
flags = [] #: Array[String]
|
4584
4644
|
flags << "repeated_parameter" if node.repeated_parameter?
|
4585
4645
|
flags.join(", ")
|
4586
4646
|
end
|
@@ -4588,7 +4648,7 @@ module Prism
|
|
4588
4648
|
# Inspect a node that has range_flags flags to display the flags as a
|
4589
4649
|
# comma-separated list.
|
4590
4650
|
def range_flags_inspect(node)
|
4591
|
-
flags = []
|
4651
|
+
flags = [] #: Array[String]
|
4592
4652
|
flags << "exclude_end" if node.exclude_end?
|
4593
4653
|
flags.join(", ")
|
4594
4654
|
end
|
@@ -4596,7 +4656,7 @@ module Prism
|
|
4596
4656
|
# Inspect a node that has regular_expression_flags flags to display the flags as a
|
4597
4657
|
# comma-separated list.
|
4598
4658
|
def regular_expression_flags_inspect(node)
|
4599
|
-
flags = []
|
4659
|
+
flags = [] #: Array[String]
|
4600
4660
|
flags << "ignore_case" if node.ignore_case?
|
4601
4661
|
flags << "extended" if node.extended?
|
4602
4662
|
flags << "multi_line" if node.multi_line?
|
@@ -4611,20 +4671,31 @@ module Prism
|
|
4611
4671
|
flags.join(", ")
|
4612
4672
|
end
|
4613
4673
|
|
4674
|
+
# Inspect a node that has shareable_constant_node_flags flags to display the flags as a
|
4675
|
+
# comma-separated list.
|
4676
|
+
def shareable_constant_node_flags_inspect(node)
|
4677
|
+
flags = [] #: Array[String]
|
4678
|
+
flags << "literal" if node.literal?
|
4679
|
+
flags << "experimental_everything" if node.experimental_everything?
|
4680
|
+
flags << "experimental_copy" if node.experimental_copy?
|
4681
|
+
flags.join(", ")
|
4682
|
+
end
|
4683
|
+
|
4614
4684
|
# Inspect a node that has string_flags flags to display the flags as a
|
4615
4685
|
# comma-separated list.
|
4616
4686
|
def string_flags_inspect(node)
|
4617
|
-
flags = []
|
4687
|
+
flags = [] #: Array[String]
|
4618
4688
|
flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
|
4619
4689
|
flags << "forced_binary_encoding" if node.forced_binary_encoding?
|
4620
4690
|
flags << "frozen" if node.frozen?
|
4691
|
+
flags << "mutable" if node.mutable?
|
4621
4692
|
flags.join(", ")
|
4622
4693
|
end
|
4623
4694
|
|
4624
4695
|
# Inspect a node that has symbol_flags flags to display the flags as a
|
4625
4696
|
# comma-separated list.
|
4626
4697
|
def symbol_flags_inspect(node)
|
4627
|
-
flags = []
|
4698
|
+
flags = [] #: Array[String]
|
4628
4699
|
flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
|
4629
4700
|
flags << "forced_binary_encoding" if node.forced_binary_encoding?
|
4630
4701
|
flags << "forced_us_ascii_encoding" if node.forced_us_ascii_encoding?
|
data/lib/prism/dsl.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
=begin
|
3
4
|
This file is generated by the templates/template.rb script and should not be
|
4
5
|
modified manually. See templates/lib/prism/dsl.rb.erb
|
@@ -15,6 +16,7 @@ module Prism
|
|
15
16
|
# [
|
16
17
|
# Prism::IntegerNode.new(
|
17
18
|
# Prism::IntegerBaseFlags::DECIMAL,
|
19
|
+
# 1,
|
18
20
|
# Prism::Location.new(source, 1, 1),
|
19
21
|
# source
|
20
22
|
# )
|
@@ -29,7 +31,7 @@ module Prism
|
|
29
31
|
# source = Prism::Source.new("[1]")
|
30
32
|
#
|
31
33
|
# ArrayNode(
|
32
|
-
# IntegerNode(Prism::IntegerBaseFlags::DECIMAL, Location(source, 1, 1)), source),
|
34
|
+
# IntegerNode(Prism::IntegerBaseFlags::DECIMAL, 1, Location(source, 1, 1)), source),
|
33
35
|
# Location(source, 0, 1),
|
34
36
|
# Location(source, 2, 1),
|
35
37
|
# source
|
@@ -42,7 +44,7 @@ module Prism
|
|
42
44
|
|
43
45
|
# Create a new Location object
|
44
46
|
def Location(source = nil, start_offset = 0, length = 0)
|
45
|
-
Location.new(source, start_offset, length)
|
47
|
+
Location.new(source, start_offset, length) # steep:ignore
|
46
48
|
end
|
47
49
|
|
48
50
|
# Create a new AliasGlobalVariableNode node
|
@@ -311,8 +313,8 @@ module Prism
|
|
311
313
|
end
|
312
314
|
|
313
315
|
# Create a new FloatNode node
|
314
|
-
def FloatNode(source = nil, location = Location())
|
315
|
-
FloatNode.new(source, location)
|
316
|
+
def FloatNode(value, source = nil, location = Location())
|
317
|
+
FloatNode.new(source, value, location)
|
316
318
|
end
|
317
319
|
|
318
320
|
# Create a new ForNode node
|
@@ -451,8 +453,8 @@ module Prism
|
|
451
453
|
end
|
452
454
|
|
453
455
|
# Create a new IntegerNode node
|
454
|
-
def IntegerNode(flags, source = nil, location = Location())
|
455
|
-
IntegerNode.new(source, flags, location)
|
456
|
+
def IntegerNode(flags, value, source = nil, location = Location())
|
457
|
+
IntegerNode.new(source, flags, value, location)
|
456
458
|
end
|
457
459
|
|
458
460
|
# Create a new InterpolatedMatchLastLineNode node
|
@@ -466,8 +468,8 @@ module Prism
|
|
466
468
|
end
|
467
469
|
|
468
470
|
# Create a new InterpolatedStringNode node
|
469
|
-
def InterpolatedStringNode(opening_loc, parts, closing_loc, source = nil, location = Location())
|
470
|
-
InterpolatedStringNode.new(source, opening_loc, parts, closing_loc, location)
|
471
|
+
def InterpolatedStringNode(flags, opening_loc, parts, closing_loc, source = nil, location = Location())
|
472
|
+
InterpolatedStringNode.new(source, flags, opening_loc, parts, closing_loc, location)
|
471
473
|
end
|
472
474
|
|
473
475
|
# Create a new InterpolatedSymbolNode node
|
@@ -480,6 +482,11 @@ module Prism
|
|
480
482
|
InterpolatedXStringNode.new(source, opening_loc, parts, closing_loc, location)
|
481
483
|
end
|
482
484
|
|
485
|
+
# Create a new ItParametersNode node
|
486
|
+
def ItParametersNode(source = nil, location = Location())
|
487
|
+
ItParametersNode.new(source, location)
|
488
|
+
end
|
489
|
+
|
483
490
|
# Create a new KeywordHashNode node
|
484
491
|
def KeywordHashNode(flags, elements, source = nil, location = Location())
|
485
492
|
KeywordHashNode.new(source, flags, elements, location)
|
@@ -700,6 +707,11 @@ module Prism
|
|
700
707
|
SelfNode.new(source, location)
|
701
708
|
end
|
702
709
|
|
710
|
+
# Create a new ShareableConstantNode node
|
711
|
+
def ShareableConstantNode(flags, write, source = nil, location = Location())
|
712
|
+
ShareableConstantNode.new(source, flags, write, location)
|
713
|
+
end
|
714
|
+
|
703
715
|
# Create a new SingletonClassNode node
|
704
716
|
def SingletonClassNode(locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc, source = nil, location = Location())
|
705
717
|
SingletonClassNode.new(source, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc, location)
|
@@ -711,8 +723,8 @@ module Prism
|
|
711
723
|
end
|
712
724
|
|
713
725
|
# Create a new SourceFileNode node
|
714
|
-
def SourceFileNode(filepath, source = nil, location = Location())
|
715
|
-
SourceFileNode.new(source, filepath, location)
|
726
|
+
def SourceFileNode(flags, filepath, source = nil, location = Location())
|
727
|
+
SourceFileNode.new(source, flags, filepath, location)
|
716
728
|
end
|
717
729
|
|
718
730
|
# Create a new SourceLineNode node
|
@@ -766,8 +778,8 @@ module Prism
|
|
766
778
|
end
|
767
779
|
|
768
780
|
# Create a new WhenNode node
|
769
|
-
def WhenNode(keyword_loc, conditions, statements, source = nil, location = Location())
|
770
|
-
WhenNode.new(source, keyword_loc, conditions, statements, location)
|
781
|
+
def WhenNode(keyword_loc, conditions, then_keyword_loc, statements, source = nil, location = Location())
|
782
|
+
WhenNode.new(source, keyword_loc, conditions, then_keyword_loc, statements, location)
|
771
783
|
end
|
772
784
|
|
773
785
|
# Create a new WhileNode node
|
data/lib/prism/ffi.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: ignore
|
2
3
|
|
3
4
|
# This file is responsible for mirroring the API provided by the C extension by
|
4
5
|
# using FFI to call into the shared library.
|
@@ -7,8 +8,6 @@ require "rbconfig"
|
|
7
8
|
require "ffi"
|
8
9
|
|
9
10
|
module Prism
|
10
|
-
BACKEND = :FFI
|
11
|
-
|
12
11
|
module LibRubyParser # :nodoc:
|
13
12
|
extend FFI::Library
|
14
13
|
|
@@ -24,15 +23,21 @@ module Prism
|
|
24
23
|
# size_t -> :size_t
|
25
24
|
# void -> :void
|
26
25
|
#
|
27
|
-
def self.resolve_type(type)
|
26
|
+
def self.resolve_type(type, callbacks)
|
28
27
|
type = type.strip
|
29
|
-
|
28
|
+
|
29
|
+
if !type.end_with?("*")
|
30
|
+
type.delete_prefix("const ").to_sym
|
31
|
+
else
|
32
|
+
type = type.delete_suffix("*").rstrip
|
33
|
+
callbacks.include?(type.to_sym) ? type.to_sym : :pointer
|
34
|
+
end
|
30
35
|
end
|
31
36
|
|
32
37
|
# Read through the given header file and find the declaration of each of the
|
33
38
|
# given functions. For each one, define a function with the same name and
|
34
39
|
# signature as the C function.
|
35
|
-
def self.load_exported_functions_from(header, *functions)
|
40
|
+
def self.load_exported_functions_from(header, *functions, callbacks)
|
36
41
|
File.foreach(File.expand_path("../../include/#{header}", __dir__)) do |line|
|
37
42
|
# We only want to attempt to load exported functions.
|
38
43
|
next unless line.start_with?("PRISM_EXPORTED_FUNCTION ")
|
@@ -56,24 +61,28 @@ module Prism
|
|
56
61
|
|
57
62
|
# Resolve the type of the argument by dropping the name of the argument
|
58
63
|
# first if it is present.
|
59
|
-
arg_types.map! { |type| resolve_type(type.sub(/\w+$/, "")) }
|
64
|
+
arg_types.map! { |type| resolve_type(type.sub(/\w+$/, ""), callbacks) }
|
60
65
|
|
61
66
|
# Attach the function using the FFI library.
|
62
|
-
attach_function name, arg_types, resolve_type(return_type)
|
67
|
+
attach_function name, arg_types, resolve_type(return_type, [])
|
63
68
|
end
|
64
69
|
|
65
70
|
# If we didn't find all of the functions, raise an error.
|
66
71
|
raise "Could not find functions #{functions.inspect}" unless functions.empty?
|
67
72
|
end
|
68
73
|
|
74
|
+
callback :pm_parse_stream_fgets_t, [:pointer, :int, :pointer], :pointer
|
75
|
+
|
69
76
|
load_exported_functions_from(
|
70
77
|
"prism.h",
|
71
78
|
"pm_version",
|
72
79
|
"pm_serialize_parse",
|
80
|
+
"pm_serialize_parse_stream",
|
73
81
|
"pm_serialize_parse_comments",
|
74
82
|
"pm_serialize_lex",
|
75
83
|
"pm_serialize_parse_lex",
|
76
|
-
"pm_parse_success_p"
|
84
|
+
"pm_parse_success_p",
|
85
|
+
[:pm_parse_stream_fgets_t]
|
77
86
|
)
|
78
87
|
|
79
88
|
load_exported_functions_from(
|
@@ -82,7 +91,8 @@ module Prism
|
|
82
91
|
"pm_buffer_init",
|
83
92
|
"pm_buffer_value",
|
84
93
|
"pm_buffer_length",
|
85
|
-
"pm_buffer_free"
|
94
|
+
"pm_buffer_free",
|
95
|
+
[]
|
86
96
|
)
|
87
97
|
|
88
98
|
load_exported_functions_from(
|
@@ -91,7 +101,8 @@ module Prism
|
|
91
101
|
"pm_string_free",
|
92
102
|
"pm_string_source",
|
93
103
|
"pm_string_length",
|
94
|
-
"pm_string_sizeof"
|
104
|
+
"pm_string_sizeof",
|
105
|
+
[]
|
95
106
|
)
|
96
107
|
|
97
108
|
# This object represents a pm_buffer_t. We only use it as an opaque pointer,
|
@@ -216,13 +227,36 @@ module Prism
|
|
216
227
|
end
|
217
228
|
|
218
229
|
# Mirror the Prism.parse_file API by using the serialization API. This uses
|
219
|
-
# native strings instead of Ruby strings because it allows us to use mmap
|
220
|
-
# it is available.
|
230
|
+
# native strings instead of Ruby strings because it allows us to use mmap
|
231
|
+
# when it is available.
|
221
232
|
def parse_file(filepath, **options)
|
222
233
|
options[:filepath] = filepath
|
223
234
|
LibRubyParser::PrismString.with_file(filepath) { |string| parse_common(string, string.read, options) }
|
224
235
|
end
|
225
236
|
|
237
|
+
# Mirror the Prism.parse_stream API by using the serialization API.
|
238
|
+
def parse_stream(stream, **options)
|
239
|
+
LibRubyParser::PrismBuffer.with do |buffer|
|
240
|
+
source = +""
|
241
|
+
callback = -> (string, size, _) {
|
242
|
+
raise "Expected size to be >= 0, got: #{size}" if size <= 0
|
243
|
+
|
244
|
+
if !(line = stream.gets(size - 1)).nil?
|
245
|
+
source << line
|
246
|
+
string.write_string("#{line}\x00", line.bytesize + 1)
|
247
|
+
end
|
248
|
+
}
|
249
|
+
|
250
|
+
# In the pm_serialize_parse_stream function it accepts a pointer to the
|
251
|
+
# IO object as a void* and then passes it through to the callback as the
|
252
|
+
# third argument, but it never touches it itself. As such, since we have
|
253
|
+
# access to the IO object already through the closure of the lambda, we
|
254
|
+
# can pass a null pointer here and not worry.
|
255
|
+
LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, dump_options(options))
|
256
|
+
Prism.load(source, buffer.read)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
226
260
|
# Mirror the Prism.parse_comments API by using the serialization API.
|
227
261
|
def parse_comments(code, **options)
|
228
262
|
LibRubyParser::PrismString.with_string(code) { |string| parse_comments_common(string, code, options) }
|
@@ -314,6 +348,24 @@ module Prism
|
|
314
348
|
LibRubyParser.pm_parse_success_p(string.pointer, string.length, dump_options(options))
|
315
349
|
end
|
316
350
|
|
351
|
+
# Return the value that should be dumped for the command_line option.
|
352
|
+
def dump_options_command_line(options)
|
353
|
+
command_line = options.fetch(:command_line, "")
|
354
|
+
raise ArgumentError, "command_line must be a string" unless command_line.is_a?(String)
|
355
|
+
|
356
|
+
command_line.each_char.inject(0) do |value, char|
|
357
|
+
case char
|
358
|
+
when "a" then value | 0b000001
|
359
|
+
when "e" then value | 0b000010
|
360
|
+
when "l" then value | 0b000100
|
361
|
+
when "n" then value | 0b001000
|
362
|
+
when "p" then value | 0b010000
|
363
|
+
when "x" then value | 0b100000
|
364
|
+
else raise ArgumentError, "invalid command_line option: #{char}"
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
317
369
|
# Convert the given options into a serialized options string.
|
318
370
|
def dump_options(options)
|
319
371
|
template = +""
|
@@ -342,6 +394,9 @@ module Prism
|
|
342
394
|
template << "C"
|
343
395
|
values << (options.fetch(:frozen_string_literal, false) ? 1 : 0)
|
344
396
|
|
397
|
+
template << "C"
|
398
|
+
values << dump_options_command_line(options)
|
399
|
+
|
345
400
|
template << "C"
|
346
401
|
values << { nil => 0, "3.3.0" => 1, "3.4.0" => 0, "latest" => 0 }.fetch(options[:version])
|
347
402
|
|
data/lib/prism/lex_compat.rb
CHANGED
@@ -185,6 +185,8 @@ module Prism
|
|
185
185
|
# However, we add a couple of convenience methods onto them to make them a
|
186
186
|
# little easier to work with. We delegate all other methods to the array.
|
187
187
|
class Token < SimpleDelegator
|
188
|
+
# @dynamic initialize, each, []
|
189
|
+
|
188
190
|
# The location of the token in the source.
|
189
191
|
def location
|
190
192
|
self[0]
|
@@ -241,10 +243,10 @@ module Prism
|
|
241
243
|
def ==(other) # :nodoc:
|
242
244
|
return false unless self[0...-1] == other[0...-1]
|
243
245
|
|
244
|
-
if self[
|
245
|
-
other[
|
246
|
+
if self[3] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
|
247
|
+
other[3] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED != 0
|
246
248
|
else
|
247
|
-
self[
|
249
|
+
self[3] == other[3]
|
248
250
|
end
|
249
251
|
end
|
250
252
|
end
|
@@ -308,7 +310,7 @@ module Prism
|
|
308
310
|
def to_a
|
309
311
|
embexpr_balance = 0
|
310
312
|
|
311
|
-
tokens.each_with_object([]) do |token, results|
|
313
|
+
tokens.each_with_object([]) do |token, results| #$ Array[Token]
|
312
314
|
case token.event
|
313
315
|
when :on_embexpr_beg
|
314
316
|
embexpr_balance += 1
|
@@ -409,7 +411,7 @@ module Prism
|
|
409
411
|
# If every line in the heredoc is blank, we still need to split up the
|
410
412
|
# string content token into multiple tokens.
|
411
413
|
if dedent.nil?
|
412
|
-
results = []
|
414
|
+
results = [] #: Array[Token]
|
413
415
|
embexpr_balance = 0
|
414
416
|
|
415
417
|
tokens.each do |token|
|
@@ -444,7 +446,7 @@ module Prism
|
|
444
446
|
# If the minimum common whitespace is 0, then we need to concatenate
|
445
447
|
# string nodes together that are immediately adjacent.
|
446
448
|
if dedent == 0
|
447
|
-
results = []
|
449
|
+
results = [] #: Array[Token]
|
448
450
|
embexpr_balance = 0
|
449
451
|
|
450
452
|
index = 0
|
@@ -477,7 +479,7 @@ module Prism
|
|
477
479
|
# insert on_ignored_sp tokens for the amount of dedent that we need to
|
478
480
|
# perform. We also need to remove the dedent from the beginning of
|
479
481
|
# each line of plain string content tokens.
|
480
|
-
results = []
|
482
|
+
results = [] #: Array[Token]
|
481
483
|
dedent_next = true
|
482
484
|
embexpr_balance = 0
|
483
485
|
|
@@ -526,7 +528,7 @@ module Prism
|
|
526
528
|
# dedent from the beginning of the line.
|
527
529
|
if (dedent > 0) && (dedent_next || index > 0)
|
528
530
|
deleting = 0
|
529
|
-
deleted_chars = []
|
531
|
+
deleted_chars = [] #: Array[String]
|
530
532
|
|
531
533
|
# Gather up all of the characters that we're going to
|
532
534
|
# delete, stopping when you hit a character that would put
|
@@ -603,15 +605,15 @@ module Prism
|
|
603
605
|
end
|
604
606
|
|
605
607
|
def result
|
606
|
-
tokens = []
|
608
|
+
tokens = [] #: Array[LexCompat::Token]
|
607
609
|
|
608
610
|
state = :default
|
609
|
-
heredoc_stack = [[]]
|
611
|
+
heredoc_stack = [[]] #: Array[Array[Heredoc::PlainHeredoc | Heredoc::DashHeredoc | Heredoc::DedentingHeredoc]]
|
610
612
|
|
611
613
|
result = Prism.lex(source, **options)
|
612
614
|
result_value = result.value
|
613
|
-
previous_state = nil
|
614
|
-
last_heredoc_end = nil
|
615
|
+
previous_state = nil #: Ripper::Lexer::State?
|
616
|
+
last_heredoc_end = nil #: Integer?
|
615
617
|
|
616
618
|
# In previous versions of Ruby, Ripper wouldn't flush the bom before the
|
617
619
|
# first token, so we had to have a hack in place to account for that. This
|
@@ -842,7 +844,7 @@ module Prism
|
|
842
844
|
# We sort by location to compare against Ripper's output
|
843
845
|
tokens.sort_by!(&:location)
|
844
846
|
|
845
|
-
ParseResult.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings,
|
847
|
+
ParseResult.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings, Source.new(source))
|
846
848
|
end
|
847
849
|
end
|
848
850
|
|
@@ -858,8 +860,8 @@ module Prism
|
|
858
860
|
end
|
859
861
|
|
860
862
|
def result
|
861
|
-
previous = []
|
862
|
-
results = []
|
863
|
+
previous = [] #: [[Integer, Integer], Symbol, String, untyped] | []
|
864
|
+
results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]]
|
863
865
|
|
864
866
|
lex(source).each do |token|
|
865
867
|
case token[1]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
=begin
|
3
4
|
This file is generated by the templates/template.rb script and should not be
|
4
5
|
modified manually. See templates/lib/prism/mutation_compiler.rb.erb
|
@@ -445,6 +446,11 @@ module Prism
|
|
445
446
|
node.copy(parts: visit_all(node.parts))
|
446
447
|
end
|
447
448
|
|
449
|
+
# Copy a ItParametersNode node
|
450
|
+
def visit_it_parameters_node(node)
|
451
|
+
node.copy
|
452
|
+
end
|
453
|
+
|
448
454
|
# Copy a KeywordHashNode node
|
449
455
|
def visit_keyword_hash_node(node)
|
450
456
|
node.copy(elements: visit_all(node.elements))
|
@@ -665,6 +671,11 @@ module Prism
|
|
665
671
|
node.copy
|
666
672
|
end
|
667
673
|
|
674
|
+
# Copy a ShareableConstantNode node
|
675
|
+
def visit_shareable_constant_node(node)
|
676
|
+
node.copy(write: visit(node.write))
|
677
|
+
end
|
678
|
+
|
668
679
|
# Copy a SingletonClassNode node
|
669
680
|
def visit_singleton_class_node(node)
|
670
681
|
node.copy(expression: visit(node.expression), body: visit(node.body))
|