prism 0.29.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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();
|