prism 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -1
  3. data/Makefile +6 -0
  4. data/README.md +2 -0
  5. data/config.yml +21 -20
  6. data/docs/configuration.md +2 -0
  7. data/docs/javascript.md +90 -0
  8. data/docs/releasing.md +27 -0
  9. data/docs/ruby_api.md +2 -0
  10. data/ext/prism/api_node.c +66 -68
  11. data/ext/prism/extension.c +73 -0
  12. data/ext/prism/extension.h +1 -1
  13. data/include/prism/ast.h +40 -40
  14. data/include/prism/defines.h +9 -0
  15. data/include/prism/enc/pm_encoding.h +1 -0
  16. data/include/prism/node.h +0 -17
  17. data/include/prism/parser.h +1 -0
  18. data/include/prism/prettyprint.h +15 -0
  19. data/include/prism/util/pm_buffer.h +10 -4
  20. data/include/prism/util/pm_constant_pool.h +1 -1
  21. data/include/prism/util/pm_newline_list.h +1 -1
  22. data/include/prism/version.h +3 -3
  23. data/include/prism.h +11 -11
  24. data/lib/prism/compiler.rb +0 -3
  25. data/lib/prism/debug.rb +20 -6
  26. data/lib/prism/desugar_compiler.rb +1 -1
  27. data/lib/prism/dispatcher.rb +0 -14
  28. data/lib/prism/dsl.rb +8 -13
  29. data/lib/prism/ffi.rb +25 -0
  30. data/lib/prism/lex_compat.rb +1 -1
  31. data/lib/prism/mutation_compiler.rb +3 -8
  32. data/lib/prism/node.rb +123 -159
  33. data/lib/prism/node_ext.rb +23 -16
  34. data/lib/prism/parse_result.rb +21 -5
  35. data/lib/prism/pattern.rb +3 -3
  36. data/lib/prism/serialize.rb +901 -305
  37. data/lib/prism/visitor.rb +0 -3
  38. data/prism.gemspec +8 -1
  39. data/rbi/prism.rbi +7261 -0
  40. data/rbi/prism_static.rbi +182 -0
  41. data/sig/prism.rbs +4439 -0
  42. data/sig/prism_static.rbs +110 -0
  43. data/src/enc/pm_unicode.c +1 -1
  44. data/src/node.c +28 -29
  45. data/src/prettyprint.c +7674 -1647
  46. data/src/prism.c +353 -300
  47. data/src/regexp.c +2 -0
  48. data/src/serialize.c +392 -381
  49. data/src/util/pm_buffer.c +47 -12
  50. data/src/util/pm_constant_pool.c +1 -1
  51. data/src/util/pm_newline_list.c +8 -54
  52. metadata +9 -2
@@ -1,7 +1,7 @@
1
1
  #ifndef PRISM_EXT_NODE_H
2
2
  #define PRISM_EXT_NODE_H
3
3
 
4
- #define EXPECTED_PRISM_VERSION "0.15.1"
4
+ #define EXPECTED_PRISM_VERSION "0.16.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>
data/include/prism/ast.h CHANGED
@@ -327,32 +327,31 @@ enum pm_node_type {
327
327
  PM_RATIONAL_NODE = 116,
328
328
  PM_REDO_NODE = 117,
329
329
  PM_REGULAR_EXPRESSION_NODE = 118,
330
- PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE = 119,
331
- PM_REQUIRED_PARAMETER_NODE = 120,
332
- PM_RESCUE_MODIFIER_NODE = 121,
333
- PM_RESCUE_NODE = 122,
334
- PM_REST_PARAMETER_NODE = 123,
335
- PM_RETRY_NODE = 124,
336
- PM_RETURN_NODE = 125,
337
- PM_SELF_NODE = 126,
338
- PM_SINGLETON_CLASS_NODE = 127,
339
- PM_SOURCE_ENCODING_NODE = 128,
340
- PM_SOURCE_FILE_NODE = 129,
341
- PM_SOURCE_LINE_NODE = 130,
342
- PM_SPLAT_NODE = 131,
343
- PM_STATEMENTS_NODE = 132,
344
- PM_STRING_CONCAT_NODE = 133,
345
- PM_STRING_NODE = 134,
346
- PM_SUPER_NODE = 135,
347
- PM_SYMBOL_NODE = 136,
348
- PM_TRUE_NODE = 137,
349
- PM_UNDEF_NODE = 138,
350
- PM_UNLESS_NODE = 139,
351
- PM_UNTIL_NODE = 140,
352
- PM_WHEN_NODE = 141,
353
- PM_WHILE_NODE = 142,
354
- PM_X_STRING_NODE = 143,
355
- PM_YIELD_NODE = 144,
330
+ PM_REQUIRED_PARAMETER_NODE = 119,
331
+ PM_RESCUE_MODIFIER_NODE = 120,
332
+ PM_RESCUE_NODE = 121,
333
+ PM_REST_PARAMETER_NODE = 122,
334
+ PM_RETRY_NODE = 123,
335
+ PM_RETURN_NODE = 124,
336
+ PM_SELF_NODE = 125,
337
+ PM_SINGLETON_CLASS_NODE = 126,
338
+ PM_SOURCE_ENCODING_NODE = 127,
339
+ PM_SOURCE_FILE_NODE = 128,
340
+ PM_SOURCE_LINE_NODE = 129,
341
+ PM_SPLAT_NODE = 130,
342
+ PM_STATEMENTS_NODE = 131,
343
+ PM_STRING_CONCAT_NODE = 132,
344
+ PM_STRING_NODE = 133,
345
+ PM_SUPER_NODE = 134,
346
+ PM_SYMBOL_NODE = 135,
347
+ PM_TRUE_NODE = 136,
348
+ PM_UNDEF_NODE = 137,
349
+ PM_UNLESS_NODE = 138,
350
+ PM_UNTIL_NODE = 139,
351
+ PM_WHEN_NODE = 140,
352
+ PM_WHILE_NODE = 141,
353
+ PM_X_STRING_NODE = 142,
354
+ PM_YIELD_NODE = 143,
356
355
  PM_SCOPE_NODE
357
356
  };
358
357
 
@@ -427,6 +426,8 @@ typedef struct pm_and_node {
427
426
  // ArgumentsNode
428
427
  //
429
428
  // Type: PM_ARGUMENTS_NODE
429
+ // Flags:
430
+ // PM_ARGUMENTS_NODE_FLAGS_KEYWORD_SPLAT
430
431
  typedef struct pm_arguments_node {
431
432
  pm_node_t base;
432
433
  struct pm_node_list arguments;
@@ -1065,8 +1066,8 @@ typedef struct pm_hash_node {
1065
1066
  typedef struct pm_hash_pattern_node {
1066
1067
  pm_node_t base;
1067
1068
  struct pm_node *constant;
1068
- struct pm_node_list assocs;
1069
- struct pm_node *kwrest;
1069
+ struct pm_node_list elements;
1070
+ struct pm_node *rest;
1070
1071
  pm_location_t opening_loc;
1071
1072
  pm_location_t closing_loc;
1072
1073
  } pm_hash_pattern_node_t;
@@ -1488,7 +1489,9 @@ typedef struct pm_module_node {
1488
1489
  // Type: PM_MULTI_TARGET_NODE
1489
1490
  typedef struct pm_multi_target_node {
1490
1491
  pm_node_t base;
1491
- struct pm_node_list targets;
1492
+ struct pm_node_list lefts;
1493
+ struct pm_node *rest;
1494
+ struct pm_node_list rights;
1492
1495
  pm_location_t lparen_loc;
1493
1496
  pm_location_t rparen_loc;
1494
1497
  } pm_multi_target_node_t;
@@ -1498,7 +1501,9 @@ typedef struct pm_multi_target_node {
1498
1501
  // Type: PM_MULTI_WRITE_NODE
1499
1502
  typedef struct pm_multi_write_node {
1500
1503
  pm_node_t base;
1501
- struct pm_node_list targets;
1504
+ struct pm_node_list lefts;
1505
+ struct pm_node *rest;
1506
+ struct pm_node_list rights;
1502
1507
  pm_location_t lparen_loc;
1503
1508
  pm_location_t rparen_loc;
1504
1509
  pm_location_t operator_loc;
@@ -1681,16 +1686,6 @@ typedef struct pm_regular_expression_node {
1681
1686
  pm_string_t unescaped;
1682
1687
  } pm_regular_expression_node_t;
1683
1688
 
1684
- // RequiredDestructuredParameterNode
1685
- //
1686
- // Type: PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE
1687
- typedef struct pm_required_destructured_parameter_node {
1688
- pm_node_t base;
1689
- struct pm_node_list parameters;
1690
- pm_location_t opening_loc;
1691
- pm_location_t closing_loc;
1692
- } pm_required_destructured_parameter_node_t;
1693
-
1694
1689
  // RequiredParameterNode
1695
1690
  //
1696
1691
  // Type: PM_REQUIRED_PARAMETER_NODE
@@ -1938,6 +1933,11 @@ typedef struct pm_yield_node {
1938
1933
  pm_location_t rparen_loc;
1939
1934
  } pm_yield_node_t;
1940
1935
 
1936
+ // ArgumentsNodeFlags
1937
+ typedef enum pm_arguments_node_flags {
1938
+ PM_ARGUMENTS_NODE_FLAGS_KEYWORD_SPLAT = 1 << 0,
1939
+ } pm_arguments_node_flags_t;
1940
+
1941
1941
  // CallNodeFlags
1942
1942
  typedef enum pm_call_node_flags {
1943
1943
  PM_CALL_NODE_FLAGS_SAFE_NAVIGATION = 1 << 0,
@@ -23,6 +23,15 @@
23
23
  # endif
24
24
  #endif
25
25
 
26
+ // PRISM_ATTRIBUTE_FORMAT
27
+ #if defined(__GNUC__)
28
+ # define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(printf, string_index, argument_index)))
29
+ #elif defined(__clang__)
30
+ # define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((__format__(__printf__, string_index, argument_index)))
31
+ #else
32
+ # define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index)
33
+ #endif
34
+
26
35
  // PRISM_ATTRIBUTE_UNUSED
27
36
  #if defined(__GNUC__)
28
37
  # define PRISM_ATTRIBUTE_UNUSED __attribute__((unused))
@@ -57,6 +57,7 @@ bool pm_encoding_ascii_isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptr
57
57
  // the parser so they need to be internally visible.
58
58
  size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n);
59
59
  size_t pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n);
60
+ bool pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n);
60
61
 
61
62
  // This lookup table is referenced in both the UTF-8 encoding file and the
62
63
  // parser directly in order to speed up the default encoding processing.
data/include/prism/node.h CHANGED
@@ -29,21 +29,4 @@ PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_typ
29
29
 
30
30
  #define PM_EMPTY_NODE_LIST ((pm_node_list_t) { .nodes = NULL, .size = 0, .capacity = 0 })
31
31
 
32
- // ScopeNodes are helper nodes, and will never be part of the AST. We manually
33
- // declare them here to avoid generating them.
34
- typedef struct pm_scope_node {
35
- pm_node_t base;
36
- struct pm_scope_node *previous;
37
- pm_node_t *ast_node;
38
- struct pm_parameters_node *parameters;
39
- pm_node_t *body;
40
- pm_constant_id_list_t locals;
41
- pm_parser_t *parser;
42
-
43
- // We don't have the CRuby types ID and st_table within Prism
44
- // so we use void *
45
- void *constants; // ID *constants
46
- void *index_lookup_table; // st_table *index_lookup_table
47
- } pm_scope_node_t;
48
-
49
32
  #endif // PRISM_NODE_H
@@ -212,6 +212,7 @@ typedef enum {
212
212
  PM_CONTEXT_EMBEXPR, // an interpolated expression
213
213
  PM_CONTEXT_ENSURE, // an ensure statement
214
214
  PM_CONTEXT_FOR, // a for loop
215
+ PM_CONTEXT_FOR_INDEX, // a for loop's index
215
216
  PM_CONTEXT_IF, // an if statement
216
217
  PM_CONTEXT_LAMBDA_BRACES, // a lambda expression with braces
217
218
  PM_CONTEXT_LAMBDA_DO_END, // a lambda expression with do..end
@@ -0,0 +1,15 @@
1
+ #ifndef PRISM_PRETTYPRINT_H
2
+ #define PRISM_PRETTYPRINT_H
3
+
4
+ #include "prism/defines.h"
5
+
6
+ #include <stdio.h>
7
+
8
+ #include "prism/ast.h"
9
+ #include "prism/parser.h"
10
+ #include "prism/util/pm_buffer.h"
11
+
12
+ // Pretty-prints the AST represented by the given node to the given buffer.
13
+ PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node);
14
+
15
+ #endif
@@ -13,9 +13,9 @@
13
13
  // block of memory. It is used to store the serialized representation of a
14
14
  // prism tree.
15
15
  typedef struct {
16
- char *value;
17
16
  size_t length;
18
17
  size_t capacity;
18
+ char *value;
19
19
  } pm_buffer_t;
20
20
 
21
21
  // Return the size of the pm_buffer_t struct.
@@ -36,17 +36,23 @@ PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(pm_buffer_t *buffer);
36
36
  // Append the given amount of space as zeroes to the buffer.
37
37
  void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length);
38
38
 
39
+ // Append a formatted string to the buffer.
40
+ void pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) PRISM_ATTRIBUTE_FORMAT(2, 3);
41
+
39
42
  // Append a string to the buffer.
40
- void pm_buffer_append_str(pm_buffer_t *buffer, const char *value, size_t length);
43
+ void pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length);
41
44
 
42
45
  // Append a list of bytes to the buffer.
43
46
  void pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length);
44
47
 
45
48
  // Append a single byte to the buffer.
46
- void pm_buffer_append_u8(pm_buffer_t *buffer, uint8_t value);
49
+ void pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value);
47
50
 
48
51
  // Append a 32-bit unsigned integer to the buffer.
49
- void pm_buffer_append_u32(pm_buffer_t *buffer, uint32_t value);
52
+ void pm_buffer_append_varint(pm_buffer_t *buffer, uint32_t value);
53
+
54
+ // Append one buffer onto another.
55
+ void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source);
50
56
 
51
57
  // Free the memory associated with the buffer.
52
58
  PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer);
@@ -76,7 +76,7 @@ typedef struct {
76
76
  bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
77
77
 
78
78
  // Return a pointer to the constant indicated by the given constant id.
79
- pm_constant_t * pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id);
79
+ pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id);
80
80
 
81
81
  // Insert a constant into a constant pool that is a slice of a source string.
82
82
  // Returns the id of the constant, or 0 if any potential calls to resize fail.
@@ -53,7 +53,7 @@ bool pm_newline_list_check_append(pm_newline_list_t *list, const uint8_t *cursor
53
53
  // Returns the line and column of the given offset. If the offset is not in the
54
54
  // list, the line and column of the closest offset less than the given offset
55
55
  // are returned.
56
- pm_line_column_t pm_newline_list_line_column(pm_newline_list_t *list, const uint8_t *cursor);
56
+ pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor);
57
57
 
58
58
  // Free the internal memory allocated for the newline list.
59
59
  void pm_newline_list_free(pm_newline_list_t *list);
@@ -1,4 +1,4 @@
1
1
  #define PRISM_VERSION_MAJOR 0
2
- #define PRISM_VERSION_MINOR 15
3
- #define PRISM_VERSION_PATCH 1
4
- #define PRISM_VERSION "0.15.1"
2
+ #define PRISM_VERSION_MINOR 16
3
+ #define PRISM_VERSION_PATCH 0
4
+ #define PRISM_VERSION "0.16.0"
data/include/prism.h CHANGED
@@ -2,16 +2,17 @@
2
2
  #define PRISM_H
3
3
 
4
4
  #include "prism/defines.h"
5
+ #include "prism/util/pm_buffer.h"
6
+ #include "prism/util/pm_char.h"
7
+ #include "prism/util/pm_memchr.h"
8
+ #include "prism/util/pm_strpbrk.h"
5
9
  #include "prism/ast.h"
6
10
  #include "prism/diagnostic.h"
7
11
  #include "prism/node.h"
8
12
  #include "prism/pack.h"
9
13
  #include "prism/parser.h"
14
+ #include "prism/prettyprint.h"
10
15
  #include "prism/regexp.h"
11
- #include "prism/util/pm_buffer.h"
12
- #include "prism/util/pm_char.h"
13
- #include "prism/util/pm_memchr.h"
14
- #include "prism/util/pm_strpbrk.h"
15
16
  #include "prism/version.h"
16
17
 
17
18
  #include <assert.h>
@@ -29,12 +30,11 @@
29
30
 
30
31
  void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
31
32
 
32
- void pm_print_node(pm_parser_t *parser, pm_node_t *node);
33
+ void pm_serialize_encoding(pm_encoding_t *encoding, pm_buffer_t *buffer);
33
34
 
34
- void pm_parser_metadata(pm_parser_t *parser, const char *metadata);
35
+ void pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer);
35
36
 
36
- // Generate a scope node from the given node.
37
- void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser);
37
+ void pm_parser_metadata(pm_parser_t *parser, const char *metadata);
38
38
 
39
39
  // The prism version and the serialization format.
40
40
  PRISM_EXPORTED_FUNCTION const char * pm_version(void);
@@ -59,15 +59,15 @@ PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser);
59
59
  // Parse the Ruby source associated with the given parser and return the tree.
60
60
  PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser);
61
61
 
62
- // Pretty-prints the AST represented by the given node to the given buffer.
63
- PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
64
-
65
62
  // Serialize the AST represented by the given node to the given buffer.
66
63
  PRISM_EXPORTED_FUNCTION void pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer);
67
64
 
68
65
  // Parse the given source to the AST and serialize the AST to the given buffer.
69
66
  PRISM_EXPORTED_FUNCTION void pm_parse_serialize(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata);
70
67
 
68
+ // Parse and serialize the comments in the given source to the given buffer.
69
+ PRISM_EXPORTED_FUNCTION void pm_parse_serialize_comments(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata);
70
+
71
71
  // Lex the given source and serialize to the given buffer.
72
72
  PRISM_EXPORTED_FUNCTION void pm_lex_serialize(const uint8_t *source, size_t size, const char *filepath, pm_buffer_t *buffer);
73
73
 
@@ -393,9 +393,6 @@ module Prism
393
393
  # Compile a RegularExpressionNode node
394
394
  alias visit_regular_expression_node visit_child_nodes
395
395
 
396
- # Compile a RequiredDestructuredParameterNode node
397
- alias visit_required_destructured_parameter_node visit_child_nodes
398
-
399
396
  # Compile a RequiredParameterNode node
400
397
  alias visit_required_parameter_node visit_child_nodes
401
398
 
data/lib/prism/debug.rb CHANGED
@@ -52,9 +52,21 @@ module Prism
52
52
  stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
53
53
 
54
54
  while (iseq = stack.pop)
55
- # For some reason, CRuby occasionally pushes this special local
56
- # variable when there are splat arguments. We get rid of that here.
57
- locals << (iseq.local_table - [:"#arg_rest"])
55
+ names = [*iseq.local_table]
56
+ names.map!.with_index do |name, index|
57
+ # When an anonymous local variable is present in the iseq's local
58
+ # table, it is represented as the stack offset from the top.
59
+ # However, when these are dumped to binary and read back in, they
60
+ # are replaced with the symbol :#arg_rest. To consistently handle
61
+ # this, we replace them here with their index.
62
+ if name == :"#arg_rest"
63
+ names.length - index + 1
64
+ else
65
+ name
66
+ end
67
+ end
68
+
69
+ locals << names
58
70
  iseq.each_child { |child| stack << child }
59
71
  end
60
72
 
@@ -110,11 +122,13 @@ module Prism
110
122
 
111
123
  # Recurse down the parameter tree to find any destructured
112
124
  # parameters and add them after the other parameters.
113
- param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse
125
+ param_stack = params.requireds.concat(params.posts).grep(MultiTargetNode).reverse
114
126
  while (param = param_stack.pop)
115
127
  case param
116
- when RequiredDestructuredParameterNode
117
- param_stack.concat(param.parameters.reverse)
128
+ when MultiTargetNode
129
+ param_stack.concat(param.rights.reverse)
130
+ param_stack << param.rest
131
+ param_stack.concat(param.lefts.reverse)
118
132
  when RequiredParameterNode
119
133
  sorted << param.name
120
134
  when SplatNode
@@ -161,7 +161,7 @@ module Prism
161
161
  nil,
162
162
  node.operator_loc.copy(length: node.operator_loc.length - 1),
163
163
  nil,
164
- ArgumentsNode.new([node.value], node.value.location),
164
+ ArgumentsNode.new([node.value], 0, node.value.location),
165
165
  nil,
166
166
  nil,
167
167
  0,
@@ -1008,14 +1008,6 @@ module Prism
1008
1008
  listeners[:on_regular_expression_node_leave]&.each { |listener| listener.on_regular_expression_node_leave(node) }
1009
1009
  end
1010
1010
 
1011
- # Dispatch enter and leave events for RequiredDestructuredParameterNode nodes and continue
1012
- # walking the tree.
1013
- def visit_required_destructured_parameter_node(node)
1014
- listeners[:on_required_destructured_parameter_node_enter]&.each { |listener| listener.on_required_destructured_parameter_node_enter(node) }
1015
- super
1016
- listeners[:on_required_destructured_parameter_node_leave]&.each { |listener| listener.on_required_destructured_parameter_node_leave(node) }
1017
- end
1018
-
1019
1011
  # Dispatch enter and leave events for RequiredParameterNode nodes and continue
1020
1012
  # walking the tree.
1021
1013
  def visit_required_parameter_node(node)
@@ -1931,12 +1923,6 @@ module Prism
1931
1923
  listeners[:on_regular_expression_node_leave]&.each { |listener| listener.on_regular_expression_node_leave(node) }
1932
1924
  end
1933
1925
 
1934
- # Dispatch enter and leave events for RequiredDestructuredParameterNode nodes.
1935
- def visit_required_destructured_parameter_node(node)
1936
- listeners[:on_required_destructured_parameter_node_enter]&.each { |listener| listener.on_required_destructured_parameter_node_enter(node) }
1937
- listeners[:on_required_destructured_parameter_node_leave]&.each { |listener| listener.on_required_destructured_parameter_node_leave(node) }
1938
- end
1939
-
1940
1926
  # Dispatch enter and leave events for RequiredParameterNode nodes.
1941
1927
  def visit_required_parameter_node(node)
1942
1928
  listeners[:on_required_parameter_node_enter]&.each { |listener| listener.on_required_parameter_node_enter(node) }
data/lib/prism/dsl.rb CHANGED
@@ -63,8 +63,8 @@ module Prism
63
63
  end
64
64
 
65
65
  # Create a new ArgumentsNode node
66
- def ArgumentsNode(arguments, location = Location())
67
- ArgumentsNode.new(arguments, location)
66
+ def ArgumentsNode(arguments, flags, location = Location())
67
+ ArgumentsNode.new(arguments, flags, location)
68
68
  end
69
69
 
70
70
  # Create a new ArrayNode node
@@ -358,8 +358,8 @@ module Prism
358
358
  end
359
359
 
360
360
  # Create a new HashPatternNode node
361
- def HashPatternNode(constant, assocs, kwrest, opening_loc, closing_loc, location = Location())
362
- HashPatternNode.new(constant, assocs, kwrest, opening_loc, closing_loc, location)
361
+ def HashPatternNode(constant, elements, rest, opening_loc, closing_loc, location = Location())
362
+ HashPatternNode.new(constant, elements, rest, opening_loc, closing_loc, location)
363
363
  end
364
364
 
365
365
  # Create a new IfNode node
@@ -538,13 +538,13 @@ module Prism
538
538
  end
539
539
 
540
540
  # Create a new MultiTargetNode node
541
- def MultiTargetNode(targets, lparen_loc, rparen_loc, location = Location())
542
- MultiTargetNode.new(targets, lparen_loc, rparen_loc, location)
541
+ def MultiTargetNode(lefts, rest, rights, lparen_loc, rparen_loc, location = Location())
542
+ MultiTargetNode.new(lefts, rest, rights, lparen_loc, rparen_loc, location)
543
543
  end
544
544
 
545
545
  # Create a new MultiWriteNode node
546
- def MultiWriteNode(targets, lparen_loc, rparen_loc, operator_loc, value, location = Location())
547
- MultiWriteNode.new(targets, lparen_loc, rparen_loc, operator_loc, value, location)
546
+ def MultiWriteNode(lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value, location = Location())
547
+ MultiWriteNode.new(lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value, location)
548
548
  end
549
549
 
550
550
  # Create a new NextNode node
@@ -632,11 +632,6 @@ module Prism
632
632
  RegularExpressionNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, location)
633
633
  end
634
634
 
635
- # Create a new RequiredDestructuredParameterNode node
636
- def RequiredDestructuredParameterNode(parameters, opening_loc, closing_loc, location = Location())
637
- RequiredDestructuredParameterNode.new(parameters, opening_loc, closing_loc, location)
638
- end
639
-
640
635
  # Create a new RequiredParameterNode node
641
636
  def RequiredParameterNode(name, location = Location())
642
637
  RequiredParameterNode.new(name, location)
data/lib/prism/ffi.rb CHANGED
@@ -70,6 +70,7 @@ module Prism
70
70
  "prism.h",
71
71
  "pm_version",
72
72
  "pm_parse_serialize",
73
+ "pm_parse_serialize_comments",
73
74
  "pm_lex_serialize",
74
75
  "pm_parse_lex_serialize"
75
76
  )
@@ -224,6 +225,30 @@ module Prism
224
225
  end
225
226
  end
226
227
 
228
+ # Mirror the Prism.parse_comments API by using the serialization API.
229
+ def self.parse_comments(code, filepath = nil)
230
+ LibRubyParser::PrismBuffer.with do |buffer|
231
+ metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
232
+ LibRubyParser.pm_parse_serialize_comments(code, code.bytesize, buffer.pointer, metadata)
233
+
234
+ source = Source.new(code)
235
+ loader = Serialize::Loader.new(source, buffer.read)
236
+
237
+ loader.load_header
238
+ loader.load_force_encoding
239
+ loader.load_comments
240
+ end
241
+ end
242
+
243
+ # Mirror the Prism.parse_file_comments API by using the serialization
244
+ # API. This uses native strings instead of Ruby strings because it allows us
245
+ # to use mmap when it is available.
246
+ def self.parse_file_comments(filepath)
247
+ LibRubyParser::PrismString.with(filepath) do |string|
248
+ parse_comments(string.read, filepath)
249
+ end
250
+ end
251
+
227
252
  # Mirror the Prism.parse_lex API by using the serialization API.
228
253
  def self.parse_lex(code, filepath = nil)
229
254
  LibRubyParser::PrismBuffer.with do |buffer|
@@ -529,7 +529,7 @@ module Prism
529
529
  line.each_char.with_index do |char, i|
530
530
  case char
531
531
  when "\r"
532
- if line.chars[i + 1] == "\n"
532
+ if line[i + 1] == "\n"
533
533
  break
534
534
  end
535
535
  when "\n"
@@ -327,7 +327,7 @@ module Prism
327
327
 
328
328
  # Copy a HashPatternNode node
329
329
  def visit_hash_pattern_node(node)
330
- node.copy(constant: visit(node.constant), assocs: visit_all(node.assocs), kwrest: visit(node.kwrest))
330
+ node.copy(constant: visit(node.constant), elements: visit_all(node.elements), rest: visit(node.rest))
331
331
  end
332
332
 
333
333
  # Copy a IfNode node
@@ -507,12 +507,12 @@ module Prism
507
507
 
508
508
  # Copy a MultiTargetNode node
509
509
  def visit_multi_target_node(node)
510
- node.copy(targets: visit_all(node.targets))
510
+ node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights))
511
511
  end
512
512
 
513
513
  # Copy a MultiWriteNode node
514
514
  def visit_multi_write_node(node)
515
- node.copy(targets: visit_all(node.targets), value: visit(node.value))
515
+ node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights), value: visit(node.value))
516
516
  end
517
517
 
518
518
  # Copy a NextNode node
@@ -600,11 +600,6 @@ module Prism
600
600
  node.copy
601
601
  end
602
602
 
603
- # Copy a RequiredDestructuredParameterNode node
604
- def visit_required_destructured_parameter_node(node)
605
- node.copy(parameters: visit_all(node.parameters))
606
- end
607
-
608
603
  # Copy a RequiredParameterNode node
609
604
  def visit_required_parameter_node(node)
610
605
  node.copy