prism 0.27.0 → 0.28.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 +26 -1
- data/config.yml +39 -27
- data/docs/configuration.md +1 -0
- data/ext/prism/api_node.c +814 -807
- data/ext/prism/extension.c +5 -3
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +38 -16
- data/include/prism/diagnostic.h +12 -5
- data/include/prism/options.h +2 -2
- data/include/prism/parser.h +10 -0
- data/include/prism/static_literals.h +8 -6
- data/include/prism/version.h +2 -2
- data/lib/prism/dot_visitor.rb +22 -6
- data/lib/prism/dsl.rb +8 -8
- data/lib/prism/ffi.rb +3 -3
- data/lib/prism/inspect_visitor.rb +2156 -0
- data/lib/prism/lex_compat.rb +1 -1
- data/lib/prism/mutation_compiler.rb +2 -2
- data/lib/prism/node.rb +589 -1715
- data/lib/prism/node_ext.rb +34 -5
- data/lib/prism/parse_result.rb +78 -0
- data/lib/prism/pattern.rb +12 -6
- data/lib/prism/polyfill/byteindex.rb +13 -0
- data/lib/prism/polyfill/unpack1.rb +14 -0
- data/lib/prism/reflection.rb +13 -13
- data/lib/prism/serialize.rb +21 -14
- data/lib/prism/translation/parser/compiler.rb +2 -2
- data/lib/prism/translation/parser.rb +6 -6
- data/lib/prism/translation/ripper.rb +13 -9
- data/lib/prism/translation/ruby_parser.rb +4 -4
- data/lib/prism.rb +2 -1
- data/prism.gemspec +36 -38
- data/rbi/prism/compiler.rbi +3 -5
- data/rbi/prism/inspect_visitor.rbi +12 -0
- data/rbi/prism/node.rbi +354 -319
- data/rbi/prism/parse_result.rbi +23 -0
- data/rbi/prism/translation/ripper.rbi +1 -11
- data/sig/prism/dsl.rbs +3 -3
- data/sig/prism/inspect_visitor.rbs +22 -0
- data/sig/prism/node.rbs +64 -47
- data/sig/prism/parse_result.rbs +12 -0
- data/src/diagnostic.c +38 -24
- data/src/node.c +41 -16
- data/src/options.c +2 -2
- data/src/prettyprint.c +61 -18
- data/src/prism.c +607 -185
- data/src/serialize.c +5 -2
- data/src/static_literals.c +120 -34
- data/src/token_type.c +4 -4
- metadata +7 -9
- data/lib/prism/node_inspector.rb +0 -68
- data/lib/prism/polyfill/string.rb +0 -12
- data/rbi/prism/desugar_compiler.rbi +0 -5
- data/rbi/prism/mutation_compiler.rbi +0 -5
- data/rbi/prism/translation/parser/compiler.rbi +0 -13
- data/rbi/prism/translation/ripper/ripper_compiler.rbi +0 -5
- data/rbi/prism/translation/ruby_parser.rbi +0 -11
data/src/serialize.c
CHANGED
@@ -590,8 +590,9 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
590
590
|
} else {
|
591
591
|
pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_node_t *)node)->parent, buffer);
|
592
592
|
}
|
593
|
-
|
593
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_path_node_t *)node)->name));
|
594
594
|
pm_serialize_location(parser, &((pm_constant_path_node_t *)node)->delimiter_loc, buffer);
|
595
|
+
pm_serialize_location(parser, &((pm_constant_path_node_t *)node)->name_loc, buffer);
|
595
596
|
break;
|
596
597
|
}
|
597
598
|
case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
|
@@ -613,8 +614,9 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
613
614
|
} else {
|
614
615
|
pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_target_node_t *)node)->parent, buffer);
|
615
616
|
}
|
616
|
-
|
617
|
+
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_path_target_node_t *)node)->name));
|
617
618
|
pm_serialize_location(parser, &((pm_constant_path_target_node_t *)node)->delimiter_loc, buffer);
|
619
|
+
pm_serialize_location(parser, &((pm_constant_path_target_node_t *)node)->name_loc, buffer);
|
618
620
|
break;
|
619
621
|
}
|
620
622
|
case PM_CONSTANT_PATH_WRITE_NODE: {
|
@@ -1625,6 +1627,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1625
1627
|
break;
|
1626
1628
|
}
|
1627
1629
|
case PM_RETURN_NODE: {
|
1630
|
+
pm_buffer_append_varuint(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1628
1631
|
pm_serialize_location(parser, &((pm_return_node_t *)node)->keyword_loc, buffer);
|
1629
1632
|
if (((pm_return_node_t *)node)->arguments == NULL) {
|
1630
1633
|
pm_buffer_append_byte(buffer, 0);
|
data/src/static_literals.c
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
#include "prism/static_literals.h"
|
2
2
|
|
3
|
+
/**
|
4
|
+
* A small struct used for passing around a subset of the information that is
|
5
|
+
* stored on the parser. We use this to avoid having static literals explicitly
|
6
|
+
* depend on the parser struct.
|
7
|
+
*/
|
8
|
+
typedef struct {
|
9
|
+
/** The list of newline offsets to use to calculate line numbers. */
|
10
|
+
const pm_newline_list_t *newline_list;
|
11
|
+
|
12
|
+
/** The line number that the parser starts on. */
|
13
|
+
int32_t start_line;
|
14
|
+
|
15
|
+
/** The name of the encoding that the parser is using. */
|
16
|
+
const char *encoding_name;
|
17
|
+
} pm_static_literals_metadata_t;
|
18
|
+
|
3
19
|
static inline uint32_t
|
4
20
|
murmur_scramble(uint32_t value) {
|
5
21
|
value *= 0xcc9e2d51;
|
@@ -48,7 +64,7 @@ murmur_hash(const uint8_t *key, size_t length) {
|
|
48
64
|
* these hashes to look for duplicates.
|
49
65
|
*/
|
50
66
|
static uint32_t
|
51
|
-
node_hash(const
|
67
|
+
node_hash(const pm_static_literals_metadata_t *metadata, const pm_node_t *node) {
|
52
68
|
switch (PM_NODE_TYPE(node)) {
|
53
69
|
case PM_INTEGER_NODE: {
|
54
70
|
// Integers hash their value.
|
@@ -68,7 +84,7 @@ node_hash(const pm_parser_t *parser, const pm_node_t *node) {
|
|
68
84
|
}
|
69
85
|
case PM_SOURCE_LINE_NODE: {
|
70
86
|
// Source lines hash their line number.
|
71
|
-
const pm_line_column_t line_column = pm_newline_list_line_column(
|
87
|
+
const pm_line_column_t line_column = pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line);
|
72
88
|
const int32_t *value = &line_column.line;
|
73
89
|
return murmur_hash((const uint8_t *) value, sizeof(int32_t));
|
74
90
|
}
|
@@ -82,14 +98,14 @@ node_hash(const pm_parser_t *parser, const pm_node_t *node) {
|
|
82
98
|
// is stored as a subnode, we hash that node and then mix in the
|
83
99
|
// fact that this is a rational node.
|
84
100
|
const pm_node_t *numeric = ((const pm_rational_node_t *) node)->numeric;
|
85
|
-
return node_hash(
|
101
|
+
return node_hash(metadata, numeric) ^ murmur_scramble((uint32_t) node->type);
|
86
102
|
}
|
87
103
|
case PM_IMAGINARY_NODE: {
|
88
104
|
// Imaginaries hash their numeric value. Because their numeric value
|
89
105
|
// is stored as a subnode, we hash that node and then mix in the
|
90
106
|
// fact that this is an imaginary node.
|
91
107
|
const pm_node_t *numeric = ((const pm_imaginary_node_t *) node)->numeric;
|
92
|
-
return node_hash(
|
108
|
+
return node_hash(metadata, numeric) ^ murmur_scramble((uint32_t) node->type);
|
93
109
|
}
|
94
110
|
case PM_STRING_NODE: {
|
95
111
|
// Strings hash their value and mix in their flags so that different
|
@@ -132,7 +148,7 @@ node_hash(const pm_parser_t *parser, const pm_node_t *node) {
|
|
132
148
|
* and must be able to compare all node types that will be stored in this hash.
|
133
149
|
*/
|
134
150
|
static pm_node_t *
|
135
|
-
pm_node_hash_insert(pm_node_hash_t *hash, const
|
151
|
+
pm_node_hash_insert(pm_node_hash_t *hash, const pm_static_literals_metadata_t *metadata, pm_node_t *node, int (*compare)(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right)) {
|
136
152
|
// If we are out of space, we need to resize the hash. This will cause all
|
137
153
|
// of the nodes to be rehashed and reinserted into the new hash.
|
138
154
|
if (hash->size * 2 >= hash->capacity) {
|
@@ -152,7 +168,7 @@ pm_node_hash_insert(pm_node_hash_t *hash, const pm_parser_t *parser, pm_node_t *
|
|
152
168
|
pm_node_t *node = hash->nodes[index];
|
153
169
|
|
154
170
|
if (node != NULL) {
|
155
|
-
uint32_t index = node_hash(
|
171
|
+
uint32_t index = node_hash(metadata, node) & mask;
|
156
172
|
new_nodes[index] = node;
|
157
173
|
}
|
158
174
|
}
|
@@ -165,14 +181,14 @@ pm_node_hash_insert(pm_node_hash_t *hash, const pm_parser_t *parser, pm_node_t *
|
|
165
181
|
|
166
182
|
// Now, insert the node into the hash.
|
167
183
|
uint32_t mask = hash->capacity - 1;
|
168
|
-
uint32_t index = node_hash(
|
184
|
+
uint32_t index = node_hash(metadata, node) & mask;
|
169
185
|
|
170
186
|
// We use linear probing to resolve collisions. This means that if the
|
171
187
|
// current index is occupied, we will move to the next index and try again.
|
172
188
|
// We are guaranteed that this will eventually find an empty slot because we
|
173
189
|
// resize the hash when it gets too full.
|
174
190
|
while (hash->nodes[index] != NULL) {
|
175
|
-
if (compare(
|
191
|
+
if (compare(metadata, hash->nodes[index], node) == 0) break;
|
176
192
|
index = (index + 1) & mask;
|
177
193
|
}
|
178
194
|
|
@@ -203,7 +219,7 @@ pm_node_hash_free(pm_node_hash_t *hash) {
|
|
203
219
|
* Return the integer value of the given node as an int64_t.
|
204
220
|
*/
|
205
221
|
static int64_t
|
206
|
-
pm_int64_value(const
|
222
|
+
pm_int64_value(const pm_static_literals_metadata_t *metadata, const pm_node_t *node) {
|
207
223
|
switch (PM_NODE_TYPE(node)) {
|
208
224
|
case PM_INTEGER_NODE: {
|
209
225
|
const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value;
|
@@ -213,7 +229,7 @@ pm_int64_value(const pm_parser_t *parser, const pm_node_t *node) {
|
|
213
229
|
return integer->negative ? -value : value;
|
214
230
|
}
|
215
231
|
case PM_SOURCE_LINE_NODE:
|
216
|
-
return (int64_t) pm_newline_list_line_column(
|
232
|
+
return (int64_t) pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line).line;
|
217
233
|
default:
|
218
234
|
assert(false && "unreachable");
|
219
235
|
return 0;
|
@@ -225,10 +241,10 @@ pm_int64_value(const pm_parser_t *parser, const pm_node_t *node) {
|
|
225
241
|
* instances.
|
226
242
|
*/
|
227
243
|
static int
|
228
|
-
pm_compare_integer_nodes(const
|
244
|
+
pm_compare_integer_nodes(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) {
|
229
245
|
if (PM_NODE_TYPE_P(left, PM_SOURCE_LINE_NODE) || PM_NODE_TYPE_P(right, PM_SOURCE_LINE_NODE)) {
|
230
|
-
int64_t left_value = pm_int64_value(
|
231
|
-
int64_t right_value = pm_int64_value(
|
246
|
+
int64_t left_value = pm_int64_value(metadata, left);
|
247
|
+
int64_t right_value = pm_int64_value(metadata, right);
|
232
248
|
return PM_NUMERIC_COMPARISON(left_value, right_value);
|
233
249
|
}
|
234
250
|
|
@@ -241,7 +257,7 @@ pm_compare_integer_nodes(const pm_parser_t *parser, const pm_node_t *left, const
|
|
241
257
|
* A comparison function for comparing two FloatNode instances.
|
242
258
|
*/
|
243
259
|
static int
|
244
|
-
pm_compare_float_nodes(PRISM_ATTRIBUTE_UNUSED const
|
260
|
+
pm_compare_float_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) {
|
245
261
|
const double left_value = ((const pm_float_node_t *) left)->value;
|
246
262
|
const double right_value = ((const pm_float_node_t *) right)->value;
|
247
263
|
return PM_NUMERIC_COMPARISON(left_value, right_value);
|
@@ -251,20 +267,20 @@ pm_compare_float_nodes(PRISM_ATTRIBUTE_UNUSED const pm_parser_t *parser, const p
|
|
251
267
|
* A comparison function for comparing two nodes that have attached numbers.
|
252
268
|
*/
|
253
269
|
static int
|
254
|
-
pm_compare_number_nodes(const
|
270
|
+
pm_compare_number_nodes(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) {
|
255
271
|
if (PM_NODE_TYPE(left) != PM_NODE_TYPE(right)) {
|
256
272
|
return PM_NUMERIC_COMPARISON(PM_NODE_TYPE(left), PM_NODE_TYPE(right));
|
257
273
|
}
|
258
274
|
|
259
275
|
switch (PM_NODE_TYPE(left)) {
|
260
276
|
case PM_IMAGINARY_NODE:
|
261
|
-
return pm_compare_number_nodes(
|
277
|
+
return pm_compare_number_nodes(metadata, ((const pm_imaginary_node_t *) left)->numeric, ((const pm_imaginary_node_t *) right)->numeric);
|
262
278
|
case PM_RATIONAL_NODE:
|
263
|
-
return pm_compare_number_nodes(
|
279
|
+
return pm_compare_number_nodes(metadata, ((const pm_rational_node_t *) left)->numeric, ((const pm_rational_node_t *) right)->numeric);
|
264
280
|
case PM_INTEGER_NODE:
|
265
|
-
return pm_compare_integer_nodes(
|
281
|
+
return pm_compare_integer_nodes(metadata, left, right);
|
266
282
|
case PM_FLOAT_NODE:
|
267
|
-
return pm_compare_float_nodes(
|
283
|
+
return pm_compare_float_nodes(metadata, left, right);
|
268
284
|
default:
|
269
285
|
assert(false && "unreachable");
|
270
286
|
return 0;
|
@@ -293,7 +309,7 @@ pm_string_value(const pm_node_t *node) {
|
|
293
309
|
* A comparison function for comparing two nodes that have attached strings.
|
294
310
|
*/
|
295
311
|
static int
|
296
|
-
pm_compare_string_nodes(PRISM_ATTRIBUTE_UNUSED const
|
312
|
+
pm_compare_string_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) {
|
297
313
|
const pm_string_t *left_string = pm_string_value(left);
|
298
314
|
const pm_string_t *right_string = pm_string_value(right);
|
299
315
|
return pm_string_compare(left_string, right_string);
|
@@ -303,7 +319,7 @@ pm_compare_string_nodes(PRISM_ATTRIBUTE_UNUSED const pm_parser_t *parser, const
|
|
303
319
|
* A comparison function for comparing two RegularExpressionNode instances.
|
304
320
|
*/
|
305
321
|
static int
|
306
|
-
pm_compare_regular_expression_nodes(PRISM_ATTRIBUTE_UNUSED const
|
322
|
+
pm_compare_regular_expression_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) {
|
307
323
|
const pm_regular_expression_node_t *left_regexp = (const pm_regular_expression_node_t *) left;
|
308
324
|
const pm_regular_expression_node_t *right_regexp = (const pm_regular_expression_node_t *) right;
|
309
325
|
|
@@ -319,23 +335,77 @@ pm_compare_regular_expression_nodes(PRISM_ATTRIBUTE_UNUSED const pm_parser_t *pa
|
|
319
335
|
* Add a node to the set of static literals.
|
320
336
|
*/
|
321
337
|
pm_node_t *
|
322
|
-
pm_static_literals_add(const
|
338
|
+
pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node) {
|
323
339
|
switch (PM_NODE_TYPE(node)) {
|
324
340
|
case PM_INTEGER_NODE:
|
325
341
|
case PM_SOURCE_LINE_NODE:
|
326
|
-
return pm_node_hash_insert(
|
342
|
+
return pm_node_hash_insert(
|
343
|
+
&literals->integer_nodes,
|
344
|
+
&(pm_static_literals_metadata_t) {
|
345
|
+
.newline_list = newline_list,
|
346
|
+
.start_line = start_line,
|
347
|
+
.encoding_name = NULL
|
348
|
+
},
|
349
|
+
node,
|
350
|
+
pm_compare_integer_nodes
|
351
|
+
);
|
327
352
|
case PM_FLOAT_NODE:
|
328
|
-
return pm_node_hash_insert(
|
353
|
+
return pm_node_hash_insert(
|
354
|
+
&literals->float_nodes,
|
355
|
+
&(pm_static_literals_metadata_t) {
|
356
|
+
.newline_list = newline_list,
|
357
|
+
.start_line = start_line,
|
358
|
+
.encoding_name = NULL
|
359
|
+
},
|
360
|
+
node,
|
361
|
+
pm_compare_float_nodes
|
362
|
+
);
|
329
363
|
case PM_RATIONAL_NODE:
|
330
364
|
case PM_IMAGINARY_NODE:
|
331
|
-
return pm_node_hash_insert(
|
365
|
+
return pm_node_hash_insert(
|
366
|
+
&literals->number_nodes,
|
367
|
+
&(pm_static_literals_metadata_t) {
|
368
|
+
.newline_list = newline_list,
|
369
|
+
.start_line = start_line,
|
370
|
+
.encoding_name = NULL
|
371
|
+
},
|
372
|
+
node,
|
373
|
+
pm_compare_number_nodes
|
374
|
+
);
|
332
375
|
case PM_STRING_NODE:
|
333
376
|
case PM_SOURCE_FILE_NODE:
|
334
|
-
return pm_node_hash_insert(
|
377
|
+
return pm_node_hash_insert(
|
378
|
+
&literals->string_nodes,
|
379
|
+
&(pm_static_literals_metadata_t) {
|
380
|
+
.newline_list = newline_list,
|
381
|
+
.start_line = start_line,
|
382
|
+
.encoding_name = NULL
|
383
|
+
},
|
384
|
+
node,
|
385
|
+
pm_compare_string_nodes
|
386
|
+
);
|
335
387
|
case PM_REGULAR_EXPRESSION_NODE:
|
336
|
-
return pm_node_hash_insert(
|
388
|
+
return pm_node_hash_insert(
|
389
|
+
&literals->regexp_nodes,
|
390
|
+
&(pm_static_literals_metadata_t) {
|
391
|
+
.newline_list = newline_list,
|
392
|
+
.start_line = start_line,
|
393
|
+
.encoding_name = NULL
|
394
|
+
},
|
395
|
+
node,
|
396
|
+
pm_compare_regular_expression_nodes
|
397
|
+
);
|
337
398
|
case PM_SYMBOL_NODE:
|
338
|
-
return pm_node_hash_insert(
|
399
|
+
return pm_node_hash_insert(
|
400
|
+
&literals->symbol_nodes,
|
401
|
+
&(pm_static_literals_metadata_t) {
|
402
|
+
.newline_list = newline_list,
|
403
|
+
.start_line = start_line,
|
404
|
+
.encoding_name = NULL
|
405
|
+
},
|
406
|
+
node,
|
407
|
+
pm_compare_string_nodes
|
408
|
+
);
|
339
409
|
case PM_TRUE_NODE: {
|
340
410
|
pm_node_t *duplicated = literals->true_node;
|
341
411
|
literals->true_node = node;
|
@@ -435,8 +505,8 @@ pm_rational_inspect(pm_buffer_t *buffer, pm_rational_node_t *node) {
|
|
435
505
|
/**
|
436
506
|
* Create a string-based representation of the given static literal.
|
437
507
|
*/
|
438
|
-
|
439
|
-
|
508
|
+
static inline void
|
509
|
+
pm_static_literal_inspect_node(pm_buffer_t *buffer, const pm_static_literals_metadata_t *metadata, const pm_node_t *node) {
|
440
510
|
switch (PM_NODE_TYPE(node)) {
|
441
511
|
case PM_FALSE_NODE:
|
442
512
|
pm_buffer_append_string(buffer, "false", 5);
|
@@ -473,7 +543,7 @@ pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const
|
|
473
543
|
const pm_node_t *numeric = ((const pm_imaginary_node_t *) node)->numeric;
|
474
544
|
pm_buffer_append_string(buffer, "(0", 2);
|
475
545
|
if (pm_static_literal_positive_p(numeric)) pm_buffer_append_byte(buffer, '+');
|
476
|
-
|
546
|
+
pm_static_literal_inspect_node(buffer, metadata, numeric);
|
477
547
|
if (PM_NODE_TYPE_P(numeric, PM_RATIONAL_NODE)) pm_buffer_append_byte(buffer, '*');
|
478
548
|
pm_buffer_append_string(buffer, "i)", 2);
|
479
549
|
break;
|
@@ -490,7 +560,7 @@ pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const
|
|
490
560
|
switch (PM_NODE_TYPE(numeric)) {
|
491
561
|
case PM_INTEGER_NODE:
|
492
562
|
pm_buffer_append_byte(buffer, '(');
|
493
|
-
|
563
|
+
pm_static_literal_inspect_node(buffer, metadata, numeric);
|
494
564
|
pm_buffer_append_string(buffer, "/1)", 3);
|
495
565
|
break;
|
496
566
|
case PM_FLOAT_NODE:
|
@@ -517,7 +587,7 @@ pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const
|
|
517
587
|
break;
|
518
588
|
}
|
519
589
|
case PM_SOURCE_ENCODING_NODE:
|
520
|
-
pm_buffer_append_format(buffer, "#<Encoding:%s>",
|
590
|
+
pm_buffer_append_format(buffer, "#<Encoding:%s>", metadata->encoding_name);
|
521
591
|
break;
|
522
592
|
case PM_SOURCE_FILE_NODE: {
|
523
593
|
const pm_string_t *filepath = &((const pm_source_file_node_t *) node)->filepath;
|
@@ -527,7 +597,7 @@ pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const
|
|
527
597
|
break;
|
528
598
|
}
|
529
599
|
case PM_SOURCE_LINE_NODE:
|
530
|
-
pm_buffer_append_format(buffer, "%d", pm_newline_list_line_column(
|
600
|
+
pm_buffer_append_format(buffer, "%d", pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line).line);
|
531
601
|
break;
|
532
602
|
case PM_STRING_NODE: {
|
533
603
|
const pm_string_t *unescaped = &((const pm_string_node_t *) node)->unescaped;
|
@@ -550,3 +620,19 @@ pm_static_literal_inspect(pm_buffer_t *buffer, const pm_parser_t *parser, const
|
|
550
620
|
break;
|
551
621
|
}
|
552
622
|
}
|
623
|
+
|
624
|
+
/**
|
625
|
+
* Create a string-based representation of the given static literal.
|
626
|
+
*/
|
627
|
+
PRISM_EXPORTED_FUNCTION void
|
628
|
+
pm_static_literal_inspect(pm_buffer_t *buffer, const pm_newline_list_t *newline_list, int32_t start_line, const char *encoding_name, const pm_node_t *node) {
|
629
|
+
pm_static_literal_inspect_node(
|
630
|
+
buffer,
|
631
|
+
&(pm_static_literals_metadata_t) {
|
632
|
+
.newline_list = newline_list,
|
633
|
+
.start_line = start_line,
|
634
|
+
.encoding_name = encoding_name
|
635
|
+
},
|
636
|
+
node
|
637
|
+
);
|
638
|
+
}
|
data/src/token_type.c
CHANGED
@@ -462,9 +462,9 @@ pm_token_type_human(pm_token_type_t token_type) {
|
|
462
462
|
case PM_TOKEN_GREATER_EQUAL:
|
463
463
|
return "'>='";
|
464
464
|
case PM_TOKEN_GREATER_GREATER:
|
465
|
-
return "
|
465
|
+
return ">>";
|
466
466
|
case PM_TOKEN_GREATER_GREATER_EQUAL:
|
467
|
-
return "
|
467
|
+
return ">>=";
|
468
468
|
case PM_TOKEN_HEREDOC_END:
|
469
469
|
return "heredoc ending";
|
470
470
|
case PM_TOKEN_HEREDOC_START:
|
@@ -590,9 +590,9 @@ pm_token_type_human(pm_token_type_t token_type) {
|
|
590
590
|
case PM_TOKEN_LESS_EQUAL_GREATER:
|
591
591
|
return "'<=>'";
|
592
592
|
case PM_TOKEN_LESS_LESS:
|
593
|
-
return "
|
593
|
+
return "<<";
|
594
594
|
case PM_TOKEN_LESS_LESS_EQUAL:
|
595
|
-
return "
|
595
|
+
return "<<=";
|
596
596
|
case PM_TOKEN_METHOD_NAME:
|
597
597
|
return "method name";
|
598
598
|
case PM_TOKEN_MINUS:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -81,17 +81,18 @@ files:
|
|
81
81
|
- lib/prism/dot_visitor.rb
|
82
82
|
- lib/prism/dsl.rb
|
83
83
|
- lib/prism/ffi.rb
|
84
|
+
- lib/prism/inspect_visitor.rb
|
84
85
|
- lib/prism/lex_compat.rb
|
85
86
|
- lib/prism/mutation_compiler.rb
|
86
87
|
- lib/prism/node.rb
|
87
88
|
- lib/prism/node_ext.rb
|
88
|
-
- lib/prism/node_inspector.rb
|
89
89
|
- lib/prism/pack.rb
|
90
90
|
- lib/prism/parse_result.rb
|
91
91
|
- lib/prism/parse_result/comments.rb
|
92
92
|
- lib/prism/parse_result/newlines.rb
|
93
93
|
- lib/prism/pattern.rb
|
94
|
-
- lib/prism/polyfill/
|
94
|
+
- lib/prism/polyfill/byteindex.rb
|
95
|
+
- lib/prism/polyfill/unpack1.rb
|
95
96
|
- lib/prism/reflection.rb
|
96
97
|
- lib/prism/serialize.rb
|
97
98
|
- lib/prism/translation.rb
|
@@ -109,25 +110,22 @@ files:
|
|
109
110
|
- prism.gemspec
|
110
111
|
- rbi/prism.rbi
|
111
112
|
- rbi/prism/compiler.rbi
|
112
|
-
- rbi/prism/
|
113
|
-
- rbi/prism/mutation_compiler.rbi
|
113
|
+
- rbi/prism/inspect_visitor.rbi
|
114
114
|
- rbi/prism/node.rbi
|
115
115
|
- rbi/prism/node_ext.rbi
|
116
116
|
- rbi/prism/parse_result.rbi
|
117
117
|
- rbi/prism/reflection.rbi
|
118
118
|
- rbi/prism/translation/parser.rbi
|
119
|
-
- rbi/prism/translation/parser/compiler.rbi
|
120
119
|
- rbi/prism/translation/parser33.rbi
|
121
120
|
- rbi/prism/translation/parser34.rbi
|
122
121
|
- rbi/prism/translation/ripper.rbi
|
123
|
-
- rbi/prism/translation/ripper/ripper_compiler.rbi
|
124
|
-
- rbi/prism/translation/ruby_parser.rbi
|
125
122
|
- rbi/prism/visitor.rbi
|
126
123
|
- sig/prism.rbs
|
127
124
|
- sig/prism/compiler.rbs
|
128
125
|
- sig/prism/dispatcher.rbs
|
129
126
|
- sig/prism/dot_visitor.rbs
|
130
127
|
- sig/prism/dsl.rbs
|
128
|
+
- sig/prism/inspect_visitor.rbs
|
131
129
|
- sig/prism/mutation_compiler.rbs
|
132
130
|
- sig/prism/node.rbs
|
133
131
|
- sig/prism/node_ext.rbs
|
data/lib/prism/node_inspector.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Prism
|
4
|
-
# This object is responsible for generating the output for the inspect method
|
5
|
-
# implementations of child nodes.
|
6
|
-
class NodeInspector # :nodoc:
|
7
|
-
attr_reader :prefix, :output
|
8
|
-
|
9
|
-
def initialize(prefix = "")
|
10
|
-
@prefix = prefix
|
11
|
-
@output = +""
|
12
|
-
end
|
13
|
-
|
14
|
-
# Appends a line to the output with the current prefix.
|
15
|
-
def <<(line)
|
16
|
-
output << "#{prefix}#{line}"
|
17
|
-
end
|
18
|
-
|
19
|
-
# This generates a string that is used as the header of the inspect output
|
20
|
-
# for any given node.
|
21
|
-
def header(node)
|
22
|
-
output = +"@ #{node.class.name.split("::").last} ("
|
23
|
-
output << "location: (#{node.location.start_line},#{node.location.start_column})-(#{node.location.end_line},#{node.location.end_column})"
|
24
|
-
output << ", newline: true" if node.newline?
|
25
|
-
output << ")\n"
|
26
|
-
output
|
27
|
-
end
|
28
|
-
|
29
|
-
# Generates a string that represents a list of nodes. It handles properly
|
30
|
-
# using the box drawing characters to make the output look nice.
|
31
|
-
def list(prefix, nodes)
|
32
|
-
output = +"(length: #{nodes.length})\n"
|
33
|
-
last_index = nodes.length - 1
|
34
|
-
|
35
|
-
nodes.each_with_index do |node, index|
|
36
|
-
pointer, preadd = (index == last_index) ? ["└── ", " "] : ["├── ", "│ "]
|
37
|
-
node_prefix = "#{prefix}#{preadd}"
|
38
|
-
output << node.inspect(NodeInspector.new(node_prefix)).sub(node_prefix, "#{prefix}#{pointer}")
|
39
|
-
end
|
40
|
-
|
41
|
-
output
|
42
|
-
end
|
43
|
-
|
44
|
-
# Generates a string that represents a location field on a node.
|
45
|
-
def location(value)
|
46
|
-
if value
|
47
|
-
"(#{value.start_line},#{value.start_column})-(#{value.end_line},#{value.end_column}) = #{value.slice.inspect}"
|
48
|
-
else
|
49
|
-
"∅"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Generates a string that represents a child node.
|
54
|
-
def child_node(node, append)
|
55
|
-
node.inspect(child_inspector(append)).delete_prefix(prefix)
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns a new inspector that can be used to inspect a child node.
|
59
|
-
def child_inspector(append)
|
60
|
-
NodeInspector.new("#{prefix}#{append}")
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns the output as a string.
|
64
|
-
def to_str
|
65
|
-
output
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Polyfill for String#unpack1 with the offset parameter.
|
4
|
-
if String.instance_method(:unpack1).parameters.none? { |_, name| name == :offset }
|
5
|
-
String.prepend(
|
6
|
-
Module.new {
|
7
|
-
def unpack1(format, offset: 0) # :nodoc:
|
8
|
-
offset == 0 ? super(format) : self[offset..].unpack1(format) # steep:ignore
|
9
|
-
end
|
10
|
-
}
|
11
|
-
)
|
12
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
# We keep these shims in here because our client libraries might not have
|
4
|
-
# ast/parser in their bundle.
|
5
|
-
module AST; end
|
6
|
-
class AST::Node; end
|
7
|
-
module Parser; end
|
8
|
-
module Parser::AST; end
|
9
|
-
class Parser::AST::Node < AST::Node; end
|
10
|
-
|
11
|
-
class Prism::Translation::Parser::Compiler < Prism::Compiler
|
12
|
-
Result = type_member { { fixed: Parser::AST::Node } }
|
13
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
# We keep this shim in here because our client libraries might not have
|
4
|
-
# ruby_parser in their bundle.
|
5
|
-
class Sexp < ::Array
|
6
|
-
Elem = type_member { { fixed: T.untyped }}
|
7
|
-
end
|
8
|
-
|
9
|
-
class Prism::Translation::RubyParser::Compiler < Prism::Compiler
|
10
|
-
Result = type_member { { fixed: Sexp } }
|
11
|
-
end
|