prism 0.29.0 → 0.30.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 +22 -1
- data/CONTRIBUTING.md +0 -4
- data/README.md +1 -0
- data/config.yml +66 -9
- data/docs/fuzzing.md +1 -1
- data/docs/ripper_translation.md +22 -0
- data/ext/prism/api_node.c +30 -12
- data/ext/prism/extension.c +107 -372
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +138 -70
- data/include/prism/diagnostic.h +7 -2
- data/include/prism/node.h +0 -21
- data/include/prism/parser.h +23 -25
- data/include/prism/regexp.h +17 -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 +16 -9
- data/include/prism/util/pm_string.h +0 -8
- data/include/prism/version.h +2 -2
- data/include/prism.h +0 -11
- data/lib/prism/compiler.rb +3 -0
- data/lib/prism/dispatcher.rb +14 -0
- data/lib/prism/dot_visitor.rb +22 -3
- data/lib/prism/dsl.rb +7 -2
- data/lib/prism/ffi.rb +24 -3
- data/lib/prism/inspect_visitor.rb +10 -8
- data/lib/prism/mutation_compiler.rb +6 -1
- data/lib/prism/node.rb +166 -241
- data/lib/prism/node_ext.rb +21 -5
- data/lib/prism/parse_result/comments.rb +0 -7
- data/lib/prism/parse_result/newlines.rb +101 -11
- data/lib/prism/parse_result.rb +17 -0
- data/lib/prism/reflection.rb +3 -1
- data/lib/prism/serialize.rb +80 -67
- data/lib/prism/translation/parser/compiler.rb +134 -114
- data/lib/prism/translation/parser.rb +6 -1
- data/lib/prism/translation/ripper.rb +8 -6
- data/lib/prism/translation/ruby_parser.rb +23 -5
- data/lib/prism/visitor.rb +3 -0
- data/lib/prism.rb +0 -4
- data/prism.gemspec +1 -4
- data/rbi/prism/node.rbi +63 -6
- data/rbi/prism/visitor.rbi +3 -0
- data/rbi/prism.rbi +6 -0
- data/sig/prism/dsl.rbs +4 -1
- data/sig/prism/mutation_compiler.rbs +1 -0
- data/sig/prism/node.rbs +28 -4
- data/sig/prism/visitor.rbs +1 -0
- data/sig/prism.rbs +21 -0
- data/src/diagnostic.c +27 -17
- data/src/node.c +408 -1666
- data/src/prettyprint.c +49 -6
- data/src/prism.c +958 -991
- data/src/regexp.c +133 -68
- data/src/serialize.c +6 -1
- data/src/static_literals.c +63 -84
- data/src/token_type.c +2 -2
- data/src/util/pm_constant_pool.c +0 -8
- data/src/util/pm_integer.c +39 -11
- data/src/util/pm_string.c +0 -12
- data/src/util/pm_strpbrk.c +32 -6
- metadata +2 -5
- data/include/prism/util/pm_string_list.h +0 -44
- data/lib/prism/debug.rb +0 -249
- data/src/util/pm_string_list.c +0 -28
data/ext/prism/extension.c
CHANGED
@@ -25,14 +25,14 @@ VALUE rb_cPrismParseLexResult;
|
|
25
25
|
|
26
26
|
VALUE rb_cPrismDebugEncoding;
|
27
27
|
|
28
|
-
ID
|
29
|
-
ID
|
30
|
-
ID
|
31
|
-
ID
|
32
|
-
ID
|
33
|
-
ID
|
34
|
-
ID
|
35
|
-
ID
|
28
|
+
ID rb_id_option_command_line;
|
29
|
+
ID rb_id_option_encoding;
|
30
|
+
ID rb_id_option_filepath;
|
31
|
+
ID rb_id_option_frozen_string_literal;
|
32
|
+
ID rb_id_option_line;
|
33
|
+
ID rb_id_option_scopes;
|
34
|
+
ID rb_id_option_version;
|
35
|
+
ID rb_id_source_for;
|
36
36
|
|
37
37
|
/******************************************************************************/
|
38
38
|
/* IO of Ruby code */
|
@@ -52,7 +52,7 @@ check_string(VALUE value) {
|
|
52
52
|
|
53
53
|
// Check if the value is a string. If it's not, then raise a type error.
|
54
54
|
if (!RB_TYPE_P(value, T_STRING)) {
|
55
|
-
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(value));
|
55
|
+
rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(value));
|
56
56
|
}
|
57
57
|
|
58
58
|
// Otherwise, return the value as a C string.
|
@@ -66,7 +66,7 @@ static void
|
|
66
66
|
input_load_string(pm_string_t *input, VALUE string) {
|
67
67
|
// Check if the string is a string. If it's not, then raise a type error.
|
68
68
|
if (!RB_TYPE_P(string, T_STRING)) {
|
69
|
-
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(string));
|
69
|
+
rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(string));
|
70
70
|
}
|
71
71
|
|
72
72
|
pm_string_constant_init(input, RSTRING_PTR(string), RSTRING_LEN(string));
|
@@ -135,15 +135,15 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
|
|
135
135
|
pm_options_t *options = (pm_options_t *) argument;
|
136
136
|
ID key_id = SYM2ID(key);
|
137
137
|
|
138
|
-
if (key_id ==
|
138
|
+
if (key_id == rb_id_option_filepath) {
|
139
139
|
if (!NIL_P(value)) pm_options_filepath_set(options, check_string(value));
|
140
|
-
} else if (key_id ==
|
140
|
+
} else if (key_id == rb_id_option_encoding) {
|
141
141
|
if (!NIL_P(value)) pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
|
142
|
-
} else if (key_id ==
|
142
|
+
} else if (key_id == rb_id_option_line) {
|
143
143
|
if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value));
|
144
|
-
} else if (key_id ==
|
144
|
+
} else if (key_id == rb_id_option_frozen_string_literal) {
|
145
145
|
if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, RTEST(value));
|
146
|
-
} else if (key_id ==
|
146
|
+
} else if (key_id == rb_id_option_version) {
|
147
147
|
if (!NIL_P(value)) {
|
148
148
|
const char *version = check_string(value);
|
149
149
|
|
@@ -151,9 +151,9 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
|
|
151
151
|
rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value);
|
152
152
|
}
|
153
153
|
}
|
154
|
-
} else if (key_id ==
|
154
|
+
} else if (key_id == rb_id_option_scopes) {
|
155
155
|
if (!NIL_P(value)) build_options_scopes(options, value);
|
156
|
-
} else if (key_id ==
|
156
|
+
} else if (key_id == rb_id_option_command_line) {
|
157
157
|
if (!NIL_P(value)) {
|
158
158
|
const char *string = check_string(value);
|
159
159
|
uint8_t command_line = 0;
|
@@ -600,7 +600,7 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
|
|
600
600
|
|
601
601
|
VALUE source_string = rb_str_new((const char *) pm_string_source(input), pm_string_length(input));
|
602
602
|
VALUE offsets = rb_ary_new();
|
603
|
-
VALUE source = rb_funcall(rb_cPrismSource,
|
603
|
+
VALUE source = rb_funcall(rb_cPrismSource, rb_id_source_for, 3, source_string, LONG2NUM(parser.start_line), offsets);
|
604
604
|
|
605
605
|
parse_lex_data_t parse_lex_data = {
|
606
606
|
.source = source,
|
@@ -761,6 +761,82 @@ parse(int argc, VALUE *argv, VALUE self) {
|
|
761
761
|
return value;
|
762
762
|
}
|
763
763
|
|
764
|
+
/**
|
765
|
+
* call-seq:
|
766
|
+
* Prism::parse_file(filepath, **options) -> ParseResult
|
767
|
+
*
|
768
|
+
* Parse the given file and return a ParseResult instance. For supported
|
769
|
+
* options, see Prism::parse.
|
770
|
+
*/
|
771
|
+
static VALUE
|
772
|
+
parse_file(int argc, VALUE *argv, VALUE self) {
|
773
|
+
pm_string_t input;
|
774
|
+
pm_options_t options = { 0 };
|
775
|
+
|
776
|
+
file_options(argc, argv, &input, &options);
|
777
|
+
|
778
|
+
VALUE value = parse_input(&input, &options);
|
779
|
+
pm_string_free(&input);
|
780
|
+
pm_options_free(&options);
|
781
|
+
|
782
|
+
return value;
|
783
|
+
}
|
784
|
+
|
785
|
+
/**
|
786
|
+
* Parse the given input and return nothing.
|
787
|
+
*/
|
788
|
+
static void
|
789
|
+
profile_input(pm_string_t *input, const pm_options_t *options) {
|
790
|
+
pm_parser_t parser;
|
791
|
+
pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
|
792
|
+
|
793
|
+
pm_node_t *node = pm_parse(&parser);
|
794
|
+
pm_node_destroy(&parser, node);
|
795
|
+
pm_parser_free(&parser);
|
796
|
+
}
|
797
|
+
|
798
|
+
/**
|
799
|
+
* call-seq:
|
800
|
+
* Prism::profile(source, **options) -> nil
|
801
|
+
*
|
802
|
+
* Parse the given string and return nothing. This method is meant to allow
|
803
|
+
* profilers to avoid the overhead of reifying the AST to Ruby. For supported
|
804
|
+
* options, see Prism::parse.
|
805
|
+
*/
|
806
|
+
static VALUE
|
807
|
+
profile(int argc, VALUE *argv, VALUE self) {
|
808
|
+
pm_string_t input;
|
809
|
+
pm_options_t options = { 0 };
|
810
|
+
|
811
|
+
string_options(argc, argv, &input, &options);
|
812
|
+
profile_input(&input, &options);
|
813
|
+
pm_string_free(&input);
|
814
|
+
pm_options_free(&options);
|
815
|
+
|
816
|
+
return Qnil;
|
817
|
+
}
|
818
|
+
|
819
|
+
/**
|
820
|
+
* call-seq:
|
821
|
+
* Prism::profile_file(filepath, **options) -> nil
|
822
|
+
*
|
823
|
+
* Parse the given file and return nothing. This method is meant to allow
|
824
|
+
* profilers to avoid the overhead of reifying the AST to Ruby. For supported
|
825
|
+
* options, see Prism::parse.
|
826
|
+
*/
|
827
|
+
static VALUE
|
828
|
+
profile_file(int argc, VALUE *argv, VALUE self) {
|
829
|
+
pm_string_t input;
|
830
|
+
pm_options_t options = { 0 };
|
831
|
+
|
832
|
+
file_options(argc, argv, &input, &options);
|
833
|
+
profile_input(&input, &options);
|
834
|
+
pm_string_free(&input);
|
835
|
+
pm_options_free(&options);
|
836
|
+
|
837
|
+
return Qnil;
|
838
|
+
}
|
839
|
+
|
764
840
|
/**
|
765
841
|
* An implementation of fgets that is suitable for use with Ruby IO objects.
|
766
842
|
*/
|
@@ -815,27 +891,6 @@ parse_stream(int argc, VALUE *argv, VALUE self) {
|
|
815
891
|
return result;
|
816
892
|
}
|
817
893
|
|
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
894
|
/**
|
840
895
|
* Parse the given input and return an array of Comment objects.
|
841
896
|
*/
|
@@ -1034,303 +1089,6 @@ parse_file_failure_p(int argc, VALUE *argv, VALUE self) {
|
|
1034
1089
|
return RTEST(parse_file_success_p(argc, argv, self)) ? Qfalse : Qtrue;
|
1035
1090
|
}
|
1036
1091
|
|
1037
|
-
/******************************************************************************/
|
1038
|
-
/* Utility functions exposed to make testing easier */
|
1039
|
-
/******************************************************************************/
|
1040
|
-
|
1041
|
-
/**
|
1042
|
-
* call-seq:
|
1043
|
-
* Debug::named_captures(source) -> Array
|
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.
|
1129
|
-
*/
|
1130
|
-
static VALUE
|
1131
|
-
profile_file(VALUE self, VALUE filepath) {
|
1132
|
-
pm_string_t input;
|
1133
|
-
|
1134
|
-
const char *checked = check_string(filepath);
|
1135
|
-
Check_Type(filepath, T_STRING);
|
1136
|
-
|
1137
|
-
if (!pm_string_mapped_init(&input, checked)) {
|
1138
|
-
#ifdef _WIN32
|
1139
|
-
int e = rb_w32_map_errno(GetLastError());
|
1140
|
-
#else
|
1141
|
-
int e = errno;
|
1142
|
-
#endif
|
1143
|
-
|
1144
|
-
rb_syserr_fail(e, checked);
|
1145
|
-
}
|
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;
|
1160
|
-
}
|
1161
|
-
|
1162
|
-
#ifndef PRISM_EXCLUDE_PRETTYPRINT
|
1163
|
-
|
1164
|
-
/**
|
1165
|
-
* call-seq:
|
1166
|
-
* Debug::inspect_node(source) -> inspected
|
1167
|
-
*
|
1168
|
-
* Inspect the AST that represents the given source using the prism pretty print
|
1169
|
-
* as opposed to the Ruby implementation.
|
1170
|
-
*/
|
1171
|
-
static VALUE
|
1172
|
-
inspect_node(VALUE self, VALUE source) {
|
1173
|
-
pm_string_t input;
|
1174
|
-
input_load_string(&input, source);
|
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;
|
1192
|
-
}
|
1193
|
-
|
1194
|
-
#endif
|
1195
|
-
|
1196
|
-
/**
|
1197
|
-
* call-seq:
|
1198
|
-
* Debug::format_errors(source, colorize) -> String
|
1199
|
-
*
|
1200
|
-
* Format the errors that are found when parsing the given source string.
|
1201
|
-
*/
|
1202
|
-
static VALUE
|
1203
|
-
format_errors(VALUE self, VALUE source, VALUE colorize) {
|
1204
|
-
pm_string_t input;
|
1205
|
-
input_load_string(&input, source);
|
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;
|
1224
|
-
}
|
1225
|
-
|
1226
|
-
/**
|
1227
|
-
* call-seq:
|
1228
|
-
* Debug::static_inspect(source) -> String
|
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]
|
1262
|
-
*
|
1263
|
-
* Return an array of all of the encodings that prism knows about.
|
1264
|
-
*/
|
1265
|
-
static VALUE
|
1266
|
-
encoding_all(VALUE self) {
|
1267
|
-
VALUE encodings = rb_ary_new();
|
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;
|
1332
|
-
}
|
1333
|
-
|
1334
1092
|
/******************************************************************************/
|
1335
1093
|
/* Initialization of the extension */
|
1336
1094
|
/******************************************************************************/
|
@@ -1364,22 +1122,20 @@ Init_prism(void) {
|
|
1364
1122
|
rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject);
|
1365
1123
|
rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject);
|
1366
1124
|
rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject);
|
1367
|
-
|
1368
1125
|
rb_cPrismResult = rb_define_class_under(rb_cPrism, "Result", rb_cObject);
|
1369
1126
|
rb_cPrismParseResult = rb_define_class_under(rb_cPrism, "ParseResult", rb_cPrismResult);
|
1370
1127
|
rb_cPrismParseLexResult = rb_define_class_under(rb_cPrism, "ParseLexResult", rb_cPrismResult);
|
1371
1128
|
|
1372
|
-
// Intern all of the
|
1373
|
-
// every time we parse.
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
rb_prism_source_id_for = rb_intern("for");
|
1129
|
+
// Intern all of the IDs eagerly that we support so that we don't have to do
|
1130
|
+
// it every time we parse.
|
1131
|
+
rb_id_option_command_line = rb_intern_const("command_line");
|
1132
|
+
rb_id_option_encoding = rb_intern_const("encoding");
|
1133
|
+
rb_id_option_filepath = rb_intern_const("filepath");
|
1134
|
+
rb_id_option_frozen_string_literal = rb_intern_const("frozen_string_literal");
|
1135
|
+
rb_id_option_line = rb_intern_const("line");
|
1136
|
+
rb_id_option_scopes = rb_intern_const("scopes");
|
1137
|
+
rb_id_option_version = rb_intern_const("version");
|
1138
|
+
rb_id_source_for = rb_intern("for");
|
1383
1139
|
|
1384
1140
|
/**
|
1385
1141
|
* The version of the prism library.
|
@@ -1390,8 +1146,10 @@ Init_prism(void) {
|
|
1390
1146
|
rb_define_singleton_method(rb_cPrism, "lex", lex, -1);
|
1391
1147
|
rb_define_singleton_method(rb_cPrism, "lex_file", lex_file, -1);
|
1392
1148
|
rb_define_singleton_method(rb_cPrism, "parse", parse, -1);
|
1393
|
-
rb_define_singleton_method(rb_cPrism, "parse_stream", parse_stream, -1);
|
1394
1149
|
rb_define_singleton_method(rb_cPrism, "parse_file", parse_file, -1);
|
1150
|
+
rb_define_singleton_method(rb_cPrism, "profile", profile, -1);
|
1151
|
+
rb_define_singleton_method(rb_cPrism, "profile_file", profile_file, -1);
|
1152
|
+
rb_define_singleton_method(rb_cPrism, "parse_stream", parse_stream, -1);
|
1395
1153
|
rb_define_singleton_method(rb_cPrism, "parse_comments", parse_comments, -1);
|
1396
1154
|
rb_define_singleton_method(rb_cPrism, "parse_file_comments", parse_file_comments, -1);
|
1397
1155
|
rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1);
|
@@ -1406,29 +1164,6 @@ Init_prism(void) {
|
|
1406
1164
|
rb_define_singleton_method(rb_cPrism, "dump_file", dump_file, -1);
|
1407
1165
|
#endif
|
1408
1166
|
|
1409
|
-
// Next, the functions that will be called by the parser to perform various
|
1410
|
-
// internal tasks. We expose these to make them easier to test.
|
1411
|
-
VALUE rb_cPrismDebug = rb_define_module_under(rb_cPrism, "Debug");
|
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);
|
1431
|
-
|
1432
1167
|
// Next, initialize the other APIs.
|
1433
1168
|
Init_prism_api_node();
|
1434
1169
|
Init_prism_pack();
|