prism 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -1
  3. data/Makefile +5 -0
  4. data/README.md +8 -6
  5. data/config.yml +236 -38
  6. data/docs/build_system.md +19 -2
  7. data/docs/cruby_compilation.md +27 -0
  8. data/docs/parser_translation.md +34 -0
  9. data/docs/parsing_rules.md +19 -0
  10. data/docs/releasing.md +3 -3
  11. data/docs/ruby_api.md +1 -1
  12. data/docs/serialization.md +17 -5
  13. data/ext/prism/api_node.c +101 -81
  14. data/ext/prism/extension.c +74 -11
  15. data/ext/prism/extension.h +1 -1
  16. data/include/prism/ast.h +1699 -504
  17. data/include/prism/defines.h +8 -0
  18. data/include/prism/diagnostic.h +39 -2
  19. data/include/prism/encoding.h +10 -0
  20. data/include/prism/options.h +40 -14
  21. data/include/prism/parser.h +33 -17
  22. data/include/prism/util/pm_buffer.h +9 -0
  23. data/include/prism/util/pm_constant_pool.h +7 -0
  24. data/include/prism/util/pm_newline_list.h +0 -11
  25. data/include/prism/version.h +2 -2
  26. data/include/prism.h +19 -2
  27. data/lib/prism/debug.rb +11 -5
  28. data/lib/prism/dot_visitor.rb +36 -14
  29. data/lib/prism/dsl.rb +22 -22
  30. data/lib/prism/ffi.rb +2 -2
  31. data/lib/prism/node.rb +1020 -737
  32. data/lib/prism/node_ext.rb +2 -2
  33. data/lib/prism/parse_result.rb +17 -9
  34. data/lib/prism/serialize.rb +53 -29
  35. data/lib/prism/translation/parser/compiler.rb +1831 -0
  36. data/lib/prism/translation/parser/lexer.rb +335 -0
  37. data/lib/prism/translation/parser/rubocop.rb +37 -0
  38. data/lib/prism/translation/parser.rb +163 -0
  39. data/lib/prism/translation.rb +11 -0
  40. data/lib/prism.rb +1 -0
  41. data/prism.gemspec +12 -5
  42. data/rbi/prism.rbi +150 -88
  43. data/rbi/prism_static.rbi +15 -3
  44. data/sig/prism.rbs +996 -961
  45. data/sig/prism_static.rbs +123 -46
  46. data/src/diagnostic.c +259 -219
  47. data/src/encoding.c +4 -8
  48. data/src/node.c +2 -6
  49. data/src/options.c +24 -5
  50. data/src/prettyprint.c +174 -42
  51. data/src/prism.c +1136 -328
  52. data/src/serialize.c +12 -9
  53. data/src/token_type.c +353 -4
  54. data/src/util/pm_buffer.c +11 -0
  55. data/src/util/pm_constant_pool.c +12 -11
  56. data/src/util/pm_newline_list.c +2 -14
  57. metadata +10 -3
  58. data/docs/building.md +0 -29
@@ -21,7 +21,7 @@ ID rb_option_id_filepath;
21
21
  ID rb_option_id_encoding;
22
22
  ID rb_option_id_line;
23
23
  ID rb_option_id_frozen_string_literal;
24
- ID rb_option_id_verbose;
24
+ ID rb_option_id_version;
25
25
  ID rb_option_id_scopes;
26
26
 
27
27
  /******************************************************************************/
@@ -129,8 +129,14 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
129
129
  if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value));
130
130
  } else if (key_id == rb_option_id_frozen_string_literal) {
131
131
  if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, value == Qtrue);
132
- } else if (key_id == rb_option_id_verbose) {
133
- pm_options_suppress_warnings_set(options, value != Qtrue);
132
+ } else if (key_id == rb_option_id_version) {
133
+ if (!NIL_P(value)) {
134
+ const char *version = check_string(value);
135
+
136
+ if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
137
+ rb_raise(rb_eArgError, "invalid version: %"PRIsVALUE, value);
138
+ }
139
+ }
134
140
  } else if (key_id == rb_option_id_scopes) {
135
141
  if (!NIL_P(value)) build_options_scopes(options, value);
136
142
  } else {
@@ -393,12 +399,22 @@ parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
393
399
  LONG2FIX(error->location.end - error->location.start)
394
400
  };
395
401
 
402
+ VALUE level = Qnil;
403
+ switch (error->level) {
404
+ case PM_ERROR_LEVEL_FATAL:
405
+ level = ID2SYM(rb_intern("fatal"));
406
+ break;
407
+ default:
408
+ rb_raise(rb_eRuntimeError, "Unknown level: %" PRIu8, error->level);
409
+ }
410
+
396
411
  VALUE error_argv[] = {
397
412
  rb_enc_str_new_cstr(error->message, encoding),
398
- rb_class_new_instance(3, location_argv, rb_cPrismLocation)
413
+ rb_class_new_instance(3, location_argv, rb_cPrismLocation),
414
+ level
399
415
  };
400
416
 
401
- rb_ary_push(errors, rb_class_new_instance(2, error_argv, rb_cPrismParseError));
417
+ rb_ary_push(errors, rb_class_new_instance(3, error_argv, rb_cPrismParseError));
402
418
  }
403
419
 
404
420
  return errors;
@@ -419,12 +435,25 @@ parser_warnings(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
419
435
  LONG2FIX(warning->location.end - warning->location.start)
420
436
  };
421
437
 
438
+ VALUE level = Qnil;
439
+ switch (warning->level) {
440
+ case PM_WARNING_LEVEL_DEFAULT:
441
+ level = ID2SYM(rb_intern("default"));
442
+ break;
443
+ case PM_WARNING_LEVEL_VERBOSE:
444
+ level = ID2SYM(rb_intern("verbose"));
445
+ break;
446
+ default:
447
+ rb_raise(rb_eRuntimeError, "Unknown level: %" PRIu8, warning->level);
448
+ }
449
+
422
450
  VALUE warning_argv[] = {
423
451
  rb_enc_str_new_cstr(warning->message, encoding),
424
- rb_class_new_instance(3, location_argv, rb_cPrismLocation)
452
+ rb_class_new_instance(3, location_argv, rb_cPrismLocation),
453
+ level
425
454
  };
426
455
 
427
- rb_ary_push(warnings, rb_class_new_instance(2, warning_argv, rb_cPrismParseWarning));
456
+ rb_ary_push(warnings, rb_class_new_instance(3, warning_argv, rb_cPrismParseWarning));
428
457
  }
429
458
 
430
459
  return warnings;
@@ -635,10 +664,13 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
635
664
  * integer or nil. Note that this is 1-indexed.
636
665
  * * `frozen_string_literal` - whether or not the frozen string literal pragma
637
666
  * has been set. This should be a boolean or nil.
638
- * * `verbose` - the current level of verbosity. This controls whether or not
639
- * the parser emits warnings. This should be a boolean or nil.
667
+ * * `version` - the version of prism that should be used to parse Ruby code. By
668
+ * default prism assumes you want to parse with the latest vesion of
669
+ * prism (which you can trigger with `nil` or `"latest"`). If you want to
670
+ * parse exactly as CRuby 3.3.0 would, then you can pass `"3.3.0"`.
640
671
  * * `scopes` - the locals that are in scope surrounding the code that is being
641
- * parsed. This should be an array of arrays of symbols or nil.
672
+ * parsed. This should be an array of arrays of symbols or nil. Scopes are
673
+ * ordered from the outermost scope to the innermost one.
642
674
  */
643
675
  static VALUE
644
676
  parse(int argc, VALUE *argv, VALUE self) {
@@ -971,6 +1003,36 @@ inspect_node(VALUE self, VALUE source) {
971
1003
  return string;
972
1004
  }
973
1005
 
1006
+ /**
1007
+ * call-seq:
1008
+ * Debug::format_errors(source, colorize) -> String
1009
+ *
1010
+ * Format the errors that are found when parsing the given source string.
1011
+ */
1012
+ static VALUE
1013
+ format_errors(VALUE self, VALUE source, VALUE colorize) {
1014
+ pm_string_t input;
1015
+ input_load_string(&input, source);
1016
+
1017
+ pm_parser_t parser;
1018
+ pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), NULL);
1019
+
1020
+ pm_node_t *node = pm_parse(&parser);
1021
+ pm_buffer_t buffer = { 0 };
1022
+
1023
+ pm_parser_errors_format(&parser, &buffer, RTEST(colorize));
1024
+
1025
+ rb_encoding *encoding = rb_enc_find(parser.encoding->name);
1026
+ VALUE result = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
1027
+
1028
+ pm_buffer_free(&buffer);
1029
+ pm_node_destroy(&parser, node);
1030
+ pm_parser_free(&parser);
1031
+ pm_string_free(&input);
1032
+
1033
+ return result;
1034
+ }
1035
+
974
1036
  /******************************************************************************/
975
1037
  /* Initialization of the extension */
976
1038
  /******************************************************************************/
@@ -1012,7 +1074,7 @@ Init_prism(void) {
1012
1074
  rb_option_id_encoding = rb_intern_const("encoding");
1013
1075
  rb_option_id_line = rb_intern_const("line");
1014
1076
  rb_option_id_frozen_string_literal = rb_intern_const("frozen_string_literal");
1015
- rb_option_id_verbose = rb_intern_const("verbose");
1077
+ rb_option_id_version = rb_intern_const("version");
1016
1078
  rb_option_id_scopes = rb_intern_const("scopes");
1017
1079
 
1018
1080
  /**
@@ -1048,6 +1110,7 @@ Init_prism(void) {
1048
1110
  rb_define_singleton_method(rb_cPrismDebug, "memsize", memsize, 1);
1049
1111
  rb_define_singleton_method(rb_cPrismDebug, "profile_file", profile_file, 1);
1050
1112
  rb_define_singleton_method(rb_cPrismDebug, "inspect_node", inspect_node, 1);
1113
+ rb_define_singleton_method(rb_cPrismDebug, "format_errors", format_errors, 2);
1051
1114
 
1052
1115
  // Next, initialize the other APIs.
1053
1116
  Init_prism_api_node();
@@ -1,7 +1,7 @@
1
1
  #ifndef PRISM_EXT_NODE_H
2
2
  #define PRISM_EXT_NODE_H
3
3
 
4
- #define EXPECTED_PRISM_VERSION "0.19.0"
4
+ #define EXPECTED_PRISM_VERSION "0.20.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>