prism 0.17.1 → 0.19.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/Makefile +5 -5
  4. data/README.md +4 -3
  5. data/config.yml +214 -68
  6. data/docs/build_system.md +6 -6
  7. data/docs/building.md +10 -3
  8. data/docs/configuration.md +11 -9
  9. data/docs/encoding.md +92 -88
  10. data/docs/heredocs.md +1 -1
  11. data/docs/javascript.md +29 -1
  12. data/docs/local_variable_depth.md +229 -0
  13. data/docs/ruby_api.md +16 -0
  14. data/docs/serialization.md +18 -13
  15. data/ext/prism/api_node.c +411 -240
  16. data/ext/prism/extconf.rb +97 -127
  17. data/ext/prism/extension.c +97 -33
  18. data/ext/prism/extension.h +1 -1
  19. data/include/prism/ast.h +377 -159
  20. data/include/prism/defines.h +17 -0
  21. data/include/prism/diagnostic.h +38 -6
  22. data/include/prism/{enc/pm_encoding.h → encoding.h} +126 -64
  23. data/include/prism/options.h +2 -2
  24. data/include/prism/parser.h +62 -36
  25. data/include/prism/regexp.h +2 -2
  26. data/include/prism/util/pm_buffer.h +9 -1
  27. data/include/prism/util/pm_memchr.h +2 -2
  28. data/include/prism/util/pm_strpbrk.h +3 -3
  29. data/include/prism/version.h +3 -3
  30. data/include/prism.h +13 -15
  31. data/lib/prism/compiler.rb +15 -3
  32. data/lib/prism/debug.rb +13 -4
  33. data/lib/prism/desugar_compiler.rb +4 -3
  34. data/lib/prism/dispatcher.rb +70 -14
  35. data/lib/prism/dot_visitor.rb +4612 -0
  36. data/lib/prism/dsl.rb +77 -57
  37. data/lib/prism/ffi.rb +19 -6
  38. data/lib/prism/lex_compat.rb +19 -9
  39. data/lib/prism/mutation_compiler.rb +26 -6
  40. data/lib/prism/node.rb +1314 -522
  41. data/lib/prism/node_ext.rb +102 -19
  42. data/lib/prism/parse_result.rb +58 -27
  43. data/lib/prism/ripper_compat.rb +49 -34
  44. data/lib/prism/serialize.rb +251 -227
  45. data/lib/prism/visitor.rb +15 -3
  46. data/lib/prism.rb +21 -4
  47. data/prism.gemspec +7 -9
  48. data/rbi/prism.rbi +688 -284
  49. data/rbi/prism_static.rbi +3 -0
  50. data/sig/prism.rbs +426 -156
  51. data/sig/prism_static.rbs +1 -0
  52. data/src/diagnostic.c +280 -216
  53. data/src/encoding.c +5137 -0
  54. data/src/node.c +99 -21
  55. data/src/options.c +21 -2
  56. data/src/prettyprint.c +1743 -1241
  57. data/src/prism.c +1774 -831
  58. data/src/regexp.c +15 -15
  59. data/src/serialize.c +261 -164
  60. data/src/util/pm_buffer.c +10 -1
  61. data/src/util/pm_memchr.c +1 -1
  62. data/src/util/pm_strpbrk.c +4 -4
  63. metadata +8 -10
  64. data/src/enc/pm_big5.c +0 -53
  65. data/src/enc/pm_euc_jp.c +0 -59
  66. data/src/enc/pm_gbk.c +0 -62
  67. data/src/enc/pm_shift_jis.c +0 -57
  68. data/src/enc/pm_tables.c +0 -743
  69. data/src/enc/pm_unicode.c +0 -2369
  70. data/src/enc/pm_windows_31j.c +0 -57
data/ext/prism/extconf.rb CHANGED
@@ -1,136 +1,106 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rbconfig"
3
+ if ARGV.delete("--help")
4
+ print(<<~TEXT)
5
+ USAGE: ruby #{$PROGRAM_NAME} [options]
6
+
7
+ Flags that are always valid:
8
+
9
+ --enable-debug-mode-build
10
+ Enable debug mode build.
11
+ You may also use set PRISM_DEBUG_MODE_BUILD environment variable.
12
+
13
+ --help
14
+ Display this message.
15
+
16
+ Environment variables used:
17
+
18
+ PRISM_DEBUG_MODE_BUILD
19
+ Equivalent to `--enable-debug-mode-build` when set, even if nil or blank.
4
20
 
5
- module Prism
6
- module ExtConf
7
- class << self
8
- def configure
9
- unless RUBY_ENGINE == "ruby"
10
- # On non-CRuby we only need the shared library, so build only that and not the C extension.
11
- # We also avoid `require "mkmf"` as that prepends the LLVM toolchain to PATH on TruffleRuby,
12
- # but we want to use the native toolchain here since librubyparser is run natively.
13
- build_shared_rubyparser
14
- File.write("Makefile", "all install clean:\n\t@#{RbConfig::CONFIG["NULLCMD"]}\n")
15
- return
16
- end
17
-
18
- require "mkmf"
19
- configure_c_extension
20
- configure_rubyparser
21
-
22
- create_makefile("prism/prism")
23
-
24
- if static_link?
25
- File.open('Makefile', 'a') do |mf|
26
- mf.puts
27
- mf.puts '# Automatically rebuild the extension if librubyparser.a changed'
28
- mf.puts '$(TARGET_SO): $(LOCAL_LIBS)'
29
- end
30
- end
31
- end
32
-
33
- def configure_c_extension
34
- append_cflags("-DPRISM_DEBUG_MODE_BUILD") if debug_mode_build?
35
- append_cflags("-fvisibility=hidden")
36
- end
37
-
38
- def configure_rubyparser
39
- if static_link?
40
- static_archive_path = File.join(build_dir, "librubyparser.a")
41
- unless File.exist?(static_archive_path)
42
- build_static_rubyparser
43
- end
44
- $LOCAL_LIBS << " #{static_archive_path}"
45
- else
46
- shared_library_path = File.join(build_dir, "librubyparser.#{RbConfig::CONFIG["SOEXT"]}")
47
- unless File.exist?(shared_library_path)
48
- build_shared_rubyparser
49
- end
50
- unless find_library("rubyparser", "pm_parser_init", build_dir)
51
- raise "could not link against #{File.basename(shared_library_path)}"
52
- end
53
- end
54
-
55
- find_header("prism.h", include_dir) or raise "prism.h is required"
56
-
57
- # Explicitly look for the extension header in the parent directory
58
- # because we want to consistently look for prism/extension.h in our
59
- # source files to line up with our mirroring in CRuby.
60
- find_header("prism/extension.h", File.join(__dir__, "..")) or raise "prism/extension.h is required"
61
- end
62
-
63
- def build_shared_rubyparser
64
- build_target_rubyparser "build/librubyparser.#{RbConfig::CONFIG["SOEXT"]}"
65
- end
66
-
67
- def build_static_rubyparser
68
- build_target_rubyparser "build/librubyparser.a"
69
- end
70
-
71
- def build_target_rubyparser(target)
72
- Dir.chdir(root_dir) do
73
- if !File.exist?("include/prism/ast.h") && Dir.exist?(".git")
74
- # this block only exists to support building the gem from a "git" source,
75
- # normally we package up the configure and other files in the gem itself
76
- system("templates/template.rb", exception: true)
77
- end
78
- system("make", target, exception: true)
79
- end
80
- end
81
-
82
- def root_dir
83
- File.expand_path("../..", __dir__)
84
- end
85
-
86
- def include_dir
87
- File.join(root_dir, "include")
88
- end
89
-
90
- def build_dir
91
- File.join(root_dir, "build")
92
- end
93
-
94
- def print_help
95
- print(<<~TEXT)
96
- USAGE: ruby #{$PROGRAM_NAME} [options]
97
-
98
- Flags that are always valid:
99
-
100
- --enable-static
101
- --disable-static
102
- Enable or disable static linking against librubyparser.
103
- The default is to statically link.
104
-
105
- --enable-debug-mode-build
106
- Enable debug mode build.
107
- You may also use set PRISM_DEBUG_MODE_BUILD environment variable.
108
-
109
- --help
110
- Display this message.
111
-
112
- Environment variables used:
113
-
114
- PRISM_DEBUG_MODE_BUILD
115
- Equivalent to `--enable-debug-mode-build` when set, even if nil or blank.
116
-
117
- TEXT
118
- end
119
-
120
- def static_link?
121
- enable_config("static", true)
122
- end
123
-
124
- def debug_mode_build?
125
- enable_config("debug-mode-build", ENV["PRISM_DEBUG_MODE_BUILD"] || false)
126
- end
21
+ TEXT
22
+ exit!(0)
23
+ end
24
+
25
+ # If this gem is being build from a git source, then we need to run
26
+ # templating if it hasn't been run yet. In normal packaging, we would have
27
+ # shipped the templated files with the gem, so this wouldn't be necessary.
28
+ def generate_templates
29
+ Dir.chdir(File.expand_path("../..", __dir__)) do
30
+ if !File.exist?("include/prism/ast.h") && Dir.exist?(".git")
31
+ system("templates/template.rb", exception: true)
127
32
  end
128
33
  end
129
34
  end
130
35
 
131
- if ARGV.delete("--help")
132
- Prism::ExtConf.print_help
133
- exit!(0)
36
+ # Runs `make` in the root directory of the project. Note that this is the
37
+ # `Makefile` for the overall project, not the `Makefile` that is being generated
38
+ # by this script.`
39
+ def make(target)
40
+ Dir.chdir(File.expand_path("../..", __dir__)) do
41
+ system("make", target, exception: true)
42
+ end
134
43
  end
135
44
 
136
- Prism::ExtConf.configure
45
+ require "rbconfig"
46
+
47
+ # On non-CRuby we only need the shared library since we'll interface with it
48
+ # through FFI, so we'll build only that and not the C extension. We also avoid
49
+ # `require "mkmf"` as that prepends the LLVM toolchain to PATH on TruffleRuby,
50
+ # but we want to use the native toolchain here since libprism is run natively.
51
+ if RUBY_ENGINE != "ruby"
52
+ generate_templates
53
+ make("build/libprism.#{RbConfig::CONFIG["SOEXT"]}")
54
+ File.write("Makefile", "all install clean:\n\t@#{RbConfig::CONFIG["NULLCMD"]}\n")
55
+ return
56
+ end
57
+
58
+ require "mkmf"
59
+
60
+ # First, ensure that we can find the header for the prism library.
61
+ generate_templates # Templates should be generated before find_header.
62
+ unless find_header("prism.h", File.expand_path("../../include", __dir__))
63
+ raise "prism.h is required"
64
+ end
65
+
66
+ # Next, ensure we can find the header for the C extension. Explicitly look for
67
+ # the extension header in the parent directory because we want to consistently
68
+ # look for `prism/extension.h` in our source files to line up with our mirroring
69
+ # in CRuby.
70
+ unless find_header("prism/extension.h", File.expand_path("..", __dir__))
71
+ raise "prism/extension.h is required"
72
+ end
73
+
74
+ # If `--enable-debug-mode-build` is passed to this script or the
75
+ # `PRISM_DEBUG_MODE_BUILD` environment variable is defined, we'll build with the
76
+ # `PRISM_DEBUG_MODE_BUILD` macro defined. This causes parse functions to
77
+ # duplicate their input so that they have clearly set bounds, which is useful
78
+ # for finding bugs that cause the parser to read off the end of the input.
79
+ if enable_config("debug-mode-build", ENV["PRISM_DEBUG_MODE_BUILD"] || false)
80
+ append_cflags("-DPRISM_DEBUG_MODE_BUILD")
81
+ end
82
+
83
+ # By default, all symbols are hidden in the shared library.
84
+ append_cflags("-fvisibility=hidden")
85
+
86
+ # We need to link against the libprism.a archive, which is built by the
87
+ # project's `Makefile`. We'll build it if it doesn't exist yet, and then add it
88
+ # to `mkmf`'s list of local libraries.
89
+ archive_target = "build/libprism.a"
90
+ archive_path = File.expand_path("../../#{archive_target}", __dir__)
91
+
92
+ make(archive_target) unless File.exist?(archive_path)
93
+ $LOCAL_LIBS << " #{archive_path}"
94
+
95
+ # Finally, we'll create the `Makefile` that is going to be used to configure and
96
+ # build the C extension.
97
+ create_makefile("prism/prism")
98
+
99
+ # Now that the `Makefile` for the C extension is built, we'll append on an extra
100
+ # rule that dictates that the extension should be rebuilt if the archive is
101
+ # updated.
102
+ File.open("Makefile", "a") do |mf|
103
+ mf.puts
104
+ mf.puts("# Automatically rebuild the extension if libprism.a changed")
105
+ mf.puts("$(TARGET_SO): $(LOCAL_LIBS)")
106
+ end
@@ -1,7 +1,7 @@
1
1
  #include "prism/extension.h"
2
2
 
3
3
  // NOTE: this file should contain only bindings. All non-trivial logic should be
4
- // in librubyparser so it can be shared its the various callers.
4
+ // in libprism so it can be shared its the various callers.
5
5
 
6
6
  VALUE rb_cPrism;
7
7
  VALUE rb_cPrismNode;
@@ -12,7 +12,6 @@ VALUE rb_cPrismLocation;
12
12
  VALUE rb_cPrismComment;
13
13
  VALUE rb_cPrismInlineComment;
14
14
  VALUE rb_cPrismEmbDocComment;
15
- VALUE rb_cPrismDATAComment;
16
15
  VALUE rb_cPrismMagicComment;
17
16
  VALUE rb_cPrismParseError;
18
17
  VALUE rb_cPrismParseWarning;
@@ -127,7 +126,7 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
127
126
  } else if (key_id == rb_option_id_encoding) {
128
127
  if (!NIL_P(value)) pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value)));
129
128
  } else if (key_id == rb_option_id_line) {
130
- if (!NIL_P(value)) pm_options_line_set(options, NUM2UINT(value));
129
+ if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value));
131
130
  } else if (key_id == rb_option_id_frozen_string_literal) {
132
131
  if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, value == Qtrue);
133
132
  } else if (key_id == rb_option_id_verbose) {
@@ -167,6 +166,7 @@ build_options(VALUE argument) {
167
166
  */
168
167
  static void
169
168
  extract_options(pm_options_t *options, VALUE filepath, VALUE keywords) {
169
+ options->line = 1; // default
170
170
  if (!NIL_P(keywords)) {
171
171
  struct build_options_data data = { .options = options, .keywords = keywords };
172
172
  struct build_options_data *argument = &data;
@@ -316,26 +316,11 @@ parser_comments(pm_parser_t *parser, VALUE source) {
316
316
  for (pm_comment_t *comment = (pm_comment_t *) parser->comment_list.head; comment != NULL; comment = (pm_comment_t *) comment->node.next) {
317
317
  VALUE location_argv[] = {
318
318
  source,
319
- LONG2FIX(comment->start - parser->start),
320
- LONG2FIX(comment->end - comment->start)
319
+ LONG2FIX(comment->location.start - parser->start),
320
+ LONG2FIX(comment->location.end - comment->location.start)
321
321
  };
322
322
 
323
- VALUE type;
324
- switch (comment->type) {
325
- case PM_COMMENT_INLINE:
326
- type = rb_cPrismInlineComment;
327
- break;
328
- case PM_COMMENT_EMBDOC:
329
- type = rb_cPrismEmbDocComment;
330
- break;
331
- case PM_COMMENT___END__:
332
- type = rb_cPrismDATAComment;
333
- break;
334
- default:
335
- type = rb_cPrismInlineComment;
336
- break;
337
- }
338
-
323
+ VALUE type = (comment->type == PM_COMMENT_EMBDOC) ? rb_cPrismEmbDocComment : rb_cPrismInlineComment;
339
324
  VALUE comment_argv[] = { rb_class_new_instance(3, location_argv, rb_cPrismLocation) };
340
325
  rb_ary_push(comments, rb_class_new_instance(1, comment_argv, type));
341
326
  }
@@ -374,6 +359,25 @@ parser_magic_comments(pm_parser_t *parser, VALUE source) {
374
359
  return magic_comments;
375
360
  }
376
361
 
362
+ /**
363
+ * Extract out the data location from the parser into a Location instance if one
364
+ * exists.
365
+ */
366
+ static VALUE
367
+ parser_data_loc(const pm_parser_t *parser, VALUE source) {
368
+ if (parser->data_loc.end == NULL) {
369
+ return Qnil;
370
+ } else {
371
+ VALUE argv[] = {
372
+ source,
373
+ LONG2FIX(parser->data_loc.start - parser->start),
374
+ LONG2FIX(parser->data_loc.end - parser->data_loc.start)
375
+ };
376
+
377
+ return rb_class_new_instance(3, argv, rb_cPrismLocation);
378
+ }
379
+ }
380
+
377
381
  /**
378
382
  * Extract the errors out of the parser into an array.
379
383
  */
@@ -385,8 +389,8 @@ parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
385
389
  for (error = (pm_diagnostic_t *) parser->error_list.head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
386
390
  VALUE location_argv[] = {
387
391
  source,
388
- LONG2FIX(error->start - parser->start),
389
- LONG2FIX(error->end - error->start)
392
+ LONG2FIX(error->location.start - parser->start),
393
+ LONG2FIX(error->location.end - error->location.start)
390
394
  };
391
395
 
392
396
  VALUE error_argv[] = {
@@ -411,8 +415,8 @@ parser_warnings(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
411
415
  for (warning = (pm_diagnostic_t *) parser->warning_list.head; warning != NULL; warning = (pm_diagnostic_t *) warning->node.next) {
412
416
  VALUE location_argv[] = {
413
417
  source,
414
- LONG2FIX(warning->start - parser->start),
415
- LONG2FIX(warning->end - warning->start)
418
+ LONG2FIX(warning->location.start - parser->start),
419
+ LONG2FIX(warning->location.end - warning->location.start)
416
420
  };
417
421
 
418
422
  VALUE warning_argv[] = {
@@ -465,7 +469,7 @@ parse_lex_token(void *data, pm_parser_t *parser, pm_token_t *token) {
465
469
  static void
466
470
  parse_lex_encoding_changed_callback(pm_parser_t *parser) {
467
471
  parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data;
468
- parse_lex_data->encoding = rb_enc_find(parser->encoding.name);
472
+ parse_lex_data->encoding = rb_enc_find(parser->encoding->name);
469
473
 
470
474
  // Since the encoding changed, we need to go back and change the encoding of
471
475
  // the tokens that were already lexed. This is only going to end up being
@@ -531,6 +535,7 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
531
535
  value,
532
536
  parser_comments(&parser, source),
533
537
  parser_magic_comments(&parser, source),
538
+ parser_data_loc(&parser, source),
534
539
  parser_errors(&parser, parse_lex_data.encoding, source),
535
540
  parser_warnings(&parser, parse_lex_data.encoding, source),
536
541
  source
@@ -538,7 +543,7 @@ parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nod
538
543
 
539
544
  pm_node_destroy(&parser, node);
540
545
  pm_parser_free(&parser);
541
- return rb_class_new_instance(6, result_argv, rb_cPrismParseResult);
546
+ return rb_class_new_instance(7, result_argv, rb_cPrismParseResult);
542
547
  }
543
548
 
544
549
  /**
@@ -594,19 +599,20 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
594
599
  pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
595
600
 
596
601
  pm_node_t *node = pm_parse(&parser);
597
- rb_encoding *encoding = rb_enc_find(parser.encoding.name);
602
+ rb_encoding *encoding = rb_enc_find(parser.encoding->name);
598
603
 
599
604
  VALUE source = pm_source_new(&parser, encoding);
600
605
  VALUE result_argv[] = {
601
606
  pm_ast_new(&parser, node, encoding),
602
607
  parser_comments(&parser, source),
603
608
  parser_magic_comments(&parser, source),
609
+ parser_data_loc(&parser, source),
604
610
  parser_errors(&parser, encoding, source),
605
611
  parser_warnings(&parser, encoding, source),
606
612
  source
607
613
  };
608
614
 
609
- VALUE result = rb_class_new_instance(6, result_argv, rb_cPrismParseResult);
615
+ VALUE result = rb_class_new_instance(7, result_argv, rb_cPrismParseResult);
610
616
 
611
617
  pm_node_destroy(&parser, node);
612
618
  pm_parser_free(&parser);
@@ -687,7 +693,7 @@ parse_input_comments(pm_string_t *input, const pm_options_t *options) {
687
693
  pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
688
694
 
689
695
  pm_node_t *node = pm_parse(&parser);
690
- rb_encoding *encoding = rb_enc_find(parser.encoding.name);
696
+ rb_encoding *encoding = rb_enc_find(parser.encoding->name);
691
697
 
692
698
  VALUE source = pm_source_new(&parser, encoding);
693
699
  VALUE comments = parser_comments(&parser, source);
@@ -792,6 +798,63 @@ parse_lex_file(int argc, VALUE *argv, VALUE self) {
792
798
  return value;
793
799
  }
794
800
 
801
+ /**
802
+ * Parse the given input and return true if it parses without errors.
803
+ */
804
+ static VALUE
805
+ parse_input_success_p(pm_string_t *input, const pm_options_t *options) {
806
+ pm_parser_t parser;
807
+ pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options);
808
+
809
+ pm_node_t *node = pm_parse(&parser);
810
+ pm_node_destroy(&parser, node);
811
+
812
+ VALUE result = parser.error_list.size == 0 ? Qtrue : Qfalse;
813
+ pm_parser_free(&parser);
814
+
815
+ return result;
816
+ }
817
+
818
+ /**
819
+ * call-seq:
820
+ * Prism::parse_success?(source, **options) -> Array
821
+ *
822
+ * Parse the given string and return true if it parses without errors. For
823
+ * supported options, see Prism::parse.
824
+ */
825
+ static VALUE
826
+ parse_success_p(int argc, VALUE *argv, VALUE self) {
827
+ pm_string_t input;
828
+ pm_options_t options = { 0 };
829
+ string_options(argc, argv, &input, &options);
830
+
831
+ VALUE result = parse_input_success_p(&input, &options);
832
+ pm_string_free(&input);
833
+ pm_options_free(&options);
834
+
835
+ return result;
836
+ }
837
+
838
+ /**
839
+ * call-seq:
840
+ * Prism::parse_file_success?(filepath, **options) -> Array
841
+ *
842
+ * Parse the given file and return true if it parses without errors. For
843
+ * supported options, see Prism::parse.
844
+ */
845
+ static VALUE
846
+ parse_file_success_p(int argc, VALUE *argv, VALUE self) {
847
+ pm_string_t input;
848
+ pm_options_t options = { 0 };
849
+ if (!file_options(argc, argv, &input, &options)) return Qnil;
850
+
851
+ VALUE result = parse_input_success_p(&input, &options);
852
+ pm_string_free(&input);
853
+ pm_options_free(&options);
854
+
855
+ return result;
856
+ }
857
+
795
858
  /******************************************************************************/
796
859
  /* Utility functions exposed to make testing easier */
797
860
  /******************************************************************************/
@@ -808,7 +871,7 @@ static VALUE
808
871
  named_captures(VALUE self, VALUE source) {
809
872
  pm_string_list_t string_list = { 0 };
810
873
 
811
- if (!pm_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, &pm_encoding_utf_8)) {
874
+ if (!pm_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, PM_ENCODING_UTF_8_ENTRY)) {
812
875
  pm_string_list_free(&string_list);
813
876
  return Qnil;
814
877
  }
@@ -898,7 +961,7 @@ inspect_node(VALUE self, VALUE source) {
898
961
 
899
962
  pm_prettyprint(&buffer, &parser, node);
900
963
 
901
- rb_encoding *encoding = rb_enc_find(parser.encoding.name);
964
+ rb_encoding *encoding = rb_enc_find(parser.encoding->name);
902
965
  VALUE string = rb_enc_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer), encoding);
903
966
 
904
967
  pm_buffer_free(&buffer);
@@ -938,7 +1001,6 @@ Init_prism(void) {
938
1001
  rb_cPrismComment = rb_define_class_under(rb_cPrism, "Comment", rb_cObject);
939
1002
  rb_cPrismInlineComment = rb_define_class_under(rb_cPrism, "InlineComment", rb_cPrismComment);
940
1003
  rb_cPrismEmbDocComment = rb_define_class_under(rb_cPrism, "EmbDocComment", rb_cPrismComment);
941
- rb_cPrismDATAComment = rb_define_class_under(rb_cPrism, "DATAComment", rb_cPrismComment);
942
1004
  rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject);
943
1005
  rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject);
944
1006
  rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject);
@@ -976,6 +1038,8 @@ Init_prism(void) {
976
1038
  rb_define_singleton_method(rb_cPrism, "parse_file_comments", parse_file_comments, -1);
977
1039
  rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1);
978
1040
  rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, -1);
1041
+ rb_define_singleton_method(rb_cPrism, "parse_success?", parse_success_p, -1);
1042
+ rb_define_singleton_method(rb_cPrism, "parse_file_success?", parse_file_success_p, -1);
979
1043
 
980
1044
  // Next, the functions that will be called by the parser to perform various
981
1045
  // internal tasks. We expose these to make them easier to test.
@@ -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.17.1"
4
+ #define EXPECTED_PRISM_VERSION "0.19.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>