prism 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -1
- data/config.yml +9 -0
- data/docs/releasing.md +1 -1
- data/docs/ruby_api.md +1 -1
- data/ext/prism/api_node.c +1814 -1303
- data/ext/prism/extension.c +230 -109
- data/ext/prism/extension.h +4 -4
- data/include/prism/ast.h +16 -0
- data/include/prism/defines.h +4 -1
- data/include/prism/options.h +47 -1
- data/include/prism/util/pm_buffer.h +10 -0
- data/include/prism/version.h +2 -2
- data/include/prism.h +4 -4
- data/lib/prism/dot_visitor.rb +16 -0
- data/lib/prism/dsl.rb +10 -2
- data/lib/prism/ffi.rb +45 -27
- data/lib/prism/inspect_visitor.rb +2 -1
- data/lib/prism/node.rb +48 -10
- data/lib/prism/parse_result/newlines.rb +1 -1
- data/lib/prism/parse_result.rb +52 -0
- data/lib/prism/polyfill/append_as_bytes.rb +15 -0
- data/lib/prism/reflection.rb +2 -2
- data/lib/prism/serialize.rb +1252 -765
- data/lib/prism/translation/parser/builder.rb +61 -0
- data/lib/prism/translation/parser/compiler.rb +192 -136
- data/lib/prism/translation/parser/lexer.rb +435 -61
- data/lib/prism/translation/parser.rb +51 -3
- data/lib/prism/translation/parser35.rb +12 -0
- data/lib/prism/translation/ripper.rb +13 -3
- data/lib/prism/translation/ruby_parser.rb +5 -4
- data/lib/prism/translation.rb +1 -0
- data/lib/prism.rb +3 -3
- data/prism.gemspec +5 -1
- data/rbi/prism/dsl.rbi +6 -3
- data/rbi/prism/node.rbi +22 -7
- data/rbi/prism/parse_result.rbi +17 -0
- data/rbi/prism/translation/parser35.rbi +6 -0
- data/rbi/prism.rbi +39 -36
- data/sig/prism/dsl.rbs +4 -2
- data/sig/prism/node.rbs +17 -7
- data/sig/prism/parse_result.rbs +10 -0
- data/sig/prism/serialize.rbs +4 -2
- data/sig/prism.rbs +22 -1
- data/src/diagnostic.c +2 -2
- data/src/node.c +21 -0
- data/src/options.c +31 -0
- data/src/prettyprint.c +30 -0
- data/src/prism.c +374 -118
- data/src/serialize.c +6 -0
- data/src/util/pm_buffer.c +40 -0
- data/src/util/pm_constant_pool.c +6 -2
- data/src/util/pm_strncasecmp.c +13 -1
- metadata +7 -7
data/sig/prism/parse_result.rbs
CHANGED
@@ -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
|
@@ -84,6 +86,7 @@ module Prism
|
|
84
86
|
|
85
87
|
def initialize: (Location location) -> void
|
86
88
|
def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped]
|
89
|
+
def slice: () -> String
|
87
90
|
end
|
88
91
|
|
89
92
|
interface _Comment
|
@@ -179,4 +182,11 @@ module Prism
|
|
179
182
|
def pretty_print: (untyped q) -> untyped
|
180
183
|
def ==: (untyped other) -> bool
|
181
184
|
end
|
185
|
+
|
186
|
+
class Scope
|
187
|
+
attr_reader locals: Array[Symbol]
|
188
|
+
attr_reader forwarding: Array[Symbol]
|
189
|
+
|
190
|
+
def initialize: (Array[Symbol] locals, Array[Symbol] forwarding) -> void
|
191
|
+
end
|
182
192
|
end
|
data/sig/prism/serialize.rbs
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Prism
|
2
2
|
module Serialize
|
3
|
-
def self.
|
4
|
-
def self.
|
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
@@ -257,8 +257,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
|
257
257
|
[PM_ERR_INVALID_VARIABLE_GLOBAL_3_3] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
|
258
258
|
[PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
|
259
259
|
[PM_ERR_INVALID_YIELD] = { "Invalid yield", PM_ERROR_LEVEL_SYNTAX },
|
260
|
-
[PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "
|
261
|
-
[PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "
|
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 },
|
262
262
|
[PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_SYNTAX },
|
263
263
|
[PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX },
|
264
264
|
[PM_ERR_LAMBDA_TERM_END] = { "expected a lambda block beginning with `do` to end with `end`", PM_ERROR_LEVEL_SYNTAX },
|
data/src/node.c
CHANGED
@@ -7347,6 +7347,18 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
|
|
7347
7347
|
const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node;
|
7348
7348
|
pm_dump_json_location(buffer, parser, &cast->base.location);
|
7349
7349
|
|
7350
|
+
// Dump the ParenthesesNodeFlags field
|
7351
|
+
pm_buffer_append_byte(buffer, ',');
|
7352
|
+
pm_buffer_append_string(buffer, "\"ParenthesesNodeFlags\":", 23);
|
7353
|
+
size_t flags = 0;
|
7354
|
+
pm_buffer_append_byte(buffer, '[');
|
7355
|
+
if (PM_NODE_FLAG_P(cast, PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS)) {
|
7356
|
+
if (flags != 0) pm_buffer_append_byte(buffer, ',');
|
7357
|
+
pm_buffer_append_string(buffer, "\"MULTIPLE_STATEMENTS\"", 21);
|
7358
|
+
flags++;
|
7359
|
+
}
|
7360
|
+
pm_buffer_append_byte(buffer, ']');
|
7361
|
+
|
7350
7362
|
// Dump the body field
|
7351
7363
|
pm_buffer_append_byte(buffer, ',');
|
7352
7364
|
pm_buffer_append_string(buffer, "\"body\":", 7);
|
@@ -7824,6 +7836,15 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
|
|
7824
7836
|
pm_buffer_append_string(buffer, "null", 4);
|
7825
7837
|
}
|
7826
7838
|
|
7839
|
+
// Dump the then_keyword_loc field
|
7840
|
+
pm_buffer_append_byte(buffer, ',');
|
7841
|
+
pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19);
|
7842
|
+
if (cast->then_keyword_loc.start != NULL) {
|
7843
|
+
pm_dump_json_location(buffer, parser, &cast->then_keyword_loc);
|
7844
|
+
} else {
|
7845
|
+
pm_buffer_append_string(buffer, "null", 4);
|
7846
|
+
}
|
7847
|
+
|
7827
7848
|
// Dump the statements field
|
7828
7849
|
pm_buffer_append_byte(buffer, ',');
|
7829
7850
|
pm_buffer_append_string(buffer, "\"statements\":", 13);
|
data/src/options.c
CHANGED
@@ -84,6 +84,11 @@ 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_CRUBY_3_4;
|
88
|
+
return true;
|
89
|
+
}
|
90
|
+
|
91
|
+
if (strncmp(version, "3.5", 3) == 0) {
|
87
92
|
options->version = PM_OPTIONS_VERSION_LATEST;
|
88
93
|
return true;
|
89
94
|
}
|
@@ -98,6 +103,11 @@ 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)) {
|
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)) {
|
101
111
|
options->version = PM_OPTIONS_VERSION_LATEST;
|
102
112
|
return true;
|
103
113
|
}
|
@@ -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
@@ -6950,6 +6950,20 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
6950
6950
|
prettyprint_location(output_buffer, parser, &node->location);
|
6951
6951
|
pm_buffer_append_string(output_buffer, ")\n", 2);
|
6952
6952
|
|
6953
|
+
// ParenthesesNodeFlags
|
6954
|
+
{
|
6955
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
6956
|
+
pm_buffer_append_string(output_buffer, "+-- ParenthesesNodeFlags:", 25);
|
6957
|
+
bool found = false;
|
6958
|
+
if (cast->base.flags & PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS) {
|
6959
|
+
if (found) pm_buffer_append_byte(output_buffer, ',');
|
6960
|
+
pm_buffer_append_string(output_buffer, " multiple_statements", 20);
|
6961
|
+
found = true;
|
6962
|
+
}
|
6963
|
+
if (!found) pm_buffer_append_string(output_buffer, " nil", 4);
|
6964
|
+
pm_buffer_append_byte(output_buffer, '\n');
|
6965
|
+
}
|
6966
|
+
|
6953
6967
|
// body
|
6954
6968
|
{
|
6955
6969
|
pm_buffer_concat(output_buffer, prefix_buffer);
|
@@ -7676,6 +7690,22 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
|
|
7676
7690
|
}
|
7677
7691
|
}
|
7678
7692
|
|
7693
|
+
// then_keyword_loc
|
7694
|
+
{
|
7695
|
+
pm_buffer_concat(output_buffer, prefix_buffer);
|
7696
|
+
pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21);
|
7697
|
+
pm_location_t *location = &cast->then_keyword_loc;
|
7698
|
+
if (location->start == NULL) {
|
7699
|
+
pm_buffer_append_string(output_buffer, " nil\n", 5);
|
7700
|
+
} else {
|
7701
|
+
pm_buffer_append_byte(output_buffer, ' ');
|
7702
|
+
prettyprint_location(output_buffer, parser, location);
|
7703
|
+
pm_buffer_append_string(output_buffer, " = \"", 4);
|
7704
|
+
pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
|
7705
|
+
pm_buffer_append_string(output_buffer, "\"\n", 2);
|
7706
|
+
}
|
7707
|
+
}
|
7708
|
+
|
7679
7709
|
// statements
|
7680
7710
|
{
|
7681
7711
|
pm_buffer_concat(output_buffer, prefix_buffer);
|