prism 0.29.0 → 1.3.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 +115 -1
- data/CONTRIBUTING.md +0 -4
- data/Makefile +1 -1
- data/README.md +4 -0
- data/config.yml +920 -148
- data/docs/build_system.md +8 -11
- data/docs/fuzzing.md +1 -1
- data/docs/parsing_rules.md +4 -1
- data/docs/relocation.md +34 -0
- data/docs/ripper_translation.md +22 -0
- data/docs/serialization.md +3 -0
- data/ext/prism/api_node.c +2863 -2079
- data/ext/prism/extconf.rb +14 -37
- data/ext/prism/extension.c +241 -391
- data/ext/prism/extension.h +2 -2
- data/include/prism/ast.h +2156 -453
- data/include/prism/defines.h +58 -7
- data/include/prism/diagnostic.h +24 -6
- data/include/prism/node.h +0 -21
- data/include/prism/options.h +94 -3
- data/include/prism/parser.h +82 -40
- data/include/prism/regexp.h +18 -8
- data/include/prism/static_literals.h +3 -2
- data/include/prism/util/pm_char.h +1 -2
- data/include/prism/util/pm_constant_pool.h +0 -8
- data/include/prism/util/pm_integer.h +22 -15
- data/include/prism/util/pm_newline_list.h +11 -0
- data/include/prism/util/pm_string.h +28 -12
- data/include/prism/version.h +3 -3
- data/include/prism.h +47 -11
- data/lib/prism/compiler.rb +3 -0
- data/lib/prism/desugar_compiler.rb +111 -74
- data/lib/prism/dispatcher.rb +16 -1
- data/lib/prism/dot_visitor.rb +55 -34
- data/lib/prism/dsl.rb +660 -468
- data/lib/prism/ffi.rb +113 -8
- data/lib/prism/inspect_visitor.rb +296 -64
- data/lib/prism/lex_compat.rb +1 -1
- data/lib/prism/mutation_compiler.rb +11 -6
- data/lib/prism/node.rb +4262 -5023
- data/lib/prism/node_ext.rb +91 -14
- data/lib/prism/parse_result/comments.rb +0 -7
- data/lib/prism/parse_result/errors.rb +65 -0
- data/lib/prism/parse_result/newlines.rb +101 -11
- data/lib/prism/parse_result.rb +183 -6
- data/lib/prism/reflection.rb +12 -10
- data/lib/prism/relocation.rb +504 -0
- data/lib/prism/serialize.rb +496 -609
- data/lib/prism/string_query.rb +30 -0
- data/lib/prism/translation/parser/compiler.rb +185 -155
- data/lib/prism/translation/parser/lexer.rb +26 -4
- data/lib/prism/translation/parser.rb +9 -4
- data/lib/prism/translation/ripper.rb +23 -25
- data/lib/prism/translation/ruby_parser.rb +86 -17
- data/lib/prism/visitor.rb +3 -0
- data/lib/prism.rb +6 -8
- data/prism.gemspec +9 -5
- data/rbi/prism/dsl.rbi +521 -0
- data/rbi/prism/node.rbi +1115 -1120
- data/rbi/prism/parse_result.rbi +29 -0
- data/rbi/prism/string_query.rbi +12 -0
- data/rbi/prism/visitor.rbi +3 -0
- data/rbi/prism.rbi +36 -30
- data/sig/prism/dsl.rbs +190 -303
- data/sig/prism/mutation_compiler.rbs +1 -0
- data/sig/prism/node.rbs +678 -632
- data/sig/prism/parse_result.rbs +22 -0
- data/sig/prism/relocation.rbs +185 -0
- data/sig/prism/string_query.rbs +11 -0
- data/sig/prism/visitor.rbs +1 -0
- data/sig/prism.rbs +103 -64
- data/src/diagnostic.c +64 -28
- data/src/node.c +502 -1739
- data/src/options.c +76 -27
- data/src/prettyprint.c +188 -112
- data/src/prism.c +3376 -2293
- data/src/regexp.c +208 -71
- data/src/serialize.c +182 -50
- data/src/static_literals.c +64 -85
- data/src/token_type.c +4 -4
- data/src/util/pm_char.c +1 -1
- data/src/util/pm_constant_pool.c +0 -8
- data/src/util/pm_integer.c +53 -25
- data/src/util/pm_newline_list.c +29 -0
- data/src/util/pm_string.c +131 -80
- data/src/util/pm_strpbrk.c +32 -6
- metadata +11 -7
- data/include/prism/util/pm_string_list.h +0 -44
- data/lib/prism/debug.rb +0 -249
- data/lib/prism/translation/parser/rubocop.rb +0 -73
- data/src/util/pm_string_list.c +0 -28
data/ext/prism/extension.c
CHANGED
@@ -21,38 +21,36 @@ VALUE rb_cPrismParseError;
|
|
21
21
|
VALUE rb_cPrismParseWarning;
|
22
22
|
VALUE rb_cPrismResult;
|
23
23
|
VALUE rb_cPrismParseResult;
|
24
|
+
VALUE rb_cPrismLexResult;
|
24
25
|
VALUE rb_cPrismParseLexResult;
|
26
|
+
VALUE rb_cPrismStringQuery;
|
25
27
|
|
26
28
|
VALUE rb_cPrismDebugEncoding;
|
27
29
|
|
28
|
-
ID
|
29
|
-
ID
|
30
|
-
ID
|
31
|
-
ID
|
32
|
-
ID
|
33
|
-
ID
|
34
|
-
ID
|
35
|
-
ID
|
30
|
+
ID rb_id_option_command_line;
|
31
|
+
ID rb_id_option_encoding;
|
32
|
+
ID rb_id_option_filepath;
|
33
|
+
ID rb_id_option_frozen_string_literal;
|
34
|
+
ID rb_id_option_line;
|
35
|
+
ID rb_id_option_main_script;
|
36
|
+
ID rb_id_option_partial_script;
|
37
|
+
ID rb_id_option_scopes;
|
38
|
+
ID rb_id_option_version;
|
39
|
+
ID rb_id_source_for;
|
36
40
|
|
37
41
|
/******************************************************************************/
|
38
42
|
/* IO of Ruby code */
|
39
43
|
/******************************************************************************/
|
40
44
|
|
41
45
|
/**
|
42
|
-
* Check if the given VALUE is a string. If it's
|
43
|
-
*
|
44
|
-
* string.
|
46
|
+
* Check if the given VALUE is a string. If it's not a string, then raise a
|
47
|
+
* TypeError. Otherwise return the VALUE as a C string.
|
45
48
|
*/
|
46
49
|
static const char *
|
47
50
|
check_string(VALUE value) {
|
48
|
-
// If the value is nil, then we don't need to do anything.
|
49
|
-
if (NIL_P(value)) {
|
50
|
-
return NULL;
|
51
|
-
}
|
52
|
-
|
53
51
|
// Check if the value is a string. If it's not, then raise a type error.
|
54
52
|
if (!RB_TYPE_P(value, T_STRING)) {
|
55
|
-
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(value));
|
53
|
+
rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(value));
|
56
54
|
}
|
57
55
|
|
58
56
|
// Otherwise, return the value as a C string.
|
@@ -66,7 +64,7 @@ static void
|
|
66
64
|
input_load_string(pm_string_t *input, VALUE string) {
|
67
65
|
// Check if the string is a string. If it's not, then raise a type error.
|
68
66
|
if (!RB_TYPE_P(string, T_STRING)) {
|
69
|
-
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(string));
|
67
|
+
rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(string));
|
70
68
|
}
|
71
69
|
|
72
70
|
pm_string_constant_init(input, RSTRING_PTR(string), RSTRING_LEN(string));
|
@@ -135,15 +133,21 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
|
|
135
133
|
pm_options_t *options = (pm_options_t *) argument;
|
136
134
|
ID key_id = SYM2ID(key);
|
137
135
|
|
138
|
-
if (key_id ==
|
136
|
+
if (key_id == rb_id_option_filepath) {
|
139
137
|
if (!NIL_P(value)) pm_options_filepath_set(options, check_string(value));
|
140
|
-
} else if (key_id ==
|
141
|
-
if (!NIL_P(value))
|
142
|
-
|
138
|
+
} else if (key_id == rb_id_option_encoding) {
|
139
|
+
if (!NIL_P(value)) {
|
140
|
+
if (value == Qfalse) {
|
141
|
+
pm_options_encoding_locked_set(options, true);
|
142
|
+
} else {
|
143
|
+
pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
|
144
|
+
}
|
145
|
+
}
|
146
|
+
} else if (key_id == rb_id_option_line) {
|
143
147
|
if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value));
|
144
|
-
} else if (key_id ==
|
148
|
+
} else if (key_id == rb_id_option_frozen_string_literal) {
|
145
149
|
if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, RTEST(value));
|
146
|
-
} else if (key_id ==
|
150
|
+
} else if (key_id == rb_id_option_version) {
|
147
151
|
if (!NIL_P(value)) {
|
148
152
|
const char *version = check_string(value);
|
149
153
|
|
@@ -151,9 +155,9 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
|
|
151
155
|
rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value);
|
152
156
|
}
|
153
157
|
}
|
154
|
-
} else if (key_id ==
|
158
|
+
} else if (key_id == rb_id_option_scopes) {
|
155
159
|
if (!NIL_P(value)) build_options_scopes(options, value);
|
156
|
-
} else if (key_id ==
|
160
|
+
} else if (key_id == rb_id_option_command_line) {
|
157
161
|
if (!NIL_P(value)) {
|
158
162
|
const char *string = check_string(value);
|
159
163
|
uint8_t command_line = 0;
|
@@ -172,6 +176,10 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
|
|
172
176
|
|
173
177
|
pm_options_command_line_set(options, command_line);
|
174
178
|
}
|
179
|
+
} else if (key_id == rb_id_option_main_script) {
|
180
|
+
if (!NIL_P(value)) pm_options_main_script_set(options, RTEST(value));
|
181
|
+
} else if (key_id == rb_id_option_partial_script) {
|
182
|
+
if (!NIL_P(value)) pm_options_partial_script_set(options, RTEST(value));
|
175
183
|
} else {
|
176
184
|
rb_raise(rb_eArgError, "unknown keyword: %" PRIsVALUE, key);
|
177
185
|
}
|
@@ -206,6 +214,7 @@ build_options(VALUE argument) {
|
|
206
214
|
static void
|
207
215
|
extract_options(pm_options_t *options, VALUE filepath, VALUE keywords) {
|
208
216
|
options->line = 1; // default
|
217
|
+
|
209
218
|
if (!NIL_P(keywords)) {
|
210
219
|
struct build_options_data data = { .options = options, .keywords = keywords };
|
211
220
|
struct build_options_data *argument = &data;
|
@@ -246,27 +255,41 @@ string_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options)
|
|
246
255
|
* Read options for methods that look like (filepath, **options).
|
247
256
|
*/
|
248
257
|
static void
|
249
|
-
file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) {
|
258
|
+
file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options, VALUE *encoded_filepath) {
|
250
259
|
VALUE filepath;
|
251
260
|
VALUE keywords;
|
252
261
|
rb_scan_args(argc, argv, "1:", &filepath, &keywords);
|
253
262
|
|
254
263
|
Check_Type(filepath, T_STRING);
|
264
|
+
*encoded_filepath = rb_str_encode_ospath(filepath);
|
265
|
+
extract_options(options, *encoded_filepath, keywords);
|
255
266
|
|
256
|
-
|
257
|
-
|
258
|
-
const char * string_source = (const char *) pm_string_source(&options->filepath);
|
267
|
+
const char *source = (const char *) pm_string_source(&options->filepath);
|
268
|
+
pm_string_init_result_t result;
|
259
269
|
|
260
|
-
|
261
|
-
|
270
|
+
switch (result = pm_string_file_init(input, source)) {
|
271
|
+
case PM_STRING_INIT_SUCCESS:
|
272
|
+
break;
|
273
|
+
case PM_STRING_INIT_ERROR_GENERIC: {
|
274
|
+
pm_options_free(options);
|
262
275
|
|
263
276
|
#ifdef _WIN32
|
264
|
-
|
277
|
+
int e = rb_w32_map_errno(GetLastError());
|
265
278
|
#else
|
266
|
-
|
279
|
+
int e = errno;
|
267
280
|
#endif
|
268
281
|
|
269
|
-
|
282
|
+
rb_syserr_fail(e, source);
|
283
|
+
break;
|
284
|
+
}
|
285
|
+
case PM_STRING_INIT_ERROR_DIRECTORY:
|
286
|
+
pm_options_free(options);
|
287
|
+
rb_syserr_fail(EISDIR, source);
|
288
|
+
break;
|
289
|
+
default:
|
290
|
+
pm_options_free(options);
|
291
|
+
rb_raise(rb_eRuntimeError, "Unknown error (%d) initializing file: %s", result, source);
|
292
|
+
break;
|
270
293
|
}
|
271
294
|
}
|
272
295
|
|
@@ -344,7 +367,8 @@ dump_file(int argc, VALUE *argv, VALUE self) {
|
|
344
367
|
pm_string_t input;
|
345
368
|
pm_options_t options = { 0 };
|
346
369
|
|
347
|
-
|
370
|
+
VALUE encoded_filepath;
|
371
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
348
372
|
|
349
373
|
VALUE value = dump_input(&input, &options);
|
350
374
|
pm_string_free(&input);
|
@@ -364,7 +388,7 @@ dump_file(int argc, VALUE *argv, VALUE self) {
|
|
364
388
|
*/
|
365
389
|
static VALUE
|
366
390
|
parser_comments(pm_parser_t *parser, VALUE source) {
|
367
|
-
VALUE comments =
|
391
|
+
VALUE comments = rb_ary_new_capa(parser->comment_list.size);
|
368
392
|
|
369
393
|
for (pm_comment_t *comment = (pm_comment_t *) parser->comment_list.head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
|
370
394
|
VALUE location_argv[] = {
|
@@ -386,7 +410,7 @@ parser_comments(pm_parser_t *parser, VALUE source) {
|
|
386
410
|
*/
|
387
411
|
static VALUE
|
388
412
|
parser_magic_comments(pm_parser_t *parser, VALUE source) {
|
389
|
-
VALUE magic_comments =
|
413
|
+
VALUE magic_comments = rb_ary_new_capa(parser->magic_comment_list.size);
|
390
414
|
|
391
415
|
for (pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) parser->magic_comment_list.head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
|
392
416
|
VALUE key_loc_argv[] = {
|
@@ -436,7 +460,7 @@ parser_data_loc(const pm_parser_t *parser, VALUE source) {
|
|
436
460
|
*/
|
437
461
|
static VALUE
|
438
462
|
parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
|
439
|
-
VALUE errors =
|
463
|
+
VALUE errors = rb_ary_new_capa(parser->error_list.size);
|
440
464
|
pm_diagnostic_t *error;
|
441
465
|
|
442
466
|
for (error = (pm_diagnostic_t *) parser->error_list.head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
|
@@ -479,7 +503,7 @@ parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
|
|
479
503
|
*/
|
480
504
|
static VALUE
|
481
505
|
parser_warnings(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
|
482
|
-
VALUE warnings =
|
506
|
+
VALUE warnings = rb_ary_new_capa(parser->warning_list.size);
|
483
507
|
pm_diagnostic_t *warning;
|
484
508
|
|
485
509
|
for (warning = (pm_diagnostic_t *) parser->warning_list.head; warning != NULL; warning = (pm_diagnostic_t *) warning->node.next) {
|
@@ -556,9 +580,10 @@ static void
|
|
556
580
|
parse_lex_token(void *data, pm_parser_t *parser, pm_token_t *token) {
|
557
581
|
parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data;
|
558
582
|
|
559
|
-
VALUE yields =
|
560
|
-
|
561
|
-
|
583
|
+
VALUE yields = rb_assoc_new(
|
584
|
+
pm_token_new(parser, token, parse_lex_data->encoding, parse_lex_data->source),
|
585
|
+
INT2FIX(parser->lex_state)
|
586
|
+
);
|
562
587
|
|
563
588
|
rb_ary_push(parse_lex_data->tokens, yields);
|
564
589
|
}
|
@@ -599,8 +624,8 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
599
624
|
pm_parser_register_encoding_changed_callback(&parser, parse_lex_encoding_changed_callback);
|
600
625
|
|
601
626
|
VALUE source_string = rb_str_new((const char *) pm_string_source(input), pm_string_length(input));
|
602
|
-
VALUE offsets =
|
603
|
-
VALUE source = rb_funcall(rb_cPrismSource,
|
627
|
+
VALUE offsets = rb_ary_new_capa(parser.newline_list.size);
|
628
|
+
VALUE source = rb_funcall(rb_cPrismSource, rb_id_source_for, 3, source_string, LONG2NUM(parser.start_line), offsets);
|
604
629
|
|
605
630
|
parse_lex_data_t parse_lex_data = {
|
606
631
|
.source = source,
|
@@ -628,16 +653,16 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
628
653
|
rb_ary_push(offsets, ULONG2NUM(parser.newline_list.offsets[index]));
|
629
654
|
}
|
630
655
|
|
631
|
-
VALUE
|
656
|
+
VALUE result;
|
632
657
|
if (return_nodes) {
|
633
|
-
value = rb_ary_new_capa(2);
|
658
|
+
VALUE value = rb_ary_new_capa(2);
|
634
659
|
rb_ary_push(value, pm_ast_new(&parser, node, parse_lex_data.encoding, source));
|
635
660
|
rb_ary_push(value, parse_lex_data.tokens);
|
661
|
+
result = parse_result_create(rb_cPrismParseLexResult, &parser, value, parse_lex_data.encoding, source);
|
636
662
|
} else {
|
637
|
-
|
663
|
+
result = parse_result_create(rb_cPrismLexResult, &parser, parse_lex_data.tokens, parse_lex_data.encoding, source);
|
638
664
|
}
|
639
665
|
|
640
|
-
VALUE result = parse_result_create(rb_cPrismParseLexResult, &parser, value, parse_lex_data.encoding, source);
|
641
666
|
pm_node_destroy(&parser, node);
|
642
667
|
pm_parser_free(&parser);
|
643
668
|
|
@@ -646,10 +671,10 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
646
671
|
|
647
672
|
/**
|
648
673
|
* call-seq:
|
649
|
-
* Prism::lex(source, **options) ->
|
674
|
+
* Prism::lex(source, **options) -> LexResult
|
650
675
|
*
|
651
|
-
* Return an array of Token instances
|
652
|
-
* supported options, see Prism::parse.
|
676
|
+
* Return a LexResult instance that contains an array of Token instances
|
677
|
+
* corresponding to the given string. For supported options, see Prism::parse.
|
653
678
|
*/
|
654
679
|
static VALUE
|
655
680
|
lex(int argc, VALUE *argv, VALUE self) {
|
@@ -666,17 +691,18 @@ lex(int argc, VALUE *argv, VALUE self) {
|
|
666
691
|
|
667
692
|
/**
|
668
693
|
* call-seq:
|
669
|
-
* Prism::lex_file(filepath, **options) ->
|
694
|
+
* Prism::lex_file(filepath, **options) -> LexResult
|
670
695
|
*
|
671
|
-
* Return an array of Token instances
|
672
|
-
* supported options, see Prism::parse.
|
696
|
+
* Return a LexResult instance that contains an array of Token instances
|
697
|
+
* corresponding to the given file. For supported options, see Prism::parse.
|
673
698
|
*/
|
674
699
|
static VALUE
|
675
700
|
lex_file(int argc, VALUE *argv, VALUE self) {
|
676
701
|
pm_string_t input;
|
677
702
|
pm_options_t options = { 0 };
|
678
703
|
|
679
|
-
|
704
|
+
VALUE encoded_filepath;
|
705
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
680
706
|
|
681
707
|
VALUE value = parse_lex_input(&input, &options, false);
|
682
708
|
pm_string_free(&input);
|
@@ -728,14 +754,27 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
|
|
728
754
|
* has been set. This should be a boolean or nil.
|
729
755
|
* * `line` - the line number that the parse starts on. This should be an
|
730
756
|
* integer or nil. Note that this is 1-indexed.
|
757
|
+
* * `main_script` - a boolean indicating whether or not the source being parsed
|
758
|
+
* is the main script being run by the interpreter. This controls whether
|
759
|
+
* or not shebangs are parsed for additional flags and whether or not the
|
760
|
+
* parser will attempt to find a matching shebang if the first one does
|
761
|
+
* not contain the word "ruby".
|
762
|
+
* * `partial_script` - when the file being parsed is considered a "partial"
|
763
|
+
* script, jumps will not be marked as errors if they are not contained
|
764
|
+
* within loops/blocks. This is used in the case that you're parsing a
|
765
|
+
* script that you know will be embedded inside another script later, but
|
766
|
+
* you do not have that context yet. For example, when parsing an ERB
|
767
|
+
* template that will be evaluated inside another script.
|
731
768
|
* * `scopes` - the locals that are in scope surrounding the code that is being
|
732
769
|
* parsed. This should be an array of arrays of symbols or nil. Scopes are
|
733
770
|
* ordered from the outermost scope to the innermost one.
|
734
771
|
* * `version` - the version of Ruby syntax that prism should used to parse Ruby
|
735
772
|
* code. By default prism assumes you want to parse with the latest version
|
736
773
|
* of Ruby syntax (which you can trigger with `nil` or `"latest"`). You
|
737
|
-
* may also restrict the syntax to a specific version of Ruby.
|
738
|
-
*
|
774
|
+
* may also restrict the syntax to a specific version of Ruby, e.g., with `"3.3.0"`.
|
775
|
+
* To parse with the same syntax version that the current Ruby is running
|
776
|
+
* use `version: RUBY_VERSION`. Raises ArgumentError if the version is not
|
777
|
+
* currently supported by Prism.
|
739
778
|
*/
|
740
779
|
static VALUE
|
741
780
|
parse(int argc, VALUE *argv, VALUE self) {
|
@@ -761,6 +800,85 @@ parse(int argc, VALUE *argv, VALUE self) {
|
|
761
800
|
return value;
|
762
801
|
}
|
763
802
|
|
803
|
+
/**
|
804
|
+
* call-seq:
|
805
|
+
* Prism::parse_file(filepath, **options) -> ParseResult
|
806
|
+
*
|
807
|
+
* Parse the given file and return a ParseResult instance. For supported
|
808
|
+
* options, see Prism::parse.
|
809
|
+
*/
|
810
|
+
static VALUE
|
811
|
+
parse_file(int argc, VALUE *argv, VALUE self) {
|
812
|
+
pm_string_t input;
|
813
|
+
pm_options_t options = { 0 };
|
814
|
+
|
815
|
+
VALUE encoded_filepath;
|
816
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
817
|
+
|
818
|
+
VALUE value = parse_input(&input, &options);
|
819
|
+
pm_string_free(&input);
|
820
|
+
pm_options_free(&options);
|
821
|
+
|
822
|
+
return value;
|
823
|
+
}
|
824
|
+
|
825
|
+
/**
|
826
|
+
* Parse the given input and return nothing.
|
827
|
+
*/
|
828
|
+
static void
|
829
|
+
profile_input(pm_string_t *input, const pm_options_t *options) {
|
830
|
+
pm_parser_t parser;
|
831
|
+
pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
|
832
|
+
|
833
|
+
pm_node_t *node = pm_parse(&parser);
|
834
|
+
pm_node_destroy(&parser, node);
|
835
|
+
pm_parser_free(&parser);
|
836
|
+
}
|
837
|
+
|
838
|
+
/**
|
839
|
+
* call-seq:
|
840
|
+
* Prism::profile(source, **options) -> nil
|
841
|
+
*
|
842
|
+
* Parse the given string and return nothing. This method is meant to allow
|
843
|
+
* profilers to avoid the overhead of reifying the AST to Ruby. For supported
|
844
|
+
* options, see Prism::parse.
|
845
|
+
*/
|
846
|
+
static VALUE
|
847
|
+
profile(int argc, VALUE *argv, VALUE self) {
|
848
|
+
pm_string_t input;
|
849
|
+
pm_options_t options = { 0 };
|
850
|
+
|
851
|
+
string_options(argc, argv, &input, &options);
|
852
|
+
profile_input(&input, &options);
|
853
|
+
pm_string_free(&input);
|
854
|
+
pm_options_free(&options);
|
855
|
+
|
856
|
+
return Qnil;
|
857
|
+
}
|
858
|
+
|
859
|
+
/**
|
860
|
+
* call-seq:
|
861
|
+
* Prism::profile_file(filepath, **options) -> nil
|
862
|
+
*
|
863
|
+
* Parse the given file and return nothing. This method is meant to allow
|
864
|
+
* profilers to avoid the overhead of reifying the AST to Ruby. For supported
|
865
|
+
* options, see Prism::parse.
|
866
|
+
*/
|
867
|
+
static VALUE
|
868
|
+
profile_file(int argc, VALUE *argv, VALUE self) {
|
869
|
+
pm_string_t input;
|
870
|
+
pm_options_t options = { 0 };
|
871
|
+
|
872
|
+
VALUE encoded_filepath;
|
873
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
874
|
+
|
875
|
+
profile_input(&input, &options);
|
876
|
+
pm_string_free(&input);
|
877
|
+
pm_options_free(&options);
|
878
|
+
|
879
|
+
return Qnil;
|
880
|
+
}
|
881
|
+
|
764
882
|
/**
|
765
883
|
* An implementation of fgets that is suitable for use with Ruby IO objects.
|
766
884
|
*/
|
@@ -773,8 +891,8 @@ parse_stream_fgets(char *string, int size, void *stream) {
|
|
773
891
|
return NULL;
|
774
892
|
}
|
775
893
|
|
776
|
-
const char *cstr =
|
777
|
-
|
894
|
+
const char *cstr = RSTRING_PTR(line);
|
895
|
+
long length = RSTRING_LEN(line);
|
778
896
|
|
779
897
|
memcpy(string, cstr, length);
|
780
898
|
string[length] = '\0';
|
@@ -815,27 +933,6 @@ parse_stream(int argc, VALUE *argv, VALUE self) {
|
|
815
933
|
return result;
|
816
934
|
}
|
817
935
|
|
818
|
-
/**
|
819
|
-
* call-seq:
|
820
|
-
* Prism::parse_file(filepath, **options) -> ParseResult
|
821
|
-
*
|
822
|
-
* Parse the given file and return a ParseResult instance. For supported
|
823
|
-
* options, see Prism::parse.
|
824
|
-
*/
|
825
|
-
static VALUE
|
826
|
-
parse_file(int argc, VALUE *argv, VALUE self) {
|
827
|
-
pm_string_t input;
|
828
|
-
pm_options_t options = { 0 };
|
829
|
-
|
830
|
-
file_options(argc, argv, &input, &options);
|
831
|
-
|
832
|
-
VALUE value = parse_input(&input, &options);
|
833
|
-
pm_string_free(&input);
|
834
|
-
pm_options_free(&options);
|
835
|
-
|
836
|
-
return value;
|
837
|
-
}
|
838
|
-
|
839
936
|
/**
|
840
937
|
* Parse the given input and return an array of Comment objects.
|
841
938
|
*/
|
@@ -888,7 +985,8 @@ parse_file_comments(int argc, VALUE *argv, VALUE self) {
|
|
888
985
|
pm_string_t input;
|
889
986
|
pm_options_t options = { 0 };
|
890
987
|
|
891
|
-
|
988
|
+
VALUE encoded_filepath;
|
989
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
892
990
|
|
893
991
|
VALUE value = parse_input_comments(&input, &options);
|
894
992
|
pm_string_free(&input);
|
@@ -899,9 +997,9 @@ parse_file_comments(int argc, VALUE *argv, VALUE self) {
|
|
899
997
|
|
900
998
|
/**
|
901
999
|
* call-seq:
|
902
|
-
* Prism::parse_lex(source, **options) ->
|
1000
|
+
* Prism::parse_lex(source, **options) -> ParseLexResult
|
903
1001
|
*
|
904
|
-
* Parse the given string and return a
|
1002
|
+
* Parse the given string and return a ParseLexResult instance that contains a
|
905
1003
|
* 2-element array, where the first element is the AST and the second element is
|
906
1004
|
* an array of Token instances.
|
907
1005
|
*
|
@@ -926,9 +1024,9 @@ parse_lex(int argc, VALUE *argv, VALUE self) {
|
|
926
1024
|
|
927
1025
|
/**
|
928
1026
|
* call-seq:
|
929
|
-
* Prism::parse_lex_file(filepath, **options) ->
|
1027
|
+
* Prism::parse_lex_file(filepath, **options) -> ParseLexResult
|
930
1028
|
*
|
931
|
-
* Parse the given file and return a
|
1029
|
+
* Parse the given file and return a ParseLexResult instance that contains a
|
932
1030
|
* 2-element array, where the first element is the AST and the second element is
|
933
1031
|
* an array of Token instances.
|
934
1032
|
*
|
@@ -943,7 +1041,8 @@ parse_lex_file(int argc, VALUE *argv, VALUE self) {
|
|
943
1041
|
pm_string_t input;
|
944
1042
|
pm_options_t options = { 0 };
|
945
1043
|
|
946
|
-
|
1044
|
+
VALUE encoded_filepath;
|
1045
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
947
1046
|
|
948
1047
|
VALUE value = parse_lex_input(&input, &options, true);
|
949
1048
|
pm_string_free(&input);
|
@@ -1013,7 +1112,8 @@ parse_file_success_p(int argc, VALUE *argv, VALUE self) {
|
|
1013
1112
|
pm_string_t input;
|
1014
1113
|
pm_options_t options = { 0 };
|
1015
1114
|
|
1016
|
-
|
1115
|
+
VALUE encoded_filepath;
|
1116
|
+
file_options(argc, argv, &input, &options, &encoded_filepath);
|
1017
1117
|
|
1018
1118
|
VALUE result = parse_input_success_p(&input, &options);
|
1019
1119
|
pm_string_free(&input);
|
@@ -1035,300 +1135,65 @@ parse_file_failure_p(int argc, VALUE *argv, VALUE self) {
|
|
1035
1135
|
}
|
1036
1136
|
|
1037
1137
|
/******************************************************************************/
|
1038
|
-
/*
|
1138
|
+
/* String query methods */
|
1039
1139
|
/******************************************************************************/
|
1040
1140
|
|
1041
1141
|
/**
|
1042
|
-
* call
|
1043
|
-
*
|
1044
|
-
*
|
1045
|
-
* Returns an array of strings corresponding to the named capture groups in the
|
1046
|
-
* given source string. If prism was unable to parse the regular expression,
|
1047
|
-
* this function returns nil.
|
1048
|
-
*/
|
1049
|
-
static VALUE
|
1050
|
-
named_captures(VALUE self, VALUE source) {
|
1051
|
-
pm_string_list_t string_list = { 0 };
|
1052
|
-
|
1053
|
-
if (!pm_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, PM_ENCODING_UTF_8_ENTRY)) {
|
1054
|
-
pm_string_list_free(&string_list);
|
1055
|
-
return Qnil;
|
1056
|
-
}
|
1057
|
-
|
1058
|
-
VALUE names = rb_ary_new();
|
1059
|
-
for (size_t index = 0; index < string_list.length; index++) {
|
1060
|
-
const pm_string_t *string = &string_list.strings[index];
|
1061
|
-
rb_ary_push(names, rb_str_new((const char *) pm_string_source(string), pm_string_length(string)));
|
1062
|
-
}
|
1063
|
-
|
1064
|
-
pm_string_list_free(&string_list);
|
1065
|
-
return names;
|
1066
|
-
}
|
1067
|
-
|
1068
|
-
/**
|
1069
|
-
* call-seq:
|
1070
|
-
* Debug::integer_parse(source) -> [Integer, String]
|
1071
|
-
*
|
1072
|
-
* Parses the given source string and returns the integer it represents, as well
|
1073
|
-
* as a decimal string representation.
|
1074
|
-
*/
|
1075
|
-
static VALUE
|
1076
|
-
integer_parse(VALUE self, VALUE source) {
|
1077
|
-
const uint8_t *start = (const uint8_t *) RSTRING_PTR(source);
|
1078
|
-
size_t length = RSTRING_LEN(source);
|
1079
|
-
|
1080
|
-
pm_integer_t integer = { 0 };
|
1081
|
-
pm_integer_parse(&integer, PM_INTEGER_BASE_UNKNOWN, start, start + length);
|
1082
|
-
|
1083
|
-
pm_buffer_t buffer = { 0 };
|
1084
|
-
pm_integer_string(&buffer, &integer);
|
1085
|
-
|
1086
|
-
VALUE string = rb_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer));
|
1087
|
-
pm_buffer_free(&buffer);
|
1088
|
-
|
1089
|
-
VALUE result = rb_ary_new_capa(2);
|
1090
|
-
rb_ary_push(result, pm_integer_new(&integer));
|
1091
|
-
rb_ary_push(result, string);
|
1092
|
-
pm_integer_free(&integer);
|
1093
|
-
|
1094
|
-
return result;
|
1095
|
-
}
|
1096
|
-
|
1097
|
-
/**
|
1098
|
-
* call-seq:
|
1099
|
-
* Debug::memsize(source) -> { length: xx, memsize: xx, node_count: xx }
|
1100
|
-
*
|
1101
|
-
* Return a hash of information about the given source string's memory usage.
|
1102
|
-
*/
|
1103
|
-
static VALUE
|
1104
|
-
memsize(VALUE self, VALUE string) {
|
1105
|
-
pm_parser_t parser;
|
1106
|
-
size_t length = RSTRING_LEN(string);
|
1107
|
-
pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(string), length, NULL);
|
1108
|
-
|
1109
|
-
pm_node_t *node = pm_parse(&parser);
|
1110
|
-
pm_memsize_t memsize;
|
1111
|
-
pm_node_memsize(node, &memsize);
|
1112
|
-
|
1113
|
-
pm_node_destroy(&parser, node);
|
1114
|
-
pm_parser_free(&parser);
|
1115
|
-
|
1116
|
-
VALUE result = rb_hash_new();
|
1117
|
-
rb_hash_aset(result, ID2SYM(rb_intern("length")), INT2FIX(length));
|
1118
|
-
rb_hash_aset(result, ID2SYM(rb_intern("memsize")), INT2FIX(memsize.memsize));
|
1119
|
-
rb_hash_aset(result, ID2SYM(rb_intern("node_count")), INT2FIX(memsize.node_count));
|
1120
|
-
return result;
|
1121
|
-
}
|
1122
|
-
|
1123
|
-
/**
|
1124
|
-
* call-seq:
|
1125
|
-
* Debug::profile_file(filepath) -> nil
|
1126
|
-
*
|
1127
|
-
* Parse the file, but do nothing with the result. This is used to profile the
|
1128
|
-
* parser for memory and speed.
|
1142
|
+
* Process the result of a call to a string query method and return an
|
1143
|
+
* appropriate value.
|
1129
1144
|
*/
|
1130
1145
|
static VALUE
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
#else
|
1141
|
-
int e = errno;
|
1142
|
-
#endif
|
1143
|
-
|
1144
|
-
rb_syserr_fail(e, checked);
|
1146
|
+
string_query(pm_string_query_t result) {
|
1147
|
+
switch (result) {
|
1148
|
+
case PM_STRING_QUERY_ERROR:
|
1149
|
+
rb_raise(rb_eArgError, "Invalid or non ascii-compatible encoding");
|
1150
|
+
return Qfalse;
|
1151
|
+
case PM_STRING_QUERY_FALSE:
|
1152
|
+
return Qfalse;
|
1153
|
+
case PM_STRING_QUERY_TRUE:
|
1154
|
+
return Qtrue;
|
1145
1155
|
}
|
1146
|
-
|
1147
|
-
pm_options_t options = { 0 };
|
1148
|
-
pm_options_filepath_set(&options, checked);
|
1149
|
-
|
1150
|
-
pm_parser_t parser;
|
1151
|
-
pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
|
1152
|
-
|
1153
|
-
pm_node_t *node = pm_parse(&parser);
|
1154
|
-
pm_node_destroy(&parser, node);
|
1155
|
-
pm_parser_free(&parser);
|
1156
|
-
pm_options_free(&options);
|
1157
|
-
pm_string_free(&input);
|
1158
|
-
|
1159
|
-
return Qnil;
|
1156
|
+
return Qfalse;
|
1160
1157
|
}
|
1161
1158
|
|
1162
|
-
#ifndef PRISM_EXCLUDE_PRETTYPRINT
|
1163
|
-
|
1164
1159
|
/**
|
1165
1160
|
* call-seq:
|
1166
|
-
*
|
1161
|
+
* Prism::StringQuery::local?(string) -> bool
|
1167
1162
|
*
|
1168
|
-
*
|
1169
|
-
*
|
1163
|
+
* Returns true if the string constitutes a valid local variable name. Note that
|
1164
|
+
* this means the names that can be set through Binding#local_variable_set, not
|
1165
|
+
* necessarily the ones that can be set through a local variable assignment.
|
1170
1166
|
*/
|
1171
1167
|
static VALUE
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
pm_parser_t parser;
|
1177
|
-
pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), NULL);
|
1178
|
-
|
1179
|
-
pm_node_t *node = pm_parse(&parser);
|
1180
|
-
pm_buffer_t buffer = { 0 };
|
1181
|
-
|
1182
|
-
pm_prettyprint(&buffer, &parser, node);
|
1183
|
-
|
1184
|
-
rb_encoding *encoding = rb_enc_find(parser.encoding->name);
|
1185
|
-
VALUE string = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
|
1186
|
-
|
1187
|
-
pm_buffer_free(&buffer);
|
1188
|
-
pm_node_destroy(&parser, node);
|
1189
|
-
pm_parser_free(&parser);
|
1190
|
-
|
1191
|
-
return string;
|
1168
|
+
string_query_local_p(VALUE self, VALUE string) {
|
1169
|
+
const uint8_t *source = (const uint8_t *) check_string(string);
|
1170
|
+
return string_query(pm_string_query_local(source, RSTRING_LEN(string), rb_enc_get(string)->name));
|
1192
1171
|
}
|
1193
1172
|
|
1194
|
-
#endif
|
1195
|
-
|
1196
1173
|
/**
|
1197
1174
|
* call-seq:
|
1198
|
-
*
|
1175
|
+
* Prism::StringQuery::constant?(string) -> bool
|
1199
1176
|
*
|
1200
|
-
*
|
1177
|
+
* Returns true if the string constitutes a valid constant name. Note that this
|
1178
|
+
* means the names that can be set through Module#const_set, not necessarily the
|
1179
|
+
* ones that can be set through a constant assignment.
|
1201
1180
|
*/
|
1202
1181
|
static VALUE
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
pm_parser_t parser;
|
1208
|
-
pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), NULL);
|
1209
|
-
|
1210
|
-
pm_node_t *node = pm_parse(&parser);
|
1211
|
-
pm_buffer_t buffer = { 0 };
|
1212
|
-
|
1213
|
-
pm_parser_errors_format(&parser, &parser.error_list, &buffer, RTEST(colorize), true);
|
1214
|
-
|
1215
|
-
rb_encoding *encoding = rb_enc_find(parser.encoding->name);
|
1216
|
-
VALUE result = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
|
1217
|
-
|
1218
|
-
pm_buffer_free(&buffer);
|
1219
|
-
pm_node_destroy(&parser, node);
|
1220
|
-
pm_parser_free(&parser);
|
1221
|
-
pm_string_free(&input);
|
1222
|
-
|
1223
|
-
return result;
|
1182
|
+
string_query_constant_p(VALUE self, VALUE string) {
|
1183
|
+
const uint8_t *source = (const uint8_t *) check_string(string);
|
1184
|
+
return string_query(pm_string_query_constant(source, RSTRING_LEN(string), rb_enc_get(string)->name));
|
1224
1185
|
}
|
1225
1186
|
|
1226
1187
|
/**
|
1227
1188
|
* call-seq:
|
1228
|
-
*
|
1229
|
-
*
|
1230
|
-
* Inspect the node as it would be inspected by the warnings used in static
|
1231
|
-
* literal sets.
|
1232
|
-
*/
|
1233
|
-
static VALUE
|
1234
|
-
static_inspect(int argc, VALUE *argv, VALUE self) {
|
1235
|
-
pm_string_t input;
|
1236
|
-
pm_options_t options = { 0 };
|
1237
|
-
string_options(argc, argv, &input, &options);
|
1238
|
-
|
1239
|
-
pm_parser_t parser;
|
1240
|
-
pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
|
1241
|
-
|
1242
|
-
pm_node_t *program = pm_parse(&parser);
|
1243
|
-
pm_node_t *node = ((pm_program_node_t *) program)->statements->body.nodes[0];
|
1244
|
-
|
1245
|
-
pm_buffer_t buffer = { 0 };
|
1246
|
-
pm_static_literal_inspect(&buffer, &parser.newline_list, parser.start_line, parser.encoding->name, node);
|
1247
|
-
|
1248
|
-
rb_encoding *encoding = rb_enc_find(parser.encoding->name);
|
1249
|
-
VALUE result = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
|
1250
|
-
|
1251
|
-
pm_buffer_free(&buffer);
|
1252
|
-
pm_node_destroy(&parser, program);
|
1253
|
-
pm_parser_free(&parser);
|
1254
|
-
pm_string_free(&input);
|
1255
|
-
pm_options_free(&options);
|
1256
|
-
|
1257
|
-
return result;
|
1258
|
-
}
|
1259
|
-
|
1260
|
-
/**
|
1261
|
-
* call-seq: Debug::Encoding.all -> Array[Debug::Encoding]
|
1189
|
+
* Prism::StringQuery::method_name?(string) -> bool
|
1262
1190
|
*
|
1263
|
-
*
|
1191
|
+
* Returns true if the string constitutes a valid method name.
|
1264
1192
|
*/
|
1265
1193
|
static VALUE
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
for (size_t index = 0; index < PM_ENCODING_MAXIMUM; index++) {
|
1270
|
-
const pm_encoding_t *encoding = &pm_encodings[index];
|
1271
|
-
|
1272
|
-
VALUE encoding_argv[] = { rb_str_new_cstr(encoding->name), encoding->multibyte ? Qtrue : Qfalse };
|
1273
|
-
rb_ary_push(encodings, rb_class_new_instance(2, encoding_argv, rb_cPrismDebugEncoding));
|
1274
|
-
}
|
1275
|
-
|
1276
|
-
return encodings;
|
1277
|
-
}
|
1278
|
-
|
1279
|
-
static const pm_encoding_t *
|
1280
|
-
encoding_find(VALUE name) {
|
1281
|
-
const uint8_t *source = (const uint8_t *) RSTRING_PTR(name);
|
1282
|
-
size_t length = RSTRING_LEN(name);
|
1283
|
-
|
1284
|
-
const pm_encoding_t *encoding = pm_encoding_find(source, source + length);
|
1285
|
-
if (encoding == NULL) { rb_raise(rb_eArgError, "Unknown encoding: %s", source); }
|
1286
|
-
|
1287
|
-
return encoding;
|
1288
|
-
}
|
1289
|
-
|
1290
|
-
/**
|
1291
|
-
* call-seq: Debug::Encoding.width(source) -> Integer
|
1292
|
-
*
|
1293
|
-
* Returns the width of the first character in the given string if it is valid
|
1294
|
-
* in the encoding. If it is not, this function returns 0.
|
1295
|
-
*/
|
1296
|
-
static VALUE
|
1297
|
-
encoding_char_width(VALUE self, VALUE name, VALUE value) {
|
1298
|
-
return ULONG2NUM(encoding_find(name)->char_width((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)));
|
1299
|
-
}
|
1300
|
-
|
1301
|
-
/**
|
1302
|
-
* call-seq: Debug::Encoding.alnum?(source) -> true | false
|
1303
|
-
*
|
1304
|
-
* Returns true if the first character in the given string is an alphanumeric
|
1305
|
-
* character in the encoding.
|
1306
|
-
*/
|
1307
|
-
static VALUE
|
1308
|
-
encoding_alnum_char(VALUE self, VALUE name, VALUE value) {
|
1309
|
-
return encoding_find(name)->alnum_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) > 0 ? Qtrue : Qfalse;
|
1310
|
-
}
|
1311
|
-
|
1312
|
-
/**
|
1313
|
-
* call-seq: Debug::Encoding.alpha?(source) -> true | false
|
1314
|
-
*
|
1315
|
-
* Returns true if the first character in the given string is an alphabetic
|
1316
|
-
* character in the encoding.
|
1317
|
-
*/
|
1318
|
-
static VALUE
|
1319
|
-
encoding_alpha_char(VALUE self, VALUE name, VALUE value) {
|
1320
|
-
return encoding_find(name)->alpha_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) > 0 ? Qtrue : Qfalse;
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
/**
|
1324
|
-
* call-seq: Debug::Encoding.upper?(source) -> true | false
|
1325
|
-
*
|
1326
|
-
* Returns true if the first character in the given string is an uppercase
|
1327
|
-
* character in the encoding.
|
1328
|
-
*/
|
1329
|
-
static VALUE
|
1330
|
-
encoding_isupper_char(VALUE self, VALUE name, VALUE value) {
|
1331
|
-
return encoding_find(name)->isupper_char((const uint8_t *) RSTRING_PTR(value), RSTRING_LEN(value)) ? Qtrue : Qfalse;
|
1194
|
+
string_query_method_name_p(VALUE self, VALUE string) {
|
1195
|
+
const uint8_t *source = (const uint8_t *) check_string(string);
|
1196
|
+
return string_query(pm_string_query_method_name(source, RSTRING_LEN(string), rb_enc_get(string)->name));
|
1332
1197
|
}
|
1333
1198
|
|
1334
1199
|
/******************************************************************************/
|
@@ -1364,22 +1229,24 @@ Init_prism(void) {
|
|
1364
1229
|
rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject);
|
1365
1230
|
rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject);
|
1366
1231
|
rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject);
|
1367
|
-
|
1368
1232
|
rb_cPrismResult = rb_define_class_under(rb_cPrism, "Result", rb_cObject);
|
1369
1233
|
rb_cPrismParseResult = rb_define_class_under(rb_cPrism, "ParseResult", rb_cPrismResult);
|
1234
|
+
rb_cPrismLexResult = rb_define_class_under(rb_cPrism, "LexResult", rb_cPrismResult);
|
1370
1235
|
rb_cPrismParseLexResult = rb_define_class_under(rb_cPrism, "ParseLexResult", rb_cPrismResult);
|
1371
|
-
|
1372
|
-
|
1373
|
-
//
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1236
|
+
rb_cPrismStringQuery = rb_define_class_under(rb_cPrism, "StringQuery", rb_cObject);
|
1237
|
+
|
1238
|
+
// Intern all of the IDs eagerly that we support so that we don't have to do
|
1239
|
+
// it every time we parse.
|
1240
|
+
rb_id_option_command_line = rb_intern_const("command_line");
|
1241
|
+
rb_id_option_encoding = rb_intern_const("encoding");
|
1242
|
+
rb_id_option_filepath = rb_intern_const("filepath");
|
1243
|
+
rb_id_option_frozen_string_literal = rb_intern_const("frozen_string_literal");
|
1244
|
+
rb_id_option_line = rb_intern_const("line");
|
1245
|
+
rb_id_option_main_script = rb_intern_const("main_script");
|
1246
|
+
rb_id_option_partial_script = rb_intern_const("partial_script");
|
1247
|
+
rb_id_option_scopes = rb_intern_const("scopes");
|
1248
|
+
rb_id_option_version = rb_intern_const("version");
|
1249
|
+
rb_id_source_for = rb_intern("for");
|
1383
1250
|
|
1384
1251
|
/**
|
1385
1252
|
* The version of the prism library.
|
@@ -1390,8 +1257,10 @@ Init_prism(void) {
|
|
1390
1257
|
rb_define_singleton_method(rb_cPrism, "lex", lex, -1);
|
1391
1258
|
rb_define_singleton_method(rb_cPrism, "lex_file", lex_file, -1);
|
1392
1259
|
rb_define_singleton_method(rb_cPrism, "parse", parse, -1);
|
1393
|
-
rb_define_singleton_method(rb_cPrism, "parse_stream", parse_stream, -1);
|
1394
1260
|
rb_define_singleton_method(rb_cPrism, "parse_file", parse_file, -1);
|
1261
|
+
rb_define_singleton_method(rb_cPrism, "profile", profile, -1);
|
1262
|
+
rb_define_singleton_method(rb_cPrism, "profile_file", profile_file, -1);
|
1263
|
+
rb_define_singleton_method(rb_cPrism, "parse_stream", parse_stream, -1);
|
1395
1264
|
rb_define_singleton_method(rb_cPrism, "parse_comments", parse_comments, -1);
|
1396
1265
|
rb_define_singleton_method(rb_cPrism, "parse_file_comments", parse_file_comments, -1);
|
1397
1266
|
rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1);
|
@@ -1406,28 +1275,9 @@ Init_prism(void) {
|
|
1406
1275
|
rb_define_singleton_method(rb_cPrism, "dump_file", dump_file, -1);
|
1407
1276
|
#endif
|
1408
1277
|
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
rb_define_singleton_method(rb_cPrismDebug, "named_captures", named_captures, 1);
|
1413
|
-
rb_define_singleton_method(rb_cPrismDebug, "integer_parse", integer_parse, 1);
|
1414
|
-
rb_define_singleton_method(rb_cPrismDebug, "memsize", memsize, 1);
|
1415
|
-
rb_define_singleton_method(rb_cPrismDebug, "profile_file", profile_file, 1);
|
1416
|
-
rb_define_singleton_method(rb_cPrismDebug, "format_errors", format_errors, 2);
|
1417
|
-
rb_define_singleton_method(rb_cPrismDebug, "static_inspect", static_inspect, -1);
|
1418
|
-
|
1419
|
-
#ifndef PRISM_EXCLUDE_PRETTYPRINT
|
1420
|
-
rb_define_singleton_method(rb_cPrismDebug, "inspect_node", inspect_node, 1);
|
1421
|
-
#endif
|
1422
|
-
|
1423
|
-
// Next, define the functions that are exposed through the private
|
1424
|
-
// Debug::Encoding class.
|
1425
|
-
rb_cPrismDebugEncoding = rb_define_class_under(rb_cPrismDebug, "Encoding", rb_cObject);
|
1426
|
-
rb_define_singleton_method(rb_cPrismDebugEncoding, "all", encoding_all, 0);
|
1427
|
-
rb_define_singleton_method(rb_cPrismDebugEncoding, "_width", encoding_char_width, 2);
|
1428
|
-
rb_define_singleton_method(rb_cPrismDebugEncoding, "_alnum?", encoding_alnum_char, 2);
|
1429
|
-
rb_define_singleton_method(rb_cPrismDebugEncoding, "_alpha?", encoding_alpha_char, 2);
|
1430
|
-
rb_define_singleton_method(rb_cPrismDebugEncoding, "_upper?", encoding_isupper_char, 2);
|
1278
|
+
rb_define_singleton_method(rb_cPrismStringQuery, "local?", string_query_local_p, 1);
|
1279
|
+
rb_define_singleton_method(rb_cPrismStringQuery, "constant?", string_query_constant_p, 1);
|
1280
|
+
rb_define_singleton_method(rb_cPrismStringQuery, "method_name?", string_query_method_name_p, 1);
|
1431
1281
|
|
1432
1282
|
// Next, initialize the other APIs.
|
1433
1283
|
Init_prism_api_node();
|