prism 0.25.0 → 0.26.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: 15343c4f2d796d38ab23791193ad8e7caad9c1f53632fc6a6de0b1f842a09202
4
- data.tar.gz: 0ef3cf6a5ed5853439e2854c4142e3f00e2a56b8e77e15c8b77bb759572745ff
3
+ metadata.gz: abad576ba53ce985475eb5d69638557386eef255c8fe625728780ce8ff66844e
4
+ data.tar.gz: a3c5e24f5d1ee0fe04d282a3f40d643cd914a518985a9cadebbb53200e4d3003
5
5
  SHA512:
6
- metadata.gz: 6d6e43bb22ed673caed7fb74e59f027a7781bfa55ff9b9d4fc386a547c615288e9d83b0e35482fa5cb8989365a6cf65b69d9d7b5e98bc42bf1603f557c80f859
7
- data.tar.gz: 174c82145e87749e11e7bdbf99185f8383e51321556158b4a2379c315eee86c1c5de36ab843ef3e2ac153224c6a251bd40fdf613d928aded37b31cc05995d65e
6
+ metadata.gz: d3255b2de64f3154500885ae2bd091389d6ac87c9b88cb8ff83b7d58026066c4e007cb7c486dcc8e8146132aad63a1c58ddd8ad598441d26bec7ad062409f6a9
7
+ data.tar.gz: 3d7563663f013a4dcc633b5e19d0a4605cae18bd0a0f99cc02c142198b25126f915185eef4080625c9a5867093a5bc5717db96ef8a8da6cdc69e849f65fbb7fd
data/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ 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.26.0] - 2024-04-18
10
+
11
+ ### Added
12
+
13
+ - Add `Prism::Node::fields`, which returns a list of `Prism::Reflection::Field` objects representing the fields of the node class. This is useful in metaprogramming contexts.
14
+ - `Prism::Location#chop`, for removing the last byte from a location.
15
+ - The void statement warning is now implemented.
16
+ - The unreachable statement warning is now implemented.
17
+ - A syntax error has been added for block arguments on yields, e.g., `yield(&foo)`.
18
+
19
+ ### Changed
20
+
21
+ - Better fidelity to `parser` when translating heredocs with interpolation.
22
+ - Fixed `RBI` and `RBS` types for `Prism::parse_*` signatures.
23
+ - Remove some incorrect warnings about unused local variables.
24
+ - More closely match CRuby error messages for global variables.
25
+ - Fix an issue with `parser` translation when line continuations are found in string literals.
26
+
9
27
  ## [0.25.0] - 2024-04-05
10
28
 
11
29
  ### Added
@@ -440,7 +458,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
440
458
 
441
459
  - 🎉 Initial release! 🎉
442
460
 
443
- [unreleased]: https://github.com/ruby/prism/compare/v0.25.0...HEAD
461
+ [unreleased]: https://github.com/ruby/prism/compare/v0.26.0...HEAD
462
+ [0.26.0]: https://github.com/ruby/prism/compare/v0.25.0...v0.26.0
444
463
  [0.25.0]: https://github.com/ruby/prism/compare/v0.24.0...v0.25.0
445
464
  [0.24.0]: https://github.com/ruby/prism/compare/v0.23.0...v0.24.0
446
465
  [0.23.0]: https://github.com/ruby/prism/compare/v0.22.0...v0.23.0
data/Makefile CHANGED
@@ -6,17 +6,20 @@ Q1 = $(V:1=)
6
6
  Q = $(Q1:0=@)
7
7
  ECHO1 = $(V:1=@ :)
8
8
  ECHO = $(ECHO1:0=@ echo)
9
- FUZZ_OUTPUT_DIR = $(shell pwd)/fuzz/output
9
+ FUZZ_OUTPUT_DIR = $(CURDIR)/fuzz/output
10
10
 
11
- SOEXT := $(shell ruby -e 'puts RbConfig::CONFIG["SOEXT"]')
11
+ SOEXT ?= $(shell ruby -e 'puts RbConfig::CONFIG["SOEXT"]')
12
12
 
13
13
  CPPFLAGS := -Iinclude $(CPPFLAGS)
14
14
  CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden $(CFLAGS)
15
- CC := cc
15
+ CC ?= cc
16
16
  WASI_SDK_PATH := /opt/wasi-sdk
17
17
 
18
- HEADERS := $(shell find include -name '*.h')
19
- SOURCES := $(shell find src -name '*.c')
18
+ MAKEDIRS ?= mkdir -p
19
+ RMALL ?= rm -f -r
20
+
21
+ HEADERS := $(wildcard include/*.h include/*/*.h include/*/*/*.h')
22
+ SOURCES := $(wildcard src/*.c src/*/*.c)
20
23
  SHARED_OBJECTS := $(subst src/,build/shared/,$(SOURCES:.c=.o))
21
24
  STATIC_OBJECTS := $(subst src/,build/static/,$(SOURCES:.c=.o))
22
25
 
@@ -45,17 +48,17 @@ java-wasm/src/test/resources/prism.wasm: Makefile $(SOURCES) $(HEADERS)
45
48
 
46
49
  build/shared/%.o: src/%.c Makefile $(HEADERS)
47
50
  $(ECHO) "compiling $@"
48
- $(Q) mkdir -p $(@D)
51
+ $(Q) $(MAKEDIRS) $(@D)
49
52
  $(Q) $(CC) $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
50
53
 
51
54
  build/static/%.o: src/%.c Makefile $(HEADERS)
52
55
  $(ECHO) "compiling $@"
53
- $(Q) mkdir -p $(@D)
56
+ $(Q) $(MAKEDIRS) $(@D)
54
57
  $(Q) $(CC) $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
55
58
 
56
59
  build/fuzz.%: $(SOURCES) fuzz/%.c fuzz/fuzz.c
57
60
  $(ECHO) "building $* fuzzer"
58
- $(Q) mkdir -p $(@D)
61
+ $(Q) $(MAKEDIRS) $(@D)
59
62
  $(ECHO) "building main fuzz binary"
60
63
  $(Q) AFL_HARDEN=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@ $^
61
64
  $(ECHO) "building cmplog binary"
@@ -66,7 +69,7 @@ build/fuzz.heisenbug.%: $(SOURCES) fuzz/%.c fuzz/heisenbug.c
66
69
 
67
70
  fuzz-debug:
68
71
  $(ECHO) "entering debug shell"
69
- $(Q) docker run -it --rm -e HISTFILE=/prism/fuzz/output/.bash_history -v $(shell pwd):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz
72
+ $(Q) docker run -it --rm -e HISTFILE=/prism/fuzz/output/.bash_history -v $(CURDIR):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz
70
73
 
71
74
  fuzz-docker-build: fuzz/docker/Dockerfile
72
75
  $(ECHO) "building docker image"
@@ -76,17 +79,17 @@ fuzz-run-%: FORCE fuzz-docker-build
76
79
  $(ECHO) "generating templates"
77
80
  $(Q) bundle exec rake templates
78
81
  $(ECHO) "running $* fuzzer"
79
- $(Q) docker run --rm -v $(shell pwd):/prism prism/fuzz /bin/bash -c "FUZZ_FLAGS=\"$(FUZZ_FLAGS)\" make build/fuzz.$*"
82
+ $(Q) docker run --rm -v $(CURDIR):/prism prism/fuzz /bin/bash -c "FUZZ_FLAGS=\"$(FUZZ_FLAGS)\" make build/fuzz.$*"
80
83
  $(ECHO) "starting AFL++ run"
81
- $(Q) mkdir -p $(FUZZ_OUTPUT_DIR)/$*
82
- $(Q) docker run -it --rm -v $(shell pwd):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz /bin/bash -c "./fuzz/$*.sh /fuzz_output/$*"
84
+ $(Q) $(MAKEDIRS) $(FUZZ_OUTPUT_DIR)/$*
85
+ $(Q) docker run -it --rm -v $(CURDIR):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz /bin/bash -c "./fuzz/$*.sh /fuzz_output/$*"
83
86
  FORCE:
84
87
 
85
88
  fuzz-clean:
86
- $(Q) rm -f -r fuzz/output
89
+ $(Q) $(RMALL) fuzz/output
87
90
 
88
91
  clean:
89
- $(Q) rm -f -r build
92
+ $(Q) $(RMALL) build
90
93
 
91
94
  .PHONY: clean fuzz-clean
92
95
 
data/config.yml CHANGED
@@ -60,7 +60,6 @@ errors:
60
60
  - DEF_ENDLESS
61
61
  - DEF_ENDLESS_SETTER
62
62
  - DEF_NAME
63
- - DEF_NAME_AFTER_RECEIVER
64
63
  - DEF_PARAMS_TERM
65
64
  - DEF_PARAMS_TERM_PAREN
66
65
  - DEF_RECEIVER
@@ -97,6 +96,7 @@ errors:
97
96
  - EXPECT_EXPRESSION_AFTER_STAR
98
97
  - EXPECT_IDENT_REQ_PARAMETER
99
98
  - EXPECT_LPAREN_REQ_PARAMETER
99
+ - EXPECT_MESSAGE
100
100
  - EXPECT_RBRACKET
101
101
  - EXPECT_RPAREN
102
102
  - EXPECT_RPAREN_AFTER_MULTI
@@ -104,6 +104,14 @@ errors:
104
104
  - EXPECT_STRING_CONTENT
105
105
  - EXPECT_WHEN_DELIMITER
106
106
  - EXPRESSION_BARE_HASH
107
+ - EXPRESSION_NOT_WRITABLE
108
+ - EXPRESSION_NOT_WRITABLE_ENCODING
109
+ - EXPRESSION_NOT_WRITABLE_FALSE
110
+ - EXPRESSION_NOT_WRITABLE_FILE
111
+ - EXPRESSION_NOT_WRITABLE_LINE
112
+ - EXPRESSION_NOT_WRITABLE_NIL
113
+ - EXPRESSION_NOT_WRITABLE_SELF
114
+ - EXPRESSION_NOT_WRITABLE_TRUE
107
115
  - FLOAT_PARSE
108
116
  - FOR_COLLECTION
109
117
  - FOR_IN
@@ -235,6 +243,7 @@ errors:
235
243
  - TERNARY_EXPRESSION_TRUE
236
244
  - UNARY_RECEIVER
237
245
  - UNDEF_ARGUMENT
246
+ - UNEXPECTED_BLOCK_ARGUMENT
238
247
  - UNEXPECTED_TOKEN_CLOSE_CONTEXT
239
248
  - UNEXPECTED_TOKEN_IGNORE
240
249
  - UNTIL_TERM
@@ -269,7 +278,9 @@ warnings:
269
278
  - LITERAL_IN_CONDITION_VERBOSE
270
279
  - SHEBANG_CARRIAGE_RETURN
271
280
  - UNEXPECTED_CARRIAGE_RETURN
281
+ - UNREACHABLE_STATEMENT
272
282
  - UNUSED_LOCAL_VARIABLE
283
+ - VOID_STATEMENT
273
284
  tokens:
274
285
  - name: EOF
275
286
  value: 1
@@ -16,6 +16,7 @@ A lot of code in prism's repository is templated from a single configuration fil
16
16
  * `lib/prism/dsl.rb` - for defining the DSL for the nodes in Ruby
17
17
  * `lib/prism/mutation_compiler.rb` - for defining the mutation compiler for the nodes in Ruby
18
18
  * `lib/prism/node.rb` - for defining the nodes in Ruby
19
+ * `lib/prism/reflection.rb` - for defining the reflection API in Ruby
19
20
  * `lib/prism/serialize.rb` - for defining how to deserialize the nodes in Ruby
20
21
  * `lib/prism/visitor.rb` - for defining the visitor interface for the nodes in Ruby
21
22
  * `src/diagnostic.c` - for defining how to build diagnostics
data/docs/releasing.md CHANGED
@@ -47,15 +47,7 @@ bundle install
47
47
  * Update the version-specific lockfiles:
48
48
 
49
49
  ```sh
50
- chruby ruby-2.7.8 && BUNDLE_GEMFILE=gemfiles/2.7/Gemfile bundle install
51
- chruby ruby-3.0.6 && BUNDLE_GEMFILE=gemfiles/3.0/Gemfile bundle install
52
- chruby ruby-3.1.4 && BUNDLE_GEMFILE=gemfiles/3.1/Gemfile bundle install
53
- chruby ruby-3.2.3 && BUNDLE_GEMFILE=gemfiles/3.2/Gemfile bundle install
54
- chruby ruby-3.3.0 && BUNDLE_GEMFILE=gemfiles/3.3/Gemfile bundle install
55
- chruby ruby-3.4.0-dev && BUNDLE_GEMFILE=gemfiles/3.4/Gemfile bundle install
56
- chruby jruby-9.4.5.0 && BUNDLE_GEMFILE=gemfiles/jruby/Gemfile bundle install
57
- chruby truffleruby-24.0.0 && BUNDLE_GEMFILE=gemfiles/truffleruby/Gemfile bundle install
58
- chruby ruby-3.4.0-dev && BUNDLE_GEMFILE=gemfiles/typecheck/Gemfile bundle install
50
+ bin/prism bundle install
59
51
  ```
60
52
 
61
53
  * Update the cargo lockfiles:
@@ -70,6 +62,12 @@ bundle exec rake cargo:build
70
62
  git commit -am "Bump to v$PRISM_VERSION"
71
63
  ```
72
64
 
65
+ * Push up the changes:
66
+
67
+ ```sh
68
+ git push
69
+ ```
70
+
73
71
  ## Publishing
74
72
 
75
73
  * Update the GitHub release page with a copy of the latest entry in the `CHANGELOG.md` file.
data/ext/prism/extconf.rb CHANGED
@@ -40,17 +40,22 @@ def generate_templates
40
40
  end
41
41
  end
42
42
 
43
+ require "rbconfig"
44
+
43
45
  # Runs `make` in the root directory of the project. Note that this is the
44
46
  # `Makefile` for the overall project, not the `Makefile` that is being generated
45
47
  # by this script.`
46
48
  def make(target)
47
49
  Dir.chdir(File.expand_path("../..", __dir__)) do
48
- system(RUBY_PLATFORM.include?("openbsd") ? "gmake" : "make", target, exception: true)
50
+ system(
51
+ RbConfig::CONFIG.slice(*%w[SOEXT CPPFLAGS CFLAGS CC AR ARFLAGS MAKEDIRS RMALL]), # env
52
+ RUBY_PLATFORM.include?("openbsd") ? "gmake" : "make",
53
+ target,
54
+ exception: true
55
+ )
49
56
  end
50
57
  end
51
58
 
52
- require "rbconfig"
53
-
54
59
  # On non-CRuby we only need the shared library since we'll interface with it
55
60
  # through FFI, so we'll build only that and not the C extension. We also avoid
56
61
  # `require "mkmf"` as that prepends the LLVM toolchain to PATH on TruffleRuby,
@@ -969,7 +969,7 @@ parse_input_success_p(pm_string_t *input, const pm_options_t *options) {
969
969
 
970
970
  /**
971
971
  * call-seq:
972
- * Prism::parse_success?(source, **options) -> Array
972
+ * Prism::parse_success?(source, **options) -> bool
973
973
  *
974
974
  * Parse the given string and return true if it parses without errors. For
975
975
  * supported options, see Prism::parse.
@@ -989,7 +989,19 @@ parse_success_p(int argc, VALUE *argv, VALUE self) {
989
989
 
990
990
  /**
991
991
  * call-seq:
992
- * Prism::parse_file_success?(filepath, **options) -> Array
992
+ * Prism::parse_failure?(source, **options) -> bool
993
+ *
994
+ * Parse the given string and return true if it parses with errors. For
995
+ * supported options, see Prism::parse.
996
+ */
997
+ static VALUE
998
+ parse_failure_p(int argc, VALUE *argv, VALUE self) {
999
+ return RTEST(parse_success_p(argc, argv, self)) ? Qfalse : Qtrue;
1000
+ }
1001
+
1002
+ /**
1003
+ * call-seq:
1004
+ * Prism::parse_file_success?(filepath, **options) -> bool
993
1005
  *
994
1006
  * Parse the given file and return true if it parses without errors. For
995
1007
  * supported options, see Prism::parse.
@@ -1008,6 +1020,18 @@ parse_file_success_p(int argc, VALUE *argv, VALUE self) {
1008
1020
  return result;
1009
1021
  }
1010
1022
 
1023
+ /**
1024
+ * call-seq:
1025
+ * Prism::parse_file_failure?(filepath, **options) -> bool
1026
+ *
1027
+ * Parse the given file and return true if it parses with errors. For
1028
+ * supported options, see Prism::parse.
1029
+ */
1030
+ static VALUE
1031
+ parse_file_failure_p(int argc, VALUE *argv, VALUE self) {
1032
+ return RTEST(parse_file_success_p(argc, argv, self)) ? Qfalse : Qtrue;
1033
+ }
1034
+
1011
1035
  /******************************************************************************/
1012
1036
  /* Utility functions exposed to make testing easier */
1013
1037
  /******************************************************************************/
@@ -1366,7 +1390,9 @@ Init_prism(void) {
1366
1390
  rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1);
1367
1391
  rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, -1);
1368
1392
  rb_define_singleton_method(rb_cPrism, "parse_success?", parse_success_p, -1);
1393
+ rb_define_singleton_method(rb_cPrism, "parse_failure?", parse_failure_p, -1);
1369
1394
  rb_define_singleton_method(rb_cPrism, "parse_file_success?", parse_file_success_p, -1);
1395
+ rb_define_singleton_method(rb_cPrism, "parse_file_failure?", parse_file_failure_p, -1);
1370
1396
 
1371
1397
  #ifndef PRISM_EXCLUDE_SERIALIZATION
1372
1398
  rb_define_singleton_method(rb_cPrism, "dump", dump, -1);
@@ -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.25.0"
4
+ #define EXPECTED_PRISM_VERSION "0.26.0"
5
5
 
6
6
  #include <ruby.h>
7
7
  #include <ruby/encoding.h>
@@ -89,7 +89,6 @@ typedef enum {
89
89
  PM_ERR_DEF_ENDLESS,
90
90
  PM_ERR_DEF_ENDLESS_SETTER,
91
91
  PM_ERR_DEF_NAME,
92
- PM_ERR_DEF_NAME_AFTER_RECEIVER,
93
92
  PM_ERR_DEF_PARAMS_TERM,
94
93
  PM_ERR_DEF_PARAMS_TERM_PAREN,
95
94
  PM_ERR_DEF_RECEIVER,
@@ -126,6 +125,7 @@ typedef enum {
126
125
  PM_ERR_EXPECT_EXPRESSION_AFTER_STAR,
127
126
  PM_ERR_EXPECT_IDENT_REQ_PARAMETER,
128
127
  PM_ERR_EXPECT_LPAREN_REQ_PARAMETER,
128
+ PM_ERR_EXPECT_MESSAGE,
129
129
  PM_ERR_EXPECT_RBRACKET,
130
130
  PM_ERR_EXPECT_RPAREN,
131
131
  PM_ERR_EXPECT_RPAREN_AFTER_MULTI,
@@ -133,6 +133,14 @@ typedef enum {
133
133
  PM_ERR_EXPECT_STRING_CONTENT,
134
134
  PM_ERR_EXPECT_WHEN_DELIMITER,
135
135
  PM_ERR_EXPRESSION_BARE_HASH,
136
+ PM_ERR_EXPRESSION_NOT_WRITABLE,
137
+ PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING,
138
+ PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE,
139
+ PM_ERR_EXPRESSION_NOT_WRITABLE_FILE,
140
+ PM_ERR_EXPRESSION_NOT_WRITABLE_LINE,
141
+ PM_ERR_EXPRESSION_NOT_WRITABLE_NIL,
142
+ PM_ERR_EXPRESSION_NOT_WRITABLE_SELF,
143
+ PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE,
136
144
  PM_ERR_FLOAT_PARSE,
137
145
  PM_ERR_FOR_COLLECTION,
138
146
  PM_ERR_FOR_IN,
@@ -264,6 +272,7 @@ typedef enum {
264
272
  PM_ERR_TERNARY_EXPRESSION_TRUE,
265
273
  PM_ERR_UNARY_RECEIVER,
266
274
  PM_ERR_UNDEF_ARGUMENT,
275
+ PM_ERR_UNEXPECTED_BLOCK_ARGUMENT,
267
276
  PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT,
268
277
  PM_ERR_UNEXPECTED_TOKEN_IGNORE,
269
278
  PM_ERR_UNTIL_TERM,
@@ -299,7 +308,9 @@ typedef enum {
299
308
  PM_WARN_LITERAL_IN_CONDITION_VERBOSE,
300
309
  PM_WARN_SHEBANG_CARRIAGE_RETURN,
301
310
  PM_WARN_UNEXPECTED_CARRIAGE_RETURN,
311
+ PM_WARN_UNREACHABLE_STATEMENT,
302
312
  PM_WARN_UNUSED_LOCAL_VARIABLE,
313
+ PM_WARN_VOID_STATEMENT,
303
314
  } pm_diagnostic_id_t;
304
315
 
305
316
  /**
@@ -13,7 +13,6 @@
13
13
  #include "prism/util/pm_constant_pool.h"
14
14
  #include "prism/util/pm_list.h"
15
15
  #include "prism/util/pm_newline_list.h"
16
- #include "prism/util/pm_state_stack.h"
17
16
  #include "prism/util/pm_string.h"
18
17
 
19
18
  #include <stdbool.h>
@@ -612,6 +611,11 @@ static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_ALL = 0x40;
612
611
  static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_DISALLOWED = -1;
613
612
  static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_NONE = 0;
614
613
 
614
+ /**
615
+ * A struct that represents a stack of boolean values.
616
+ */
617
+ typedef uint32_t pm_state_stack_t;
618
+
615
619
  /**
616
620
  * This struct represents the overall parser. It contains a reference to the
617
621
  * source file, as well as pointers that indicate where in the source it's
@@ -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 25
17
+ #define PRISM_VERSION_MINOR 26
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.25.0"
27
+ #define PRISM_VERSION "0.26.0"
28
28
 
29
29
  #endif
@@ -73,6 +73,8 @@ module Prism
73
73
 
74
74
  # Desugar `x += y` to `x = x + y`
75
75
  def compile
76
+ operator_loc = node.operator_loc.chop
77
+
76
78
  write_class.new(
77
79
  source,
78
80
  *arguments,
@@ -82,8 +84,8 @@ module Prism
82
84
  0,
83
85
  read_class.new(source, *arguments, node.name_loc),
84
86
  nil,
85
- node.operator_loc.slice.chomp("=").to_sym,
86
- node.operator_loc.copy(length: node.operator_loc.length - 1),
87
+ operator_loc.slice.to_sym,
88
+ operator_loc,
87
89
  nil,
88
90
  ArgumentsNode.new(source, 0, [node.value], node.value.location),
89
91
  nil,
data/lib/prism/ffi.rb CHANGED
@@ -286,12 +286,22 @@ module Prism
286
286
  LibRubyParser::PrismString.with_string(code) { |string| parse_file_success_common(string, options) }
287
287
  end
288
288
 
289
+ # Mirror the Prism.parse_failure? API by using the serialization API.
290
+ def parse_failure?(code, **options)
291
+ !parse_success?(code, **options)
292
+ end
293
+
289
294
  # Mirror the Prism.parse_file_success? API by using the serialization API.
290
295
  def parse_file_success?(filepath, **options)
291
296
  options[:filepath] = filepath
292
297
  LibRubyParser::PrismString.with_file(filepath) { |string| parse_file_success_common(string, options) }
293
298
  end
294
299
 
300
+ # Mirror the Prism.parse_file_failure? API by using the serialization API.
301
+ def parse_file_failure?(filepath, **options)
302
+ !parse_file_success?(filepath, **options)
303
+ end
304
+
295
305
  private
296
306
 
297
307
  def dump_common(string, options) # :nodoc:
data/lib/prism/node.rb CHANGED
@@ -68,6 +68,17 @@ module Prism
68
68
  DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot
69
69
  end
70
70
 
71
+ # Returns a list of the fields that exist for this node class. Fields
72
+ # describe the structure of the node. This kind of reflection is useful for
73
+ # things like recursively visiting each node _and_ field in the tree.
74
+ def self.fields
75
+ # This method should only be called on subclasses of Node, not Node
76
+ # itself.
77
+ raise NoMethodError, "undefined method `fields' for #{inspect}" if self == Node
78
+
79
+ Reflection.fields_for(self)
80
+ end
81
+
71
82
  # --------------------------------------------------------------------------
72
83
  # :section: Node interface
73
84
  # These methods are effectively abstract methods that must be implemented by
@@ -110,6 +121,11 @@ module Prism
110
121
  def inspect(inspector = NodeInspector.new)
111
122
  raise NoMethodError, "undefined method `inspect' for #{inspect}"
112
123
  end
124
+
125
+ # Returns the type of the node as a symbol.
126
+ def self.type
127
+ raise NoMethodError, "undefined method `type' for #{inspect}"
128
+ end
113
129
  end
114
130
 
115
131
  # Represents the use of the `alias` keyword to alias a global variable.
@@ -161,6 +161,11 @@ module Prism
161
161
  Location.new(source, start_offset, length)
162
162
  end
163
163
 
164
+ # Returns a new location that is the result of chopping off the last byte.
165
+ def chop
166
+ copy(length: length == 0 ? length : length - 1)
167
+ end
168
+
164
169
  # Returns a string representation of this location.
165
170
  def inspect
166
171
  "#<Prism::Location @start_offset=#{@start_offset} @length=#{@length} start_line=#{start_line}>"