prism 0.20.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 742f60637c4fd77f62b7713f484e87d70249e6e9dfeefc2c2ba0bfe667eed034
4
- data.tar.gz: 67bd239271c1d848536389668722a0617419b19b6bb250ed39cf17b7a414da4c
3
+ metadata.gz: 407353660e25fcada7fe3b7e7c79d58584bf3bc1c4d9ffad8f74d178a0fbe2b7
4
+ data.tar.gz: a23b28dada65ba503b2d2c6cb74e9389386bb9c59a504820ea46bdeddcc16169
5
5
  SHA512:
6
- metadata.gz: d0a90337f2635d35b08b0932ad6d928610406bb3f908c1b7b601f5fcb08b404604745f93bffd9a4bb84fc13cde0b6b4a71015390546a077daa4e05d7d8cf965e
7
- data.tar.gz: 231693786022302c486d3c4ea2c8841636e3c94cb37f6b5e410f1ab6ac4ce7fc12e53cd4d67f43d6a38f3292867fda808e655391528619d626823a5163cbf722
6
+ metadata.gz: aa848ed878d8fbc2b83b04789748d7d228226a5ca0963601c3dadfa901bc5b6c528667791d220e187399a91f6b1d8c2edcaee2c65721473683c349a7c8e4cebc
7
+ data.tar.gz: 6c7c4671fc9f53ca898fdce09de14eb4a79bf2ace45f88efff8302f99d6ae871c0336730d143c5bd87a8a8698a558a3d008fa68e9797c4502c7515fc67cc3099
data/CHANGELOG.md CHANGED
@@ -6,7 +6,40 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ## [0.20.0] - 2024-01-01
9
+ ## [0.22.0] - 2024-02-07
10
+
11
+ ### Added
12
+
13
+ - More support for `Prism::RipperCompat` is added.
14
+ - Support for Ruby 2.7 has been added, and the minimum Ruby requirement has been lowered to 2.7.
15
+
16
+ ### Changed
17
+
18
+ - The error for an invalid source encoding has a new `:argument` level to indicate it raises an argument error.
19
+ - `BeginNode` nodes that are used when a class, singleton class, module, method definition, or block have an inline `rescue`/`ensure`/`else` now have their opening locations set to the beginning of the respective keyword.
20
+ - Improved error messages for invalid characters.
21
+ - `Prism.parse_file` and similar APIs will raise more appropriate errors when the file does not exist or cannot be mapped.
22
+ - Correctly handle the `recover` parameter for `Prism::Translation::Parser`.
23
+
24
+ ## [0.21.0] - 2024-02-05
25
+
26
+ ### Added
27
+
28
+ - Add the `pm_constant_pool_find` API for finding a constant.
29
+
30
+ ### Changed
31
+
32
+ - Fixes for `Prism::Translation::Parser`.
33
+ - Ensure all errors flow through `parser.diagnostics.process`.
34
+ - Fix the find pattern node.
35
+ - Fix block forwarding with `NumberedParametersNode`.
36
+ - Ensure we can parse strings with invalid bytes for the encoding.
37
+ - Fix hash pairs in pattern matching.
38
+ - Properly reject operator writes on operator calls, e.g., `a.+ -= b`.
39
+ - Fix multi-byte escapes.
40
+ - Handle missing body in `begin` within the receiver of a method call.
41
+
42
+ ## [0.20.0] - 2024-02-01
10
43
 
11
44
  ### Added
12
45
 
@@ -323,7 +356,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
323
356
 
324
357
  - 🎉 Initial release! 🎉
325
358
 
326
- [unreleased]: https://github.com/ruby/prism/compare/v0.20.0...HEAD
359
+ [unreleased]: https://github.com/ruby/prism/compare/v0.22.0...HEAD
360
+ [0.22.0]: https://github.com/ruby/prism/compare/v0.21.0...v0.22.0
361
+ [0.21.0]: https://github.com/ruby/prism/compare/v0.20.0...v0.21.0
327
362
  [0.20.0]: https://github.com/ruby/prism/compare/v0.19.0...v0.20.0
328
363
  [0.19.0]: https://github.com/ruby/prism/compare/v0.18.0...v0.19.0
329
364
  [0.18.0]: https://github.com/ruby/prism/compare/v0.17.1...v0.18.0
@@ -9,7 +9,7 @@ The `parser` gem provides multiple parsers to support different versions of the
9
9
  You can use the `prism` parser like you would any other. After requiring the parser, you should be able to call any of the regular `Parser::Base` APIs that you would normally use.
10
10
 
11
11
  ```ruby
12
- require "prism/translation/parser"
12
+ require "prism"
13
13
 
14
14
  Prism::Translation::Parser.parse_file("path/to/file.rb")
15
15
  ```
data/docs/releasing.md CHANGED
@@ -18,6 +18,24 @@ To release a new version of Prism, perform the following steps:
18
18
  * `templates/javascript/src/deserialize.js.erb` in the version constants
19
19
  * `templates/lib/prism/serialize.rb.erb` in the version constants
20
20
  * Run `bundle install` to update the `Gemfile.lock` file.
21
+
22
+ ```sh
23
+ bundle install
24
+ ```
25
+
26
+ * Run `bundle install` with the various other gemfiles:
27
+
28
+ ```sh
29
+ chruby ruby-2.7.8 && BUNDLE_GEMFILE=gemfiles/2.7/Gemfile bundle install
30
+ chruby ruby-3.0.6 && BUNDLE_GEMFILE=gemfiles/3.0/Gemfile bundle install
31
+ chruby ruby-3.1.4 && BUNDLE_GEMFILE=gemfiles/3.1/Gemfile bundle install
32
+ chruby ruby-3.2.3 && BUNDLE_GEMFILE=gemfiles/3.2/Gemfile bundle install
33
+ chruby ruby-3.3.0 && BUNDLE_GEMFILE=gemfiles/3.3/Gemfile bundle install
34
+ chruby ruby-3.4.0-dev && BUNDLE_GEMFILE=gemfiles/3.4/Gemfile bundle install
35
+ chruby jruby-9.4.5.0 && BUNDLE_GEMFILE=gemfiles/jruby/Gemfile bundle install
36
+ chruby truffleruby-23.1.2 && BUNDLE_GEMFILE=gemfiles/truffleruby/Gemfile bundle install
37
+ ```
38
+
21
39
  * Update `rust/ruby-prism-sys/Cargo.toml` to match the new version and run `cargo build`
22
40
  * Update `rust/ruby-prism/Cargo.toml` to match the new version and run `cargo build`
23
41
  * Commit all of the updated files.
@@ -1,5 +1,9 @@
1
1
  #include "prism/extension.h"
2
2
 
3
+ #ifdef _WIN32
4
+ #include <ruby/win32.h>
5
+ #endif
6
+
3
7
  // NOTE: this file should contain only bindings. All non-trivial logic should be
4
8
  // in libprism so it can be shared its the various callers.
5
9
 
@@ -212,20 +216,29 @@ string_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options)
212
216
  /**
213
217
  * Read options for methods that look like (filepath, **options).
214
218
  */
215
- static bool
219
+ static void
216
220
  file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) {
217
221
  VALUE filepath;
218
222
  VALUE keywords;
219
223
  rb_scan_args(argc, argv, "1:", &filepath, &keywords);
220
224
 
225
+ Check_Type(filepath, T_STRING);
226
+
221
227
  extract_options(options, filepath, keywords);
222
228
 
223
- if (!pm_string_mapped_init(input, (const char *) pm_string_source(&options->filepath))) {
229
+ const char * string_source = (const char *) pm_string_source(&options->filepath);
230
+
231
+ if (!pm_string_mapped_init(input, string_source)) {
224
232
  pm_options_free(options);
225
- return false;
226
- }
227
233
 
228
- return true;
234
+ #ifdef _WIN32
235
+ int e = rb_w32_map_errno(GetLastError());
236
+ #else
237
+ int e = errno;
238
+ #endif
239
+
240
+ rb_syserr_fail(e, string_source);
241
+ }
229
242
  }
230
243
 
231
244
  /******************************************************************************/
@@ -299,7 +312,8 @@ static VALUE
299
312
  dump_file(int argc, VALUE *argv, VALUE self) {
300
313
  pm_string_t input;
301
314
  pm_options_t options = { 0 };
302
- if (!file_options(argc, argv, &input, &options)) return Qnil;
315
+
316
+ file_options(argc, argv, &input, &options);
303
317
 
304
318
  VALUE value = dump_input(&input, &options);
305
319
  pm_string_free(&input);
@@ -404,6 +418,9 @@ parser_errors(pm_parser_t *parser, rb_encoding *encoding, VALUE source) {
404
418
  case PM_ERROR_LEVEL_FATAL:
405
419
  level = ID2SYM(rb_intern("fatal"));
406
420
  break;
421
+ case PM_ERROR_LEVEL_ARGUMENT:
422
+ level = ID2SYM(rb_intern("argument"));
423
+ break;
407
424
  default:
408
425
  rb_raise(rb_eRuntimeError, "Unknown level: %" PRIu8, error->level);
409
426
  }
@@ -606,7 +623,8 @@ static VALUE
606
623
  lex_file(int argc, VALUE *argv, VALUE self) {
607
624
  pm_string_t input;
608
625
  pm_options_t options = { 0 };
609
- if (!file_options(argc, argv, &input, &options)) return Qnil;
626
+
627
+ file_options(argc, argv, &input, &options);
610
628
 
611
629
  VALUE value = parse_lex_input(&input, &options, false);
612
630
  pm_string_free(&input);
@@ -707,7 +725,8 @@ static VALUE
707
725
  parse_file(int argc, VALUE *argv, VALUE self) {
708
726
  pm_string_t input;
709
727
  pm_options_t options = { 0 };
710
- if (!file_options(argc, argv, &input, &options)) return Qnil;
728
+
729
+ file_options(argc, argv, &input, &options);
711
730
 
712
731
  VALUE value = parse_input(&input, &options);
713
732
  pm_string_free(&input);
@@ -767,7 +786,8 @@ static VALUE
767
786
  parse_file_comments(int argc, VALUE *argv, VALUE self) {
768
787
  pm_string_t input;
769
788
  pm_options_t options = { 0 };
770
- if (!file_options(argc, argv, &input, &options)) return Qnil;
789
+
790
+ file_options(argc, argv, &input, &options);
771
791
 
772
792
  VALUE value = parse_input_comments(&input, &options);
773
793
  pm_string_free(&input);
@@ -821,7 +841,8 @@ static VALUE
821
841
  parse_lex_file(int argc, VALUE *argv, VALUE self) {
822
842
  pm_string_t input;
823
843
  pm_options_t options = { 0 };
824
- if (!file_options(argc, argv, &input, &options)) return Qnil;
844
+
845
+ file_options(argc, argv, &input, &options);
825
846
 
826
847
  VALUE value = parse_lex_input(&input, &options, true);
827
848
  pm_string_free(&input);
@@ -878,7 +899,8 @@ static VALUE
878
899
  parse_file_success_p(int argc, VALUE *argv, VALUE self) {
879
900
  pm_string_t input;
880
901
  pm_options_t options = { 0 };
881
- if (!file_options(argc, argv, &input, &options)) return Qnil;
902
+
903
+ file_options(argc, argv, &input, &options);
882
904
 
883
905
  VALUE result = parse_input_success_p(&input, &options);
884
906
  pm_string_free(&input);
@@ -956,7 +978,17 @@ profile_file(VALUE self, VALUE filepath) {
956
978
  pm_string_t input;
957
979
 
958
980
  const char *checked = check_string(filepath);
959
- if (!pm_string_mapped_init(&input, checked)) return Qnil;
981
+ Check_Type(filepath, T_STRING);
982
+
983
+ if (!pm_string_mapped_init(&input, checked)) {
984
+ #ifdef _WIN32
985
+ int e = rb_w32_map_errno(GetLastError());
986
+ #else
987
+ int e = errno;
988
+ #endif
989
+
990
+ rb_syserr_fail(e, checked);
991
+ }
960
992
 
961
993
  pm_options_t options = { 0 };
962
994
  pm_options_filepath_set(&options, checked);
@@ -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.20.0"
4
+ #define EXPECTED_PRISM_VERSION "0.22.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>
data/include/prism/ast.h CHANGED
@@ -1042,7 +1042,7 @@ static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS
1042
1042
  * Cast the type to an enum to allow the compiler to provide exhaustiveness
1043
1043
  * checking.
1044
1044
  */
1045
- #define PM_NODE_TYPE(node) ((enum pm_node_type) node->type)
1045
+ #define PM_NODE_TYPE(node) ((enum pm_node_type) (node)->type)
1046
1046
 
1047
1047
  /**
1048
1048
  * Return true if the type of the given node matches the given type.
@@ -19,7 +19,10 @@
19
19
  */
20
20
  typedef enum {
21
21
  /** For errors that cannot be recovered from. */
22
- PM_ERROR_LEVEL_FATAL = 0
22
+ PM_ERROR_LEVEL_FATAL = 0,
23
+
24
+ /** For errors that should raise an argument error. */
25
+ PM_ERROR_LEVEL_ARGUMENT = 1
23
26
  } pm_error_level_t;
24
27
 
25
28
  /**
@@ -28,6 +31,7 @@ typedef enum {
28
31
  typedef enum {
29
32
  /** For warnings which should be emitted if $VERBOSE != nil. */
30
33
  PM_WARNING_LEVEL_DEFAULT = 0,
34
+
31
35
  /** For warnings which should be emitted if $VERBOSE == true. */
32
36
  PM_WARNING_LEVEL_VERBOSE = 1
33
37
  } pm_warning_level_t;
@@ -192,8 +196,10 @@ typedef enum {
192
196
  PM_ERR_INVALID_NUMBER_HEXADECIMAL,
193
197
  PM_ERR_INVALID_NUMBER_OCTAL,
194
198
  PM_ERR_INVALID_NUMBER_UNDERSCORE,
199
+ PM_ERR_INVALID_CHARACTER,
200
+ PM_ERR_INVALID_MULTIBYTE_CHARACTER,
201
+ PM_ERR_INVALID_PRINTABLE_CHARACTER,
195
202
  PM_ERR_INVALID_PERCENT,
196
- PM_ERR_INVALID_TOKEN,
197
203
  PM_ERR_INVALID_VARIABLE_GLOBAL,
198
204
  PM_ERR_IT_NOT_ALLOWED,
199
205
  PM_ERR_LAMBDA_OPEN,
@@ -626,7 +626,7 @@ struct pm_parser {
626
626
  * This is the path of the file being parsed. We use the filepath when
627
627
  * constructing SourceFileNodes.
628
628
  */
629
- pm_string_t filepath_string;
629
+ pm_string_t filepath;
630
630
 
631
631
  /**
632
632
  * This constant pool keeps all of the constants defined throughout the file
@@ -154,6 +154,17 @@ bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
154
154
  */
155
155
  pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id);
156
156
 
157
+ /**
158
+ * Find a constant in a constant pool. Returns the id of the constant, or 0 if
159
+ * the constant is not found.
160
+ *
161
+ * @param pool The pool to find the constant in.
162
+ * @param start A pointer to the start of the constant.
163
+ * @param length The length of the constant.
164
+ * @return The id of the constant.
165
+ */
166
+ pm_constant_id_t pm_constant_pool_find(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
167
+
157
168
  /**
158
169
  * Insert a constant into a constant pool that is a slice of a source string.
159
170
  * Returns the id of the constant, or 0 if any potential calls to resize fail.
@@ -14,7 +14,7 @@
14
14
  /**
15
15
  * The minor version of the Prism library as an int.
16
16
  */
17
- #define PRISM_VERSION_MINOR 20
17
+ #define PRISM_VERSION_MINOR 22
18
18
 
19
19
  /**
20
20
  * The patch version of the Prism library as an int.
@@ -24,6 +24,6 @@
24
24
  /**
25
25
  * The version of the Prism library as a constant string.
26
26
  */
27
- #define PRISM_VERSION "0.20.0"
27
+ #define PRISM_VERSION "0.22.0"
28
28
 
29
29
  #endif
data/lib/prism/ffi.rb CHANGED
@@ -160,8 +160,13 @@ module Prism
160
160
  pointer = FFI::MemoryPointer.new(SIZEOF)
161
161
 
162
162
  begin
163
- raise unless LibRubyParser.pm_string_mapped_init(pointer, filepath)
164
- yield new(pointer)
163
+ raise TypeError unless filepath.is_a?(String)
164
+
165
+ if LibRubyParser.pm_string_mapped_init(pointer, filepath)
166
+ yield new(pointer)
167
+ else
168
+ raise SystemCallError.new(filepath, FFI.errno)
169
+ end
165
170
  ensure
166
171
  LibRubyParser.pm_string_free(pointer)
167
172
  pointer.free
@@ -860,7 +860,7 @@ module Prism
860
860
  previous = []
861
861
  results = []
862
862
 
863
- Ripper.lex(source, raise_errors: true).each do |token|
863
+ lex(source).each do |token|
864
864
  case token[1]
865
865
  when :on_sp
866
866
  # skip
@@ -886,6 +886,21 @@ module Prism
886
886
 
887
887
  results
888
888
  end
889
+
890
+ private
891
+
892
+ if Ripper.method(:lex).parameters.assoc(:keyrest)
893
+ def lex(source)
894
+ Ripper.lex(source, raise_errors: true)
895
+ end
896
+ else
897
+ def lex(source)
898
+ ripper = Ripper::Lexer.new(source)
899
+ ripper.lex.tap do |result|
900
+ raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any?
901
+ end
902
+ end
903
+ end
889
904
  end
890
905
 
891
906
  private_constant :LexRipper