prism 1.3.0 → 1.5.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -1
  3. data/Makefile +2 -1
  4. data/README.md +1 -0
  5. data/config.yml +273 -37
  6. data/docs/parser_translation.md +8 -23
  7. data/docs/releasing.md +1 -1
  8. data/docs/ripper_translation.md +1 -1
  9. data/docs/ruby_api.md +1 -1
  10. data/ext/prism/api_node.c +1816 -1303
  11. data/ext/prism/extension.c +244 -110
  12. data/ext/prism/extension.h +4 -4
  13. data/include/prism/ast.h +291 -49
  14. data/include/prism/defines.h +4 -1
  15. data/include/prism/diagnostic.h +4 -0
  16. data/include/prism/options.h +89 -3
  17. data/include/prism/regexp.h +2 -2
  18. data/include/prism/util/pm_buffer.h +18 -0
  19. data/include/prism/util/pm_integer.h +4 -0
  20. data/include/prism/util/pm_list.h +6 -0
  21. data/include/prism/util/pm_string.h +12 -2
  22. data/include/prism/version.h +2 -2
  23. data/include/prism.h +41 -16
  24. data/lib/prism/compiler.rb +456 -151
  25. data/lib/prism/desugar_compiler.rb +1 -0
  26. data/lib/prism/dispatcher.rb +16 -0
  27. data/lib/prism/dot_visitor.rb +21 -1
  28. data/lib/prism/dsl.rb +13 -2
  29. data/lib/prism/ffi.rb +62 -34
  30. data/lib/prism/inspect_visitor.rb +5 -1
  31. data/lib/prism/lex_compat.rb +1 -0
  32. data/lib/prism/mutation_compiler.rb +3 -0
  33. data/lib/prism/node.rb +554 -345
  34. data/lib/prism/node_ext.rb +4 -1
  35. data/lib/prism/pack.rb +2 -0
  36. data/lib/prism/parse_result/comments.rb +1 -0
  37. data/lib/prism/parse_result/errors.rb +1 -0
  38. data/lib/prism/parse_result/newlines.rb +2 -1
  39. data/lib/prism/parse_result.rb +53 -0
  40. data/lib/prism/pattern.rb +1 -0
  41. data/lib/prism/polyfill/append_as_bytes.rb +15 -0
  42. data/lib/prism/polyfill/scan_byte.rb +14 -0
  43. data/lib/prism/polyfill/warn.rb +42 -0
  44. data/lib/prism/reflection.rb +5 -2
  45. data/lib/prism/relocation.rb +1 -0
  46. data/lib/prism/serialize.rb +1275 -783
  47. data/lib/prism/string_query.rb +1 -0
  48. data/lib/prism/translation/parser/builder.rb +62 -0
  49. data/lib/prism/translation/parser/compiler.rb +230 -152
  50. data/lib/prism/translation/parser/lexer.rb +446 -64
  51. data/lib/prism/translation/parser.rb +64 -4
  52. data/lib/prism/translation/parser33.rb +1 -0
  53. data/lib/prism/translation/parser34.rb +1 -0
  54. data/lib/prism/translation/parser35.rb +13 -0
  55. data/lib/prism/translation/parser_current.rb +24 -0
  56. data/lib/prism/translation/ripper/sexp.rb +1 -0
  57. data/lib/prism/translation/ripper.rb +30 -4
  58. data/lib/prism/translation/ruby_parser.rb +291 -7
  59. data/lib/prism/translation.rb +3 -0
  60. data/lib/prism/visitor.rb +457 -152
  61. data/lib/prism.rb +5 -3
  62. data/prism.gemspec +9 -1
  63. data/rbi/prism/dsl.rbi +9 -6
  64. data/rbi/prism/node.rbi +43 -16
  65. data/rbi/prism/parse_result.rbi +17 -0
  66. data/rbi/prism/translation/parser35.rbi +6 -0
  67. data/rbi/prism.rbi +39 -36
  68. data/sig/prism/dispatcher.rbs +3 -0
  69. data/sig/prism/dsl.rbs +7 -5
  70. data/sig/prism/node.rbs +461 -37
  71. data/sig/prism/node_ext.rbs +84 -17
  72. data/sig/prism/parse_result/comments.rbs +38 -0
  73. data/sig/prism/parse_result.rbs +14 -0
  74. data/sig/prism/reflection.rbs +1 -1
  75. data/sig/prism/serialize.rbs +4 -2
  76. data/sig/prism.rbs +22 -1
  77. data/src/diagnostic.c +9 -3
  78. data/src/node.c +23 -0
  79. data/src/options.c +33 -2
  80. data/src/prettyprint.c +32 -0
  81. data/src/prism.c +620 -242
  82. data/src/serialize.c +8 -0
  83. data/src/token_type.c +36 -34
  84. data/src/util/pm_buffer.c +40 -0
  85. data/src/util/pm_constant_pool.c +6 -2
  86. data/src/util/pm_strncasecmp.c +13 -1
  87. metadata +11 -7
@@ -1,46 +1,40 @@
1
1
  module Prism
2
+ class Node
3
+ def deprecated: (*String replacements) -> void
4
+ end
5
+
2
6
  class InterpolatedMatchLastLineNode < Node
3
- # Returns a numeric value that represents the flags that were used to create
4
- # the regular expression.
5
7
  def options: () -> Integer
6
8
  end
7
9
 
8
10
  class InterpolatedRegularExpressionNode < Node
9
- # Returns a numeric value that represents the flags that were used to create
10
- # the regular expression.
11
11
  def options: () -> Integer
12
12
  end
13
13
 
14
14
  class MatchLastLineNode < Node
15
- # Returns a numeric value that represents the flags that were used to create
16
- # the regular expression.
17
15
  def options: () -> Integer
18
16
  end
19
17
 
20
18
  class RegularExpressionNode < Node
21
- # Returns a numeric value that represents the flags that were used to create
22
- # the regular expression.
23
19
  def options: () -> Integer
24
20
  end
25
21
 
26
22
  class InterpolatedStringNode < Node
27
- # Returns true if this node was represented as a heredoc in the source code.
28
- def heredoc?: () -> bool?
23
+ def heredoc?: () -> bool
29
24
  end
30
25
 
31
26
  class InterpolatedXStringNode < Node
32
- # Returns true if this node was represented as a heredoc in the source code.
33
- def heredoc?: () -> bool?
27
+ def heredoc?: () -> bool
34
28
  end
35
29
 
36
30
  class StringNode < Node
37
- # Returns true if this node was represented as a heredoc in the source code.
38
- def heredoc?: () -> bool?
31
+ def heredoc?: () -> bool
32
+ def to_interpolated: () -> InterpolatedStringNode
39
33
  end
40
34
 
41
35
  class XStringNode < Node
42
- # Returns true if this node was represented as a heredoc in the source code.
43
- def heredoc?: () -> bool?
36
+ def heredoc?: () -> bool
37
+ def to_interpolated: () -> InterpolatedXStringNode
44
38
  end
45
39
 
46
40
  class ImaginaryNode < Node
@@ -49,10 +43,16 @@ module Prism
49
43
 
50
44
  class RationalNode < Node
51
45
  def value: () -> Rational
46
+ def numeric: () -> (IntegerNode | FloatNode)
52
47
  end
53
48
 
54
49
  class ConstantReadNode < Node
55
- def full_name_parts: () -> [Symbol]
50
+ def full_name_parts: () -> Array[Symbol]
51
+ def full_name: () -> String
52
+ end
53
+
54
+ class ConstantWriteNode < Node
55
+ def full_name_parts: () -> Array[Symbol]
56
56
  def full_name: () -> String
57
57
  end
58
58
 
@@ -65,11 +65,18 @@ module Prism
65
65
 
66
66
  def full_name_parts: () -> Array[Symbol]
67
67
  def full_name: () -> String
68
+ def child: () -> (ConstantReadNode | MissingNode)
68
69
  end
69
70
 
70
71
  class ConstantPathTargetNode < Node
71
72
  def full_name_parts: () -> Array[Symbol]
72
73
  def full_name: () -> String
74
+ def child: () -> (ConstantReadNode | MissingNode)
75
+ end
76
+
77
+ class ConstantTargetNode < Node
78
+ def full_name_parts: () -> Array[Symbol]
79
+ def full_name: () -> String
73
80
  end
74
81
 
75
82
  class ParametersNode < Node
@@ -79,4 +86,64 @@ module Prism
79
86
  class CallNode < Node
80
87
  def full_message_loc: () -> Location?
81
88
  end
89
+
90
+ class CallOperatorWriteNode < Node
91
+ def operator: () -> Symbol
92
+ def operator_loc: () -> Location
93
+ end
94
+
95
+ class ClassVariableOperatorWriteNode < Node
96
+ def operator: () -> Symbol
97
+ def operator_loc: () -> Location
98
+ end
99
+
100
+ class ConstantOperatorWriteNode < Node
101
+ def operator: () -> Symbol
102
+ def operator_loc: () -> Location
103
+ end
104
+
105
+ class ConstantPathOperatorWriteNode < Node
106
+ def operator: () -> Symbol
107
+ def operator_loc: () -> Location
108
+ end
109
+
110
+ class GlobalVariableOperatorWriteNode < Node
111
+ def operator: () -> Symbol
112
+ def operator_loc: () -> Location
113
+ end
114
+
115
+ class IndexOperatorWriteNode < Node
116
+ def operator: () -> Symbol
117
+ def operator_loc: () -> Location
118
+ end
119
+
120
+ class InstanceVariableOperatorWriteNode < Node
121
+ def operator: () -> Symbol
122
+ def operator_loc: () -> Location
123
+ end
124
+
125
+ class LocalVariableOperatorWriteNode < Node
126
+ def operator: () -> Symbol
127
+ def operator_loc: () -> Location
128
+ end
129
+
130
+ class CaseMatchNode < Node
131
+ def consequent: () -> ElseNode?
132
+ end
133
+
134
+ class CaseNode < Node
135
+ def consequent: () -> ElseNode?
136
+ end
137
+
138
+ class IfNode < Node
139
+ def consequent: () -> (ElseNode | IfNode | nil)
140
+ end
141
+
142
+ class RescueNode < Node
143
+ def consequent: () -> RescueNode?
144
+ end
145
+
146
+ class UnlessNode < Node
147
+ def consequent: () -> ElseNode?
148
+ end
82
149
  end
@@ -0,0 +1,38 @@
1
+ module Prism
2
+ class ParseResult < Result
3
+ class Comments
4
+ interface _Target
5
+ def start_offset: () -> Integer
6
+ def end_offset: () -> Integer
7
+ def encloses?: (comment) -> bool
8
+ def leading_comment: (comment) -> void
9
+ def trailing_comment: (comment) -> void
10
+ end
11
+
12
+ class NodeTarget
13
+ include _Target
14
+
15
+ attr_reader node: node
16
+
17
+ def initialize: (node) -> void
18
+ end
19
+
20
+ class LocationTarget
21
+ include _Target
22
+
23
+ attr_reader location: Location
24
+
25
+ def initialize: (Location location) -> void
26
+ end
27
+
28
+ attr_reader parse_result: ParseResult
29
+
30
+ def initialize: (ParseResult parse_result) -> void
31
+ def attach!: () -> void
32
+
33
+ private
34
+
35
+ def nearest_targets: (node, comment) -> [_Target?, _Target, _Target?]
36
+ end
37
+ end
38
+ end
@@ -9,6 +9,8 @@ module Prism
9
9
  attr_reader offsets: Array[Integer]
10
10
 
11
11
  def initialize: (String source, ?Integer start_line, ?Array[Integer] offsets) -> void
12
+ def replace_start_line: (Integer start_line) -> void
13
+ def replace_offsets: (Array[Integer] offsets) -> void
12
14
  def encoding: () -> Encoding
13
15
  def lines: () -> Array[String]
14
16
  def slice: (Integer byte_offset, Integer length) -> String
@@ -22,6 +24,7 @@ module Prism
22
24
  def code_units_offset: (Integer byte_offset, Encoding encoding) -> Integer
23
25
  def code_units_cache: (Encoding encoding) -> _CodeUnitsCache
24
26
  def code_units_column: (Integer byte_offset, Encoding encoding) -> Integer
27
+ def deep_freeze: () -> void
25
28
 
26
29
  def self.for: (String source) -> Source
27
30
  end
@@ -84,6 +87,7 @@ module Prism
84
87
 
85
88
  def initialize: (Location location) -> void
86
89
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
90
+ def slice: () -> String
87
91
  end
88
92
 
89
93
  interface _Comment
@@ -142,6 +146,7 @@ module Prism
142
146
 
143
147
  def initialize: (Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
144
148
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
149
+ def encoding: () -> Encoding
145
150
  def success?: () -> bool
146
151
  def failure?: () -> bool
147
152
  def code_units_cache: (Encoding encoding) -> _CodeUnitsCache
@@ -152,6 +157,7 @@ module Prism
152
157
 
153
158
  def initialize: (ProgramNode value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void
154
159
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
160
+ def errors_format: () -> String
155
161
  end
156
162
 
157
163
  class LexResult < Result
@@ -178,5 +184,13 @@ module Prism
178
184
  def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
179
185
  def pretty_print: (untyped q) -> untyped
180
186
  def ==: (untyped other) -> bool
187
+ def deep_freeze: () -> void
188
+ end
189
+
190
+ class Scope
191
+ attr_reader locals: Array[Symbol]
192
+ attr_reader forwarding: Array[Symbol]
193
+
194
+ def initialize: (Array[Symbol] locals, Array[Symbol] forwarding) -> void
181
195
  end
182
196
  end
@@ -45,6 +45,6 @@ module Prism
45
45
  def initialize: (Symbol name, Array[Symbol] flags) -> void
46
46
  end
47
47
 
48
- def self.fields_for: (node_singleton node) -> Array[Field]
48
+ def self.fields_for: (singleton(Node) node) -> Array[Field]
49
49
  end
50
50
  end
@@ -1,6 +1,8 @@
1
1
  module Prism
2
2
  module Serialize
3
- def self.load: (String, String) -> ParseResult
4
- def self.load_tokens: (Source, String) -> LexResult
3
+ def self.load_parse: (String, String, bool) -> ParseResult
4
+ def self.load_lex: (String, String, bool) -> LexResult
5
+ def self.load_parse_comments: (String, String, bool) -> Array[comment]
6
+ def self.load_parse_lex: (String, String, bool) -> ParseLexResult
5
7
  end
6
8
  end
data/sig/prism.rbs CHANGED
@@ -12,6 +12,7 @@ module Prism
12
12
  String source,
13
13
  ?encoding: Encoding | false,
14
14
  ?filepath: String,
15
+ ?freeze: bool,
15
16
  ?frozen_string_literal: bool,
16
17
  ?line: Integer,
17
18
  ?main_script: bool,
@@ -24,6 +25,7 @@ module Prism
24
25
  String source,
25
26
  ?encoding: Encoding | false,
26
27
  ?filepath: String,
28
+ ?freeze: bool,
27
29
  ?frozen_string_literal: bool,
28
30
  ?line: Integer,
29
31
  ?main_script: bool,
@@ -36,6 +38,7 @@ module Prism
36
38
  String source,
37
39
  ?encoding: Encoding | false,
38
40
  ?filepath: String,
41
+ ?freeze: bool,
39
42
  ?frozen_string_literal: bool,
40
43
  ?line: Integer,
41
44
  ?main_script: bool,
@@ -48,6 +51,7 @@ module Prism
48
51
  String source,
49
52
  ?encoding: Encoding | false,
50
53
  ?filepath: String,
54
+ ?freeze: bool,
51
55
  ?frozen_string_literal: bool,
52
56
  ?line: Integer,
53
57
  ?main_script: bool,
@@ -60,6 +64,7 @@ module Prism
60
64
  String source,
61
65
  ?encoding: Encoding | false,
62
66
  ?filepath: String,
67
+ ?freeze: bool,
63
68
  ?frozen_string_literal: bool,
64
69
  ?line: Integer,
65
70
  ?main_script: bool,
@@ -72,6 +77,7 @@ module Prism
72
77
  String source,
73
78
  ?encoding: Encoding | false,
74
79
  ?filepath: String,
80
+ ?freeze: bool,
75
81
  ?frozen_string_literal: bool,
76
82
  ?line: Integer,
77
83
  ?main_script: bool,
@@ -84,6 +90,7 @@ module Prism
84
90
  String source,
85
91
  ?encoding: Encoding | false,
86
92
  ?filepath: String,
93
+ ?freeze: bool,
87
94
  ?frozen_string_literal: bool,
88
95
  ?line: Integer,
89
96
  ?main_script: bool,
@@ -96,6 +103,7 @@ module Prism
96
103
  String source,
97
104
  ?encoding: Encoding | false,
98
105
  ?filepath: String,
106
+ ?freeze: bool,
99
107
  ?frozen_string_literal: bool,
100
108
  ?line: Integer,
101
109
  ?main_script: bool,
@@ -108,6 +116,7 @@ module Prism
108
116
  String source,
109
117
  ?encoding: Encoding | false,
110
118
  ?filepath: String,
119
+ ?freeze: bool,
111
120
  ?frozen_string_literal: bool,
112
121
  ?line: Integer,
113
122
  ?main_script: bool,
@@ -118,7 +127,8 @@ module Prism
118
127
 
119
128
  def self.load: (
120
129
  String source,
121
- String serialized
130
+ String serialized,
131
+ ?bool freeze
122
132
  ) -> ParseResult
123
133
 
124
134
  def self.lex_ripper: (
@@ -130,6 +140,7 @@ module Prism
130
140
  def self.parse_file: (
131
141
  String filepath,
132
142
  ?encoding: Encoding | false,
143
+ ?freeze: bool,
133
144
  ?frozen_string_literal: bool,
134
145
  ?line: Integer,
135
146
  ?main_script: bool,
@@ -141,6 +152,7 @@ module Prism
141
152
  def self.profile_file: (
142
153
  String filepath,
143
154
  ?encoding: Encoding | false,
155
+ ?freeze: bool,
144
156
  ?frozen_string_literal: bool,
145
157
  ?line: Integer,
146
158
  ?main_script: bool,
@@ -152,6 +164,7 @@ module Prism
152
164
  def self.lex_file: (
153
165
  String filepath,
154
166
  ?encoding: Encoding | false,
167
+ ?freeze: bool,
155
168
  ?frozen_string_literal: bool,
156
169
  ?line: Integer,
157
170
  ?main_script: bool,
@@ -163,6 +176,7 @@ module Prism
163
176
  def self.parse_lex_file: (
164
177
  String filepath,
165
178
  ?encoding: Encoding | false,
179
+ ?freeze: bool,
166
180
  ?frozen_string_literal: bool,
167
181
  ?line: Integer,
168
182
  ?main_script: bool,
@@ -174,6 +188,7 @@ module Prism
174
188
  def self.dump_file: (
175
189
  String filepath,
176
190
  ?encoding: Encoding | false,
191
+ ?freeze: bool,
177
192
  ?frozen_string_literal: bool,
178
193
  ?line: Integer,
179
194
  ?main_script: bool,
@@ -185,6 +200,7 @@ module Prism
185
200
  def self.parse_file_comments: (
186
201
  String filepath,
187
202
  ?encoding: Encoding | false,
203
+ ?freeze: bool,
188
204
  ?frozen_string_literal: bool,
189
205
  ?line: Integer,
190
206
  ?main_script: bool,
@@ -196,6 +212,7 @@ module Prism
196
212
  def self.parse_file_success?: (
197
213
  String filepath,
198
214
  ?encoding: Encoding | false,
215
+ ?freeze: bool,
199
216
  ?frozen_string_literal: bool,
200
217
  ?line: Integer,
201
218
  ?main_script: bool,
@@ -207,6 +224,7 @@ module Prism
207
224
  def self.parse_file_failure?: (
208
225
  String filepath,
209
226
  ?encoding: Encoding | false,
227
+ ?freeze: bool,
210
228
  ?frozen_string_literal: bool,
211
229
  ?line: Integer,
212
230
  ?main_script: bool,
@@ -223,6 +241,7 @@ module Prism
223
241
  _Stream stream,
224
242
  ?encoding: Encoding | false,
225
243
  ?filepath: String,
244
+ ?freeze: bool,
226
245
  ?frozen_string_literal: bool,
227
246
  ?line: Integer,
228
247
  ?main_script: bool,
@@ -230,4 +249,6 @@ module Prism
230
249
  ?scopes: Array[Array[Symbol]],
231
250
  ?verbose: bool
232
251
  ) -> ParseResult
252
+
253
+ def self.scope: (?locals: Array[Symbol], ?forwarding: Array[Symbol]) -> Scope
233
254
  end
data/src/diagnostic.c CHANGED
@@ -1,3 +1,5 @@
1
+ /* :markup: markdown */
2
+
1
3
  /*----------------------------------------------------------------------------*/
2
4
  /* This file is generated by the templates/template.rb script and should not */
3
5
  /* be modified manually. See */
@@ -8,7 +10,7 @@
8
10
 
9
11
  #include "prism/diagnostic.h"
10
12
 
11
- #define PM_DIAGNOSTIC_ID_MAX 319
13
+ #define PM_DIAGNOSTIC_ID_MAX 321
12
14
 
13
15
  /** This struct holds the data for each diagnostic. */
14
16
  typedef struct {
@@ -192,6 +194,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
192
194
  [PM_ERR_EXPECT_FOR_DELIMITER] = { "unexpected %s; expected a 'do', newline, or ';' after the 'for' loop collection", PM_ERROR_LEVEL_SYNTAX },
193
195
  [PM_ERR_EXPECT_IDENT_REQ_PARAMETER] = { "expected an identifier for the required parameter", PM_ERROR_LEVEL_SYNTAX },
194
196
  [PM_ERR_EXPECT_IN_DELIMITER] = { "expected a delimiter after the patterns of an `in` clause", PM_ERROR_LEVEL_SYNTAX },
197
+ [PM_ERR_EXPECT_LPAREN_AFTER_NOT_LPAREN] = { "expected a `(` immediately after `not`", PM_ERROR_LEVEL_SYNTAX },
198
+ [PM_ERR_EXPECT_LPAREN_AFTER_NOT_OTHER] = { "expected a `(` after `not`", PM_ERROR_LEVEL_SYNTAX },
195
199
  [PM_ERR_EXPECT_LPAREN_REQ_PARAMETER] = { "expected a `(` to start a required parameter", PM_ERROR_LEVEL_SYNTAX },
196
200
  [PM_ERR_EXPECT_MESSAGE] = { "unexpected %s; expecting a message to send to the receiver", PM_ERROR_LEVEL_SYNTAX },
197
201
  [PM_ERR_EXPECT_RBRACKET] = { "expected a matching `]`", PM_ERROR_LEVEL_SYNTAX },
@@ -257,8 +261,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
257
261
  [PM_ERR_INVALID_VARIABLE_GLOBAL_3_3] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
258
262
  [PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
259
263
  [PM_ERR_INVALID_YIELD] = { "Invalid yield", PM_ERROR_LEVEL_SYNTAX },
260
- [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when a numbered parameter is already used", PM_ERROR_LEVEL_SYNTAX },
261
- [PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "`it` is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX },
264
+ [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "'it' is not allowed when a numbered parameter is already used", PM_ERROR_LEVEL_SYNTAX },
265
+ [PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "'it' is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX },
262
266
  [PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_SYNTAX },
263
267
  [PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX },
264
268
  [PM_ERR_LAMBDA_TERM_END] = { "expected a lambda block beginning with `do` to end with `end`", PM_ERROR_LEVEL_SYNTAX },
@@ -519,6 +523,8 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
519
523
  case PM_ERR_EXPECT_FOR_DELIMITER: return "expect_for_delimiter";
520
524
  case PM_ERR_EXPECT_IDENT_REQ_PARAMETER: return "expect_ident_req_parameter";
521
525
  case PM_ERR_EXPECT_IN_DELIMITER: return "expect_in_delimiter";
526
+ case PM_ERR_EXPECT_LPAREN_AFTER_NOT_LPAREN: return "expect_lparen_after_not_lparen";
527
+ case PM_ERR_EXPECT_LPAREN_AFTER_NOT_OTHER: return "expect_lparen_after_not_other";
522
528
  case PM_ERR_EXPECT_LPAREN_REQ_PARAMETER: return "expect_lparen_req_parameter";
523
529
  case PM_ERR_EXPECT_MESSAGE: return "expect_message";
524
530
  case PM_ERR_EXPECT_RBRACKET: return "expect_rbracket";
data/src/node.c CHANGED
@@ -1,3 +1,5 @@
1
+ /* :markup: markdown */
2
+
1
3
  /*----------------------------------------------------------------------------*/
2
4
  /* This file is generated by the templates/template.rb script and should not */
3
5
  /* be modified manually. See */
@@ -7347,6 +7349,18 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
7347
7349
  const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node;
7348
7350
  pm_dump_json_location(buffer, parser, &cast->base.location);
7349
7351
 
7352
+ // Dump the ParenthesesNodeFlags field
7353
+ pm_buffer_append_byte(buffer, ',');
7354
+ pm_buffer_append_string(buffer, "\"ParenthesesNodeFlags\":", 23);
7355
+ size_t flags = 0;
7356
+ pm_buffer_append_byte(buffer, '[');
7357
+ if (PM_NODE_FLAG_P(cast, PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS)) {
7358
+ if (flags != 0) pm_buffer_append_byte(buffer, ',');
7359
+ pm_buffer_append_string(buffer, "\"MULTIPLE_STATEMENTS\"", 21);
7360
+ flags++;
7361
+ }
7362
+ pm_buffer_append_byte(buffer, ']');
7363
+
7350
7364
  // Dump the body field
7351
7365
  pm_buffer_append_byte(buffer, ',');
7352
7366
  pm_buffer_append_string(buffer, "\"body\":", 7);
@@ -7824,6 +7838,15 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
7824
7838
  pm_buffer_append_string(buffer, "null", 4);
7825
7839
  }
7826
7840
 
7841
+ // Dump the then_keyword_loc field
7842
+ pm_buffer_append_byte(buffer, ',');
7843
+ pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19);
7844
+ if (cast->then_keyword_loc.start != NULL) {
7845
+ pm_dump_json_location(buffer, parser, &cast->then_keyword_loc);
7846
+ } else {
7847
+ pm_buffer_append_string(buffer, "null", 4);
7848
+ }
7849
+
7827
7850
  // Dump the statements field
7828
7851
  pm_buffer_append_byte(buffer, ',');
7829
7852
  pm_buffer_append_string(buffer, "\"statements\":", 13);
data/src/options.c CHANGED
@@ -84,7 +84,12 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
84
84
  }
85
85
 
86
86
  if (strncmp(version, "3.4", 3) == 0) {
87
- options->version = PM_OPTIONS_VERSION_LATEST;
87
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_4;
88
+ return true;
89
+ }
90
+
91
+ if (strncmp(version, "3.5", 3) == 0) {
92
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_5;
88
93
  return true;
89
94
  }
90
95
 
@@ -98,7 +103,12 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
98
103
  }
99
104
 
100
105
  if (strncmp(version, "3.4.", 4) == 0 && is_number(version + 4, length - 4)) {
101
- options->version = PM_OPTIONS_VERSION_LATEST;
106
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_4;
107
+ return true;
108
+ }
109
+
110
+ if (strncmp(version, "3.5.", 4) == 0 && is_number(version + 4, length - 4)) {
111
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_5;
102
112
  return true;
103
113
  }
104
114
  }
@@ -129,6 +139,14 @@ pm_options_partial_script_set(pm_options_t *options, bool partial_script) {
129
139
  options->partial_script = partial_script;
130
140
  }
131
141
 
142
+ /**
143
+ * Set the freeze option on the given options struct.
144
+ */
145
+ PRISM_EXPORTED_FUNCTION void
146
+ pm_options_freeze_set(pm_options_t *options, bool freeze) {
147
+ options->freeze = freeze;
148
+ }
149
+
132
150
  // For some reason, GCC analyzer thinks we're leaking allocated scopes and
133
151
  // locals here, even though we definitely aren't. This is a false positive.
134
152
  // Ideally we wouldn't need to suppress this.
@@ -163,6 +181,7 @@ PRISM_EXPORTED_FUNCTION bool
163
181
  pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count) {
164
182
  scope->locals_count = locals_count;
165
183
  scope->locals = xcalloc(locals_count, sizeof(pm_string_t));
184
+ scope->forwarding = PM_OPTIONS_SCOPE_FORWARDING_NONE;
166
185
  return scope->locals != NULL;
167
186
  }
168
187
 
@@ -174,6 +193,14 @@ pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index) {
174
193
  return &scope->locals[index];
175
194
  }
176
195
 
196
+ /**
197
+ * Set the forwarding option on the given scope struct.
198
+ */
199
+ PRISM_EXPORTED_FUNCTION void
200
+ pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding) {
201
+ scope->forwarding = forwarding;
202
+ }
203
+
177
204
  /**
178
205
  * Free the internal memory associated with the options.
179
206
  */
@@ -264,6 +291,7 @@ pm_options_read(pm_options_t *options, const char *data) {
264
291
  options->encoding_locked = ((uint8_t) *data++) > 0;
265
292
  options->main_script = ((uint8_t) *data++) > 0;
266
293
  options->partial_script = ((uint8_t) *data++) > 0;
294
+ options->freeze = ((uint8_t) *data++) > 0;
267
295
 
268
296
  uint32_t scopes_count = pm_options_read_u32(data);
269
297
  data += 4;
@@ -281,6 +309,9 @@ pm_options_read(pm_options_t *options, const char *data) {
281
309
  return;
282
310
  }
283
311
 
312
+ uint8_t forwarding = (uint8_t) *data++;
313
+ pm_options_scope_forwarding_set(&options->scopes[scope_index], forwarding);
314
+
284
315
  for (size_t local_index = 0; local_index < locals_count; local_index++) {
285
316
  uint32_t local_length = pm_options_read_u32(data);
286
317
  data += 4;
data/src/prettyprint.c CHANGED
@@ -1,3 +1,5 @@
1
+ /* :markup: markdown */
2
+
1
3
  /*----------------------------------------------------------------------------*/
2
4
  /* This file is generated by the templates/template.rb script and should not */
3
5
  /* be modified manually. See */
@@ -6950,6 +6952,20 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
6950
6952
  prettyprint_location(output_buffer, parser, &node->location);
6951
6953
  pm_buffer_append_string(output_buffer, ")\n", 2);
6952
6954
 
6955
+ // ParenthesesNodeFlags
6956
+ {
6957
+ pm_buffer_concat(output_buffer, prefix_buffer);
6958
+ pm_buffer_append_string(output_buffer, "+-- ParenthesesNodeFlags:", 25);
6959
+ bool found = false;
6960
+ if (cast->base.flags & PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS) {
6961
+ if (found) pm_buffer_append_byte(output_buffer, ',');
6962
+ pm_buffer_append_string(output_buffer, " multiple_statements", 20);
6963
+ found = true;
6964
+ }
6965
+ if (!found) pm_buffer_append_string(output_buffer, " nil", 4);
6966
+ pm_buffer_append_byte(output_buffer, '\n');
6967
+ }
6968
+
6953
6969
  // body
6954
6970
  {
6955
6971
  pm_buffer_concat(output_buffer, prefix_buffer);
@@ -7676,6 +7692,22 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
7676
7692
  }
7677
7693
  }
7678
7694
 
7695
+ // then_keyword_loc
7696
+ {
7697
+ pm_buffer_concat(output_buffer, prefix_buffer);
7698
+ pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21);
7699
+ pm_location_t *location = &cast->then_keyword_loc;
7700
+ if (location->start == NULL) {
7701
+ pm_buffer_append_string(output_buffer, " nil\n", 5);
7702
+ } else {
7703
+ pm_buffer_append_byte(output_buffer, ' ');
7704
+ prettyprint_location(output_buffer, parser, location);
7705
+ pm_buffer_append_string(output_buffer, " = \"", 4);
7706
+ pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
7707
+ pm_buffer_append_string(output_buffer, "\"\n", 2);
7708
+ }
7709
+ }
7710
+
7679
7711
  // statements
7680
7712
  {
7681
7713
  pm_buffer_concat(output_buffer, prefix_buffer);