prism 1.5.1 → 1.9.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -1
  3. data/Makefile +12 -5
  4. data/README.md +2 -1
  5. data/config.yml +34 -8
  6. data/docs/build_system.md +2 -2
  7. data/docs/cruby_compilation.md +1 -1
  8. data/docs/design.md +2 -2
  9. data/docs/parser_translation.md +1 -1
  10. data/docs/releasing.md +4 -25
  11. data/docs/ripper_translation.md +8 -17
  12. data/docs/ruby_api.md +1 -0
  13. data/ext/prism/api_node.c +7 -3
  14. data/ext/prism/extconf.rb +1 -1
  15. data/ext/prism/extension.c +10 -2
  16. data/ext/prism/extension.h +1 -1
  17. data/include/prism/ast.h +89 -25
  18. data/include/prism/diagnostic.h +3 -0
  19. data/include/prism/options.h +8 -2
  20. data/include/prism/parser.h +3 -0
  21. data/include/prism/version.h +3 -3
  22. data/include/prism.h +1 -1
  23. data/lib/prism/compiler.rb +152 -152
  24. data/lib/prism/dot_visitor.rb +5 -0
  25. data/lib/prism/dsl.rb +2 -2
  26. data/lib/prism/ffi.rb +11 -3
  27. data/lib/prism/inspect_visitor.rb +1 -0
  28. data/lib/prism/lex_compat.rb +133 -150
  29. data/lib/prism/node.rb +1184 -34
  30. data/lib/prism/parse_result.rb +11 -15
  31. data/lib/prism/polyfill/scan_byte.rb +1 -1
  32. data/lib/prism/polyfill/warn.rb +16 -22
  33. data/lib/prism/reflection.rb +1 -1
  34. data/lib/prism/serialize.rb +8 -5
  35. data/lib/prism/translation/parser/compiler.rb +16 -16
  36. data/lib/prism/translation/parser.rb +12 -3
  37. data/lib/prism/translation/parser_current.rb +5 -3
  38. data/lib/prism/translation/parser_versions.rb +36 -0
  39. data/lib/prism/translation/ripper/filter.rb +53 -0
  40. data/lib/prism/translation/ripper/lexer.rb +135 -0
  41. data/lib/prism/translation/ripper.rb +86 -40
  42. data/lib/prism/translation/ruby_parser.rb +55 -20
  43. data/lib/prism/translation.rb +5 -3
  44. data/lib/prism/visitor.rb +152 -152
  45. data/lib/prism.rb +21 -14
  46. data/prism.gemspec +5 -7
  47. data/rbi/prism/dsl.rbi +3 -3
  48. data/rbi/prism/node.rbi +24 -8
  49. data/rbi/prism/translation/parser_versions.rbi +23 -0
  50. data/rbi/prism.rbi +0 -3
  51. data/sig/prism/dsl.rbs +2 -2
  52. data/sig/prism/node.rbs +22 -8
  53. data/sig/prism/parse_result.rbs +1 -0
  54. data/sig/prism.rbs +58 -40
  55. data/src/diagnostic.c +7 -1
  56. data/src/encoding.c +172 -67
  57. data/src/node.c +9 -0
  58. data/src/options.c +17 -7
  59. data/src/prettyprint.c +16 -0
  60. data/src/prism.c +1335 -1958
  61. data/src/serialize.c +7 -1
  62. data/src/token_type.c +2 -2
  63. data/src/util/pm_constant_pool.c +1 -1
  64. data/src/util/pm_string.c +6 -8
  65. metadata +7 -9
  66. data/lib/prism/translation/parser33.rb +0 -13
  67. data/lib/prism/translation/parser34.rb +0 -13
  68. data/lib/prism/translation/parser35.rb +0 -13
  69. data/rbi/prism/translation/parser33.rbi +0 -6
  70. data/rbi/prism/translation/parser34.rbi +0 -6
  71. data/rbi/prism/translation/parser35.rbi +0 -6
data/sig/prism.rbs CHANGED
@@ -6,123 +6,136 @@ module Prism
6
6
  BACKEND: :CEXT | :FFI
7
7
  VERSION: String
8
8
 
9
+ class CurrentVersionError < ArgumentError
10
+ def initialize: (String version) -> void
11
+ end
12
+
9
13
  # Methods taking a Ruby source code string:
10
14
 
11
15
  def self.parse: (
12
16
  String source,
17
+ ?command_line: String,
13
18
  ?encoding: Encoding | false,
14
19
  ?filepath: String,
15
20
  ?freeze: bool,
16
21
  ?frozen_string_literal: bool,
17
22
  ?line: Integer,
18
23
  ?main_script: bool,
19
- ?offset: Integer,
24
+ ?partial_script: bool,
20
25
  ?scopes: Array[Array[Symbol]],
21
- ?verbose: bool
26
+ ?version: String
22
27
  ) -> ParseResult
23
28
 
24
29
  def self.profile: (
25
30
  String source,
31
+ ?command_line: String,
26
32
  ?encoding: Encoding | false,
27
33
  ?filepath: String,
28
34
  ?freeze: bool,
29
35
  ?frozen_string_literal: bool,
30
36
  ?line: Integer,
31
37
  ?main_script: bool,
32
- ?offset: Integer,
38
+ ?partial_script: bool,
33
39
  ?scopes: Array[Array[Symbol]],
34
- ?verbose: bool
40
+ ?version: String
35
41
  ) -> nil
36
42
 
37
43
  def self.lex: (
38
44
  String source,
45
+ ?command_line: String,
39
46
  ?encoding: Encoding | false,
40
47
  ?filepath: String,
41
48
  ?freeze: bool,
42
49
  ?frozen_string_literal: bool,
43
50
  ?line: Integer,
44
51
  ?main_script: bool,
45
- ?offset: Integer,
52
+ ?partial_script: bool,
46
53
  ?scopes: Array[Array[Symbol]],
47
- ?verbose: bool
54
+ ?version: String
48
55
  ) -> LexResult
49
56
 
50
57
  def self.lex_compat: (
51
58
  String source,
59
+ ?command_line: String,
52
60
  ?encoding: Encoding | false,
53
61
  ?filepath: String,
54
62
  ?freeze: bool,
55
63
  ?frozen_string_literal: bool,
56
64
  ?line: Integer,
57
65
  ?main_script: bool,
58
- ?offset: Integer,
66
+ ?partial_script: bool,
59
67
  ?scopes: Array[Array[Symbol]],
60
- ?verbose: bool
68
+ ?version: String
61
69
  ) -> LexCompat::Result
62
70
 
63
71
  def self.parse_lex: (
64
72
  String source,
73
+ ?command_line: String,
65
74
  ?encoding: Encoding | false,
66
75
  ?filepath: String,
67
76
  ?freeze: bool,
68
77
  ?frozen_string_literal: bool,
69
78
  ?line: Integer,
70
79
  ?main_script: bool,
71
- ?offset: Integer,
80
+ ?partial_script: bool,
72
81
  ?scopes: Array[Array[Symbol]],
73
- ?verbose: bool
82
+ ?version: String
74
83
  ) -> ParseLexResult
75
84
 
76
85
  def self.dump: (
77
86
  String source,
87
+ ?command_line: String,
78
88
  ?encoding: Encoding | false,
79
89
  ?filepath: String,
80
90
  ?freeze: bool,
81
91
  ?frozen_string_literal: bool,
82
92
  ?line: Integer,
83
93
  ?main_script: bool,
84
- ?offset: Integer,
94
+ ?partial_script: bool,
85
95
  ?scopes: Array[Array[Symbol]],
86
- ?verbose: bool
96
+ ?version: String
87
97
  ) -> String
88
98
 
89
99
  def self.parse_comments: (
90
100
  String source,
101
+ ?command_line: String,
91
102
  ?encoding: Encoding | false,
92
103
  ?filepath: String,
93
104
  ?freeze: bool,
94
105
  ?frozen_string_literal: bool,
95
106
  ?line: Integer,
96
107
  ?main_script: bool,
97
- ?offset: Integer,
108
+ ?partial_script: bool,
98
109
  ?scopes: Array[Array[Symbol]],
99
- ?verbose: bool
110
+ ?version: String
100
111
  ) -> Array[comment]
101
112
 
102
113
  def self.parse_success?: (
103
114
  String source,
115
+ ?command_line: String,
104
116
  ?encoding: Encoding | false,
105
117
  ?filepath: String,
106
118
  ?freeze: bool,
107
119
  ?frozen_string_literal: bool,
108
120
  ?line: Integer,
109
121
  ?main_script: bool,
110
- ?offset: Integer,
122
+ ?partial_script: bool,
111
123
  ?scopes: Array[Array[Symbol]],
112
- ?verbose: bool
124
+ ?version: String
113
125
  ) -> bool
114
126
 
115
127
  def self.parse_failure?: (
116
128
  String source,
129
+ ?command_line: String,
117
130
  ?encoding: Encoding | false,
118
131
  ?filepath: String,
119
132
  ?freeze: bool,
120
133
  ?frozen_string_literal: bool,
121
134
  ?line: Integer,
122
135
  ?main_script: bool,
123
- ?offset: Integer,
136
+ ?partial_script: bool,
124
137
  ?scopes: Array[Array[Symbol]],
125
- ?verbose: bool
138
+ ?version: String
126
139
  ) -> bool
127
140
 
128
141
  def self.load: (
@@ -131,106 +144,110 @@ module Prism
131
144
  ?bool freeze
132
145
  ) -> ParseResult
133
146
 
134
- def self.lex_ripper: (
135
- String source
136
- ) -> Array[[[Integer, Integer], Symbol, String, untyped]]
137
-
138
147
  # Methods taking a path to a Ruby file:
139
148
 
140
149
  def self.parse_file: (
141
150
  String filepath,
151
+ ?command_line: String,
142
152
  ?encoding: Encoding | false,
143
153
  ?freeze: bool,
144
154
  ?frozen_string_literal: bool,
145
155
  ?line: Integer,
146
156
  ?main_script: bool,
147
- ?offset: Integer,
157
+ ?partial_script: bool,
148
158
  ?scopes: Array[Array[Symbol]],
149
- ?verbose: bool
159
+ ?version: String
150
160
  ) -> ParseResult
151
161
 
152
162
  def self.profile_file: (
153
163
  String filepath,
164
+ ?command_line: String,
154
165
  ?encoding: Encoding | false,
155
166
  ?freeze: bool,
156
167
  ?frozen_string_literal: bool,
157
168
  ?line: Integer,
158
169
  ?main_script: bool,
159
- ?offset: Integer,
170
+ ?partial_script: bool,
160
171
  ?scopes: Array[Array[Symbol]],
161
- ?verbose: bool
172
+ ?version: String
162
173
  ) -> nil
163
174
 
164
175
  def self.lex_file: (
165
176
  String filepath,
177
+ ?command_line: String,
166
178
  ?encoding: Encoding | false,
167
179
  ?freeze: bool,
168
180
  ?frozen_string_literal: bool,
169
181
  ?line: Integer,
170
182
  ?main_script: bool,
171
- ?offset: Integer,
183
+ ?partial_script: bool,
172
184
  ?scopes: Array[Array[Symbol]],
173
- ?verbose: bool
185
+ ?version: String
174
186
  ) -> LexResult
175
187
 
176
188
  def self.parse_lex_file: (
177
189
  String filepath,
190
+ ?command_line: String,
178
191
  ?encoding: Encoding | false,
179
192
  ?freeze: bool,
180
193
  ?frozen_string_literal: bool,
181
194
  ?line: Integer,
182
195
  ?main_script: bool,
183
- ?offset: Integer,
196
+ ?partial_script: bool,
184
197
  ?scopes: Array[Array[Symbol]],
185
- ?verbose: bool
198
+ ?version: String
186
199
  ) -> ParseLexResult
187
200
 
188
201
  def self.dump_file: (
189
202
  String filepath,
203
+ ?command_line: String,
190
204
  ?encoding: Encoding | false,
191
205
  ?freeze: bool,
192
206
  ?frozen_string_literal: bool,
193
207
  ?line: Integer,
194
208
  ?main_script: bool,
195
- ?offset: Integer,
209
+ ?partial_script: bool,
196
210
  ?scopes: Array[Array[Symbol]],
197
- ?verbose: bool
211
+ ?version: String
198
212
  ) -> String
199
213
 
200
214
  def self.parse_file_comments: (
201
215
  String filepath,
216
+ ?command_line: String,
202
217
  ?encoding: Encoding | false,
203
218
  ?freeze: bool,
204
219
  ?frozen_string_literal: bool,
205
220
  ?line: Integer,
206
221
  ?main_script: bool,
207
- ?offset: Integer,
222
+ ?partial_script: bool,
208
223
  ?scopes: Array[Array[Symbol]],
209
- ?verbose: bool
224
+ ?version: String
210
225
  ) -> Array[comment]
211
226
 
212
227
  def self.parse_file_success?: (
213
228
  String filepath,
229
+ ?command_line: String,
214
230
  ?encoding: Encoding | false,
215
231
  ?freeze: bool,
216
232
  ?frozen_string_literal: bool,
217
233
  ?line: Integer,
218
234
  ?main_script: bool,
219
- ?offset: Integer,
235
+ ?partial_script: bool,
220
236
  ?scopes: Array[Array[Symbol]],
221
- ?verbose: bool
237
+ ?version: String
222
238
  ) -> bool
223
239
 
224
240
  def self.parse_file_failure?: (
225
241
  String filepath,
242
+ ?command_line: String,
226
243
  ?encoding: Encoding | false,
227
244
  ?freeze: bool,
228
245
  ?frozen_string_literal: bool,
229
246
  ?line: Integer,
230
247
  ?main_script: bool,
231
- ?offset: Integer,
248
+ ?partial_script: bool,
232
249
  ?scopes: Array[Array[Symbol]],
233
- ?verbose: bool
250
+ ?version: String
234
251
  ) -> bool
235
252
 
236
253
  interface _Stream
@@ -239,15 +256,16 @@ module Prism
239
256
 
240
257
  def self.parse_stream: (
241
258
  _Stream stream,
259
+ ?command_line: String,
242
260
  ?encoding: Encoding | false,
243
261
  ?filepath: String,
244
262
  ?freeze: bool,
245
263
  ?frozen_string_literal: bool,
246
264
  ?line: Integer,
247
265
  ?main_script: bool,
248
- ?offset: Integer,
266
+ ?partial_script: bool,
249
267
  ?scopes: Array[Array[Symbol]],
250
- ?verbose: bool
268
+ ?version: String
251
269
  ) -> ParseResult
252
270
 
253
271
  def self.scope: (?locals: Array[Symbol], ?forwarding: Array[Symbol]) -> Scope
data/src/diagnostic.c CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  #include "prism/diagnostic.h"
12
12
 
13
- #define PM_DIAGNOSTIC_ID_MAX 321
13
+ #define PM_DIAGNOSTIC_ID_MAX 324
14
14
 
15
15
  /** This struct holds the data for each diagnostic. */
16
16
  typedef struct {
@@ -154,6 +154,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
154
154
  [PM_ERR_CONDITIONAL_WHILE_PREDICATE] = { "expected a predicate expression for the `while` statement", PM_ERROR_LEVEL_SYNTAX },
155
155
  [PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = { "expected a constant after the `::` operator", PM_ERROR_LEVEL_SYNTAX },
156
156
  [PM_ERR_DEF_ENDLESS] = { "could not parse the endless method body", PM_ERROR_LEVEL_SYNTAX },
157
+ [PM_ERR_DEF_ENDLESS_PARAMETERS] = { "could not parse the endless method parameters", PM_ERROR_LEVEL_SYNTAX },
157
158
  [PM_ERR_DEF_ENDLESS_SETTER] = { "invalid method name; a setter method cannot be defined in an endless method definition", PM_ERROR_LEVEL_SYNTAX },
158
159
  [PM_ERR_DEF_NAME] = { "unexpected %s; expected a method name", PM_ERROR_LEVEL_SYNTAX },
159
160
  [PM_ERR_DEF_PARAMS_TERM] = { "expected a delimiter to close the parameters", PM_ERROR_LEVEL_SYNTAX },
@@ -310,6 +311,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
310
311
  [PM_ERR_PARAMETER_UNEXPECTED_NO_KW] = { "unexpected **nil; no keywords marker disallowed after keywords", PM_ERROR_LEVEL_SYNTAX },
311
312
  [PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS] = { "unexpected multiple '*' rest patterns in an array pattern", PM_ERROR_LEVEL_SYNTAX },
312
313
  [PM_ERR_PATTERN_CAPTURE_DUPLICATE] = { "duplicated variable name", PM_ERROR_LEVEL_SYNTAX },
314
+ [PM_ERR_PATTERN_CAPTURE_IN_ALTERNATIVE] = { "variable capture in alternative pattern", PM_ERROR_LEVEL_SYNTAX },
313
315
  [PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = { "expected a pattern expression after the `[` operator", PM_ERROR_LEVEL_SYNTAX },
314
316
  [PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = { "expected a pattern expression after `,`", PM_ERROR_LEVEL_SYNTAX },
315
317
  [PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = { "expected a pattern expression after `=>`", PM_ERROR_LEVEL_SYNTAX },
@@ -370,6 +372,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
370
372
  [PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index assignment; keywords are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
371
373
  [PM_ERR_UNEXPECTED_LABEL] = { "unexpected label", PM_ERROR_LEVEL_SYNTAX },
372
374
  [PM_ERR_UNEXPECTED_MULTI_WRITE] = { "unexpected multiple assignment; multiple assignment is not allowed in this context", PM_ERROR_LEVEL_SYNTAX },
375
+ [PM_ERR_UNEXPECTED_PARAMETER_DEFAULT_VALUE] = { "unexpected %s; expected a default value for a parameter", PM_ERROR_LEVEL_SYNTAX },
373
376
  [PM_ERR_UNEXPECTED_RANGE_OPERATOR] = { "unexpected range operator; .. and ... are non-associative and cannot be chained", PM_ERROR_LEVEL_SYNTAX },
374
377
  [PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX },
375
378
  [PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX },
@@ -482,6 +485,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
482
485
  case PM_ERR_CONDITIONAL_WHILE_PREDICATE: return "conditional_while_predicate";
483
486
  case PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT: return "constant_path_colon_colon_constant";
484
487
  case PM_ERR_DEF_ENDLESS: return "def_endless";
488
+ case PM_ERR_DEF_ENDLESS_PARAMETERS: return "def_endless_parameters";
485
489
  case PM_ERR_DEF_ENDLESS_SETTER: return "def_endless_setter";
486
490
  case PM_ERR_DEF_NAME: return "def_name";
487
491
  case PM_ERR_DEF_PARAMS_TERM: return "def_params_term";
@@ -640,6 +644,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
640
644
  case PM_ERR_PARAMETER_WILD_LOOSE_COMMA: return "parameter_wild_loose_comma";
641
645
  case PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS: return "pattern_array_multiple_rests";
642
646
  case PM_ERR_PATTERN_CAPTURE_DUPLICATE: return "pattern_capture_duplicate";
647
+ case PM_ERR_PATTERN_CAPTURE_IN_ALTERNATIVE: return "pattern_capture_in_alternative";
643
648
  case PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET: return "pattern_expression_after_bracket";
644
649
  case PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA: return "pattern_expression_after_comma";
645
650
  case PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET: return "pattern_expression_after_hrocket";
@@ -701,6 +706,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
701
706
  case PM_ERR_UNEXPECTED_INDEX_KEYWORDS: return "unexpected_index_keywords";
702
707
  case PM_ERR_UNEXPECTED_LABEL: return "unexpected_label";
703
708
  case PM_ERR_UNEXPECTED_MULTI_WRITE: return "unexpected_multi_write";
709
+ case PM_ERR_UNEXPECTED_PARAMETER_DEFAULT_VALUE: return "unexpected_parameter_default_value";
704
710
  case PM_ERR_UNEXPECTED_RANGE_OPERATOR: return "unexpected_range_operator";
705
711
  case PM_ERR_UNEXPECTED_SAFE_NAVIGATION: return "unexpected_safe_navigation";
706
712
  case PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT: return "unexpected_token_close_context";