prism 0.19.0 → 0.20.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.
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>