prism 0.29.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/CONTRIBUTING.md +0 -4
  4. data/README.md +1 -0
  5. data/config.yml +66 -9
  6. data/docs/fuzzing.md +1 -1
  7. data/docs/ripper_translation.md +22 -0
  8. data/ext/prism/api_node.c +30 -12
  9. data/ext/prism/extension.c +107 -372
  10. data/ext/prism/extension.h +1 -1
  11. data/include/prism/ast.h +138 -70
  12. data/include/prism/diagnostic.h +7 -2
  13. data/include/prism/node.h +0 -21
  14. data/include/prism/parser.h +23 -25
  15. data/include/prism/regexp.h +17 -8
  16. data/include/prism/static_literals.h +3 -2
  17. data/include/prism/util/pm_char.h +1 -2
  18. data/include/prism/util/pm_constant_pool.h +0 -8
  19. data/include/prism/util/pm_integer.h +16 -9
  20. data/include/prism/util/pm_string.h +0 -8
  21. data/include/prism/version.h +2 -2
  22. data/include/prism.h +0 -11
  23. data/lib/prism/compiler.rb +3 -0
  24. data/lib/prism/dispatcher.rb +14 -0
  25. data/lib/prism/dot_visitor.rb +22 -3
  26. data/lib/prism/dsl.rb +7 -2
  27. data/lib/prism/ffi.rb +24 -3
  28. data/lib/prism/inspect_visitor.rb +10 -8
  29. data/lib/prism/mutation_compiler.rb +6 -1
  30. data/lib/prism/node.rb +166 -241
  31. data/lib/prism/node_ext.rb +21 -5
  32. data/lib/prism/parse_result/comments.rb +0 -7
  33. data/lib/prism/parse_result/newlines.rb +101 -11
  34. data/lib/prism/parse_result.rb +17 -0
  35. data/lib/prism/reflection.rb +3 -1
  36. data/lib/prism/serialize.rb +80 -67
  37. data/lib/prism/translation/parser/compiler.rb +134 -114
  38. data/lib/prism/translation/parser.rb +6 -1
  39. data/lib/prism/translation/ripper.rb +8 -6
  40. data/lib/prism/translation/ruby_parser.rb +23 -5
  41. data/lib/prism/visitor.rb +3 -0
  42. data/lib/prism.rb +0 -4
  43. data/prism.gemspec +1 -4
  44. data/rbi/prism/node.rbi +63 -6
  45. data/rbi/prism/visitor.rbi +3 -0
  46. data/rbi/prism.rbi +6 -0
  47. data/sig/prism/dsl.rbs +4 -1
  48. data/sig/prism/mutation_compiler.rbs +1 -0
  49. data/sig/prism/node.rbs +28 -4
  50. data/sig/prism/visitor.rbs +1 -0
  51. data/sig/prism.rbs +21 -0
  52. data/src/diagnostic.c +27 -17
  53. data/src/node.c +408 -1666
  54. data/src/prettyprint.c +49 -6
  55. data/src/prism.c +958 -991
  56. data/src/regexp.c +133 -68
  57. data/src/serialize.c +6 -1
  58. data/src/static_literals.c +63 -84
  59. data/src/token_type.c +2 -2
  60. data/src/util/pm_constant_pool.c +0 -8
  61. data/src/util/pm_integer.c +39 -11
  62. data/src/util/pm_string.c +0 -12
  63. data/src/util/pm_strpbrk.c +32 -6
  64. metadata +2 -5
  65. data/include/prism/util/pm_string_list.h +0 -44
  66. data/lib/prism/debug.rb +0 -249
  67. data/src/util/pm_string_list.c +0 -28
@@ -48,6 +48,9 @@ typedef struct {
48
48
  * from the string itself.
49
49
  */
50
50
  typedef enum {
51
+ /** The default decimal base, with no prefix. Leading 0s will be ignored. */
52
+ PM_INTEGER_BASE_DEFAULT,
53
+
51
54
  /** The binary base, indicated by a 0b or 0B prefix. */
52
55
  PM_INTEGER_BASE_BINARY,
53
56
 
@@ -79,15 +82,7 @@ typedef enum {
79
82
  * @param start The start of the string.
80
83
  * @param end The end of the string.
81
84
  */
82
- PRISM_EXPORTED_FUNCTION void pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end);
83
-
84
- /**
85
- * Return the memory size of the integer.
86
- *
87
- * @param integer The integer to get the memory size of.
88
- * @return The size of the memory associated with the integer.
89
- */
90
- size_t pm_integer_memsize(const pm_integer_t *integer);
85
+ void pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end);
91
86
 
92
87
  /**
93
88
  * Compare two integers. This function returns -1 if the left integer is less
@@ -100,6 +95,18 @@ size_t pm_integer_memsize(const pm_integer_t *integer);
100
95
  */
101
96
  int pm_integer_compare(const pm_integer_t *left, const pm_integer_t *right);
102
97
 
98
+ /**
99
+ * Reduce a ratio of integers to its simplest form.
100
+ *
101
+ * If either the numerator or denominator do not fit into a 32-bit integer, then
102
+ * this function is a no-op. In the future, we may consider reducing even the
103
+ * larger numbers, but for now we're going to keep it simple.
104
+ *
105
+ * @param numerator The numerator of the ratio.
106
+ * @param denominator The denominator of the ratio.
107
+ */
108
+ void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator);
109
+
103
110
  /**
104
111
  * Convert an integer to a decimal string.
105
112
  *
@@ -120,14 +120,6 @@ PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const ch
120
120
  */
121
121
  PRISM_EXPORTED_FUNCTION bool pm_string_file_init(pm_string_t *string, const char *filepath);
122
122
 
123
- /**
124
- * Returns the memory size associated with the string.
125
- *
126
- * @param string The string to get the memory size of.
127
- * @return The size of the memory associated with the string.
128
- */
129
- size_t pm_string_memsize(const pm_string_t *string);
130
-
131
123
  /**
132
124
  * Ensure the string is owned. If it is not, then reinitialize it as owned and
133
125
  * copy over the previous source.
@@ -14,7 +14,7 @@
14
14
  /**
15
15
  * The minor version of the Prism library as an int.
16
16
  */
17
- #define PRISM_VERSION_MINOR 29
17
+ #define PRISM_VERSION_MINOR 30
18
18
 
19
19
  /**
20
20
  * The patch version of the Prism library as an int.
@@ -24,6 +24,6 @@
24
24
  /**
25
25
  * The version of the Prism library as a constant string.
26
26
  */
27
- #define PRISM_VERSION "0.29.0"
27
+ #define PRISM_VERSION "0.30.0"
28
28
 
29
29
  #endif
data/include/prism.h CHANGED
@@ -219,17 +219,6 @@ PRISM_EXPORTED_FUNCTION const char * pm_token_type_name(pm_token_type_t token_ty
219
219
  */
220
220
  const char * pm_token_type_human(pm_token_type_t token_type);
221
221
 
222
- /**
223
- * Format the errors on the parser into the given buffer.
224
- *
225
- * @param parser The parser to format the errors for.
226
- * @param error_list The list of errors to format.
227
- * @param buffer The buffer to format the errors into.
228
- * @param colorize Whether or not to colorize the errors with ANSI escape sequences.
229
- * @param inline_messages Whether or not to inline the messages with the source.
230
- */
231
- PRISM_EXPORTED_FUNCTION void pm_parser_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, pm_buffer_t *buffer, bool colorize, bool inline_messages);
232
-
233
222
  // We optionally support dumping to JSON. For systems that don't want or need
234
223
  // this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define.
235
224
  #ifndef PRISM_EXCLUDE_JSON
@@ -301,6 +301,9 @@ module Prism
301
301
  # Compile a InterpolatedXStringNode node
302
302
  alias visit_interpolated_x_string_node visit_child_nodes
303
303
 
304
+ # Compile a ItLocalVariableReadNode node
305
+ alias visit_it_local_variable_read_node visit_child_nodes
306
+
304
307
  # Compile a ItParametersNode node
305
308
  alias visit_it_parameters_node visit_child_nodes
306
309
 
@@ -762,6 +762,14 @@ module Prism
762
762
  listeners[:on_interpolated_x_string_node_leave]&.each { |listener| listener.on_interpolated_x_string_node_leave(node) }
763
763
  end
764
764
 
765
+ # Dispatch enter and leave events for ItLocalVariableReadNode nodes and continue
766
+ # walking the tree.
767
+ def visit_it_local_variable_read_node(node)
768
+ listeners[:on_it_local_variable_read_node_enter]&.each { |listener| listener.on_it_local_variable_read_node_enter(node) }
769
+ super
770
+ listeners[:on_it_local_variable_read_node_leave]&.each { |listener| listener.on_it_local_variable_read_node_leave(node) }
771
+ end
772
+
765
773
  # Dispatch enter and leave events for ItParametersNode nodes and continue
766
774
  # walking the tree.
767
775
  def visit_it_parameters_node(node)
@@ -1795,6 +1803,12 @@ module Prism
1795
1803
  listeners[:on_interpolated_x_string_node_leave]&.each { |listener| listener.on_interpolated_x_string_node_leave(node) }
1796
1804
  end
1797
1805
 
1806
+ # Dispatch enter and leave events for ItLocalVariableReadNode nodes.
1807
+ def visit_it_local_variable_read_node(node)
1808
+ listeners[:on_it_local_variable_read_node_enter]&.each { |listener| listener.on_it_local_variable_read_node_enter(node) }
1809
+ listeners[:on_it_local_variable_read_node_leave]&.each { |listener| listener.on_it_local_variable_read_node_leave(node) }
1810
+ end
1811
+
1798
1812
  # Dispatch enter and leave events for ItParametersNode nodes.
1799
1813
  def visit_it_parameters_node(node)
1800
1814
  listeners[:on_it_parameters_node_enter]&.each { |listener| listener.on_it_parameters_node_enter(node) }
@@ -2780,6 +2780,20 @@ module Prism
2780
2780
  super
2781
2781
  end
2782
2782
 
2783
+ # Visit a ItLocalVariableReadNode node.
2784
+ def visit_it_local_variable_read_node(node)
2785
+ table = Table.new("ItLocalVariableReadNode")
2786
+ id = node_id(node)
2787
+
2788
+ digraph.nodes << <<~DOT
2789
+ #{id} [
2790
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2791
+ ];
2792
+ DOT
2793
+
2794
+ super
2795
+ end
2796
+
2783
2797
  # Visit a ItParametersNode node.
2784
2798
  def visit_it_parameters_node(node)
2785
2799
  table = Table.new("ItParametersNode")
@@ -3779,9 +3793,14 @@ module Prism
3779
3793
  table = Table.new("RationalNode")
3780
3794
  id = node_id(node)
3781
3795
 
3782
- # numeric
3783
- table.field("numeric", port: true)
3784
- digraph.edge("#{id}:numeric -> #{node_id(node.numeric)};")
3796
+ # flags
3797
+ table.field("flags", integer_base_flags_inspect(node))
3798
+
3799
+ # numerator
3800
+ table.field("numerator", node.numerator.inspect)
3801
+
3802
+ # denominator
3803
+ table.field("denominator", node.denominator.inspect)
3785
3804
 
3786
3805
  digraph.nodes << <<~DOT
3787
3806
  #{id} [
data/lib/prism/dsl.rb CHANGED
@@ -482,6 +482,11 @@ module Prism
482
482
  InterpolatedXStringNode.new(source, opening_loc, parts, closing_loc, location)
483
483
  end
484
484
 
485
+ # Create a new ItLocalVariableReadNode node
486
+ def ItLocalVariableReadNode(source = nil, location = Location())
487
+ ItLocalVariableReadNode.new(source, location)
488
+ end
489
+
485
490
  # Create a new ItParametersNode node
486
491
  def ItParametersNode(source = nil, location = Location())
487
492
  ItParametersNode.new(source, location)
@@ -653,8 +658,8 @@ module Prism
653
658
  end
654
659
 
655
660
  # Create a new RationalNode node
656
- def RationalNode(numeric, source = nil, location = Location())
657
- RationalNode.new(source, numeric, location)
661
+ def RationalNode(flags, numerator, denominator, source = nil, location = Location())
662
+ RationalNode.new(source, flags, numerator, denominator, location)
658
663
  end
659
664
 
660
665
  # Create a new RedoNode node
data/lib/prism/ffi.rb CHANGED
@@ -200,8 +200,8 @@ module Prism
200
200
 
201
201
  class << self
202
202
  # Mirror the Prism.dump API by using the serialization API.
203
- def dump(code, **options)
204
- LibRubyParser::PrismString.with_string(code) { |string| dump_common(string, options) }
203
+ def dump(source, **options)
204
+ LibRubyParser::PrismString.with_string(source) { |string| dump_common(string, options) }
205
205
  end
206
206
 
207
207
  # Mirror the Prism.dump_file API by using the serialization API.
@@ -302,6 +302,27 @@ module Prism
302
302
  !parse_file_success?(filepath, **options)
303
303
  end
304
304
 
305
+ # Mirror the Prism.profile API by using the serialization API.
306
+ def profile(source, **options)
307
+ LibRubyParser::PrismString.with_string(source) do |string|
308
+ LibRubyParser::PrismBuffer.with do |buffer|
309
+ LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options))
310
+ nil
311
+ end
312
+ end
313
+ end
314
+
315
+ # Mirror the Prism.profile_file API by using the serialization API.
316
+ def profile_file(filepath, **options)
317
+ LibRubyParser::PrismString.with_file(filepath) do |string|
318
+ LibRubyParser::PrismBuffer.with do |buffer|
319
+ options[:filepath] = filepath
320
+ LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options))
321
+ nil
322
+ end
323
+ end
324
+ end
325
+
305
326
  private
306
327
 
307
328
  def dump_common(string, options) # :nodoc:
@@ -394,7 +415,7 @@ module Prism
394
415
 
395
416
  template << "L"
396
417
  if (encoding = options[:encoding])
397
- name = encoding.name
418
+ name = encoding.is_a?(Encoding) ? encoding.name : encoding
398
419
  values.push(name.bytesize, name.b)
399
420
  template << "A*"
400
421
  else
@@ -1310,6 +1310,11 @@ module Prism
1310
1310
  commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1311
1311
  end
1312
1312
 
1313
+ # Inspect a ItLocalVariableReadNode node.
1314
+ def visit_it_local_variable_read_node(node)
1315
+ commands << [inspect_node("ItLocalVariableReadNode", node), indent]
1316
+ end
1317
+
1313
1318
  # Inspect a ItParametersNode node.
1314
1319
  def visit_it_parameters_node(node)
1315
1320
  commands << [inspect_node("ItParametersNode", node), indent]
@@ -1777,8 +1782,10 @@ module Prism
1777
1782
  # Inspect a RationalNode node.
1778
1783
  def visit_rational_node(node)
1779
1784
  commands << [inspect_node("RationalNode", node), indent]
1780
- commands << ["└── numeric:\n", indent]
1781
- commands << [node.numeric, "#{indent} "]
1785
+ flags = [("binary" if node.binary?), ("decimal" if node.decimal?), ("octal" if node.octal?), ("hexadecimal" if node.hexadecimal?)].compact
1786
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1787
+ commands << ["├── numerator: #{node.numerator.inspect}\n", indent]
1788
+ commands << ["└── denominator: #{node.denominator.inspect}\n", indent]
1782
1789
  end
1783
1790
 
1784
1791
  # Inspect a RedoNode node.
@@ -2135,13 +2142,8 @@ module Prism
2135
2142
 
2136
2143
  # Compose a header for the given node.
2137
2144
  def inspect_node(name, node)
2138
- result = +"@ #{name} ("
2139
-
2140
2145
  location = node.location
2141
- result << "location: (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})"
2142
- result << ", newline: true" if node.newline?
2143
-
2144
- result << ")\n"
2146
+ "@ #{name} (location: (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}))\n"
2145
2147
  end
2146
2148
 
2147
2149
  # Compose a string representing the given inner location field.
@@ -446,6 +446,11 @@ module Prism
446
446
  node.copy(parts: visit_all(node.parts))
447
447
  end
448
448
 
449
+ # Copy a ItLocalVariableReadNode node
450
+ def visit_it_local_variable_read_node(node)
451
+ node.copy
452
+ end
453
+
449
454
  # Copy a ItParametersNode node
450
455
  def visit_it_parameters_node(node)
451
456
  node.copy
@@ -618,7 +623,7 @@ module Prism
618
623
 
619
624
  # Copy a RationalNode node
620
625
  def visit_rational_node(node)
621
- node.copy(numeric: visit(node.numeric))
626
+ node.copy
622
627
  end
623
628
 
624
629
  # Copy a RedoNode node