prism 0.28.0 → 0.30.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 +41 -1
- data/CONTRIBUTING.md +0 -4
- data/README.md +1 -0
- data/config.yml +95 -26
- data/docs/fuzzing.md +1 -1
- data/docs/ripper_translation.md +22 -0
- data/ext/prism/api_node.c +70 -52
- data/ext/prism/extconf.rb +27 -23
- data/ext/prism/extension.c +107 -372
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +170 -102
- data/include/prism/diagnostic.h +18 -3
- 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/desugar_compiler.rb +4 -4
- data/lib/prism/dispatcher.rb +14 -0
- data/lib/prism/dot_visitor.rb +54 -35
- data/lib/prism/dsl.rb +23 -18
- data/lib/prism/ffi.rb +25 -4
- data/lib/prism/inspect_visitor.rb +26 -24
- data/lib/prism/mutation_compiler.rb +6 -1
- data/lib/prism/node.rb +314 -389
- data/lib/prism/node_ext.rb +175 -17
- data/lib/prism/parse_result/comments.rb +1 -8
- data/lib/prism/parse_result/newlines.rb +102 -12
- data/lib/prism/parse_result.rb +17 -0
- data/lib/prism/reflection.rb +11 -9
- data/lib/prism/serialize.rb +91 -68
- data/lib/prism/translation/parser/compiler.rb +288 -138
- data/lib/prism/translation/parser.rb +7 -2
- data/lib/prism/translation/ripper.rb +24 -22
- data/lib/prism/translation/ruby_parser.rb +32 -14
- data/lib/prism/visitor.rb +3 -0
- data/lib/prism.rb +0 -4
- data/prism.gemspec +2 -4
- data/rbi/prism/node.rbi +114 -57
- data/rbi/prism/node_ext.rbi +5 -0
- data/rbi/prism/parse_result.rbi +1 -1
- data/rbi/prism/visitor.rbi +3 -0
- data/rbi/prism.rbi +6 -0
- data/sig/prism/dsl.rbs +13 -10
- data/sig/prism/lex_compat.rbs +10 -0
- data/sig/prism/mutation_compiler.rbs +1 -0
- data/sig/prism/node.rbs +72 -48
- data/sig/prism/node_ext.rbs +4 -0
- data/sig/prism/visitor.rbs +1 -0
- data/sig/prism.rbs +21 -0
- data/src/diagnostic.c +56 -27
- data/src/node.c +432 -1690
- data/src/prettyprint.c +97 -54
- data/src/prism.c +1286 -1196
- data/src/regexp.c +133 -68
- data/src/serialize.c +22 -17
- data/src/static_literals.c +63 -84
- data/src/token_type.c +4 -4
- 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 +3 -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();
|