prism 0.18.0 → 0.19.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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/README.md +2 -1
  4. data/config.yml +188 -55
  5. data/docs/building.md +9 -2
  6. data/docs/configuration.md +10 -9
  7. data/docs/encoding.md +24 -56
  8. data/docs/local_variable_depth.md +229 -0
  9. data/docs/ruby_api.md +2 -0
  10. data/docs/serialization.md +18 -13
  11. data/ext/prism/api_node.c +337 -195
  12. data/ext/prism/extconf.rb +13 -7
  13. data/ext/prism/extension.c +96 -32
  14. data/ext/prism/extension.h +1 -1
  15. data/include/prism/ast.h +340 -137
  16. data/include/prism/defines.h +17 -0
  17. data/include/prism/diagnostic.h +11 -5
  18. data/include/prism/encoding.h +248 -0
  19. data/include/prism/options.h +2 -2
  20. data/include/prism/parser.h +62 -42
  21. data/include/prism/regexp.h +2 -2
  22. data/include/prism/util/pm_buffer.h +9 -1
  23. data/include/prism/util/pm_memchr.h +2 -2
  24. data/include/prism/util/pm_strpbrk.h +3 -3
  25. data/include/prism/version.h +2 -2
  26. data/include/prism.h +13 -15
  27. data/lib/prism/compiler.rb +12 -0
  28. data/lib/prism/debug.rb +9 -4
  29. data/lib/prism/desugar_compiler.rb +3 -3
  30. data/lib/prism/dispatcher.rb +56 -0
  31. data/lib/prism/dot_visitor.rb +476 -198
  32. data/lib/prism/dsl.rb +66 -46
  33. data/lib/prism/ffi.rb +16 -3
  34. data/lib/prism/lex_compat.rb +19 -9
  35. data/lib/prism/mutation_compiler.rb +20 -0
  36. data/lib/prism/node.rb +1173 -450
  37. data/lib/prism/node_ext.rb +41 -16
  38. data/lib/prism/parse_result.rb +12 -15
  39. data/lib/prism/ripper_compat.rb +49 -34
  40. data/lib/prism/serialize.rb +242 -212
  41. data/lib/prism/visitor.rb +12 -0
  42. data/lib/prism.rb +20 -4
  43. data/prism.gemspec +4 -10
  44. data/rbi/prism.rbi +605 -230
  45. data/rbi/prism_static.rbi +3 -0
  46. data/sig/prism.rbs +379 -124
  47. data/sig/prism_static.rbs +1 -0
  48. data/src/diagnostic.c +228 -222
  49. data/src/encoding.c +5137 -0
  50. data/src/node.c +66 -0
  51. data/src/options.c +21 -2
  52. data/src/prettyprint.c +806 -406
  53. data/src/prism.c +1092 -700
  54. data/src/regexp.c +3 -3
  55. data/src/serialize.c +227 -157
  56. data/src/util/pm_buffer.c +10 -1
  57. data/src/util/pm_memchr.c +1 -1
  58. data/src/util/pm_strpbrk.c +4 -4
  59. metadata +5 -11
  60. data/include/prism/enc/pm_encoding.h +0 -227
  61. data/src/enc/pm_big5.c +0 -116
  62. data/src/enc/pm_cp51932.c +0 -57
  63. data/src/enc/pm_euc_jp.c +0 -69
  64. data/src/enc/pm_gbk.c +0 -65
  65. data/src/enc/pm_shift_jis.c +0 -57
  66. data/src/enc/pm_tables.c +0 -2073
  67. data/src/enc/pm_unicode.c +0 -2369
  68. data/src/enc/pm_windows_31j.c +0 -57
data/src/node.c CHANGED
@@ -237,6 +237,12 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
237
237
  pm_node_destroy(parser, (pm_node_t *)cast->value);
238
238
  break;
239
239
  }
240
+ #line 58 "node.c.erb"
241
+ case PM_CALL_TARGET_NODE: {
242
+ pm_call_target_node_t *cast = (pm_call_target_node_t *) node;
243
+ pm_node_destroy(parser, (pm_node_t *)cast->receiver);
244
+ break;
245
+ }
240
246
  #line 58 "node.c.erb"
241
247
  case PM_CAPTURE_PATTERN_NODE: {
242
248
  pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node;
@@ -572,6 +578,10 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
572
578
  pm_node_destroy(parser, (pm_node_t *)cast->value);
573
579
  break;
574
580
  }
581
+ #line 58 "node.c.erb"
582
+ case PM_IMPLICIT_REST_NODE: {
583
+ break;
584
+ }
575
585
  #line 58 "node.c.erb"
576
586
  case PM_IN_NODE: {
577
587
  pm_in_node_t *cast = (pm_in_node_t *) node;
@@ -626,6 +636,18 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
626
636
  pm_node_destroy(parser, (pm_node_t *)cast->value);
627
637
  break;
628
638
  }
639
+ #line 58 "node.c.erb"
640
+ case PM_INDEX_TARGET_NODE: {
641
+ pm_index_target_node_t *cast = (pm_index_target_node_t *) node;
642
+ pm_node_destroy(parser, (pm_node_t *)cast->receiver);
643
+ if (cast->arguments != NULL) {
644
+ pm_node_destroy(parser, (pm_node_t *)cast->arguments);
645
+ }
646
+ if (cast->block != NULL) {
647
+ pm_node_destroy(parser, (pm_node_t *)cast->block);
648
+ }
649
+ break;
650
+ }
629
651
  #line 58 "node.c.erb"
630
652
  case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
631
653
  pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node;
@@ -824,6 +846,10 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
824
846
  case PM_NO_KEYWORDS_PARAMETER_NODE: {
825
847
  break;
826
848
  }
849
+ #line 58 "node.c.erb"
850
+ case PM_NUMBERED_PARAMETERS_NODE: {
851
+ break;
852
+ }
827
853
  #line 58 "node.c.erb"
828
854
  case PM_NUMBERED_REFERENCE_READ_NODE: {
829
855
  break;
@@ -1337,6 +1363,13 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
1337
1363
  pm_node_memsize_node((pm_node_t *)cast->value, memsize);
1338
1364
  break;
1339
1365
  }
1366
+ #line 103 "node.c.erb"
1367
+ case PM_CALL_TARGET_NODE: {
1368
+ pm_call_target_node_t *cast = (pm_call_target_node_t *) node;
1369
+ memsize->memsize += sizeof(*cast);
1370
+ pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
1371
+ break;
1372
+ }
1340
1373
  #line 103 "node.c.erb"
1341
1374
  case PM_CAPTURE_PATTERN_NODE: {
1342
1375
  pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node;
@@ -1743,6 +1776,12 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
1743
1776
  pm_node_memsize_node((pm_node_t *)cast->value, memsize);
1744
1777
  break;
1745
1778
  }
1779
+ #line 103 "node.c.erb"
1780
+ case PM_IMPLICIT_REST_NODE: {
1781
+ pm_implicit_rest_node_t *cast = (pm_implicit_rest_node_t *) node;
1782
+ memsize->memsize += sizeof(*cast);
1783
+ break;
1784
+ }
1746
1785
  #line 103 "node.c.erb"
1747
1786
  case PM_IN_NODE: {
1748
1787
  pm_in_node_t *cast = (pm_in_node_t *) node;
@@ -1801,6 +1840,19 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
1801
1840
  pm_node_memsize_node((pm_node_t *)cast->value, memsize);
1802
1841
  break;
1803
1842
  }
1843
+ #line 103 "node.c.erb"
1844
+ case PM_INDEX_TARGET_NODE: {
1845
+ pm_index_target_node_t *cast = (pm_index_target_node_t *) node;
1846
+ memsize->memsize += sizeof(*cast);
1847
+ pm_node_memsize_node((pm_node_t *)cast->receiver, memsize);
1848
+ if (cast->arguments != NULL) {
1849
+ pm_node_memsize_node((pm_node_t *)cast->arguments, memsize);
1850
+ }
1851
+ if (cast->block != NULL) {
1852
+ pm_node_memsize_node((pm_node_t *)cast->block, memsize);
1853
+ }
1854
+ break;
1855
+ }
1804
1856
  #line 103 "node.c.erb"
1805
1857
  case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
1806
1858
  pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node;
@@ -2062,6 +2114,12 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
2062
2114
  memsize->memsize += sizeof(*cast);
2063
2115
  break;
2064
2116
  }
2117
+ #line 103 "node.c.erb"
2118
+ case PM_NUMBERED_PARAMETERS_NODE: {
2119
+ pm_numbered_parameters_node_t *cast = (pm_numbered_parameters_node_t *) node;
2120
+ memsize->memsize += sizeof(*cast);
2121
+ break;
2122
+ }
2065
2123
  #line 103 "node.c.erb"
2066
2124
  case PM_NUMBERED_REFERENCE_READ_NODE: {
2067
2125
  pm_numbered_reference_read_node_t *cast = (pm_numbered_reference_read_node_t *) node;
@@ -2473,6 +2531,8 @@ pm_node_type_to_str(pm_node_type_t node_type)
2473
2531
  return "PM_CALL_OPERATOR_WRITE_NODE";
2474
2532
  case PM_CALL_OR_WRITE_NODE:
2475
2533
  return "PM_CALL_OR_WRITE_NODE";
2534
+ case PM_CALL_TARGET_NODE:
2535
+ return "PM_CALL_TARGET_NODE";
2476
2536
  case PM_CAPTURE_PATTERN_NODE:
2477
2537
  return "PM_CAPTURE_PATTERN_NODE";
2478
2538
  case PM_CASE_MATCH_NODE:
@@ -2567,6 +2627,8 @@ pm_node_type_to_str(pm_node_type_t node_type)
2567
2627
  return "PM_IMAGINARY_NODE";
2568
2628
  case PM_IMPLICIT_NODE:
2569
2629
  return "PM_IMPLICIT_NODE";
2630
+ case PM_IMPLICIT_REST_NODE:
2631
+ return "PM_IMPLICIT_REST_NODE";
2570
2632
  case PM_IN_NODE:
2571
2633
  return "PM_IN_NODE";
2572
2634
  case PM_INDEX_AND_WRITE_NODE:
@@ -2575,6 +2637,8 @@ pm_node_type_to_str(pm_node_type_t node_type)
2575
2637
  return "PM_INDEX_OPERATOR_WRITE_NODE";
2576
2638
  case PM_INDEX_OR_WRITE_NODE:
2577
2639
  return "PM_INDEX_OR_WRITE_NODE";
2640
+ case PM_INDEX_TARGET_NODE:
2641
+ return "PM_INDEX_TARGET_NODE";
2578
2642
  case PM_INSTANCE_VARIABLE_AND_WRITE_NODE:
2579
2643
  return "PM_INSTANCE_VARIABLE_AND_WRITE_NODE";
2580
2644
  case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE:
@@ -2639,6 +2703,8 @@ pm_node_type_to_str(pm_node_type_t node_type)
2639
2703
  return "PM_NIL_NODE";
2640
2704
  case PM_NO_KEYWORDS_PARAMETER_NODE:
2641
2705
  return "PM_NO_KEYWORDS_PARAMETER_NODE";
2706
+ case PM_NUMBERED_PARAMETERS_NODE:
2707
+ return "PM_NUMBERED_PARAMETERS_NODE";
2642
2708
  case PM_NUMBERED_REFERENCE_READ_NODE:
2643
2709
  return "PM_NUMBERED_REFERENCE_READ_NODE";
2644
2710
  case PM_OPTIONAL_KEYWORD_PARAMETER_NODE:
data/src/options.c CHANGED
@@ -20,7 +20,7 @@ pm_options_encoding_set(pm_options_t *options, const char *encoding) {
20
20
  * Set the line option on the given options struct.
21
21
  */
22
22
  PRISM_EXPORTED_FUNCTION void
23
- pm_options_line_set(pm_options_t *options, uint32_t line) {
23
+ pm_options_line_set(pm_options_t *options, int32_t line) {
24
24
  options->line = line;
25
25
  }
26
26
 
@@ -114,6 +114,22 @@ pm_options_read_u32(const char *data) {
114
114
  }
115
115
  }
116
116
 
117
+ /**
118
+ * Read a 32-bit signed integer from a pointer. This function is used to read
119
+ * the options that are passed into the parser from the Ruby implementation. It
120
+ * handles aligned and unaligned reads.
121
+ */
122
+ static int32_t
123
+ pm_options_read_s32(const char *data) {
124
+ if (((uintptr_t) data) % sizeof(int32_t) == 0) {
125
+ return *((int32_t *) data);
126
+ } else {
127
+ int32_t value;
128
+ memcpy(&value, data, sizeof(int32_t));
129
+ return value;
130
+ }
131
+ }
132
+
117
133
  /**
118
134
  * Deserialize an options struct from the given binary string. This is used to
119
135
  * pass options to the parser from an FFI call so that consumers of the library
@@ -123,6 +139,9 @@ pm_options_read_u32(const char *data) {
123
139
  */
124
140
  void
125
141
  pm_options_read(pm_options_t *options, const char *data) {
142
+ options->line = 1; // default
143
+ if (data == NULL) return;
144
+
126
145
  uint32_t filepath_length = pm_options_read_u32(data);
127
146
  data += 4;
128
147
 
@@ -131,7 +150,7 @@ pm_options_read(pm_options_t *options, const char *data) {
131
150
  data += filepath_length;
132
151
  }
133
152
 
134
- options->line = pm_options_read_u32(data);
153
+ options->line = pm_options_read_s32(data);
135
154
  data += 4;
136
155
 
137
156
  uint32_t encoding_length = pm_options_read_u32(data);